From 8abab96a3e24d2205dea47b4bfc5a88cf4d19193 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Tue, 28 Feb 2023 23:48:17 +0000 Subject: [PATCH] HPA_DCO_003 - Add HPA,DCO capability 1. For devices that support HPA/DCO (not NVMe) nwipe displays the HPA status, it toggles every two seconds the size and the temperature i.e "[ 1TB][ 35C]" with the HPA status such as [HPA disabled], [HPA ENABLED!], [HPA unknown]. The HPA ENABLED is highlighted with red text and a white background. HPA_disabled is standard white text on blue background. More code to follow, a new option to be added, HPA, disable/enable which will disable the HPA and shut down the system. On manually powering back up the HPA should be reported as disabled. Then lots of testing. --- src/context.h | 5 +- src/create_pdf.c | 9 ++-- src/device.c | 12 +++++ src/gui.c | 117 ++++++++++++++++++++++++++++++++++------------ src/hpa_dco.c | 14 ++++-- src/hpa_dco.h | 1 + src/nwipe.c | 3 ++ src/temperature.c | 1 + 8 files changed, 124 insertions(+), 38 deletions(-) diff --git a/src/context.h b/src/context.h index 15e3aac..27c5547 100644 --- a/src/context.h +++ b/src/context.h @@ -157,13 +157,16 @@ typedef struct nwipe_context_t_ time_t end_time; // End time of wipe u64 fsyncdata_errors; // The number of fsyncdata errors across all passes. char PDF_filename[256]; // The filename of the PDF certificate/report. - int HPA_status; // 0 = No HPA found/disabled, 1 = HPA detected, 2 = Unknown, unable to checked + int HPA_status; // 0 = No HPA found/disabled, 1 = HPA detected, 2 = Unknown, unable to checked, + // 3 = Not applicable to this device u64 HPA_reported_set; // the 'HPA set' value reported hdparm -N, i.e the first value of n/n u64 HPA_reported_real; // the 'HPA real' value reported hdparm -N, i.e the second value of n/n 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 HPA_size; // 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 /* * Identity contains the raw serial number of the drive diff --git a/src/create_pdf.c b/src/create_pdf.c index aac51ed..197e9f4 100644 --- a/src/create_pdf.c +++ b/src/create_pdf.c @@ -376,14 +376,15 @@ int create_pdf( nwipe_context_t* ptr ) pdf_set_font( pdf, "Helvetica" ); /********************* - * Populate HPA status + * Populate HPA status (and size if not applicable, NVMe and VIRT) */ - if( !strcmp( c->device_type_str, "NVME" ) ) + if( !strcmp( c->device_type_str, "NVME" ) || !strcmp( c->device_type_str, "VIRT" ) ) { - snprintf( HPA_status_text, sizeof( HPA_status_text ), "Not applicable to NVME" ); - snprintf( HPA_size_text, sizeof( HPA_size_text ), "Not applicable to NVME" ); + snprintf( HPA_status_text, sizeof( HPA_status_text ), "Not applicable to %s", c->device_type_str ); pdf_set_font( pdf, "Helvetica-Bold" ); pdf_add_text( pdf, NULL, HPA_status_text, 12, 95, 190, 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, 12, 360, 190, PDF_DARK_GREEN ); pdf_set_font( pdf, "Helvetica" ); } else diff --git a/src/device.c b/src/device.c index 1b30800..fb71f6c 100644 --- a/src/device.c +++ b/src/device.c @@ -288,6 +288,18 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount ) } } + /* Initialise the variables that toggle the [size][temp c] with [HPA status] + */ + next_device->HPA_toggle_time = time( NULL ); + next_device->HPA_display_toggle_state = 0; + + /* Initialise the HPA variables for this device + */ + next_device->HPA_reported_set = 0; + next_device->HPA_reported_real = 0; + next_device->DCO_reported_real_max_sectors = 0; + next_device->HPA_status = HPA_NOT_APPLICABLE; + /* All device strings should be 4 characters, prefix with space if under 4 characters * We also set a switch for certain devices to check for the host protected area (HPA) */ diff --git a/src/gui.c b/src/gui.c index 8f6f685..3b9ec54 100644 --- a/src/gui.c +++ b/src/gui.c @@ -44,6 +44,7 @@ #include "version.h" #include "temperature.h" #include "miscellaneous.h" +#include "hpa_dco.h" #define NWIPE_GUI_PANE 8 @@ -742,48 +743,43 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) if( nwipe_options.method == &nwipe_verify_zero || nwipe_options.method == &nwipe_verify_one ) { wprintw( main_window, - "[vrfy] %s %s [%s] ", + "[vrfy] %s %s ", c[i + offset]->gui_device_name, - c[i + offset]->device_type_str, - c[i + offset]->device_size_text ); + c[i + offset]->device_type_str ); } else { wprintw( main_window, - "[wipe] %s %s [%s] ", + "[wipe] %s %s ", c[i + offset]->gui_device_name, - c[i + offset]->device_type_str, - c[i + offset]->device_size_text ); + c[i + offset]->device_type_str ); } break; case NWIPE_SELECT_FALSE: /* Print an element that is not selected. */ wprintw( main_window, - "[ ] %s %s [%s] ", + "[ ] %s %s ", c[i + offset]->gui_device_name, - c[i + offset]->device_type_str, - c[i + offset]->device_size_text ); + c[i + offset]->device_type_str ); break; case NWIPE_SELECT_TRUE_PARENT: /* This element will be wiped when its parent is wiped. */ wprintw( main_window, - "[****] %s %s [%s] ", + "[****] %s %s ", c[i + offset]->gui_device_name, - c[i + offset]->device_type_str, - c[i + offset]->device_size_text ); + c[i + offset]->device_type_str ); break; case NWIPE_SELECT_FALSE_CHILD: /* We can't wipe this element because it has a child that is being wiped. */ wprintw( main_window, - "[----] %s %s [%s] ", + "[----] %s %s ", c[i + offset]->gui_device_name, - c[i + offset]->device_type_str, - c[i + offset]->device_size_text ); + c[i + offset]->device_type_str ); break; case NWIPE_SELECT_DISABLED: @@ -799,14 +795,72 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) } /* switch select */ - /* Read the drive temperature values */ - nwipe_update_temperature( c[i + offset] ); + /* Toggle the [size][temp C] with [HDA Status] + */ + switch( c[i + offset]->HPA_display_toggle_state ) + { + case 0: + wprintw( main_window, "[%s] ", c[i + offset]->device_size_text ); - /* print the temperature */ - wprintw_temperature( c[i + offset] ); + /* Read the drive temperature values */ + nwipe_update_temperature( c[i + offset] ); + + /* print the temperature */ + wprintw_temperature( c[i + offset] ); + break; + + case 1: + switch( c[i + offset]->HPA_status ) + { + case HPA_ENABLED: + wattron( main_window, COLOR_PAIR( 9 ) ); + wprintw( main_window, "[HDA ENABLED!]" ); + wattroff( main_window, COLOR_PAIR( 9 ) ); + break; + + case HPA_DISABLED: + wprintw( main_window, "[HDA disabled]" ); + break; + + case HPA_UNKNOWN: + wattron( main_window, COLOR_PAIR( 9 ) ); + wprintw( main_window, "[HDA unknown ]" ); + wattroff( main_window, COLOR_PAIR( 9 ) ); + break; + + case HPA_NOT_APPLICABLE: + wprintw( main_window, "[%s] ", c[i + offset]->device_size_text ); + + /* Read the drive temperature values */ + nwipe_update_temperature( c[i + offset] ); + + /* print the temperature */ + wprintw_temperature( c[i + offset] ); + break; + + default: + + break; + } + } + + if( c[i + offset]->HPA_toggle_time + 1 < time( NULL ) ) + { + switch( c[i + offset]->HPA_display_toggle_state ) + { + case 0: + c[i + offset]->HPA_display_toggle_state = 1; + break; + + case 1: + c[i + offset]->HPA_display_toggle_state = 0; + break; + } + c[i + offset]->HPA_toggle_time = time( NULL ); + } /* print the drive model and serial number */ - wprintw( main_window, "%s/%s", c[i + offset]->device_model, c[i + offset]->device_serial_no ); + wprintw( main_window, " %s/%s", c[i + offset]->device_model, c[i + offset]->device_serial_no ); } else { @@ -1278,8 +1332,11 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) * this change and exits the valid key hit loop so the windows can be updated */ getmaxyx( stdscr, stdscr_lines, stdscr_cols ); - /* Update the selection window every 60 seconds specifically so that the drive temperatures are updated */ - if( time( NULL ) > ( temperature_check_time + 60 ) ) + /* Update the selection window every 1 second specifically + * so that the drive temperatures are updated and also the line toggle that + * occurs with the HPA status and the drive size & temperature. + */ + if( time( NULL ) > ( temperature_check_time + 1 ) ) { temperature_check_time = time( NULL ); validkeyhit = 1; @@ -3225,14 +3282,14 @@ void wprintw_temperature( nwipe_context_t* c ) { /* blue on blue */ wattron( main_window, COLOR_PAIR( 12 ) ); - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); wattroff( main_window, COLOR_PAIR( 12 ) ); } else { /* red on blue */ wattron( main_window, COLOR_PAIR( 3 ) ); - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); wattroff( main_window, COLOR_PAIR( 3 ) ); } } @@ -3245,7 +3302,7 @@ void wprintw_temperature( nwipe_context_t* c ) { /* red on blue */ wattron( main_window, COLOR_PAIR( 3 ) ); - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); wattroff( main_window, COLOR_PAIR( 3 ) ); } else @@ -3258,14 +3315,14 @@ void wprintw_temperature( nwipe_context_t* c ) { /* blue on blue */ wattron( main_window, COLOR_PAIR( 12 ) ); - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); wattroff( main_window, COLOR_PAIR( 12 ) ); } else { /* black on blue */ wattron( main_window, COLOR_PAIR( 11 ) ); - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); wattroff( main_window, COLOR_PAIR( 11 ) ); } } @@ -3277,13 +3334,13 @@ void wprintw_temperature( nwipe_context_t* c ) { /* black on blue */ wattron( main_window, COLOR_PAIR( 11 ) ); - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); wattroff( main_window, COLOR_PAIR( 11 ) ); } else { /* Default white on blue */ - wprintw( main_window, "[%dC] ", c->temp1_input ); + wprintw( main_window, "[%dC]", c->temp1_input ); } } } @@ -3291,6 +3348,6 @@ void wprintw_temperature( nwipe_context_t* c ) } else { - wprintw( main_window, "[--C] " ); + wprintw( main_window, "[--C]" ); } } diff --git a/src/hpa_dco.c b/src/hpa_dco.c index c0e5d7a..b9fd3b1 100644 --- a/src/hpa_dco.c +++ b/src/hpa_dco.c @@ -371,23 +371,31 @@ int hpa_dco_status( nwipe_context_t* ptr ) * to reset the HPA. */ /* If all three values match 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 ) + 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_status = HPA_DISABLED; } 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 ) + if( ( c->HPA_reported_set == c->DCO_reported_real_max_sectors ) && c->HPA_reported_set != 0 ) { c->HPA_status = HPA_DISABLED; } else { - if( c->HPA_reported_set != c->DCO_reported_real_max_sectors ) + if( c->HPA_reported_set != c->DCO_reported_real_max_sectors && c->HPA_reported_set != 0 ) { c->HPA_status = HPA_ENABLED; } + else + { + if( !strcmp( c->device_type_str, "NVME" ) ) + { + c->HPA_status = HPA_NOT_APPLICABLE; + } + } } } diff --git a/src/hpa_dco.h b/src/hpa_dco.h index 3a7bbb2..98012ff 100644 --- a/src/hpa_dco.h +++ b/src/hpa_dco.h @@ -24,6 +24,7 @@ #define HPA_DISABLED 0 #define HPA_ENABLED 1 #define HPA_UNKNOWN 2 +#define HPA_NOT_APPLICABLE 3 int hpa_dco_status( nwipe_context_t* ); diff --git a/src/nwipe.c b/src/nwipe.c index 830fe56..d6dfa7c 100644 --- a/src/nwipe.c +++ b/src/nwipe.c @@ -51,6 +51,7 @@ #include #include #include "version.h" +#include "hpa_dco.h" int terminate_signal; int user_abort; @@ -351,6 +352,8 @@ int main( int argc, char** argv ) } } + /* Initialise some of the variables in the drive contexts + */ for( i = 0; i < nwipe_enumerated; i++ ) { /* Set the PRNG implementation, which must always come after the function nwipe_gui_select ! */ diff --git a/src/temperature.c b/src/temperature.c index 39650ae..074abdf 100644 --- a/src/temperature.c +++ b/src/temperature.c @@ -36,6 +36,7 @@ #include "device.h" #include "logging.h" #include "temperature.h" +#include "miscellaneous.h" int nwipe_init_temperature( nwipe_context_t* c ) {