HPA_DCO_012 Continuation of HPA/DCO integration

Simplified the code that determines whether a HPA/DCO
is present and in the process fixed some related bugs
to do with the HPA/DCO fields in the PDF document
displaying incorrect information in some drive specific
cases.
This commit is contained in:
PartialVolume
2023-04-11 22:12:25 +01:00
parent 3d2ba87967
commit d981159f04
5 changed files with 79 additions and 113 deletions

View File

@@ -94,6 +94,7 @@ typedef struct nwipe_context_t_
char device_name_without_path[100];
char gui_device_name[100];
unsigned long long device_size; // The device size in bytes.
u64 device_size_in_sectors; // The device size in sectors
unsigned long long bytes_erased; // Irrespective of pass, this how much of the drive has been erased, CANNOT be
// greater than device_size.
char* device_size_text; // The device size in a more (human)readable format.

View File

@@ -567,7 +567,7 @@ int create_pdf( nwipe_context_t* ptr )
{
if( c->HPA_status == HPA_ENABLED )
{
snprintf( HPA_status_text, sizeof( HPA_status_text ), "HIDDEN AREA FOUND!" );
snprintf( HPA_status_text, sizeof( HPA_status_text ), "Hidden sectors found!" );
pdf_set_font( pdf, "Helvetica-Bold" );
pdf_add_text( pdf, NULL, HPA_status_text, text_size_data, 130, 210, PDF_RED );
pdf_set_font( pdf, "Helvetica" );
@@ -576,7 +576,7 @@ int create_pdf( nwipe_context_t* ptr )
{
if( c->HPA_status == HPA_DISABLED )
{
snprintf( HPA_status_text, sizeof( HPA_status_text ), "NO HIDDEN AREA" );
snprintf( HPA_status_text, sizeof( HPA_status_text ), "No hidden sectors" );
pdf_set_font( pdf, "Helvetica-Bold" );
pdf_add_text( pdf, NULL, HPA_status_text, text_size_data, 130, 210, PDF_DARK_GREEN );
pdf_set_font( pdf, "Helvetica" );
@@ -585,7 +585,7 @@ int create_pdf( nwipe_context_t* ptr )
{
if( c->HPA_status == HPA_UNKNOWN )
{
snprintf( HPA_status_text, sizeof( HPA_status_text ), "STATUS UNKNOWN" );
snprintf( HPA_status_text, sizeof( HPA_status_text ), "Status unknown" );
pdf_set_font( pdf, "Helvetica-Bold" );
pdf_add_text( pdf, NULL, HPA_status_text, text_size_data, 130, 210, PDF_RED );
pdf_set_font( pdf, "Helvetica" );
@@ -594,7 +594,7 @@ int create_pdf( nwipe_context_t* ptr )
{
if( c->HPA_status == HPA_NOT_SUPPORTED_BY_DRIVE )
{
snprintf( HPA_status_text, sizeof( HPA_status_text ), "NO HIDDEN AREA **DDNSHDA" );
snprintf( HPA_status_text, sizeof( HPA_status_text ), "No hidden sectors **DDNSHDA" );
pdf_set_font( pdf, "Helvetica-Bold" );
pdf_add_text( pdf, NULL, HPA_status_text, text_size_data, 130, 210, PDF_DARK_GREEN );
pdf_set_font( pdf, "Helvetica" );

View File

@@ -220,6 +220,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;
next_device->device_size_in_sectors = next_device->device_size / next_device->device_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;

View File

@@ -247,7 +247,6 @@ int hpa_dco_status( nwipe_context_t* ptr )
{
if( strstr( result, "invalid" ) != 0 )
{
c->HPA_status = HPA_ENABLED;
nwipe_log(
NWIPE_LOG_WARNING,
"hdparm reports invalid output, sector information may be invalid, buggy "
@@ -277,6 +276,21 @@ int hpa_dco_status( nwipe_context_t* ptr )
c->HPA_reported_set = str_ascii_number_to_ll( result );
/* Check whether the number was too large or no number found & log */
if( c->HPA_reported_set == -1 )
{
nwipe_log( NWIPE_LOG_INFO, "HPA_set_value: HPA set value too large on %s", c->device_name );
c->HPA_reported_set = 0;
}
else
{
if( c->HPA_reported_set == -2 )
{
nwipe_log( NWIPE_LOG_INFO, "HPA_set_value: No HPA set value found %s", c->device_name );
c->HPA_reported_set = 0;
}
}
/* Extract the 'HPA real' value, the second value in the line and convert
* to binary and save in context, this is a little more difficult as sometimes
* a odd value is returned so instead of nnnnn/nnnnn you get nnnnnn/1(nnnnnn).
@@ -294,6 +308,22 @@ int hpa_dco_status( nwipe_context_t* ptr )
c->HPA_reported_real = str_ascii_number_to_ll( p + 1 );
}
}
/* Check whether the number was too large or no number found & log */
if( c->HPA_reported_real == -1 )
{
nwipe_log( NWIPE_LOG_INFO, "HPA_set_value: HPA real value too large on %s", c->device_name );
c->HPA_reported_real = 0;
}
else
{
if( c->HPA_reported_real == -2 )
{
nwipe_log( NWIPE_LOG_INFO, "HPA_set_value: No HPA real value found %s", c->device_name );
c->HPA_reported_real = 0;
}
}
nwipe_log( NWIPE_LOG_INFO,
"HPA values %lli / %lli on %s",
c->HPA_reported_set,
@@ -434,6 +464,11 @@ int hpa_dco_status( nwipe_context_t* ptr )
nwipe_log( NWIPE_LOG_INFO, "DCO Real max sectors not found" );
}
nwipe_log( NWIPE_LOG_INFO,
"libata: apparent max sectors reported as %lli on %s",
c->device_size_in_sectors,
c->device_name );
/* close */
r = pclose( fp );
if( r > 0 )
@@ -517,112 +552,34 @@ int hpa_dco_status( nwipe_context_t* ptr )
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 )
/* If any of the HPA or DCO values are larger than the apparent size then HPA is enabled. */
if( /*c->HPA_reported_set > c->device_size_in_sectors || */ c->HPA_reported_real > c->device_size_in_sectors
|| c->DCO_reported_real_max_sectors > c->device_size_in_sectors )
{
c->HPA_status = HPA_DISABLED;
c->HPA_status = HPA_ENABLED;
nwipe_log( NWIPE_LOG_WARNING, " *********************************" );
nwipe_log( NWIPE_LOG_WARNING, " *** HIDDEN SECTORS DETECTED ! *** on %s", c->device_name );
nwipe_log( NWIPE_LOG_WARNING, " *********************************" );
}
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
&& c->DCO_reported_real_max_sectors != 0 )
/* 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->DCO_reported_real_max_sectors <= 1 )
{
c->HPA_status = HPA_UNKNOWN;
if( c->device_bus == NWIPE_DEVICE_USB )
{
nwipe_log( NWIPE_LOG_WARNING,
"HIDDEN SECTORS INDETERMINATE! on %s, Some USB adapters & memory sticks don't support "
"ATA pass through",
c->device_name );
}
}
else
{
c->HPA_status = HPA_DISABLED;
}
else
{
if( c->DCO_reported_real_max_sectors > 0 && c->DCO_reported_real_max_sectors == ( c->device_size / 512 ) )
{
c->HPA_status = HPA_DISABLED;
}
else
{
if( c->DCO_reported_real_max_sectors > 0
&& c->DCO_reported_real_max_sectors != ( c->device_size / 512 ) )
{
c->HPA_status = HPA_ENABLED;
}
else
{
if( c->HPA_reported_set == c->HPA_reported_real && c->DCO_reported_real_max_sectors == 0 )
{
c->HPA_status = HPA_NOT_APPLICABLE;
}
else
{
if( c->HPA_reported_set != c->DCO_reported_real_max_sectors && c->HPA_reported_set != 0 )
{
c->HPA_status = HPA_ENABLED;
}
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 )
{
c->HPA_status = HPA_UNKNOWN;
}
else
{
/* 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;
}
}
}
}
}
}
}
}
}
if( c->HPA_status == HPA_DISABLED )
{
nwipe_log( NWIPE_LOG_INFO, "No hidden sectors on %s", c->device_name );
}
else
{
if( c->HPA_status == HPA_ENABLED )
{
nwipe_log( NWIPE_LOG_WARNING, " *********************************" );
nwipe_log( NWIPE_LOG_WARNING, " *** HIDDEN SECTORS DETECTED ! *** on %s", c->device_name );
nwipe_log( NWIPE_LOG_WARNING, " *********************************" );
}
else
{
if( c->HPA_status == HPA_UNKNOWN )
{
if( c->device_bus == NWIPE_DEVICE_USB )
nwipe_log( NWIPE_LOG_WARNING,
"HIDDEN SECTORS INDETERMINATE! on %s, Some USB adapters & memory sticks don't support "
"ATA pass through",
c->device_name );
else
{
if( c->HPA_status == HPA_NOT_APPLICABLE )
{
nwipe_log( NWIPE_LOG_WARNING, "%s may not support HPA/DCO", c->device_name );
}
else
{
nwipe_log(
NWIPE_LOG_SANITY, "Unrecognised HPA_status, should not be possible %s", c->device_name );
}
}
}
nwipe_log( NWIPE_LOG_INFO, "No hidden sectors on %s", c->device_name );
}
}
@@ -649,9 +606,10 @@ int hpa_dco_status( nwipe_context_t* ptr )
}
else
{
/* If the DCO is reporting a real max sectors > 1 then that is what we will use as the real disc size
/* If the DCO is reporting a real max sectors > the apparent size
* as reported by libata then that is what we will use as the real disc size
*/
if( c->DCO_reported_real_max_size > 1 )
if( c->DCO_reported_real_max_size > c->device_size_in_sectors )
{
c->Calculated_real_max_size_in_bytes = c->DCO_reported_real_max_sectors * c->device_sector_size;
}
@@ -661,13 +619,13 @@ int hpa_dco_status( nwipe_context_t* ptr )
* 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 )
if( c->HPA_reported_real > c->device_size_in_sectors )
{
c->Calculated_real_max_size_in_bytes = c->HPA_reported_real * c->device_sector_size;
}
else
{
if( c->HPA_reported_set > 0 )
if( c->HPA_reported_set > c->device_size_in_sectors )
{
c->Calculated_real_max_size_in_bytes = c->HPA_reported_set * c->device_sector_size;
}
@@ -707,13 +665,19 @@ int hpa_dco_status( nwipe_context_t* ptr )
nwipe_log( NWIPE_LOG_DEBUG,
"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->DCO_reported_real_max_size=%lli, c->DCO_reported_real_max_sectors=%lli, c->HPA_sectors=%lli, "
"c->HPA_reported_set=%lli, c->HPA_reported_real=%lli, c->device_type=%i, "
"libata:c->device_size_in_sectors=%lli ",
c->Calculated_real_max_size_in_bytes,
c->device_size,
c->device_sector_size,
c->DCO_reported_real_max_size,
c->DCO_reported_real_max_sectors,
c->HPA_sectors,
c->device_type );
c->HPA_reported_set,
c->HPA_reported_real,
c->device_type,
c->device_size_in_sectors );
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.84 Development code, not for production use!";
const char* version_string = "0.34.85 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.84 Development code, not for production use!";
const char* banner = "nwipe 0.34.85 Development code, not for production use!";