From fb09802c0fd0bd74ab5d8df2b6991372e14e736b Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sat, 22 Aug 2015 15:18:25 +0100 Subject: [PATCH] [ui] prompt users how they want to write ISOHybrid images * Closes #543 * Also update localization messages and image analysis report --- res/localization/ChangeLog.txt | 13 +++ res/localization/rufus.loc | 17 +++- src/iso.c | 40 +++++----- src/localization.c | 4 +- src/localization_data.h | 7 ++ src/msapi_utf8.h | 12 +++ src/resource.h | 24 +++--- src/rufus.c | 56 ++++++++++--- src/rufus.h | 6 +- src/rufus.rc | 29 +++++-- src/stdlg.c | 139 ++++++++++++++++++++++++++++++++- src/vhd.c | 15 ++-- 12 files changed, 298 insertions(+), 64 deletions(-) diff --git a/res/localization/ChangeLog.txt b/res/localization/ChangeLog.txt index b950eec7..12b1b6d1 100644 --- a/res/localization/ChangeLog.txt +++ b/res/localization/ChangeLog.txt @@ -15,6 +15,19 @@ content. PLEASE, do not just look at this Changelog when updating your translation, but always use the English section of rufus.loc as your base. For instance, MSG_114, that was introduced in v1.0.8 is MORE than one line! +o Upcoming changes for Rufus 2.4 (TRANSLATORS, PLEASE DO NOT START WORKING ON THOSE UNTIL ADVISED TO DO SO!!!) + - Changed MSG_081 "Unsupported ISO" -> "Unsupported image" + - Changed MSG_082 -> "This image is either non-bootable, or uses a boot/compression method that is unsupported by Rufus..." + - *NEW* MSG_269 "Preserve timestamps" (use the Alt-T cheat mode to see this message) + - *NEW* MSG_270 "USB debug" (use the Alt-. cheat mode to see this message) + - *NEW* MSG_271 "Computing image checksums: %0.1f%% completed" + - *NEW* MSG_272 "Compute the SHA1 and MD5 checksums for the selected image" + - *NEW* MSG_273 "Change the application language" + - *NEW* MSG_274 "ISOHybrid image detected" + - *NEW* MSG_275 "The image you have selected is..." [TRANSLATORS: See 'rufus.loc' for the FULL message] + - *NEW* MSG_276 "Write in %s mode (Recommended)" + - *NEW* MSG_277 "Write in %s mode" + o Version 1.0.17 (2015.02.04) - *NEW CONTROL* IDC_WINDOWS_INSTALL "Standard Windows installation" (Main dialog) - *NEW CONTROL* IDC_WINDOWS_TO_GO "Windows To Go" (Main dialog) diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc index 197caa17..9e3fc083 100644 --- a/res/localization/rufus.loc +++ b/res/localization/rufus.loc @@ -265,9 +265,8 @@ t MSG_080 "Rufus detected that Windows is still flushing its internal buffers on "Depending on the speed of your USB device, this operation may take a long time to complete, " "especially for large files.\n\nWe recommend that you let Windows finish, to avoid corruption. " "But if you grow tired of waiting, you can just unplug the device..." -t MSG_081 "Unsupported ISO" -t MSG_082 "This version of Rufus only supports bootable ISOs based on bootmgr, EFI, Grub4DOS, GRUB 2, " - "isolinux, or WinPE.\nThis ISO doesn't appear to use either..." +t MSG_081 "Unsupported image" +t MSG_082 "This image is either non-bootable, or uses a boot/compression method that is unsupported by Rufus..." t MSG_083 "Replace %s?" t MSG_084 "This ISO image seems to use an obsolete version of '%s'.\n" "Boot menus may not display properly because of this.\n\n" @@ -520,6 +519,18 @@ t MSG_270 "USB debug" t MSG_271 "Computing image checksums: %0.1f%% completed" t MSG_272 "Compute the SHA1 and MD5 checksums for the selected image" t MSG_273 "Change the application language" +t MSG_274 "ISOHybrid image detected" +# '%s' below will be replaced with your translations for MSG_036 ("ISO Image") and MSG_095 ("DD Image") +t MSG_275 "The image you have selected is an 'ISOHybrid' image. This means it can be written either in " + "%s (file copy) mode or %s (disk image) mode .\n" + "Rufus recommends using %s mode, so that you always have full access to the drive after writing it.\n" + "However, if you encounter issues during boot, you can try writing this image again in %s mode.\n\n" + "Please select the mode Rufus should use to write this image:" +# '%s' below will be replaced with your translation for MSG_036 ("ISO Image") +t MSG_276 "Write in %s mode (Recommended)" +# '%s' below will be replaced with your translation for MSG_095 ("DD Image") +t MSG_277 "Write in %s mode" + ################################################################################ ############################# TRANSLATOR END COPY ############################## diff --git a/src/iso.c b/src/iso.c index 0567cafd..76121e70 100644 --- a/src/iso.c +++ b/src/iso.c @@ -653,15 +653,19 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan) const char* basedir[] = { "i386", "minint" }; const char* tmp_sif = ".\\txtsetup.sif~"; iso_extension_mask_t iso_extension_mask = ISO_EXTENSION_ALL; + char* spacing = " "; if ((!enable_iso) || (src_iso == NULL) || (dest_dir == NULL)) return FALSE; scan_only = scan; + if (!scan_only) + spacing = ""; cdio_log_set_handler(log_handler); psz_extract_dir = dest_dir; // Change progress style to marquee for scanning if (scan_only) { + uprintf("ISO analysis:"); SendMessage(hMainDialog, UM_PROGRESS_INIT, PBS_MARQUEE, 0); total_blocks = 0; memset(&iso_report, 0, sizeof(iso_report)); @@ -687,11 +691,11 @@ BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan) p_udf = udf_open(src_iso); if (p_udf == NULL) goto try_iso; - uprintf("Disc image is an UDF image\n"); + uprintf("%sImage is an UDF image", spacing); p_udf_root = udf_get_root(p_udf, true, 0); if (p_udf_root == NULL) { - uprintf("Could not locate UDF root directory\n"); + uprintf("%sCould not locate UDF root directory", spacing); goto out; } if (scan_only) { @@ -714,11 +718,11 @@ try_iso: p_iso = iso9660_open_ext(src_iso, iso_extension_mask); if (p_iso == NULL) { - uprintf("'%s' doesn't look like an ISO image\n", src_iso); + uprintf("%s'%s' doesn't look like an ISO image", spacing, src_iso); r = 1; goto out; } - uprintf("Disc image is an ISO9660 image\n"); + uprintf("%sImage is an ISO9660 image", spacing); i_joliet_level = iso9660_ifs_get_joliet_level(p_iso); if (scan_only) { if (iso9660_ifs_get_volume_id(p_iso, &tmp)) { @@ -728,10 +732,10 @@ try_iso: iso_report.label[0] = 0; } else { if (iso_extension_mask & (ISO_EXTENSION_JOLIET|ISO_EXTENSION_ROCK_RIDGE)) - uprintf("This image will be extracted using %s extensions (if present)", + uprintf("%sThis image will be extracted using %s extensions (if present)", spacing, (iso_extension_mask & ISO_EXTENSION_JOLIET)?"Joliet":"Rock Ridge"); else - uprintf("This image will not be extracted using any ISO extensions"); + uprintf("%sThis image will not be extracted using any ISO extensions", spacing); } r = iso_extract_files(p_iso, ""); @@ -771,12 +775,12 @@ out: if (safe_strlen(iso_report.cfg_path) >= safe_strlen(config_path.String[i])) safe_strcpy(iso_report.cfg_path, sizeof(iso_report.cfg_path), config_path.String[i]); } - uprintf("Will use '%s' for Syslinux\n", iso_report.cfg_path); + uprintf(" Will use '%s' for Syslinux", iso_report.cfg_path); // Extract all of the isolinux.bin files we found to identify their versions for (i=0; i= 5)) ) - uprintf("Warning: Conflict between Isolinux version and the presence of ldlinux.c32...\n"); + uprintf(" Warning: Conflict between Isolinux version and the presence of ldlinux.c32..."); } else { // Couldn't find a version from isolinux.bin. Force set to the versions we embed iso_report.sl_version = embedded_sl_version[has_ldlinux_c32?1:0]; static_sprintf(iso_report.sl_version_str, "%d.%02d", SL_MAJOR(iso_report.sl_version), SL_MINOR(iso_report.sl_version)); - uprintf("Warning: Could not detect Isolinux version - Forcing to %s (embedded)", + uprintf(" Warning: Could not detect Isolinux version - Forcing to %s (embedded)", iso_report.sl_version_str); } } @@ -829,7 +833,7 @@ out: if (tmp != NULL) { for (i=0; i create a new one if (fd == NULL) { - uprintf("Unable to create %s - booting from USB will not work\n", path); + uprintf("Unable to create %s - booting from USB will not work", path); r = 1; } else { fprintf(fd, "DEFAULT loadconfig\n\nLABEL loadconfig\n CONFIG %s\n", iso_report.cfg_path); @@ -886,7 +890,7 @@ out: fprintf(fd, " APPEND %s/\n", iso_report.cfg_path); iso_report.cfg_path[i] = '/'; } - uprintf("Created: %s\n", path); + uprintf("Created: %s", path); } } if (fd != NULL) diff --git a/src/localization.c b/src/localization.c index 4d803929..15509404 100644 --- a/src/localization.c +++ b/src/localization.c @@ -345,12 +345,12 @@ void apply_localization(int dlg_id, HWND hDlg) break; case LC_MOVE: if (hCtrl != NULL) { - ResizeMoveCtrl(hDlg, hCtrl, lcmd->num[0], lcmd->num[1], 0, 0); + ResizeMoveCtrl(hDlg, hCtrl, lcmd->num[0], lcmd->num[1], 0, 0, fScale); } break; case LC_SIZE: if (hCtrl != NULL) { - ResizeMoveCtrl(hDlg, hCtrl, 0, 0, lcmd->num[0], lcmd->num[1]); + ResizeMoveCtrl(hDlg, hCtrl, 0, 0, lcmd->num[0], lcmd->num[1], fScale); } break; } diff --git a/src/localization_data.h b/src/localization_data.h index 1db2f95f..414b6211 100644 --- a/src/localization_data.h +++ b/src/localization_data.h @@ -30,6 +30,7 @@ const loc_control_id control_id[] = { LOC_CTRL(IDD_DIALOG), LOC_CTRL(IDD_ABOUTBOX), LOC_CTRL(IDD_NOTIFICATION), + LOC_CTRL(IDD_SELECTION), LOC_CTRL(IDD_LICENSE), LOC_CTRL(IDD_LOG), LOC_CTRL(IDD_UPDATE_POLICY), @@ -89,6 +90,11 @@ const loc_control_id control_id[] = { LOC_CTRL(IDC_DOWNLOAD_URL), LOC_CTRL(IDC_MD5), LOC_CTRL(IDC_SHA1), + LOC_CTRL(IDC_SELECTION_ICON), + LOC_CTRL(IDC_SELECTION_TEXT), + LOC_CTRL(IDC_SELECTION_LINE), + LOC_CTRL(IDC_SELECTION_CHOICE1), + LOC_CTRL(IDC_SELECTION_CHOICE2), LOC_CTRL(IDS_DEVICE_TXT), LOC_CTRL(IDS_PARTITION_TYPE_TXT), LOC_CTRL(IDS_FILESYSTEM_TXT), @@ -399,6 +405,7 @@ loc_dlg_list loc_dlg[] = { LOC_DLG(IDD_DIALOG), LOC_DLG(IDD_ABOUTBOX), LOC_DLG(IDD_NOTIFICATION), + LOC_DLG(IDD_SELECTION), LOC_DLG(IDD_LICENSE), LOC_DLG(IDD_LOG), LOC_DLG(IDD_UPDATE_POLICY), diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h index b6d584bf..44a190bb 100644 --- a/src/msapi_utf8.h +++ b/src/msapi_utf8.h @@ -207,6 +207,18 @@ static __inline int MessageBoxU(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT return ret; } +static __inline int DrawTextU(HDC hDC, LPCSTR lpText, int nCount, LPRECT lpRect, UINT uFormat) +{ + int ret; + DWORD err = ERROR_INVALID_DATA; + wconvert(lpText); + ret = DrawTextW(hDC, wlpText, nCount, lpRect, uFormat); + err = GetLastError(); + wfree(lpText); + SetLastError(err); + return ret; +} + static __inline int GetWindowTextU(HWND hWnd, char* lpString, int nMaxCount) { int ret = 0; diff --git a/src/resource.h b/src/resource.h index 81c94984..4ff1035c 100644 --- a/src/resource.h +++ b/src/resource.h @@ -5,14 +5,15 @@ #define IDD_DIALOG 101 #define IDD_ABOUTBOX 102 #define IDD_NOTIFICATION 103 -#define IDD_LICENSE 104 -#define IDD_LOG 105 -#define IDD_UPDATE_POLICY 106 -#define IDD_NEW_VERSION 107 -#define IDD_CHECKSUM 108 -#define IDI_ICON 110 -#define IDI_UP 111 -#define IDI_DOWN 112 +#define IDD_SELECTION 104 +#define IDD_LICENSE 105 +#define IDD_LOG 106 +#define IDD_UPDATE_POLICY 107 +#define IDD_NEW_VERSION 108 +#define IDD_CHECKSUM 109 +#define IDI_ICON 120 +#define IDI_UP 121 +#define IDI_DOWN 122 #define IDD_DIALOG_XP 151 #define IDD_ABOUTBOX_XP 152 #define IDD_NOTIFICATION_XP 153 @@ -127,6 +128,11 @@ #define IDC_DOWNLOAD_URL 1070 #define IDC_MD5 1071 #define IDC_SHA1 1072 +#define IDC_SELECTION_ICON 1073 +#define IDC_SELECTION_TEXT 1074 +#define IDC_SELECTION_LINE 1075 +#define IDC_SELECTION_CHOICE1 1076 +#define IDC_SELECTION_CHOICE2 1077 #define IDS_DEVICE_TXT 2000 #define IDS_PARTITION_TYPE_TXT 2001 #define IDS_FILESYSTEM_TXT 2002 @@ -429,7 +435,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 505 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1073 +#define _APS_NEXT_CONTROL_VALUE 1078 #define _APS_NEXT_SYMED_VALUE 4000 #endif #endif diff --git a/src/rufus.c b/src/rufus.c index ca90b54e..f5669acd 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -171,6 +171,15 @@ static float previous_end; // TODO: Remember to update copyright year in stdlg's AboutCallback() WM_INITDIALOG, // localization_data.sh and the .rc when the year changes! +// Set the combo selection according to the data +static __inline void SetComboEntry(HWND hDlg, int data) { + int i; + for (i = 0; i < ComboBox_GetCount(hDlg); i++) { + if (ComboBox_GetItemData(hDlg, i) == data) + IGNORE_RETVAL(ComboBox_SetCurSel(hDlg, i)); + } +} + #define KB 1024LL #define MB 1048576LL #define GB 1073741824LL @@ -975,7 +984,7 @@ static void DisplayISOProps(void) } // TODO: Only report features that are present - uprintf("ISO label: %s", iso_report.label); + uprintf("ISO label: '%s'", iso_report.label); uprintf(" Size: %" PRIu64 " bytes", iso_report.projected_size); uprintf(" Has a >64 chars filename: %s", YesNo(iso_report.has_long_filename)); uprintf(" Has Symlinks: %s", YesNo(iso_report.has_symlinks)); @@ -1005,15 +1014,16 @@ static void DisplayISOProps(void) DWORD WINAPI ISOScanThread(LPVOID param) { int i; - BOOL r; + BOOL is_iso, is_img; if (image_path == NULL) goto out; PrintInfoDebug(0, MSG_202); user_notified = FALSE; EnableControls(FALSE); - r = ExtractISO(image_path, "", TRUE) || IsHDImage(image_path); - if (!r) { + is_iso = ExtractISO(image_path, "", TRUE); + is_img = IsHDImage(image_path); + if (!is_iso && !is_img) { SendMessage(hMainDialog, UM_PROGRESS_EXIT, 0, 0); PrintInfoDebug(0, MSG_203); safe_free(image_path); @@ -1024,11 +1034,13 @@ DWORD WINAPI ISOScanThread(LPVOID param) goto out; } - if (iso_report.is_bootable_img) { - uprintf("'%s' is a %sbootable %s image", image_path, - (iso_report.compression_type != BLED_COMPRESSION_NONE)?"compressed ":"", iso_report.is_vhd?"VHD":"disk"); + if (is_img) { + uprintf(" Image is a %sbootable %s image", + (iso_report.compression_type != BLED_COMPRESSION_NONE) ? "compressed " : "", iso_report.is_vhd ? "VHD" : "disk"); selection_default = BT_IMG; - } else { + } + if (is_iso) { + // Will override BT_IMG above for ISOHybrid selection_default = BT_ISO; DisplayISOProps(); } @@ -1082,7 +1094,7 @@ out: // Move a control along the Y axis according to the advanced mode setting static __inline void MoveCtrlY(HWND hDlg, int nID, float vertical_shift) { - ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, nID), 0, (int)vertical_shift, 0, 0); + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, nID), 0, (int)vertical_shift, 0, 0, fScale); } static void SetPassesTooltip(void) @@ -1211,7 +1223,7 @@ static void ToggleToGo(void) MoveCtrlY(hMainDialog, IDC_EXTRA_PARTITION, dialog_shift); MoveCtrlY(hMainDialog, IDC_RUFUS_MBR, dialog_shift); MoveCtrlY(hMainDialog, IDC_DISK_ID, dialog_shift); - ResizeMoveCtrl(hMainDialog, GetDlgItem(hMainDialog, IDS_FORMAT_OPTIONS_GRP), 0, 0, 0, (int)dialog_shift); + ResizeMoveCtrl(hMainDialog, GetDlgItem(hMainDialog, IDS_FORMAT_OPTIONS_GRP), 0, 0, 0, (int)dialog_shift, fScale); #ifdef RUFUS_TEST MoveCtrlY(hMainDialog, IDC_TEST, dialog_shift); @@ -1724,7 +1736,7 @@ void InitDialog(HWND hDlg) IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), BT_FREEDOS)); IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_036)), BT_ISO)); IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_095)), BT_IMG)); - IGNORE_RETVAL(ComboBox_SetCurSel(hBootType, selection_default)); + SetComboEntry(hBootType, selection_default); // Fill up the MBR masqueraded disk IDs ("8 disks should be enough for anybody") IGNORE_RETVAL(ComboBox_SetItemData(hDiskID, ComboBox_AddStringU(hDiskID, lmprintf(MSG_030, LEFT_TO_RIGHT_MARK "0x80")), 0x80)); for (i=1; i<=7; i++) { @@ -1811,8 +1823,8 @@ void InitDialog(HWND hDlg) // The things one needs to do to keep things looking good... if (nWindowsVersion == WINDOWS_7) { - ResizeMoveCtrl(hDlg, GetDlgItem(hMainDialog, IDS_ADVANCED_OPTIONS_GRP), 0, -1, 0, 2); - ResizeMoveCtrl(hDlg, hProgress, 0, 1, 0, 0); + ResizeMoveCtrl(hDlg, GetDlgItem(hMainDialog, IDS_ADVANCED_OPTIONS_GRP), 0, -1, 0, 2, fScale); + ResizeMoveCtrl(hDlg, hProgress, 0, 1, 0, 0, fScale); } // Subclass the Info box so that we can align its text vertically @@ -2441,6 +2453,24 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA } } + // Ask users how they want to write ISOHybrid images + if ((IsChecked(IDC_BOOT)) && (iso_report.is_bootable_img) && + (ComboBox_GetItemData(hBootType, ComboBox_GetCurSel(hBootType)) == BT_ISO)) { + char* iso_image = lmprintf(MSG_036); + char* dd_image = lmprintf(MSG_095); + i = Selection(lmprintf(MSG_274), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), + lmprintf(MSG_276, iso_image), lmprintf(MSG_277, dd_image)); + if (i < 0) { // Cancel + format_op_in_progress = FALSE; + break; + } else if (i == 2) { + selection_default = BT_IMG; + uprintf("CURSEL = %d", ComboBox_GetCurSel(hBootType)); + SetComboEntry(hBootType, selection_default); + uprintf("CURSEL = %d", ComboBox_GetCurSel(hBootType)); + } + } + GetWindowTextU(hDeviceList, tmp, ARRAYSIZE(tmp)); if (MessageBoxU(hMainDialog, lmprintf(MSG_003, tmp), APPLICATION_NAME, MB_OKCANCEL|MB_ICONWARNING|MB_IS_RTL) == IDCANCEL) { diff --git a/src/rufus.h b/src/rufus.h index 38b8fa97..3c58d559 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -182,7 +182,7 @@ enum action_type { }; /* File system indexes in our FS combobox */ -enum { +enum fs_type { FS_UNKNOWN = -1, FS_FAT16 = 0, FS_FAT32, @@ -392,7 +392,7 @@ extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_unit extern HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); extern INT_PTR MyDialogBox(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc); extern void CenterDialog(HWND hDlg); -extern void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh); +extern void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh, float scale); extern void CreateStatusBar(void); extern void SetTitleBarIcon(HWND hDlg); extern BOOL CreateTaskbarList(void); @@ -403,7 +403,7 @@ extern BOOL CreateTooltip(HWND hControl, const char* message, int duration); extern void DestroyTooltip(HWND hWnd); extern void DestroyAllTooltips(void); extern BOOL Notification(int type, const notification_info* more_info, char* title, char* format, ...); -extern BOOL Question(char* title, char* format, ...); +extern int Selection(char* title, char* message, char* selection1, char* selection2); extern SIZE GetTextSize(HWND hCtrl); extern BOOL ExtractDOS(const char* path); extern BOOL ExtractISO(const char* src_iso, const char* dest_dir, BOOL scan); diff --git a/src/rufus.rc b/src/rufus.rc index 70ce8af2..d11ec2d1 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.3.699" +CAPTION "Rufus 2.3.700" FONT 8, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -132,6 +132,21 @@ BEGIN PUSHBUTTON "Yes",IDYES,154,44,50,14,NOT WS_VISIBLE END +IDD_SELECTION DIALOGEX 0, 0, 312, 71 +STYLE DS_SETFONT | DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME +CAPTION "Rufus" +FONT 8, "Segoe UI Symbol", 400, 0, 0x0 +BEGIN + LTEXT "",IDC_SELECTION_LINE,0,0,312,47 + CONTROL "",IDC_STATIC,"Static",SS_WHITERECT,0,0,312,46 + LTEXT "Message",IDC_SELECTION_TEXT,35,5,269,8 + ICON IDI_ICON,IDC_SELECTION_ICON,6,6,20,20,0,WS_EX_TRANSPARENT + DEFPUSHBUTTON "Cancel",IDCANCEL,254,52,50,14 + PUSHBUTTON "OK",IDOK,196,52,50,14 + CONTROL "Choice 1",IDC_SELECTION_CHOICE1,"Button",BS_AUTORADIOBUTTON,35,18,269,10,WS_EX_TRANSPARENT + CONTROL "Choice 2",IDC_SELECTION_CHOICE2,"Button",BS_AUTORADIOBUTTON,35,31,269,10,WS_EX_TRANSPARENT +END + IDD_UPDATE_POLICY DIALOGEX 0, 0, 287, 198 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Update policy and settings" @@ -281,6 +296,10 @@ BEGIN BEGIN END + IDD_SELECTION, DIALOG + BEGIN + END + IDD_UPDATE_POLICY, DIALOG BEGIN END @@ -298,8 +317,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,3,699,0 - PRODUCTVERSION 2,3,699,0 + FILEVERSION 2,3,700,0 + PRODUCTVERSION 2,3,700,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -316,13 +335,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.3.699" + VALUE "FileVersion", "2.3.700" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.3.699" + VALUE "ProductVersion", "2.3.700" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index 80222fd5..92e535d6 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -54,6 +54,7 @@ PF_TYPE_DECL(WINAPI, LPITEMIDLIST, SHSimpleIDListFromPath, (PCWSTR pszPath)); static HICON hMessageIcon = (HICON)INVALID_HANDLE_VALUE; static char* szMessageText = NULL; static char* szMessageTitle = NULL; +static char *szChoice1, *szChoice2; static HWND hBrowseEdit; extern HWND hUpdatesDlg; static WNDPROC pOrgBrowseWndproc; @@ -538,7 +539,7 @@ SIZE GetBorderSize(HWND hDlg) return size; } -void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh) +void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh, float scale) { RECT rect; POINT point; @@ -552,9 +553,9 @@ void ResizeMoveCtrl(HWND hDlg, HWND hCtrl, int dx, int dy, int dw, int dh) // If the control has any borders (dialog, edit box), take them into account border = GetBorderSize(hCtrl); - MoveWindow(hCtrl, point.x + (int)(fScale*(float)dx), point.y + (int)(fScale*(float)dy), - (rect.right - rect.left) + (int)(fScale*(float)dw + border.cx), - (rect.bottom - rect.top) + (int)(fScale*(float)dh + border.cy), TRUE); + MoveWindow(hCtrl, point.x + (int)(scale*(float)dx), point.y + (int)(scale*(float)dy), + (rect.right - rect.left) + (int)(scale*(float)dw + border.cx), + (rect.bottom - rect.top) + (int)(scale*(float)dh + border.cy), TRUE); InvalidateRect(hCtrl, NULL, TRUE); } @@ -804,6 +805,136 @@ BOOL Notification(int type, const notification_info* more_info, char* title, cha return ret; } +/* +* Custom dialog for radio button selection dialog +*/ +INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT loc; + int i, dh, r = -1; + // Prevent resizing + static LRESULT disabled[9] = { HTLEFT, HTRIGHT, HTTOP, HTBOTTOM, HTSIZE, + HTTOPLEFT, HTTOPRIGHT, HTBOTTOMLEFT, HTBOTTOMRIGHT }; + static HBRUSH background_brush, separator_brush; + // To use the system message font + NONCLIENTMETRICS ncm; + RECT rect; + HFONT hDlgFont; + HWND hCtrl; + HDC dc; + + switch (message) { + case WM_INITDIALOG: + // Get the system message box font. See http://stackoverflow.com/a/6057761 + ncm.cbSize = sizeof(ncm); + // If we're compiling with the Vista SDK or later, the NONCLIENTMETRICS struct + // will be the wrong size for previous versions, so we need to adjust it. +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) + if (nWindowsVersion >= WINDOWS_VISTA) { + // In versions of Windows prior to Vista, the iPaddedBorderWidth member + // is not present, so we need to subtract its size from cbSize. + ncm.cbSize -= sizeof(ncm.iPaddedBorderWidth); + } +#endif + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); + hDlgFont = CreateFontIndirect(&(ncm.lfMessageFont)); + // Set the dialog to use the system message box font + SendMessage(hDlg, WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0)); + SendMessage(GetDlgItem(hDlg, IDC_SELECTION_TEXT), WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0)); + SendMessage(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1), WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0)); + SendMessage(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0)); + SendMessage(GetDlgItem(hDlg, IDYES), WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0)); + SendMessage(GetDlgItem(hDlg, IDNO), WM_SETFONT, (WPARAM)hDlgFont, MAKELPARAM(TRUE, 0)); + + apply_localization(IDD_SELECTION, hDlg); + background_brush = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT)); + separator_brush = CreateSolidBrush(GetSysColor(COLOR_3DLIGHT)); + SetTitleBarIcon(hDlg); + CenterDialog(hDlg); + // Change the default icon and set the text + Static_SetIcon(GetDlgItem(hDlg, IDC_SELECTION_ICON), LoadIcon(NULL, IDI_QUESTION)); + SetWindowTextU(hDlg, szMessageTitle); + SetWindowTextU(GetDlgItem(hDlg, IDCANCEL), lmprintf(MSG_007)); + SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_TEXT), szMessageText); + SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1), szChoice1); + SetWindowTextU(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), szChoice2); + + // Move/Resize the controls as needed to fit our text + hCtrl = GetDlgItem(hDlg, IDC_SELECTION_TEXT); + dc = GetDC(hCtrl); + SelectFont(dc, hDlgFont); // Yes, you *MUST* reapply the font to the DC, even after SetWindowText! + GetWindowRect(hCtrl, &rect); + dh = rect.bottom - rect.top; + DrawTextU(dc, szMessageText, -1, &rect, DT_CALCRECT | DT_WORDBREAK); + dh = rect.bottom - rect.top - dh; + ReleaseDC(hCtrl, dc); + + ResizeMoveCtrl(hDlg, hCtrl, 0, 0, 0, dh, 1.0f); + ResizeMoveCtrl(hDlg, hDlg, 0, 0, 0, dh, 1.0f); + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, -1), 0, 0, 0, dh, 1.0f); // IDC_STATIC = -1 + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDC_SELECTION_LINE), 0, dh, 0, 0, 1.0f); + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDC_SELECTION_CHOICE1), 0, dh, 0, 0, 1.0f); + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), 0, dh, 0, 0, 1.0f); + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDOK), 0, dh, 0, 0, 1.0f); + ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, IDCANCEL), 0, dh, 0, 0, 1.0f); + CenterDialog(hDlg); + + // Set the radio selection + Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1), BST_CHECKED); + Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), BST_UNCHECKED); + return (INT_PTR)TRUE; + case WM_CTLCOLORSTATIC: + // Change the background colour for static text and icon + SetBkMode((HDC)wParam, TRANSPARENT); + if ((HWND)lParam == GetDlgItem(hDlg, IDC_NOTIFICATION_LINE)) { + return (INT_PTR)separator_brush; + } + return (INT_PTR)background_brush; + case WM_NCHITTEST: + // Check coordinates to prevent resize actions + loc = DefWindowProc(hDlg, message, wParam, lParam); + for (i = 0; i < 9; i++) { + if (loc == disabled[i]) { + return (INT_PTR)TRUE; + } + } + return (INT_PTR)FALSE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + if (Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2)) == BST_CHECKED) + r = 2; + else + r = 1; + // Fall through + case IDNO: + case IDCANCEL: + EndDialog(hDlg, r); + return (INT_PTR)TRUE; + } + break; + } + return (INT_PTR)FALSE; +} + +/* +* Display a selection question +*/ +int Selection(char* title, char* message, char* choice1, char* choice2) +{ + int ret; + + dialog_showing++; + szMessageTitle = title; + szMessageText = message; + szChoice1 = choice1; + szChoice2 = choice2; + ret = (int)MyDialogBox(hMainInstance, IDD_SELECTION, hMainDialog, SelectionCallback); + dialog_showing--; + + return ret; +} + static struct { HWND hTip; // Tooltip handle HWND hCtrl; // Handle of the control the tooltip belongs to diff --git a/src/vhd.c b/src/vhd.c index 2224a32b..f5a97cb1 100644 --- a/src/vhd.c +++ b/src/vhd.c @@ -283,19 +283,20 @@ BOOL IsHDImage(const char* path) uint32_t checksum, old_checksum; LARGE_INTEGER ptr; + uprintf("Disk image analysis:"); handle = CreateFileU(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { - uprintf("Could not open image '%s'", path); + uprintf(" Could not open image '%s'", path); goto out; } iso_report.is_bootable_img = (BOOLEAN)IsCompressedBootableImage(path); if (iso_report.compression_type == BLED_COMPRESSION_NONE) - iso_report.is_bootable_img = (BOOLEAN)AnalyzeMBR(handle, "Image"); + iso_report.is_bootable_img = (BOOLEAN)AnalyzeMBR(handle, " Image"); if (!GetFileSizeEx(handle, &liImageSize)) { - uprintf("Could not get image size: %s", WindowsErrorString()); + uprintf(" Could not get image size: %s", WindowsErrorString()); goto out; } iso_report.projected_size = (uint64_t)liImageSize.QuadPart; @@ -306,14 +307,14 @@ BOOL IsHDImage(const char* path) ptr.QuadPart = iso_report.projected_size - size; if ( (footer == NULL) || (!SetFilePointerEx(handle, ptr, NULL, FILE_BEGIN)) || (!ReadFile(handle, footer, size, &size, NULL)) || (size != sizeof(vhd_footer)) ) { - uprintf("Could not read VHD footer"); + uprintf(" Could not read VHD footer"); goto out; } if (memcmp(footer->cookie, conectix_str, sizeof(footer->cookie)) == 0) { iso_report.projected_size -= sizeof(vhd_footer); if ( (bswap_uint32(footer->file_format_version) != VHD_FOOTER_FILE_FORMAT_V1_0) || (bswap_uint32(footer->disk_type) != VHD_FOOTER_TYPE_FIXED_HARD_DISK)) { - uprintf("Unsupported type of VHD image"); + uprintf(" Unsupported type of VHD image"); iso_report.is_bootable_img = FALSE; goto out; } @@ -324,9 +325,9 @@ BOOL IsHDImage(const char* path) checksum += ((uint8_t*)footer)[i]; checksum = ~checksum; if (checksum != old_checksum) - uprintf("Warning: VHD footer seems corrupted (checksum: %04X, expected: %04X)", old_checksum, checksum); + uprintf(" Warning: VHD footer seems corrupted (checksum: %04X, expected: %04X)", old_checksum, checksum); // Need to remove the footer from our payload - uprintf("Image is a Fixed Hard Disk VHD file"); + uprintf(" Image is a Fixed Hard Disk VHD file"); iso_report.is_vhd = TRUE; } }