From d981159f04eb12a22a360b8c1b42a3129e9dc046 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Tue, 11 Apr 2023 22:12:25 +0100 Subject: [PATCH] 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. --- src/context.h | 1 + src/create_pdf.c | 8 +-- src/device.c | 1 + src/hpa_dco.c | 178 +++++++++++++++++++---------------------------- src/version.c | 4 +- 5 files changed, 79 insertions(+), 113 deletions(-) diff --git a/src/context.h b/src/context.h index e2275b1..bf5c4fc 100644 --- a/src/context.h +++ b/src/context.h @@ -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. diff --git a/src/create_pdf.c b/src/create_pdf.c index c3a9369..f7b7289 100644 --- a/src/create_pdf.c +++ b/src/create_pdf.c @@ -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" ); diff --git a/src/device.c b/src/device.c index 2feb6d9..23c3be7 100644 --- a/src/device.c +++ b/src/device.c @@ -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; diff --git a/src/hpa_dco.c b/src/hpa_dco.c index b55c9d2..705e27f 100644 --- a/src/hpa_dco.c +++ b/src/hpa_dco.c @@ -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; } diff --git a/src/version.c b/src/version.c index d0f062a..8fc3fd1 100644 --- a/src/version.c +++ b/src/version.c @@ -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 \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!";