From fd0e6d4b3bff89e1c20c46b601ca82f3882ffa67 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 1 Feb 2012 14:26:36 +0000 Subject: [PATCH] [iso] UI ISO support improvements * add ISO scan and extract progress dialog * compute sizes and set properties * allow cancellation * minor other updates --- src/format.c | 5 ++ src/iso.c | 142 +++++++++++++++++++++---------- src/libcdio/iso9660/iso9660_fs.c | 8 +- src/libcdio/iso9660/rock.c | 2 +- src/ms-sys/.msvc/ms-sys_sources | 2 +- src/resource.h | 8 +- src/rufus.c | 88 ++++++++++++++++--- src/rufus.h | 28 +++++- src/rufus.rc | 29 +++++-- src/stdio.c | 4 + 10 files changed, 238 insertions(+), 78 deletions(-) diff --git a/src/format.c b/src/format.c index 55470399..f0ee1b12 100644 --- a/src/format.c +++ b/src/format.c @@ -385,6 +385,11 @@ void __cdecl FormatThread(void* param) FILE* log_fd; int r; +#ifdef RUFUS_TEST + ExtractISO(ISO_IMAGE, ISO_DEST, FALSE); + goto out; +#endif + hPhysicalDrive = GetDriveHandle(num, NULL, TRUE, TRUE); if (hPhysicalDrive == INVALID_HANDLE_VALUE) { FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_OPEN_FAILED; diff --git a/src/iso.c b/src/iso.c index a2a35e4c..a9bc4fe2 100644 --- a/src/iso.c +++ b/src/iso.c @@ -38,26 +38,33 @@ #include #include "rufus.h" +#include "msapi_utf8.h" +#include "resource.h" #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif +#ifndef PBS_MARQUEE +#define PBS_MARQUEE 0x08 +#endif +#ifndef PBM_SETMARQUEE +#define PBM_SETMARQUEE (WM_USER+10) +#endif +// How often should we update the progress bar (in 2K blocks) as updating +// the progress bar for every block will bring extraction to a crawl +#define PROGRESS_UPDATE 1024 +#define FOUR_GIGABYTES 4294967296LL -#define print_vd_info(title, fn) \ - if (fn(p_iso, &psz_str)) { \ - uprintf(title ": %s\n", psz_str); \ - } \ - free(psz_str); \ - psz_str = NULL; - -/* Needed for UDF ISO access */ -// TODO: should be able to elmininate those with an alternate approach +// Needed for UDF ISO access CdIo_t* cdio_open (const char *psz_source, driver_id_t driver_id) {return NULL;} void cdio_destroy (CdIo_t *p_cdio) {} -const char *psz_extract_dir = "D:/tmp/iso"; +RUFUS_ISO_REPORT iso_report; +static const char *psz_extract_dir; +static uint64_t total_blocks, nb_blocks; +static BOOL scan_only = FALSE; -// TODO: Unicode support, progress computation, timestamp preservation +// TODO: Unicode support, timestamp & permissions preservation static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const char *psz_path) { @@ -72,7 +79,8 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha if ((p_udf_dirent == NULL) || (psz_path == NULL)) return 1; - while (udf_readdir(p_udf_dirent)) { + while ((p_udf_dirent = udf_readdir(p_udf_dirent)) != NULL) { + if (FormatStatus) goto out; psz_basename = udf_get_filename(p_udf_dirent); i_length = (int)(3 + strlen(psz_path) + strlen(psz_basename) + strlen(psz_extract_dir)); psz_fullpath = (char*)calloc(sizeof(char), i_length); @@ -84,22 +92,34 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha if (i_length < 0) { goto out; } - uprintf("Extracting: %s\n", psz_fullpath); if (udf_is_dir(p_udf_dirent)) { - _mkdir(psz_fullpath); + if (!scan_only) + _mkdir(psz_fullpath); p_udf_dirent2 = udf_opendir(p_udf_dirent); if (p_udf_dirent2 != NULL) { if (udf_extract_files(p_udf, p_udf_dirent2, &psz_fullpath[strlen(psz_extract_dir)])) goto out; } } else { + i_file_length = udf_get_file_length(p_udf_dirent); + if (scan_only) { + if (i_file_length >= FOUR_GIGABYTES) + iso_report.has_4GB_file = TRUE; + total_blocks += i_file_length/UDF_BLOCKSIZE; + if ((i_file_length != 0) && (i_file_length%UDF_BLOCKSIZE == 0)) + total_blocks++; + safe_free(psz_fullpath); + continue; + } + uprintf("Extracting: %s\n", psz_fullpath); + SetWindowTextU(hISOFileName, psz_fullpath); fd = fopen(psz_fullpath, "wb"); if (fd == NULL) { uprintf(" Unable to create file\n"); goto out; } - i_file_length = udf_get_file_length(p_udf_dirent); while (i_file_length > 0) { + if (FormatStatus) goto out; memset(buf, 0, UDF_BLOCKSIZE); i_read = udf_read_block(p_udf_dirent, buf, 1); if (i_read < 0) { @@ -112,18 +132,22 @@ static int udf_extract_files(udf_t *p_udf, udf_dirent_t *p_udf_dirent, const cha goto out; } i_file_length -= i_read; + if (nb_blocks++ % PROGRESS_UPDATE == 0) + SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0); } fclose(fd); fd = NULL; } - free(psz_fullpath); + safe_free(psz_fullpath); } return 0; out: + if (p_udf_dirent != NULL) + udf_dirent_free(p_udf_dirent); if (fd != NULL) fclose(fd); - free(psz_fullpath); + safe_free(psz_fullpath); return 1; } @@ -154,6 +178,7 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) return 1; _CDIO_LIST_FOREACH (p_entnode, p_entlist) { + if (FormatStatus) goto out; p_statbuf = (iso9660_stat_t*) _cdio_list_node_data(p_entnode); /* Eliminate . and .. entries */ if ( (strcmp(p_statbuf->filename, ".") == 0) @@ -161,18 +186,28 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) continue; iso9660_name_translate(p_statbuf->filename, psz_basename); if (p_statbuf->type == _STAT_DIR) { - _mkdir(psz_fullpath); + if (!scan_only) + _mkdir(psz_fullpath); if (iso_extract_files(p_iso, psz_iso_name)) goto out; } else { + i_file_length = p_statbuf->size; + if (scan_only) { + if (i_file_length >= FOUR_GIGABYTES) + iso_report.has_4GB_file = TRUE; + total_blocks += i_file_length/ISO_BLOCKSIZE; + if ((i_file_length != 0) && (i_file_length%ISO_BLOCKSIZE == 0)) + total_blocks++; + continue; + } uprintf("Extracting: %s\n", psz_fullpath); fd = fopen(psz_fullpath, "wb"); if (fd == NULL) { uprintf(" Unable to create file\n"); goto out; } - i_file_length = p_statbuf->size; for (i = 0; i_file_length > 0; i++) { + if (FormatStatus) goto out; memset(buf, 0, ISO_BLOCKSIZE); lsn = p_statbuf->lsn + (lsn_t)i; if (iso9660_iso_seek_read(p_iso, buf, lsn, 1) != ISO_BLOCKSIZE) { @@ -186,6 +221,8 @@ static int iso_extract_files(iso9660_t* p_iso, const char *psz_path) goto out; } i_file_length -= ISO_BLOCKSIZE; + if (nb_blocks++ % PROGRESS_UPDATE == 0) + SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)((MAX_PROGRESS*nb_blocks)/total_blocks), 0); } fclose(fd); fd = NULL; @@ -200,17 +237,46 @@ out: return r; } -BOOL ExtractISO(const char* src_iso, const char* dest_dir) +BOOL ExtractISO(const char* src_iso, const char* dest_dir, bool scan) { BOOL r = FALSE; iso9660_t* p_iso = NULL; udf_t* p_udf = NULL; udf_dirent_t* p_udf_root; - char *psz_str = NULL; - char vol_id[UDF_VOLID_SIZE] = ""; - char volset_id[UDF_VOLSET_ID_SIZE+1] = ""; + LONG progress_style; + const char* scan_text = "Scanning ISO image...\n"; + if ((src_iso == NULL) || (dest_dir == NULL)) + return FALSE; + + scan_only = scan; cdio_loglevel_default = CDIO_LOG_DEBUG; + psz_extract_dir = dest_dir; + progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE); + if (scan_only) { + uprintf(scan_text); + total_blocks = 0; + iso_report.projected_size = 0; + iso_report.has_4GB_file = FALSE; + // Change the Window title and static text + SetWindowTextU(hISOProgressDlg, scan_text); + SetWindowTextU(hISOFileName, scan_text); + // Change progress style to marquee for scanning + SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style | PBS_MARQUEE); + SendMessage(hISOProgressBar, PBM_SETMARQUEE, TRUE, 0); + } else { + uprintf("Extracting files...\n"); + if (total_blocks == 0) { + uprintf("Error: ISO has not been properly scanned.\n"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_ISO_SCAN); + goto out; + } + nb_blocks = 0; + SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE)); + SendMessage(hISOProgressBar, PBM_SETPOS, 0, 0); + } + ShowWindow(hISOProgressDlg, SW_SHOW); + UpdateWindow(hISOProgressDlg); /* First try to open as UDF - fallback to ISO if it failed */ p_udf = udf_open(src_iso); @@ -222,20 +288,7 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir) uprintf("Couldn't locate UDF root directory\n"); goto out; } - vol_id[0] = 0; volset_id[0] = 0; - - /* Show basic UDF Volume info */ - if (udf_get_volume_id(p_udf, vol_id, sizeof(vol_id)) > 0) - uprintf("Volume id: %s\n", vol_id); - if (udf_get_volume_id(p_udf, volset_id, sizeof(volset_id)) >0 ) { - volset_id[UDF_VOLSET_ID_SIZE]='\0'; - uprintf("Volume set id: %s\n", volset_id); - } - uprintf("Partition number: %d\n", udf_get_part_number(p_udf)); - - /* Recursively extract files */ r = udf_extract_files(p_udf, p_udf_root, ""); - goto out; try_iso: @@ -244,22 +297,19 @@ try_iso: uprintf("Unable to open image '%s'.\n", src_iso); goto out; } - - /* Show basic ISO9660 info from the Primary Volume Descriptor. */ - print_vd_info("Application", iso9660_ifs_get_application_id); - print_vd_info("Preparer ", iso9660_ifs_get_preparer_id); - print_vd_info("Publisher ", iso9660_ifs_get_publisher_id); - print_vd_info("System ", iso9660_ifs_get_system_id); - print_vd_info("Volume ", iso9660_ifs_get_volume_id); - print_vd_info("Volume Set ", iso9660_ifs_get_volumeset_id); - r = iso_extract_files(p_iso, ""); out: + if (scan_only) { + // We use the fact that UDF_BLOCKSIZE and ISO_BLOCKSIZE are the same here + iso_report.projected_size = total_blocks * ISO_BLOCKSIZE; + } + SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0); if (p_iso != NULL) iso9660_close(p_iso); if (p_udf != NULL) udf_close(p_udf); - + if ((r != 0) && (FormatStatus == 0)) + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(scan_only?ERROR_ISO_SCAN:ERROR_ISO_EXTRACT); return r; } diff --git a/src/libcdio/iso9660/iso9660_fs.c b/src/libcdio/iso9660/iso9660_fs.c index cf7c2577..272c5dd7 100644 --- a/src/libcdio/iso9660/iso9660_fs.c +++ b/src/libcdio/iso9660/iso9660_fs.c @@ -1431,14 +1431,14 @@ find_lsn_recurse (void *p_image, iso9660_readdir_t iso9660_readdir, } if (statbuf->lsn == lsn) { - iso9660_stat_t *ret_stat = calloc(1, len); - len = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1; + const unsigned int len2 = sizeof(iso9660_stat_t)+strlen(statbuf->filename)+1; + iso9660_stat_t *ret_stat = calloc(1, len2); if (!ret_stat) { - cdio_warn("Couldn't calloc(1, %d)", len); + cdio_warn("Couldn't calloc(1, %d)", len2); return NULL; } - memcpy(ret_stat, statbuf, len); + memcpy(ret_stat, statbuf, len2); _cdio_list_free (entlist, true); _cdio_list_free (dirlist, true); return ret_stat; diff --git a/src/libcdio/iso9660/rock.c b/src/libcdio/iso9660/rock.c index 8dc000a8..f83825fd 100644 --- a/src/libcdio/iso9660/rock.c +++ b/src/libcdio/iso9660/rock.c @@ -101,7 +101,7 @@ realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t i_grow) #define CHECK_CE \ { cont_extent = from_733(*rr->u.CE.extent); \ cont_offset = from_733(*rr->u.CE.offset); \ - cont_size = from_733(*rr->u.CE.size); \ + cont_size = from_733(*rr->u.CE.size); \ (void)cont_extent; (void)cont_offset, (void)cont_size; } #define SETUP_ROCK_RIDGE(DE,CHR,LEN) \ diff --git a/src/ms-sys/.msvc/ms-sys_sources b/src/ms-sys/.msvc/ms-sys_sources index 6f140e4d..33c56004 100644 --- a/src/ms-sys/.msvc/ms-sys_sources +++ b/src/ms-sys/.msvc/ms-sys_sources @@ -1,7 +1,7 @@ TARGETNAME=ms-sys TARGETTYPE=LIBRARY -INCLUDES=$(DDK_INC_PATH);.\inc +INCLUDES=$(DDK_INC_PATH);.\inc;..\msvc-missing C_DEFINES=$(C_DEFINES) /DDDKBUILD /DUNICODE /D_UNICODE /DISOLATION_AWARE_ENABLED !IFNDEF MSC_WARNING_LEVEL diff --git a/src/resource.h b/src/resource.h index 7ad7f913..5ef4a34d 100644 --- a/src/resource.h +++ b/src/resource.h @@ -7,7 +7,8 @@ #define IDD_ABOUTBOX 103 #define IDD_NOTIFICATION 104 #define IDD_LICENSE 105 -#define IDS_VERSION 106 +#define IDD_ISO_EXTRACT 106 +#define IDS_VERSION 107 #define IDR_FD_COMMAND_COM 300 #define IDR_FD_KERNEL_SYS 301 #define IDR_FD_DISPLAY_EXE 302 @@ -53,6 +54,9 @@ #define IDC_DOSTYPE 1013 #define IDC_NBPASSES 1014 #define IDC_TEST 1015 +#define IDC_ISO_PROGRESS 1020 +#define IDC_ISO_FILENAME 1021 +#define IDC_ISO_ABORT 1022 #define IDC_ABOUT_LICENSE 1030 #define IDC_ABOUT_ICON 1031 #define IDC_RUFUS_BOLD 1032 @@ -69,7 +73,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_RESOURCE_VALUE 108 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1043 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/src/rufus.c b/src/rufus.c index a282d54b..30c4c556 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -56,6 +56,7 @@ char szFolderPath[MAX_PATH]; float fScale = 1.0f; int default_fs; HWND hDeviceList, hCapacity, hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses; +HWND hISOProgressDlg = NULL, hISOProgressBar, hISOFileName; BOOL bWithFreeDOS, bWithSyslinux; static HWND hDeviceTooltip = NULL, hFSTooltip = NULL, hProgress = NULL; @@ -880,6 +881,42 @@ static void CALLBACK ClockTimer(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dw SendMessageA(GetDlgItem(hWnd, IDC_STATUS), SB_SETTEXTA, SBT_OWNERDRAW | 1, (LPARAM)szTimer); } +/* Callback for the modeless ISO extraction progress */ +BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_INITDIALOG: + CenterDialog(hDlg); + hISOProgressBar = GetDlgItem(hDlg, IDC_ISO_PROGRESS); + hISOFileName = GetDlgItem(hDlg, IDC_ISO_FILENAME); + // Use maximum granularity for the progress bar + SendMessage(hISOProgressBar, PBM_SETRANGE, 0, MAX_PROGRESS<<16); + return TRUE; + case UM_ISO_EXIT: + DestroyWindow(hDlg); + hISOProgressDlg = NULL; + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ISO_ABORT: + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|ERROR_CANCELLED; + PrintStatus(0, "Cancelling - please wait..."); + return TRUE; + } + case WM_CLOSE: // prevent closure using Alt-F4 + return TRUE; + } + return FALSE; +} + +// The scanning process can be blocking for message processing => use a thread +void __cdecl ISOScanThread(void* param) +{ + ExtractISO(ISO_IMAGE, ISO_DEST, TRUE); + uprintf("Projected size: %lld\nHas 4GB: %s\n", iso_report.projected_size, iso_report.has_4GB_file?"TRUE":"FALSE"); + _endthread(); +} + /* * Main dialog callback */ @@ -1000,13 +1037,23 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA case IDC_ABOUT: CreateAboutBox(); break; +#ifdef RUFUS_TEST case IDC_TEST: -// ExtractISO("D:\\Incoming\\GRMSDKX_EN_DVD.iso", NULL); -// ExtractISO("D:\\fd11src.iso", NULL); -// ExtractISO("D:\\Incoming\\en_windows_driver_kit_3790.iso", NULL); -// ExtractISO("D:\\Incoming\\en_windows_7_ultimate_with_sp1_x64_dvd_618240.iso", NULL); - ExtractISO("D:\\Incoming\\Windows 8 Preview\\WindowsDeveloperPreview-64bit-English-Developer.iso", NULL); + FormatStatus = 0; + // You'd think that Windows would let you instantiate a modeless dialog wherever + // but you'd be wrong. It has to be done in the main callback! + if (!IsWindow(hISOProgressDlg)) { + hISOProgressDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_ISO_EXTRACT), + hDlg, (DLGPROC)ISOProc); + // The window is not visible by default but takes focus => restore it + SetFocus(hDlg); + } + if (_beginthread(ISOScanThread, 0, NULL) == -1L) { + uprintf("Unable to start ISO scanning thread"); + FormatStatus = ERROR_SEVERITY_ERROR|FAC(FACILITY_STORAGE)|APPERR(ERROR_CANT_START_THREAD); + } break; +#endif case IDC_DEVICE: switch (HIWORD(wParam)) { case CBN_SELCHANGE: @@ -1043,6 +1090,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA if (format_thid != -1L) { return (INT_PTR)TRUE; } + FormatStatus = 0; nDeviceIndex = ComboBox_GetCurSel(hDeviceList); if (nDeviceIndex != CB_ERR) { GetWindowTextA(hDeviceList, tmp, sizeof(tmp)); @@ -1054,6 +1102,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); FormatStatus = 0; InitProgress(); + if (!IsWindow(hISOProgressDlg)) { + hISOProgressDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_ISO_EXTRACT), + hDlg, (DLGPROC)ISOProc); + // The window is not visible by default but takes focus => restore it + SetFocus(hDlg); + } format_thid = _beginthread(FormatThread, 0, (void*)(uintptr_t)DeviceNum); if (format_thid == -1L) { uprintf("Unable to start formatting thread"); @@ -1157,22 +1211,28 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine MessageBoxA(NULL, "Could not create Window", "DialogBox failure", MB_ICONSTOP); goto out; } - CenterDialog(hDlg); +// CenterDialog(hDlg); +#ifndef RUFUS_TEST + ShowWindow(GetDlgItem(hDlg, IDC_TEST), SW_HIDE); +#endif ShowWindow(hDlg, SW_SHOWNORMAL); UpdateWindow(hDlg); // Do our own event processing and process "magic" commands while(GetMessage(&msg, NULL, 0, 0)) { + // The following ensures the processing of the ISO progress window messages + if (!IsWindow(hISOProgressDlg) || !IsDialogMessage(hISOProgressDlg, &msg)) { #ifdef DISABLE_AUTORUN - // Alt-D => Delete the NoDriveTypeAutorun key on exit (useful if the app crashed) - if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'D')) { - PrintStatus(0, "NoDriveTypeAutorun will be deleted on exit."); - existing_key = FALSE; - continue; - } + // Alt-D => Delete the NoDriveTypeAutorun key on exit (useful if the app crashed) + if ((msg.message == WM_SYSKEYDOWN) && (msg.wParam == 'D')) { + PrintStatus(0, "NoDriveTypeAutorun will be deleted on exit."); + existing_key = FALSE; + continue; + } #endif - TranslateMessage(&msg); - DispatchMessage(&msg); + TranslateMessage(&msg); + DispatchMessage(&msg); + } } out: diff --git a/src/rufus.h b/src/rufus.h index 4d1b5c47..9ae1f756 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -17,6 +17,7 @@ */ #include #include // for DISK_GEOMETRY +#include #pragma once @@ -24,6 +25,15 @@ #define RUFUS_DEBUG // print debug info to Debug facility (use debugview to consult) #define DISABLE_AUTORUN // disable new USB drive notification from explorer when application is running +/* Features not ready for prime time and that may *DESTROY* your data - USE AT YOUR OWN RISKS! */ +//#define RUFUS_TEST +#define ISO_DEST "D:/tmp/iso" +#define ISO_IMAGE "D:\\Incoming\\Windows 8 Preview\\WindowsDeveloperPreview-64bit-English-Developer.iso" +//#define ISO_IMAGE "D:\\fd11src.iso", "D:/tmp/iso" +//#define ISO_IMAGE "D:\\Incoming\\GRMSDKX_EN_DVD.iso" +//#define ISO_IMAGE "D:\\Incoming\\en_windows_driver_kit_3790.iso" +//#define ISO_IMAGE "D:\\Incoming\\en_windows_7_ultimate_with_sp1_x64_dvd_618240.iso" + #define STR_NO_LABEL "NO_LABEL" #define RUFUS_CANCELBOX_TITLE "Rufus - Cancellation" #define DRIVE_INDEX_MIN 0x80 @@ -74,7 +84,8 @@ extern void _uprintf(const char *format, ...); /* Custom Windows messages */ enum user_message_type { - UM_FORMAT_COMPLETED = WM_APP + UM_FORMAT_COMPLETED = WM_APP, + UM_ISO_EXIT }; /* Custom notifications */ @@ -136,18 +147,26 @@ typedef struct { } ClusterSize[FS_MAX]; } RUFUS_DRIVE_INFO; +/* ISO details that the application may want */ +typedef struct { + uint64_t projected_size; + BOOL has_4GB_file; +} RUFUS_ISO_REPORT; + /* * Globals */ extern HINSTANCE hMainInstance; extern HWND hMainDialog, hStatus, hDeviceList, hCapacity; extern HWND hFileSystem, hClusterSize, hLabel, hDOSType, hNBPasses; +extern HWND hISOProgressDlg, hISOProgressBar, hISOFileName; extern float fScale; extern char szFolderPath[MAX_PATH]; extern DWORD FormatStatus; extern RUFUS_DRIVE_INFO SelectedDrive; extern const int nb_steps[FS_MAX]; extern BOOL bWithFreeDOS; +extern RUFUS_ISO_REPORT iso_report; /* * Shared prototypes @@ -165,13 +184,14 @@ extern void DestroyTooltip(HWND hWnd); extern void DestroyAllTooltips(void); extern BOOL Notification(int type, char* title, char* format, ...); extern BOOL ExtractDOS(const char* path); -extern BOOL ExtractISO(const char* src_iso, const char* dest_dir); +extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); extern BOOL InstallSyslinux(DWORD num, const char* drive_name); extern void __cdecl FormatThread(void* param); extern BOOL CreatePartition(HANDLE hDrive); extern HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive); extern BOOL GetDriveLabel(DWORD DriveIndex, char* letter, char** label); extern BOOL UnmountDrive(HANDLE hDrive); +extern BOOL CreateProgress(void); __inline static BOOL UnlockDrive(HANDLE hDrive) { @@ -191,6 +211,8 @@ extern void StrArrayAdd(StrArray* arr, const char* str); extern void StrArrayClear(StrArray* arr); extern void StrArrayDestroy(StrArray* arr); + + /* Clang/MinGW32 has an issue with intptr_t */ #ifndef _UINTPTR_T_DEFINED #define _UINTPTR_T_DEFINED @@ -218,3 +240,5 @@ typedef struct { #define ERROR_INVALID_VOLUME_SIZE 0x1204 #define ERROR_CANT_START_THREAD 0x1205 #define ERROR_BADBLOCKS_FAILURE 0x1206 +#define ERROR_ISO_SCAN 0x1207 +#define ERROR_ISO_EXTRACT 0x1208 diff --git a/src/rufus.rc b/src/rufus.rc index 3553e3a1..11f8213f 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -31,9 +31,9 @@ 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 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.0.7.121" +CAPTION "Rufus v1.0.7.122" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,236,50,14 @@ -70,7 +70,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.7 (Build 121)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.0.7 (Build 122)",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 @@ -91,6 +91,16 @@ BEGIN DEFPUSHBUTTON "Close",IDCANCEL,211,44,50,14 END +IDD_ISO_EXTRACT DIALOGEX 0, 0, 262, 73 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION +CAPTION "Extracting Files..." +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "",IDC_ISO_FILENAME,14,9,232,14 + CONTROL "",IDC_ISO_PROGRESS,"msctls_progress32",WS_BORDER,14,32,231,8 + PUSHBUTTON "Abort",IDC_ISO_ABORT,112,50,50,14 +END + IDD_LICENSE DIALOGEX 0, 0, 335, 205 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Rufus License" @@ -184,7 +194,6 @@ GUIDELINES DESIGNINFO BEGIN IDD_DIALOG, DIALOG BEGIN - BOTTOMMARGIN, 264 END IDD_ABOUTBOX, DIALOG @@ -195,6 +204,10 @@ BEGIN BEGIN END + IDD_ISO_EXTRACT, DIALOG + BEGIN + END + IDD_LICENSE, DIALOG BEGIN END @@ -208,8 +221,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,7,121 - PRODUCTVERSION 1,0,7,121 + FILEVERSION 1,0,7,122 + PRODUCTVERSION 1,0,7,122 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -226,13 +239,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.0.7.121" + VALUE "FileVersion", "1.0.7.122" 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.7.121" + VALUE "ProductVersion", "1.0.7.122" END END BLOCK "VarFileInfo" diff --git a/src/stdio.c b/src/stdio.c index a919c86f..7aa58c7a 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -217,6 +217,10 @@ const char* StrError(DWORD error_code) return "Unable to create formatting thread"; case ERROR_BADBLOCKS_FAILURE: return "Bad blocks check didn't complete"; + case ERROR_ISO_SCAN: + return "ISO image scan failure"; + case ERROR_ISO_EXTRACT: + return "ISO image scan failure"; default: uprintf("Unknown error: %08X\n", error_code); SetLastError(error_code);