Merge pull request #460 from PartialVolume/HPA_DCO_008

HPA_DCO_008 continuation of HPA/DCO integration.
This commit is contained in:
PartialVolume
2023-04-03 23:19:20 +01:00
committed by GitHub
5 changed files with 217 additions and 51 deletions

View File

@@ -164,9 +164,12 @@ typedef struct nwipe_context_t_
int DCO_status; // 0 = No DCO found, 1 = DCO detected, 2 = Unknown, unable to checked
u64 DCO_reported_real_max_sectors; // real max sectors as reported by hdparm --dco-identify
u64 DCO_reported_real_max_size; // real max sectors in bytes
u64 Calculated_real_max_size_in_bytes; // This value is determined from all the possible variations for drives that
// don't support DCO/HPA and those that do. Also drives that can't provide
// HPA/DCO due to the chips they use (USB adapters)
char DCO_reported_real_max_size_text[NWIPE_DEVICE_SIZE_TXT_LENGTH]; // real max size in human readable form i.e 1TB
// etc
u64 HPA_size; // The size of the host protected area in sectors
u64 HPA_sectors; // The size of the host protected area in sectors
char HPA_size_text[NWIPE_DEVICE_SIZE_TXT_LENGTH]; // Human readable size bytes, KB, MB, GB ..
int HPA_display_toggle_state; // 0 or 1 Used to toggle between "[1TB] [ 33C]" and [HDA STATUS]
time_t HPA_toggle_time; // records a time, then if for instance 3 seconds has elapsed the display changes

View File

