diff --git a/README.md b/README.md index 1bf6347d..80f8934a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Rufus: The Reliable USB Formatting Utility ========================================== -![Rufus logo](https://raw.githubusercontent.com/pbatard/rufus/master/res/icon-set/rufus-256.png) +![Rufus logo](https://raw.githubusercontent.com/pbatard/rufus/master/res/icon-set/rufus-128.png) Features -------- diff --git a/res/localization/rufus.loc b/res/localization/rufus.loc index 3bb0699d..c7688d8d 100644 --- a/res/localization/rufus.loc +++ b/res/localization/rufus.loc @@ -518,6 +518,8 @@ t MSG_268 "Applying Windows image..." t MSG_269 "Preserve timestamps" t MSG_270 "USB debug" t MSG_271 "Computing image checksum: %0.1f%% completed" +t MSG_272 "Click here to compute the SHA-1 and MD5 checksums for the selected image" +t MSG_273 "Change the application language" ################################################################################ ############################# TRANSLATOR END COPY ############################## diff --git a/src/resource.h b/src/resource.h index 7b5823c3..de43eda0 100644 --- a/src/resource.h +++ b/src/resource.h @@ -94,6 +94,7 @@ #define IDC_DISK_ID 1022 #define IDC_EXTRA_PARTITION 1023 #define IDC_ENABLE_FIXED_DISKS 1024 +#define IDC_HASH 1025 #define IDC_ABOUT_LICENSE 1030 #define IDC_ABOUT_ICON 1031 #define IDC_ABOUT_UPDATES 1032 diff --git a/src/rufus.c b/src/rufus.c index 62cc4a3a..6c172761 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -103,6 +103,7 @@ static BOOL log_displayed = FALSE; static BOOL iso_provided = FALSE; static BOOL user_notified = FALSE; static BOOL relaunch = FALSE; +static BOOL hash_enabled = FALSE; extern BOOL force_large_fat32, enable_iso, enable_joliet, enable_rockridge, enable_ntfs_compression, preserve_timestamps, usb_debug; extern uint8_t* grub2_buf; extern long grub2_len; @@ -131,7 +132,7 @@ float fScale = 1.0f; int default_fs; uint32_t dur_mins, dur_secs; HWND hDeviceList, hPartitionScheme, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog = NULL; -HWND hLogDlg = NULL, hProgress = NULL, hInfo, hDiskID; +HWND hLogDlg = NULL, hProgress = NULL, hInfo, hDiskID, hHash; BOOL use_own_c32[NB_OLD_C32] = {FALSE, FALSE}, detect_fakes = TRUE, mbr_selected_by_user = FALSE; BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE, right_to_left_mode = FALSE; BOOL enable_HDDs = FALSE, advanced_mode = TRUE, force_update = FALSE, use_fake_units = TRUE; @@ -804,6 +805,14 @@ void UpdateProgress(int op, float percent) SetTaskbarProgressValue(pos, MAX_PROGRESS); } +static void EnableHash(BOOL bEnable) +{ + // Can't use EnableWindow() for hHash as it overrides our WM_PAINT suppression + // and we'd end up with an out of place disabled button + hash_enabled = bEnable; + SendMessage(hStatus, SB_SETTEXTW, SBT_OWNERDRAW | SB_SECTION_MIDDLE, 0); +} + /* * Toggle controls according to operation */ @@ -818,6 +827,7 @@ static void EnableControls(BOOL bEnable) EnableWindow(hNBPasses, bEnable); EnableWindow(GetDlgItem(hMainDialog, IDC_ADVANCED), bEnable); EnableWindow(hLangToolbar, bEnable); + EnableHash(bEnable); EnableWindow(GetDlgItem(hMainDialog, IDC_ENABLE_FIXED_DISKS), bEnable); SetDlgItemTextU(hMainDialog, IDCANCEL, lmprintf(bEnable?MSG_006:MSG_007)); if (selection_default == BT_IMG) @@ -1063,7 +1073,6 @@ DWORD WINAPI ISOScanThread(LPVOID param) InvalidateRect(hMainDialog, NULL, TRUE); out: - SendMessageLU(hStatus, SB_SETTEXTW, SBT_OWNERDRAW | SB_SECTION_MIDDLE, ""); PrintInfo(0, MSG_210); ExitThread(0); } @@ -1102,8 +1111,9 @@ static void ToggleAdvanced(void) MoveWindow(hMainDialog, rect.left, rect.top, point.x, point.y + (int)(fScale*dialog_shift), TRUE); - // Move the status bar up or down + // Move the controls up or down MoveCtrlY(hMainDialog, IDC_STATUS, dialog_shift); + MoveCtrlY(hMainDialog, IDC_HASH, dialog_shift); MoveCtrlY(hMainDialog, IDC_START, dialog_shift); MoveCtrlY(hMainDialog, IDC_INFO, dialog_shift); MoveCtrlY(hMainDialog, IDC_PROGRESS, dialog_shift); @@ -1185,6 +1195,7 @@ static void ToggleToGo(void) // Move the controls up or down MoveCtrlY(hMainDialog, IDC_STATUS, dialog_shift); + MoveCtrlY(hMainDialog, IDC_HASH, dialog_shift); MoveCtrlY(hMainDialog, IDC_START, dialog_shift); MoveCtrlY(hMainDialog, IDC_INFO, dialog_shift); MoveCtrlY(hMainDialog, IDC_PROGRESS, dialog_shift); @@ -1692,6 +1703,8 @@ void InitDialog(HWND hDlg) selection_default = BT_FREEDOS; // Create the status line and initialize the taskbar icon for progress overlay CreateStatusBar(); + // Create the hash sign on the status bar + EnableHash(FALSE); CreateTaskbarList(); SetTaskbarProgressState(TASKBAR_NORMAL); @@ -1842,6 +1855,8 @@ void InitDialog(HWND hDlg) CreateTooltip(GetDlgItem(hDlg, IDC_ABOUT), lmprintf(MSG_172), -1); CreateTooltip(GetDlgItem(hDlg, IDC_WINDOWS_INSTALL), lmprintf(MSG_199), -1); CreateTooltip(GetDlgItem(hDlg, IDC_WINDOWS_TO_GO), lmprintf(MSG_200), -1); + CreateTooltip(hHash, lmprintf(MSG_272), -1); + CreateTooltip(hLangToolbar, lmprintf(MSG_273), -1); // Set a label for the Advanced Mode and Select Image button for screen readers if (nWindowsVersion > WINDOWS_XP) { @@ -1852,9 +1867,6 @@ void InitDialog(HWND hDlg) ToggleAdvanced(); // We start in advanced mode => go to basic mode ToggleToGo(); - // Create the hash sign on the status bar - SendMessageLU(hStatus, SB_SETTEXTW, SBT_OWNERDRAW | SB_SECTION_MIDDLE, ""); - // Process commandline parameters if (iso_provided) { // Simulate a button click for ISO selection @@ -2055,12 +2067,12 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA #endif return (INT_PTR)FALSE; - // The things one must do to get an ellipsis text alignment on the status bar... + // The things one must do to get an ellipsis and text alignment on the status bar... case WM_DRAWITEM: if (wParam == IDC_STATUS) { pDI = (DRAWITEMSTRUCT*)lParam; pDI->rcItem.top -= (int)((4.0f * fScale) - 6.0f); - pDI->rcItem.left += (int)(4.0f * fScale); + pDI->rcItem.left += (int)(((pDI->itemID == SB_SECTION_MIDDLE)?-2.0f:4.0f) * fScale); SetBkMode(pDI->hDC, TRANSPARENT); switch(pDI->itemID) { case SB_SECTION_LEFT: @@ -2069,8 +2081,8 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA DT_LEFT|DT_END_ELLIPSIS|DT_PATH_ELLIPSIS, NULL); return (INT_PTR)TRUE; case SB_SECTION_MIDDLE: - SetTextColor(pDI->hDC, (image_path==NULL)?GetSysColor(COLOR_3DSHADOW):GetSysColor(COLOR_BTNTEXT)); - DrawTextExA(pDI->hDC, "#", -1, &pDI->rcItem, DT_LEFT, NULL); + SetTextColor(pDI->hDC, ((image_path==NULL)||(!hash_enabled))?GetSysColor(COLOR_3DSHADOW):GetSysColor(COLOR_BTNTEXT)); + DrawTextExA(pDI->hDC, "#", -1, &pDI->rcItem, DT_CENTER, NULL); return (INT_PTR)TRUE; case SB_SECTION_RIGHT: SetTextColor(pDI->hDC, GetSysColor(COLOR_3DSHADOW)); @@ -2080,45 +2092,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA } break; - // Detect a click on the "hash" sign in the status bar - case WM_PARENTNOTIFY: - if (wParam == WM_LBUTTONDOWN) { - GetClientRect(hMainDialog, &DialogRect); - MessagePos = GetMessagePos(); - Point.x = GET_X_LPARAM(MessagePos); - Point.y = GET_Y_LPARAM(MessagePos); - ScreenToClient(hDlg, &Point); - if ( (Point.x >= DialogRect.right - (int)(SB_EDGE_1*fScale)) && - (Point.x <= DialogRect.right - (int)(SB_EDGE_2*fScale)) && - ((format_thid == NULL) && (image_path != NULL)) ) { - FormatStatus = 0; - format_op_in_progress = TRUE; - no_confirmation_on_cancel = TRUE; - // Reset all progress bars - SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0); - SetTaskbarProgressState(TASKBAR_NORMAL); - SetTaskbarProgressValue(0, MAX_PROGRESS); - SendMessage(hProgress, PBM_SETPOS, 0, 0); - // Disable all controls except cancel - EnableControls(FALSE); - InitProgress(FALSE); - format_thid = CreateThread(NULL, 0, SumThread, NULL, 0, NULL); - if (format_thid != NULL) { - PrintInfo(0, -1); - timer = 0; - safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); - SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); - SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); - } else { - uprintf("Unable to start checksum thread"); - FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD); - PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0); - format_op_in_progress = FALSE; - } - } - } - break; - case WM_COMMAND: if ((LOWORD(wParam) >= UM_LANGUAGE_MENU) && (LOWORD(wParam) < UM_LANGUAGE_MENU_MAX)) { selected_language = LOWORD(wParam) - UM_LANGUAGE_MENU; @@ -2341,6 +2314,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA iso_provided = FALSE; // One off thing... } else { safe_free(image_path); + EnableHash(FALSE); image_path = FileDialog(FALSE, NULL, (selection_default == BT_IMG)?&img_ext:&iso_ext, 0); if (image_path == NULL) { CreateTooltip(hSelectISO, lmprintf(MSG_173), -1); @@ -2446,6 +2420,34 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA if (format_thid == NULL) format_op_in_progress = FALSE; break; + case IDC_HASH: + if ((format_thid == NULL) && (image_path != NULL) && (hash_enabled)) { + FormatStatus = 0; + format_op_in_progress = TRUE; + no_confirmation_on_cancel = TRUE; + // Reset all progress bars + SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0); + SetTaskbarProgressState(TASKBAR_NORMAL); + SetTaskbarProgressValue(0, MAX_PROGRESS); + SendMessage(hProgress, PBM_SETPOS, 0, 0); + // Disable all controls except cancel + EnableControls(FALSE); + InitProgress(FALSE); + format_thid = CreateThread(NULL, 0, SumThread, NULL, 0, NULL); + if (format_thid != NULL) { + PrintInfo(0, -1); + timer = 0; + safe_sprintf(szTimer, sizeof(szTimer), "00:00:00"); + SendMessageA(hStatus, SB_SETTEXTA, SBT_OWNERDRAW | SB_SECTION_RIGHT, (LPARAM)szTimer); + SetTimer(hMainDialog, TID_APP_TIMER, 1000, ClockTimer); + } else { + uprintf("Unable to start checksum thread"); + FormatStatus = ERROR_SEVERITY_ERROR | FAC(FACILITY_STORAGE) | APPERR(ERROR_CANT_START_THREAD); + PostMessage(hMainDialog, UM_FORMAT_COMPLETED, (WPARAM)FALSE, 0); + format_op_in_progress = FALSE; + } + } + break; default: return (INT_PTR)FALSE; } diff --git a/src/rufus.h b/src/rufus.h index 718ff808..0ee4d9f1 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -357,7 +357,7 @@ enum WindowsVersion { extern HINSTANCE hMainInstance; extern HWND hMainDialog, hLogDlg, hStatus, hDeviceList, hCapacity; extern HWND hPartitionScheme, hFileSystem, hClusterSize, hLabel, hBootType, hNBPasses, hLog; -extern HWND hInfo, hProgress, hDiskID; +extern HWND hInfo, hProgress, hDiskID, hHash; extern float fScale; extern char szFolderPath[MAX_PATH], app_dir[MAX_PATH], system_dir[MAX_PATH]; extern char* image_path; diff --git a/src/rufus.rc b/src/rufus.rc index 76e9ec1d..af0a6d9c 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.688" +CAPTION "Rufus 2.3.689" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -157,7 +157,7 @@ END IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.3.688" +CAPTION "Rufus 2.3.689" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -283,7 +283,7 @@ END IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.3.688" +CAPTION "Rufus 2.3.689" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -415,7 +415,7 @@ END IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.3.688" +CAPTION "Rufus 2.3.689" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -671,8 +671,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,3,688,0 - PRODUCTVERSION 2,3,688,0 + FILEVERSION 2,3,689,0 + PRODUCTVERSION 2,3,689,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -689,13 +689,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.3.688" + VALUE "FileVersion", "2.3.689" 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.688" + VALUE "ProductVersion", "2.3.689" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index e39d95e1..88e31886 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -56,7 +56,7 @@ static char* szMessageText = NULL; static char* szMessageTitle = NULL; static HWND hBrowseEdit; extern HWND hUpdatesDlg; -static WNDPROC pOrgBrowseWndproc; +static WNDPROC pOrgBrowseWndproc, pOrgHashWdnProc; static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8}; static BOOL notification_is_question; static const notification_info* notification_more_info; @@ -395,28 +395,68 @@ fallback: return filepath; } +// Subclass the Hash button, so that it will be active but not display in the UI +static INT_PTR CALLBACK HashCallback(HWND hCtrl, UINT message, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT ps; + if (message == WM_PAINT) { + // Even though we really don't want to paint anything, we *MUST* call Begin/EndPaint + BeginPaint(hCtrl , &ps); + EndPaint(hCtrl, &ps); + return TRUE; + } + return CallWindowProc(pOrgHashWdnProc, hCtrl, message, wParam, lParam); +} + /* * Create the application status bar */ void CreateStatusBar(void) { RECT rect; + LONG height; int edge[3]; + HFONT hFont; - // Create the status bar. - hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, - 0, 0, 0, 0, hMainDialog, (HMENU)IDC_STATUS, hMainInstance, NULL); + // Create the status bar (WS_CLIPSIBLINGS since we have an overlapping button) + hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_TOOLTIPS | WS_CLIPSIBLINGS, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hMainDialog, + (HMENU)IDC_STATUS, hMainInstance, NULL); + + // Keep track of the status bar height + GetClientRect(hStatus, &rect); + height = rect.bottom; // Create 3 status areas GetClientRect(hMainDialog, &rect); edge[0] = rect.right - (int)(SB_EDGE_1 * fScale); edge[1] = rect.right - (int)(SB_EDGE_2 * fScale); edge[2] = rect.right; - SendMessage(hStatus, SB_SETPARTS, (WPARAM) ARRAYSIZE(edge), (LPARAM)&edge); + SendMessage(hStatus, SB_SETPARTS, (WPARAM)ARRAYSIZE(edge), (LPARAM)&edge); // NB: To add an icon on the status bar, you can use something like this: -// SendMessage(hStatus, SB_SETICON, (WPARAM) 1, (LPARAM)LoadImage(GetLibraryHandle("rasdlg"), -// MAKEINTRESOURCE(50), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR | LR_SHARED)); + // SendMessage(hStatus, SB_SETICON, (WPARAM) 1, (LPARAM)LoadImage(GetLibraryHandle("rasdlg"), + // MAKEINTRESOURCE(50), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR | LR_SHARED)); + + // This is supposed to create a toolips for a statusbar section (when SBARS_TOOLTIPS is in use)... but doesn't :( + // SendMessageLU(hStatus, SB_SETTIPTEXT, (WPARAM)2, (LPARAM)"HELLO"); + + // Manually create the Hash button on the status bar + hHash = CreateWindowEx(WS_EX_TRANSPARENT, WC_BUTTON, TEXT("#"), WS_CHILD | WS_VISIBLE | WS_TABSTOP, + edge[0], rect.bottom - height +1, edge[1] - edge[0] - 1, height - 1, hMainDialog, + (HMENU)IDC_HASH, hMainInstance, NULL); + + // Subclass our button so that we can hide it from the UI + pOrgHashWdnProc = (WNDPROC)SetWindowLongPtr(hHash, GWLP_WNDPROC, (LONG_PTR)HashCallback); + + // Set the font we'll use to display the '#' sign + hFont = CreateFontA(-MulDiv(10, GetDeviceCaps(GetDC(hMainDialog), LOGPIXELSY), 72), + 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, DEFAULT_CHARSET, + 0, 0, PROOF_QUALITY, 0, (nWindowsVersion >= WINDOWS_VISTA)?"Segoe UI":"Arial Unicode MS"); + SendDlgItemMessageA(hMainDialog, IDC_HASH, WM_SETFONT, (WPARAM)hFont, TRUE); + + // Update our Z-order, just to be on the safe side + SetWindowPos(hStatus, hHash, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); } /* @@ -813,6 +853,10 @@ BOOL CreateTooltip(HWND hControl, const char* message, int duration) toolInfo.cbSize = sizeof(toolInfo); toolInfo.hwnd = ttlist[i].hTip; // Set to the tooltip itself to ease up subclassing toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS | ((right_to_left_mode)?TTF_RTLREADING:0); + // set TTF_NOTBUTTON and TTF_CENTERTIP if it isn't a button + if (!(SendMessage(hControl, WM_GETDLGCODE, 0, 0) & DLGC_BUTTON)) + toolInfo.uFlags |= 0x80000000L | TTF_CENTERTIP; + toolInfo.uId = (UINT_PTR)hControl; toolInfo.lpszText = LPSTR_TEXTCALLBACKW; SendMessageW(ttlist[i].hTip, TTM_ADDTOOLW, 0, (LPARAM)&toolInfo);