From 76c64d49ea96719bf1a5d185053619001b0aa533 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 24 Sep 2023 01:26:02 +0200 Subject: Windows: Add tooltip message and help button for new option to disable memory protection Also a dedicated page in the documentation was added for it. --- src/Common/Dlgcode.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Common/Dlgcode.h | 3 ++ src/Common/Language.xml | 3 +- src/Common/Resource.h | 3 +- src/Mount/Mount.c | 24 ++++++++++ src/Mount/Mount.rc | 3 +- src/Mount/Resource.h | 6 +-- src/Setup/Setup.rc | 5 +- src/Setup/Wizard.c | 26 +++++++++++ 9 files changed, 187 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 325a2579..a81dc984 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -1759,6 +1759,88 @@ void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT h } } +// Resizes width of a checkbox according to actual width in pixels of its label text (font size is taken into account) +void AccommodateCheckBoxTextWidth (HWND hwndDlg, UINT ctrlId) +{ + RECT rec; + HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); + int width, origWidth, origHeight; + int horizSubOffset; + wchar_t text [MAX_URL_LENGTH]; + HFONT hFont = (HFONT) SendDlgItemMessage (hwndDlg, ctrlId, WM_GETFONT, 0, 0); + + // Resize the field according to its length and font size and move if centered or right-aligned + + GetWindowTextW (hwndCtrl, text, sizeof (text) / sizeof (wchar_t)); + + width = GetTextGfxWidth (hwndCtrl, text, hFont); + + // add to width variable value the width of the checkbox square. We use SM_CXMENUCHECK which is a little larger than actual width + width += GetSystemMetrics(SM_CXMENUCHECK); + + + GetClientRect (hwndCtrl, &rec); + origWidth = rec.right; + origHeight = rec.bottom; + + if (width >= 0 + && (origWidth > width)) // The original width of the field is the maximum allowed size + { + horizSubOffset = origWidth - width; + + // Resize the text field + SetWindowPos (hwndCtrl, 0, 0, 0, + origWidth - horizSubOffset, + origHeight, + SWP_NOMOVE | SWP_NOZORDER); + + InvalidateRect (hwndCtrl, NULL, TRUE); + } +} + +// makes controls contiguous by moving the second control right next to the first one horizontally +void MakeControlsContiguous(HWND hwndDlg, UINT ctrl1ID, UINT ctrl2ID) { + HWND hwndCtrl1 = GetDlgItem(hwndDlg, ctrl1ID); + HWND hwndCtrl2 = GetDlgItem(hwndDlg, ctrl2ID); + RECT rect1, rect2; + POINT pt1, pt2; + int newLeftPosition; + + // Exit silently if one or both controls are missing + if (!hwndCtrl1 || !hwndCtrl2) { + return; + } + + + GetWindowRect(hwndCtrl1, &rect1); + GetWindowRect(hwndCtrl2, &rect2); + + // Convert the top-right point of the first control from screen to client coordinates + pt1.x = rect1.right; + pt1.y = rect1.top; + if (!ScreenToClient(hwndDlg, &pt1)) { + return; // Exit if the conversion fails + } + + // Convert the top-left point of the second control from screen to client coordinates + pt2.x = rect2.left; + pt2.y = rect2.top; + if (!ScreenToClient(hwndDlg, &pt2)) { + return; // Exit if the conversion fails + } + + // Ensure the second control is always placed to the right of the first one + newLeftPosition = pt1.x + 1; + + if (pt2.x < pt1.x) { // if the second control is to the left of the first one + newLeftPosition += (pt1.x - pt2.x); + } + + // Move the second control to its new position + SetWindowPos(hwndCtrl2, NULL, newLeftPosition, pt2.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); +} + + // Note that the user can still close the window by right-clicking its taskbar icon and selecting 'Close window', or by pressing Alt-F4, or using the Task Manager. void DisableCloseButton (HWND hwndDlg) { @@ -2129,6 +2211,42 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam return 0; } +HWND CreateToolTip(int toolID, HWND hDlg, const char* strID) +{ + if (!toolID || !hDlg) + { + return FALSE; + } + + // Create the tooltip. + HWND hwndTip = CreateWindowExW(NULL, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_ALWAYSTIP | TTS_NOPREFIX | TTS_BALLOON, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hDlg, NULL, + hInst, NULL); + + if (!hwndTip) + { + return (HWND)NULL; + } + + // Associate the tooltip with the tool. + TOOLINFOW toolInfo = { 0 }; + toolInfo.cbSize = sizeof(toolInfo); + toolInfo.hwnd = hDlg; + toolInfo.uFlags = TTF_SUBCLASS | TTF_IDISHWND; + toolInfo.uId = (UINT_PTR) GetDlgItem(hDlg, toolID); + toolInfo.lpszText = GetString(strID); + + // set tooltip maximum width + SendMessage(hwndTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM) 300); + + SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo); + + return hwndTip; +} + static HWND StaticModelessWaitDlgHandle = NULL; @@ -11093,6 +11211,10 @@ void Applink (const char *dest) { StringCbCopyW (page, sizeof (page),L"Personal%20Iterations%20Multiplier%20%28PIM%29.html"); } + else if (strcmp(dest, "memoryprotection") == 0) + { + StringCbCopyW (page, sizeof (page),L"VeraCrypt%20Memory%20Protection.html"); + } else { StringCbCopyW (url, sizeof (url),TC_APPLINK); diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 7947fcf9..3611371d 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -327,6 +327,7 @@ void HandCursor (); void AddComboPair (HWND hComboBox, const wchar_t *lpszItem, int value); void SelectAlgo ( HWND hComboBox , int *nCipher ); void PopulateWipeModeCombo (HWND hComboBox, BOOL bNA, BOOL bInPlaceEncryption, BOOL bHeaderWipe); +HWND CreateToolTip(int toolID, HWND hDlg, const char* strID); wchar_t *GetWipeModeName (WipeAlgorithmId modeId); wchar_t *GetPathType (const wchar_t *path, BOOL bUpperCase, BOOL *bIsPartition); LRESULT CALLBACK CustomDlgProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam ); @@ -532,6 +533,8 @@ void EnableCloseButton (HWND hwndDlg); void ToBootPwdField (HWND hwndDlg, UINT ctrlId); void ToNormalPwdField (HWND hwndDlg, UINT ctrlId); void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT hFont); +void AccommodateCheckBoxTextWidth (HWND hwndDlg, UINT ctrlId); +void MakeControlsContiguous(HWND hwndDlg, UINT ctrl1ID, UINT ctrl2ID); BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize); BOOL GetSysDevicePaths (HWND hwndDlg); BOOL DoDriverInstall (HWND hwndDlg); diff --git a/src/Common/Language.xml b/src/Common/Language.xml index ddb20159..32930193 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1633,7 +1633,8 @@ Extending file system ...\n Warning: The system partition you attempted to mount was not fully encrypted. As a safety measure to prevent potential corruption or unwanted modifications, volume '%s' was mounted as read-only. Important information on using third-party file extensions - Disable memory protection in VeraCrypt + Disable memory protection for Accessibility tools compatibility + WARNING: Disabling memory protection significantly reduces security. Enable this option ONLY if you rely on Accessibility tools, like Screen Readers, to interact with VeraCrypt's UI. diff --git a/src/Common/Resource.h b/src/Common/Resource.h index b6ad14c0..0098542e 100644 --- a/src/Common/Resource.h +++ b/src/Common/Resource.h @@ -227,6 +227,7 @@ #define IDC_KEYFILES_SIZE_UNIT 5143 #define IDC_LINK_KEYFILES_EXTENSIONS_WARNING 5144 #define IDC_DISABLE_MEMORY_PROTECTION 5145 +#define IDC_DISABLE_MEMORY_PROTECTION_HELP 5146 // Next default values for new objects // @@ -235,7 +236,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 578 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 5146 +#define _APS_NEXT_CONTROL_VALUE 5147 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 28418a44..76de34b6 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -11574,6 +11574,7 @@ void NotifyService (DWORD dwNotifyCmd) static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { + static HWND hDisableMemProtectionTooltipWnd = NULL; WORD lw = LOWORD (wParam); switch (msg) @@ -11652,9 +11653,24 @@ static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_HW_ACCELERATION); ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION); + + hDisableMemProtectionTooltipWnd = CreateToolTip (IDC_DISABLE_MEMORY_PROTECTION, hwndDlg, "DISABLE_MEMORY_PROTECTION_WARNING"); + // make IDC_DISABLE_MEMORY_PROTECTION control fit the text so that the tooltip is shown only when mouse is over the text + AccommodateCheckBoxTextWidth(hwndDlg, IDC_DISABLE_MEMORY_PROTECTION); + // make the help button adjacent to the checkbox + MakeControlsContiguous(hwndDlg, IDC_DISABLE_MEMORY_PROTECTION, IDC_DISABLE_MEMORY_PROTECTION_HELP); } return 0; + // handle message to destroy hDisableMemProtectionTooltipWnd when the dialog is closed + case WM_DESTROY: + if (hDisableMemProtectionTooltipWnd) + { + DestroyWindow (hDisableMemProtectionTooltipWnd); + hDisableMemProtectionTooltipWnd = NULL; + } + break; + case WM_COMMAND: switch (lw) @@ -11852,10 +11868,18 @@ static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM BOOL originalDisableMemoryProtection = !ReadMemoryProtectionConfig(); if (disableMemoryProtection != originalDisableMemoryProtection) { + if (disableMemoryProtection) + { + Warning ("DISABLE_MEMORY_PROTECTION_WARNING", hwndDlg); + } + Warning ("SETTING_REQUIRES_REBOOT", hwndDlg); } } return 1; + case IDC_DISABLE_MEMORY_PROTECTION_HELP: + Applink ("memoryprotection"); + return 1; case IDC_BENCHMARK: Benchmark (hwndDlg); return 1; diff --git a/src/Mount/Mount.rc b/src/Mount/Mount.rc index 9e823493..553914b5 100644 --- a/src/Mount/Mount.rc +++ b/src/Mount/Mount.rc @@ -345,8 +345,9 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,237,335,10 CONTROL "Activate encryption of keys and passwords stored in RAM",IDC_ENABLE_RAM_ENCRYPTION, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,250,337,10 - CONTROL "Disable memory protection in VeraCrypt",IDC_DISABLE_MEMORY_PROTECTION, + CONTROL "Disable memory protection for Accessibility tools compatibility",IDC_DISABLE_MEMORY_PROTECTION, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,263,339,10 + PUSHBUTTON "?",IDC_DISABLE_MEMORY_PROTECTION_HELP,364,259,7,14 PUSHBUTTON "&Benchmark",IDC_BENCHMARK,7,279,59,14 DEFPUSHBUTTON "OK",IDOK,257,279,50,14 PUSHBUTTON "Cancel",IDCANCEL,314,279,50,14 diff --git a/src/Mount/Resource.h b/src/Mount/Resource.h index 0b778b4c..fef9da49 100644 --- a/src/Mount/Resource.h +++ b/src/Mount/Resource.h @@ -198,8 +198,8 @@ #define IDC_FORCE_NEXT_BOOT_VERACRYPT 1176 #define IDC_FORCE_VERACRYPT_BOOT_ENTRY 1177 #define IDC_FORCE_VERACRYPT_FIRST_BOOT_ENTRY 1178 -#define IDC_ENABLE_EMV_SUPPORT 1179 -#define IDT_EMV_OPTIONS 1180 +#define IDC_ENABLE_EMV_SUPPORT 1179 +#define IDT_EMV_OPTIONS 1180 #define IDM_HELP 40001 #define IDM_ABOUT 40002 #define IDM_UNMOUNT_VOLUME 40003 @@ -277,7 +277,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 120 #define _APS_NEXT_COMMAND_VALUE 40070 -#define _APS_NEXT_CONTROL_VALUE 1179 +#define _APS_NEXT_CONTROL_VALUE 1181 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/Setup/Setup.rc b/src/Setup/Setup.rc index 7b31fc0f..2ab818d5 100644 --- a/src/Setup/Setup.rc +++ b/src/Setup/Setup.rc @@ -151,8 +151,9 @@ BEGIN CONTROL "Add VeraCrypt icon to &desktop",IDC_DESKTOP_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,92,168,11 CONTROL "Associate the .hc file &extension with VeraCrypt",IDC_FILE_TYPE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,104,232,11 - CONTROL "Disable memory protection in VeraCrypt",IDC_DISABLE_MEMORY_PROTECTION, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,115,218,10 + CONTROL "Disable memory protection for Accessibility tools compatibility",IDC_DISABLE_MEMORY_PROTECTION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,115,315,10 + PUSHBUTTON "?",IDC_DISABLE_MEMORY_PROTECTION_HELP,337,111,7,14 CONTROL "Create System &Restore point",IDC_SYSTEM_RESTORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,125,194,11 LTEXT "Please select or type the location where you want to install the VeraCrypt program files. If the specified folder does not exist, it will be automatically created.",IDT_INSTALL_DESTINATION,11,14,319,25 END diff --git a/src/Setup/Wizard.c b/src/Setup/Wizard.c index 857eb2de..66e24571 100644 --- a/src/Setup/Wizard.c +++ b/src/Setup/Wizard.c @@ -212,6 +212,7 @@ static int GetDonVal (int minVal, int maxVal) BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static char PageDebugId[128]; + static HWND hDisableMemProtectionTooltipWnd = NULL; WORD lw = LOWORD (wParam); WORD hw = HIWORD (wParam); @@ -439,9 +440,16 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa EnableWindow (GetDlgItem (hwndDlg, IDC_SYSTEM_RESTORE), FALSE); } + hDisableMemProtectionTooltipWnd = CreateToolTip (IDC_DISABLE_MEMORY_PROTECTION, hwndDlg, "DISABLE_MEMORY_PROTECTION_WARNING"); + // make IDC_DISABLE_MEMORY_PROTECTION control fit the text so that the tooltip is shown only when mouse is over the text + AccommodateCheckBoxTextWidth(hwndDlg, IDC_DISABLE_MEMORY_PROTECTION); + // make the help button adjacent to the checkbox + MakeControlsContiguous(hwndDlg, IDC_DISABLE_MEMORY_PROTECTION, IDC_DISABLE_MEMORY_PROTECTION_HELP); + SetCheckBox (hwndDlg, IDC_ALL_USERS, bForAllUsers); SetCheckBox (hwndDlg, IDC_FILE_TYPE, bRegisterFileExt); SetCheckBox (hwndDlg, IDC_PROG_GROUP, bAddToStartMenu); + SetCheckBox (hwndDlg, IDC_DISABLE_MEMORY_PROTECTION, bDisableMemoryProtection); SetCheckBox (hwndDlg, IDC_DESKTOP_ICON, bDesktopIcon); SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString (bUpgrade ? "UPGRADE" : "INSTALL")); @@ -687,6 +695,14 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa case IDC_DISABLE_MEMORY_PROTECTION: bDisableMemoryProtection = IsButtonChecked (GetDlgItem (hCurPage, IDC_DISABLE_MEMORY_PROTECTION)); + if (bDisableMemoryProtection) + { + Warning ("DISABLE_MEMORY_PROTECTION_WARNING", hwndDlg); + } + return 1; + + case IDC_DISABLE_MEMORY_PROTECTION_HELP: + Applink("memoryprotection") return 1; case IDC_FILE_TYPE: @@ -764,6 +780,16 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa } return 0; + case WM_DESTROY: + + if (hDisableMemProtectionTooltipWnd != NULL) + { + DestroyWindow (hDisableMemProtectionTooltipWnd); + hDisableMemProtectionTooltipWnd = NULL; + } + + break; + } return 0; -- cgit v1.2.3