@@ -188,8 +188,8 @@ int create_pdf( nwipe_context_t* ptr )
pdf_add_text( pdf, NULL, "Size(Apparent): ", 12, 60, 390, PDF_GRAY );
pdf_set_font( pdf, "Helvetica-Bold" );
snprintf( device_size, sizeof( device_size ), "%s, %lli bytes", c->device_size_text, c->device_size );
if( c->device_size == c->DCO_reported_real_max_size || !strcmp( c->device_type_str, "NVME" )
|| !strcmp( c->device_type_str, "VIRT" ) )
if( ( c->device_size == c->DCO_reported_real_max_size ) || c->device_type == NWIPE_DEVICE_NVME
|| c->device_type == NWIPE_DEVICE_VIRT || c->HPA_status == HPA_NOT_APPLICABLE )
{
pdf_add_text( pdf, NULL, device_size, text_size_data, 145, 390, PDF_DARK_GREEN );
}
@@ -202,7 +202,7 @@ int create_pdf( nwipe_context_t* ptr )
/* Size (Real) */
pdf_add_text( pdf, NULL, "Size(Real):", 12, 60, 370, PDF_GRAY );
pdf_set_font( pdf, "Helvetica-Bold" );
if( !strcmp( c->device_type_str, "NVME" ) || !strcmp( c->device_type_str, "VIRT" )
if( c->device_type == NWIPE_DEVICE_NVME || c->device_type == NWIPE_DEVICE_VIRT
|| c->HPA_status == HPA_NOT_APPLICABLE )
{
snprintf( device_size, sizeof( device_size ), "%s, %lli bytes", c->device_size_text, c->device_size );
@@ -231,6 +231,26 @@ int create_pdf( nwipe_context_t* ptr )
snprintf( device_size, sizeof( device_size ), "Unknown" );
pdf_add_text( pdf, NULL, device_size, text_size_data, 125, 370, PDF_RED );
}
else
{
/* we are already here because c->DCO_reported_real_max_size < 1 so if HPA enabled then use the
* value we determine from whether HPA set, HPA real exist and if not assume libata's value*/
if( c->HPA_status == HPA_ENABLED )
{
snprintf( device_size,
sizeof( device_size ),
"%s, %lli bytes",
c->device_size_text,
c->Calculated_real_max_size_in_bytes );
pdf_add_text( pdf, NULL, device_size, text_size_data, 125, 370, PDF_DARK_GREEN );
}
else
{
/* Sanity check, should never get here! */
snprintf( device_size, sizeof( device_size ), "Sanity: HPA_status = %i", c->HPA_status );
pdf_add_text( pdf, NULL, device_size, text_size_data, 125, 370, PDF_RED );
}
}
}
}
@@ -285,8 +305,8 @@ int create_pdf( nwipe_context_t* ptr )
pdf_set_font( pdf, "Helvetica-Bold" );
if( !strcmp( c->wipe_status_txt, "ERASED" )
&& ( c->HPA_status == HPA_DISABLED || !strcmp( c->device_type_str, "NVME" )
|| !strcmp( c->device_type_str, "VIRT" ) ) )
&& ( c->HPA_status == HPA_DISABLED || c->HPA_status == HPA_NOT_APPLICABLE || c->device_type == NWIPE_DEVICE_NVME
|| c->device_type == NWIPE_DEVICE_VIRT ) )
{
pdf_add_text( pdf, NULL, c->wipe_status_txt, 12, 365, 290, PDF_DARK_GREEN );
pdf_add_ellipse( pdf, NULL, 390, 295, 45, 10, 2, PDF_DARK_GREEN, PDF_TRANSPARENT );
@@ -327,7 +347,7 @@ int create_pdf( nwipe_context_t* ptr )
pdf_add_image_data( pdf, NULL, 450, 665, 100, 100, bin2c_redcross_jpg, 60331 );
status_icon = STATUS_ICON_RED_CROSS; // used later on page 2
}
pdf_add_ellipse( pdf, NULL, 390, 275, 45, 10, 2, PDF_RED, PDF_TRANSPARENT );
pdf_add_ellipse( pdf, NULL, 390, 295, 45, 10, 2, PDF_RED, PDF_TRANSPARENT );
}
}
pdf_set_font( pdf, "Helvetica" );
@@ -430,6 +450,43 @@ int create_pdf( nwipe_context_t* ptr )
}
else
{
if( c->device_type == NWIPE_DEVICE_NVME || c->device_type == NWIPE_DEVICE_VIRT
|| c->HPA_status == HPA_NOT_APPLICABLE )
{
snprintf( bytes_erased,
sizeof( bytes_erased ),
"%lli, (%.1f%%)",
c->bytes_erased,
(float) ( (float) c->bytes_erased / (float) ( (float) c->device_size ) ) * 100 );
if( c->bytes_erased == c->device_size )
{
pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN );
}
else
{
pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_RED );
}
}
else
{
snprintf( bytes_erased,
sizeof( bytes_erased ),
"%lli, %lli, (%.1f%%)",
c->bytes_erased,
c->Calculated_real_max_size_in_bytes,
(double) ( (double) c->bytes_erased / (double) ( (double) c->Calculated_real_max_size_in_bytes ) )
* 100 );
if( c->bytes_erased == c->Calculated_real_max_size_in_bytes )
{
pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN );
}
else
{
pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_RED );
}
}
#if 0
/* Use real max sectors taken from DCO if not zero */
if( c->DCO_reported_real_max_sectors != 0 )
{
@@ -438,9 +495,9 @@ int create_pdf( nwipe_context_t* ptr )
sizeof( bytes_erased ),
"%lli (%.1f%%)",
c->bytes_erased,
(double) ( (double) c->bytes_erased / (double) ( (double) c->DCO_reported_real_max_sectors * 512 ) )
(double) ( (double) c->bytes_erased / (double) ( (double) c->DCO_reported_real_max_sectors * c->device_sector_size ) )
* 100 );
if( c->bytes_erased == ( c->DCO_reported_real_max_sectors * 512 ) )
if( c->bytes_erased == ( c->DCO_reported_real_max_sectors * c->device_sector_size ) )
{
pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_DARK_GREEN );
}
@@ -467,6 +524,7 @@ int create_pdf( nwipe_context_t* ptr )
pdf_add_text( pdf, NULL, bytes_erased, text_size_data, 145, 230, PDF_RED );
}
}
#endif
}
pdf_set_font( pdf, "Helvetica" );
@@ -499,40 +557,49 @@ int create_pdf( nwipe_context_t* ptr )
/*******************
* Populate HPA size
*/
pdf_set_font( pdf, "Helvetica-Bold" );
if( c->HPA_status == HPA_ENABLED )
{
snprintf( HPA_size_text, sizeof( HPA_size_text ), "%lli sectors", c->HPA_size );
snprintf( HPA_size_text, sizeof( HPA_size_text ), "%lli sectors", c->HPA_sectors );
pdf_add_text( pdf, NULL, HPA_size_text, text_size_data, 390, 210, PDF_RED );
}
else
{
if( c->HPA_status == HPA_DISABLED )
{
snprintf( HPA_size_text, sizeof( HPA_size_text ), "Zero sectors" );
snprintf( HPA_size_text, sizeof( HPA_size_text ), "No hidden sectors" );
pdf_add_text( pdf, NULL, HPA_size_text, text_size_data, 390, 210, PDF_DARK_GREEN );
}
else
{
if( c->HPA_status == HPA_UNKNOWN )
if( c->HPA_status == HPA_NOT_APPLICABLE )
{
snprintf( HPA_size_text, sizeof( HPA_size_text ), "UNKNOWN" );
pdf_add_text( pdf, NULL, HPA_size_text, text_size_data, 390, 210, PDF_RED );
snprintf( HPA_size_text, sizeof( HPA_size_text ), "Not Applicable" );
pdf_add_text( pdf, NULL, HPA_size_text, text_size_data, 390, 210, PDF_DARK_GREEN );
}
else
{
if( c->HPA_status == HPA_UNKNOWN )
{
snprintf( HPA_size_text, sizeof( HPA_size_text ), "UNKNOWN" );
pdf_add_text( pdf, NULL, HPA_size_text, text_size_data, 390, 210, PDF_RED );
}
}
}
}
pdf_set_font( pdf, "Helvetica" );
/*********************
* Populate HPA status (and size if not applicable, NVMe and VIRT)
*/
if( !strcmp( c->device_type_str, "NVME" ) || !strcmp( c->device_type_str, "VIRT" ) )
if( c->device_type == NWIPE_DEVICE_NVME || c->device_type == NWIPE_DEVICE_VIRT
|| c->HPA_status == HPA_NOT_APPLICABLE )
{
snprintf( HPA_status_text, sizeof( HPA_status_text ), "Not applicable to %s", c->device_type_str );
snprintf( HPA_status_text, sizeof( HPA_status_text ), "Not applicable" );
pdf_set_font( pdf, "Helvetica-Bold" );
pdf_add_text( pdf, NULL, HPA_status_text, text_size_data, 130, 210, PDF_DARK_GREEN );
snprintf( HPA_size_text, sizeof( HPA_size_text ), "Not applicable to %s", c->device_type_str );
pdf_add_text( pdf, NULL, HPA_size_text, text_size_data, 400, 210, PDF_DARK_GREEN );
pdf_set_font( pdf, "Helvetica" );
}
else

