From d27e73137d1eaf709eb4bce0b0598cf65bf91c36 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Fri, 30 Dec 2011 21:23:13 +0000 Subject: [PATCH] [bb] generate a log report when bad blocks are found * closes #6 --- src/badblocks.c | 31 +++++++++++++++++++++++++------ src/badblocks.h | 2 +- src/format.c | 40 +++++++++++++++++++++++++++++++++++----- src/msapi_utf8.h | 24 ++++++++++++++++++++++++ src/rufus.rc | 12 ++++++------ 5 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/badblocks.c b/src/badblocks.c index 585443c0..9a3ef7e0 100644 --- a/src/badblocks.c +++ b/src/badblocks.c @@ -43,6 +43,10 @@ #include "rufus.h" #include "badblocks.h" #include "file.h" +#include "msapi_utf8.h" + +FILE* log_fd = NULL; +static const char* abort_msg = "Too many bad blocks, aborting test\n"; /* *From e2fsprogs/lib/ext2fs/badblocks.c @@ -316,6 +320,9 @@ static int bb_output (blk_t bad, enum error_types error_type) return 0; uprintf("%lu\n", (unsigned long) bad); + fprintf(log_fd, "Block %lu: %s error\n", (unsigned long)bad, (error_type==READ_ERROR)?"read": + ((error_type == WRITE_ERROR)?"write":"corruption")); + fflush(log_fd); error_code = ext2fs_badblocks_list_add(bb_list, bad); if (error_code) { @@ -497,7 +504,9 @@ static unsigned int test_ro (HANDLE hDrive, blk_t last_block, { if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { - uprintf("Too many bad blocks, aborting test\n"); + uprintf(abort_msg); + fprintf(log_fd, abort_msg); + fflush(log_fd); } cancel_ops = -1; break; @@ -576,7 +585,9 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk while (currently_testing < last_block) { if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { - uprintf("Too many bad blocks, aborting test\n"); + uprintf(abort_msg); + fprintf(log_fd, abort_msg); + fflush(log_fd); } cancel_ops = -1; break; @@ -615,7 +626,9 @@ static unsigned int test_rw(HANDLE hDrive, blk_t last_block, int block_size, blk if (cancel_ops) goto out; if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { - uprintf("Too many bad blocks, aborting test\n"); + uprintf(abort_msg); + fprintf(log_fd, abort_msg); + fflush(log_fd); } break; } @@ -746,7 +759,9 @@ static unsigned int test_nd(HANDLE hDrive, blk_t last_block, while (currently_testing < last_block) { if (max_bb && bb_count >= max_bb) { if (s_flag || v_flag) { - uprintf("Too many bad blocks, aborting test\n"); + uprintf(abort_msg); + fprintf(log_fd, abort_msg); + fflush(log_fd); } cancel_ops = -1; break; @@ -895,7 +910,7 @@ static unsigned int test_nd(HANDLE hDrive, blk_t last_block, } BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, - int test_type, badblocks_report *report) + int test_type, badblocks_report *report, FILE* fd) { errcode_t error_code; unsigned int (*test_func)(HANDLE, blk_t, int, blk_t, unsigned int); @@ -903,6 +918,11 @@ BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, if (report == NULL) return FALSE; report->bb_count = 0; + if (fd != NULL) { + log_fd = fd; + } else { + log_fd = freopen(NULL, "w", stderr); + } error_code = ext2fs_badblocks_list_create(&bb_list, 0); if (error_code) { @@ -928,7 +948,6 @@ BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, KillTimer(hMainDialog, TID_BADBLOCKS_UPDATE); free(bb_list->list); free(bb_list); - // TODO: report first problem block for each error or create a report file report->num_read_errors = num_read_errors; report->num_write_errors = num_write_errors; report->num_corruption_errors = num_corruption_errors; diff --git a/src/badblocks.h b/src/badblocks.h index 7cb36660..3c3f5eb4 100644 --- a/src/badblocks.h +++ b/src/badblocks.h @@ -65,4 +65,4 @@ typedef struct { * Shared prototypes */ BOOL BadBlocks(HANDLE hPhysicalDrive, ULONGLONG disk_size, int block_size, - int test_type, badblocks_report *report); + int test_type, badblocks_report *report, FILE* fd); diff --git a/src/format.c b/src/format.c index 722d98c7..1b89f9e4 100644 --- a/src/format.c +++ b/src/format.c @@ -374,8 +374,11 @@ void __cdecl FormatThread(void* param) DWORD num = (DWORD)(uintptr_t)param; HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE; HANDLE hLogicalVolume = INVALID_HANDLE_VALUE; + SYSTEMTIME lt; char drive_name[] = "?:"; - char bb_msg[256]; + char bb_msg[512]; + char logfile[MAX_PATH], *userdir; + FILE* log_fd; int r; hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); @@ -401,8 +404,26 @@ void __cdecl FormatThread(void* param) if (IsChecked(IDC_BADBLOCKS)) { do { + // create a log file for bad blocks report. Since %USERPROFILE% may + // have localised characters, we use the UTF-8 API. + userdir = getenvU("USERPROFILE"); + safe_strcpy(logfile, MAX_PATH, userdir); + safe_free(userdir); + GetLocalTime(<); + safe_sprintf(&logfile[strlen(logfile)], sizeof(logfile)-strlen(logfile)-1, + "\\rufus_%04d%02d%02d_%02d%02d%02d.log", + lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); + log_fd = fopenU(logfile, "w+"); + if (log_fd == NULL) { + uprintf("Could not create log file for bad blocks check\n"); + } else { + fprintf(log_fd, "Rufus bad blocks check started on: %04d.%02d.%02d %02d:%02d:%02d\n", + lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond); + fflush(log_fd); + } + if (!BadBlocks(hPhysicalDrive, SelectedDrive.DiskSize, - SelectedDrive.Geometry.BytesPerSector, BADBLOCKS_RW, &report)) { + SelectedDrive.Geometry.BytesPerSector, BADBLOCKS_RW, &report, log_fd)) { uprintf("Bad blocks check failed.\n"); if (!FormatStatus) FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)| @@ -415,12 +436,21 @@ void __cdecl FormatThread(void* param) report.num_read_errors, report.num_write_errors, report.num_corruption_errors); r = IDOK; if (report.bb_count) { - safe_sprintf(bb_msg, sizeof(bb_msg), "Check completed - %u bad block%s found:\n" - " %d read errors\n %d write errors\n %d corruption errors", + safe_sprintf(bb_msg, sizeof(bb_msg), "Check completed: %u bad block%s found.\n" + " %d read errors\n %d write errors\n %d corruption errors\n", report.bb_count, (report.bb_count==1)?"":"s", report.num_read_errors, report.num_write_errors, report.num_corruption_errors); - r = MessageBoxA(hMainDialog, bb_msg, "Bad blocks check", MB_ABORTRETRYIGNORE|MB_ICONWARNING); + fprintf(log_fd, "%s", bb_msg); + fclose(log_fd); + safe_sprintf(&bb_msg[strlen(bb_msg)], sizeof(bb_msg)-strlen(bb_msg)-1, + "\nA more detailed report can be found in:\n%s\n", logfile); + r = MessageBoxU(hMainDialog, bb_msg, "Bad blocks found", MB_ABORTRETRYIGNORE|MB_ICONWARNING); + } else { + // We didn't get any errors => delete the log file + // NB: the log doesn't get deleted on abort + fclose(log_fd); + _unlink(logfile); } } while (r == IDRETRY); if (r == IDABORT) { diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h index 2833c626..243c8248 100644 --- a/src/msapi_utf8.h +++ b/src/msapi_utf8.h @@ -159,6 +159,20 @@ static __inline HWND CreateWindowU(char* lpClassName, char* lpWindowName, return ret; } +static __inline int MessageBoxU(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) +{ + int ret; + DWORD err = ERROR_INVALID_DATA; + wconvert(lpText); + wconvert(lpCaption); + ret = MessageBoxW(hWnd, wlpText, wlpCaption, uType); + err = GetLastError(); + wfree(lpText); + wfree(lpCaption); + SetLastError(err); + return ret; +} + static __inline int GetWindowTextU(HWND hWnd, char* lpString, int nMaxCount) { int ret = 0; @@ -579,6 +593,16 @@ static __inline FILE* fopenU(const char* filename, const char* mode) return ret; } +// returned UTF-8 string must be freed +static __inline char* getenvU(const char* varname) +{ + wconvert(varname); + char* ret; + ret = wchar_to_utf8(_wgetenv(wvarname)); + wfree(varname); + return ret; +} + #ifdef __cplusplus } #endif diff --git a/src/rufus.rc b/src/rufus.rc index 7fe7d395..8e60537d 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 206, 278 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.0.6.107" +CAPTION "Rufus v1.0.6.108" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,236,50,14 @@ -65,7 +65,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP CONTROL "http://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.0.6 (Build 107)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.0.6 (Build 108)",IDC_STATIC,46,19,78,8 PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 @@ -170,8 +170,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,6,107 - PRODUCTVERSION 1,0,6,107 + FILEVERSION 1,0,6,108 + PRODUCTVERSION 1,0,6,108 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -188,13 +188,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.0.6.107" + VALUE "FileVersion", "1.0.6.108" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.0.6.107" + VALUE "ProductVersion", "1.0.6.108" END END BLOCK "VarFileInfo"