View File

@@ -219,6 +219,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
}
next_device->device_size = dev->length * dev->sector_size;
next_device->device_sector_size = dev->sector_size;
Determine_C_B_nomenclature( next_device->device_size, next_device->device_size_txt, NWIPE_DEVICE_SIZE_TXT_LENGTH );
next_device->device_size_text = next_device->device_size_txt;
next_device->result = -2;
@@ -294,6 +295,9 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
*/
check_HPA = 0;
// WARNING TEMP LINE WARNING
// next_device->device_type = NWIPE_DEVICE_ATA;
switch( next_device->device_type )
{
case NWIPE_DEVICE_UNKNOWN:

View File

@@ -462,7 +462,27 @@ int hpa_dco_status( nwipe_context_t* ptr )
* HPA_ENABLED, HPA_UNKNOWN or HPA_NOT_APPLICABLE. The HPA flag
* will be displayed in the GUI and on the certificate and is
* used to determine whether to reset the HPA.
*
*/
/* WARNING temp assignments WARNING
* s=28,r=28,rm=0
*
*/
#if 0
c->HPA_reported_set = 10;
c->HPA_reported_real = 28;
c->DCO_reported_real_max_sectors = 0;
c->HPA_reported_set = 28;
c->HPA_reported_real = 28;
c->DCO_reported_real_max_sectors = 0;
c->HPA_reported_set = 1000;
c->HPA_reported_real = 2048;
c->DCO_reported_real_max_sectors = 2048;
#endif
/* If all three values match and none are zero then there is NO hidden disc area. HPA is disabled. */
if( c->HPA_reported_set == c->HPA_reported_real && c->DCO_reported_real_max_sectors == c->HPA_reported_set
&& c->HPA_reported_set != 0 && c->HPA_reported_real != 0 && c->DCO_reported_real_max_sectors != 0 )
@@ -472,39 +492,47 @@ int hpa_dco_status( nwipe_context_t* ptr )
else
{
/* If HPA set and DCO max sectors are equal it can also be considered that HPA is disabled */
if( ( c->HPA_reported_set == c->DCO_reported_real_max_sectors ) && c->HPA_reported_set != 0 )
if( ( c->HPA_reported_set == c->DCO_reported_real_max_sectors ) && c->HPA_reported_set != 0
&& c->DCO_reported_real_max_sectors != 0 )
{
c->HPA_status = HPA_DISABLED;
}
else
{
if( c->HPA_reported_set != c->DCO_reported_real_max_sectors && c->HPA_reported_set != 0 )
if( c->HPA_reported_set == c->HPA_reported_real && c->DCO_reported_real_max_sectors == 0 )
{
c->HPA_status = HPA_ENABLED;
c->HPA_status = HPA_NOT_APPLICABLE;
}
else
{
/* This occurs when a SG_IO error occurs with USB devices that don't support ATA pass through */
if( c->HPA_reported_set == 0 && c->HPA_reported_real == 1 )
if( c->HPA_reported_set != c->DCO_reported_real_max_sectors && c->HPA_reported_set != 0 )
{
c->HPA_status = HPA_UNKNOWN;
c->HPA_status = HPA_ENABLED;
}
else
{
/* NVMe drives don't support HPA/DCO */
if( !strcmp( c->device_type_str, "NVME" )
|| ( c->HPA_reported_set > 1 && c->DCO_reported_real_max_sectors < 2 ) )
/* This occurs when a SG_IO error occurs with USB devices that don't support ATA pass through */
if( c->HPA_reported_set == 0 && c->HPA_reported_real == 1 )
{
c->HPA_status = HPA_NOT_APPLICABLE;
c->HPA_status = HPA_UNKNOWN;
}
else
{
/* For recent enterprise and new drives that don't provide HPA/DCO anymore */
if( c->HPA_reported_set > 0 && c->HPA_reported_real == 1
&& c->DCO_reported_real_max_sectors < 2 )
/* NVMe drives don't support HPA/DCO */
if( c->device_type == NWIPE_DEVICE_NVME || c->device_type == NWIPE_DEVICE_VIRT
|| ( c->HPA_reported_set > 1 && c->DCO_reported_real_max_sectors < 2 ) )
{
c->HPA_status = HPA_NOT_APPLICABLE;
}
else
{
/* For recent enterprise and new drives that don't provide HPA/DCO anymore */
if( c->HPA_reported_set > 0 && c->HPA_reported_real == 1
&& c->DCO_reported_real_max_sectors < 2 )
{
c->HPA_status = HPA_NOT_APPLICABLE;
}
}
}
}
}
@@ -548,31 +576,95 @@ int hpa_dco_status( nwipe_context_t* ptr )
}
}
/* Determine the size of the HPA if it's enabled and store the results in the context.*/
if( c->HPA_status == HPA_ENABLED )
{
c->HPA_size = c->DCO_reported_real_max_sectors - c->HPA_reported_set;
/* Convert the size to a human readable format and save in context */
Determine_C_B_nomenclature( c->HPA_size, c->HPA_size_text, NWIPE_DEVICE_SIZE_TXT_LENGTH );
}
else
{
/* HPA not enabled so initialise these values */
c->HPA_size = 0;
c->HPA_size_text[0] = 0;
}
/* create two variables for later use based on real max sectors
* DCO_reported_real_max_size = real max sectors * 512 = bytes
/* -------------------------------------------------------------------
* create two variables for later use based on real max sectors
* DCO_reported_real_max_size = real max sectors * sector size = bytes
* DCO_reported_real_max_size_text = human readable string, i.e 1TB etc.
*/
c->DCO_reported_real_max_size = c->DCO_reported_real_max_sectors * 512;
c->DCO_reported_real_max_size = c->DCO_reported_real_max_sectors * c->device_sector_size;
Determine_C_B_nomenclature(
c->DCO_reported_real_max_size, c->DCO_reported_real_max_size_text, NWIPE_DEVICE_SIZE_TXT_LENGTH );
nwipe_dco_real_max_sectors = nwipe_read_dco_real_max_sectors( c->device_name );
/* Analyse all the variations to produce the final real max bytes which takes into
* account drives that don't support DCO or HPA. This result is used in the PDF
* creation functions.
*/
if( c->device_type == NWIPE_DEVICE_NVME || c->device_type == NWIPE_DEVICE_VIRT
|| c->HPA_status == HPA_NOT_APPLICABLE )
{
c->Calculated_real_max_size_in_bytes = c->device_size;
}
else
{
/* If the DCO is reporting a real max sectors > 1 then that is what we will use as the real disc size
*/
if( c->DCO_reported_real_max_size > 1 )
{
c->Calculated_real_max_size_in_bytes = c->DCO_reported_real_max_sectors * c->device_sector_size;
}
else
{
/* If HPA is enabled and DCO real max sectors did not exist, then we have to assume - c->HPA_reported_real
* is the value we need, however if that is zero, then c->HPA_reported_set and if that is zero then
* c->device_size as reported by libata
*/
if( c->HPA_reported_real > 0 )
{
c->Calculated_real_max_size_in_bytes = c->HPA_reported_real * c->device_sector_size;
}
else
{
if( c->HPA_reported_set > 0 )
{
c->Calculated_real_max_size_in_bytes = c->HPA_reported_set * c->device_sector_size;
}
else
{
c->Calculated_real_max_size_in_bytes = c->device_size;
}
}
}
}
/* ----------------------------------------------------------------------------------
* Determine the size of the HPA if it's enabled and store the results in the context
*/
if( c->HPA_status == HPA_ENABLED )
{
if( c->Calculated_real_max_size_in_bytes != c->device_size )
{
c->HPA_sectors =
( (u64) ( c->Calculated_real_max_size_in_bytes - c->device_size ) / c->device_sector_size );
}
else
{
c->HPA_sectors = 0;
}
/* Convert the size to a human readable format and save in context */
Determine_C_B_nomenclature( c->HPA_sectors, c->HPA_size_text, NWIPE_DEVICE_SIZE_TXT_LENGTH );
}
else
{
/* HPA not enabled so initialise these values */
c->HPA_sectors = 0;
c->HPA_size_text[0] = 0;
}
nwipe_log( NWIPE_LOG_INFO,
"c->Calculated_real_max_size_in_bytes=%lli, c->device_size=%lli, c->device_sector_size=%lli, "
"c->DCO_reported_real_max_size=%lli, c->HPA_sectors=%lli c->device_type=%i ",
c->Calculated_real_max_size_in_bytes,
c->device_size,
c->device_sector_size,
c->DCO_reported_real_max_size,
c->HPA_sectors,
c->device_type );
return set_return_value;
}

View File

@@ -4,7 +4,7 @@
* used by configure to dynamically assign those values
* to documentation files.
*/
const char* version_string = "0.34.81 Development code, not for production use!";
const char* version_string = "0.34.82 Development code, not for production use!";
const char* program_name = "nwipe";
const char* author_name = "Martijn van Brummelen";
const char* email_address = "git@brumit.nl";
@@ -14,4 +14,4 @@ Modifications to original dwipe Copyright Andy Beverley <andy@andybev.com>\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS\n\
FOR A PARTICULAR PURPOSE.\n";
const char* banner = "nwipe 0.34.81 Development code, not for production use!";
const char* banner = "nwipe 0.34.82 Development code, not for production use!";