VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Dlgcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Dlgcode.c')
-rw-r--r--src/Common/Dlgcode.c362
1 files changed, 354 insertions, 8 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 341fcb85..c7185a84 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -210,6 +210,14 @@ BOOL EnableMemoryProtection = FALSE;
BOOL WaitDialogDisplaying = FALSE;
+wchar_t DefaultKeyboardLayout [KL_NAMELENGTH];
+HKL hklDefaultKeyboardLayout;
+HKL hklUSKeyboardLayout;
+int iPwdCounter = 0;
+wchar_t TranslatedPassword[MAX_PASSWORD + 1];
+BOOL bAltKeyDown = FALSE;
+BOOL bAltKeyWarningShown = FALSE; /* TRUE if the user has been informed that it is not possible to type characters by pressing keys while the right Alt key is held down. */
+
/* Handle to the device driver */
HANDLE hDriver = INVALID_HANDLE_VALUE;
@@ -1273,23 +1281,293 @@ void HandlePasswordEditWmChar (HWND hwnd, WPARAM wParam)
SendMessage(hwnd, EM_HIDEBALLOONTIP, 0, 0);
}
-// Protects an input field from having its content updated by a Paste action (call ToBootPwdField() to use this).
+/* Protects an input field from having its content updated by a Paste action and translates password into
+ US keyboard layout (call ToBootPwdField() to use this). */
static LRESULT CALLBACK BootPwdFieldProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
WNDPROC wp = (WNDPROC) GetWindowLongPtrW (hwnd, GWLP_USERDATA);
-
+
switch (message)
{
case WM_PASTE:
+ Error ("ERROR_PASTE_ACTION", GetParent(hwnd));
return 1;
+
+ case WM_LBUTTONDOWN:
+ if (CheckKeyboardLayout())
+ {
+ // put caret at the end if user tries to change caret position
+ int iLength = GetWindowTextLength (hwnd);
+ SendMessage (hwnd, EM_SETSEL, MAKELONG (iLength, iLength), MAKELONG (iLength, iLength));
+ SetFocus(hwnd);
+ return 1;
+ }
+ break;
+
+ case WM_DEADCHAR:
+ {
+ if (CheckKeyboardLayout())
+ {
+ if ((GetKeyState (VK_RMENU) < 0) || (GetKeyState (VK_MENU) < 0 && GetKeyState (VK_CONTROL) < 0))
+ {
+ bAltKeyDown = TRUE;
+
+ if (!bAltKeyWarningShown)
+ {
+ bAltKeyWarningShown = TRUE;
+
+ wchar_t szTmp [4096];
+ StringCbCopyW (szTmp, sizeof(szTmp), GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION"));
+ StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
+ StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
+ MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
+ }
+
+ return 1;
+ }
+
+ Warning ("DEAD_KEY_SUPPORT", GetParent (hwnd));
+ if (!(TranslatePwdToUSKbdLayout(hwnd, lParam, TRUE)))
+ return 1;
+ }
+ break;
+ }
+
+ case WM_SYSDEADCHAR:
+ {
+ if (GetKeyState (VK_MENU) < 0)
+ {
+ bAltKeyDown = TRUE;
+
+ if (!bAltKeyWarningShown)
+ {
+ bAltKeyWarningShown = TRUE;
+
+ wchar_t szTmp [4096];
+ StringCbCopyW (szTmp, sizeof(szTmp), GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION"));
+ StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
+ StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
+ MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
+ }
+
+ return 1;
+ }
+ break;
+ }
+
+ case WM_SYSCHAR:
+ if (GetKeyState (VK_MENU) < 0)
+ {
+ if (!bAltKeyWarningShown)
+ {
+ bAltKeyWarningShown = TRUE;
+
+ wchar_t szTmp [4096];
+ StringCbCopyW (szTmp, sizeof(szTmp), GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION"));
+ StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
+ StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
+ MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
+ }
+
+ return 1;
+ }
+ break;
+
case WM_CHAR:
+ {
+ if (bAltKeyDown == TRUE)
+ {
+ bAltKeyDown = FALSE;
+ return 1;
+ }
+
+ if (CheckKeyboardLayout ())
+ {
+ if (GetKeyState (VK_RMENU) < 0)
+ return 1;
+
+ if (!(TranslatePwdToUSKbdLayout(hwnd, lParam, FALSE)))
+ return 1;
+ }
+ else
+ {
+ wchar_t OrigPassword[MAX_PASSWORD + 1];
+ GetWindowText (hwnd, OrigPassword, ARRAYSIZE (OrigPassword));
+
+ iPwdCounter = (int) wcslen (OrigPassword);
+ TranslatedPassword[iPwdCounter] = (wchar_t) wParam;
+ iPwdCounter++;
+ TranslatedPassword[iPwdCounter] = '\0';
+ burn (OrigPassword, sizeof (OrigPassword));
+ }
+
HandlePasswordEditWmChar (hwnd, wParam);
break;
}
+ case WM_KEYDOWN:
+ if (CheckKeyboardLayout ())
+ {
+ if (wParam == VK_LEFT || wParam == VK_HOME)
+ {
+ // put caret at the end if user tries to change caret position
+ int iLength = GetWindowTextLength (hwnd);
+ SendMessage(hwnd, EM_SETSEL, MAKELONG (iLength, iLength), MAKELONG (iLength, iLength));
+ return 1;
+ }
+ }
+ break;
+ }
return CallWindowProcW (wp, hwnd, message, wParam, lParam);
}
+BOOL TranslatePwdToUSKbdLayout (HWND hwnd, LPARAM lParam, BOOL deadKey)
+{
+ BYTE keyState[256];
+ UINT scanCode = (lParam >> 16) & 0xFF;
+ UINT virtualKey = MapVirtualKeyExW (scanCode, MAPVK_VSC_TO_VK_EX, hklUSKeyboardLayout);
+
+ BOOL bKeyboardState = GetKeyboardState (keyState);
+ if (!bKeyboardState)
+ Error ("ERROR_GETTING_KEYB_STATE", GetParent (hwnd));
+
+ unsigned short tempChar[2] = {0};
+ wchar_t OrigPassword[MAX_PASSWORD + 1];
+
+ if (deadKey)
+ {
+ int iTemp;
+
+ do
+ iTemp = ToUnicode (virtualKey, scanCode, keyState, (LPWSTR)tempChar, sizeof (tempChar), 0);
+ while (iTemp < 0);
+
+ wchar_t tempOrigPwd[MAX_PASSWORD + 1];
+ GetWindowText (hwnd, tempOrigPwd, sizeof (tempOrigPwd));
+
+ int iLength = (int) wcslen (tempOrigPwd);
+ tempOrigPwd[iLength] = tempChar[0];
+ tempOrigPwd[++iLength] = '\0';
+
+ SetWindowText(hwnd, tempOrigPwd);
+ int iWindowTextLength = GetWindowTextLength (hwnd);
+ SendMessage (hwnd, EM_SETSEL, MAKELONG (iWindowTextLength, iWindowTextLength), MAKELONG (iWindowTextLength, iWindowTextLength));
+
+ tempChar[0] = '\0';
+
+ do
+ iTemp = ToUnicodeEx (virtualKey, scanCode, keyState, (LPWSTR)tempChar, sizeof ((LPWSTR)tempChar) / 2, 0, hklUSKeyboardLayout);
+ while (iTemp < 0);
+
+ if (iTemp == 0)
+ Error ("ERR_NO_TRANSLATION", GetParent(hwnd));
+
+ burn (tempOrigPwd, sizeof (tempOrigPwd));
+ }
+ else
+ {
+ // function MapVirtualKey map numpad keys like PageUp, PageDown, ... so they need to be set to right values
+ switch (scanCode)
+ {
+ case 71:
+ tempChar[0] = '7';
+ break;
+ case 72:
+ tempChar[0] = '8';
+ break;
+ case 73:
+ tempChar[0] = '9';
+ break;
+ case 75:
+ tempChar[0] = '4';
+ break;
+ case 76:
+ tempChar[0] = '5';
+ break;
+ case 77:
+ tempChar[0] = '6';
+ break;
+ case 79:
+ tempChar[0] = '1';
+ break;
+ case 80:
+ tempChar[0] = '2';
+ break;
+ case 81:
+ tempChar[0] = '3';
+ break;
+ case 82:
+ tempChar[0] = '0';
+ break;
+ case 83:
+ tempChar[0] = ',';
+ break;
+ case 57:
+ tempChar[0] = ' ';
+ break;
+ default:
+ int iReturnAscii;
+
+ iReturnAscii = ToAsciiEx (virtualKey, scanCode, keyState, tempChar, 0, hklUSKeyboardLayout);
+ if (iReturnAscii == 0)
+ Error ("ERR_NO_TRANSLATION", GetParent(hwnd));
+ break;
+ }
+ }
+
+ GetWindowText (hwnd, OrigPassword, ARRAYSIZE (OrigPassword));
+
+ if (tempChar[0] != '\0')
+ {
+ if ((wcslen (OrigPassword) == 0) && iPwdCounter != 0)
+ {
+ iPwdCounter = 0;
+ TranslatedPassword[iPwdCounter] = tempChar[0];
+ }
+ else if (iPwdCounter == 0)
+ {
+ TranslatedPassword[iPwdCounter] = tempChar[0];
+ }
+ else
+ {
+ if (deadKey)
+ iPwdCounter = wcslen (OrigPassword) - 1; // Dead key is already written in edit control
+ else
+ iPwdCounter = wcslen (OrigPassword);
+
+ TranslatedPassword[iPwdCounter] = tempChar[0];
+ }
+ TranslatedPassword[++iPwdCounter] = '\0';
+ }
+ else
+ {
+ burn (tempChar, sizeof (tempChar));
+ burn (OrigPassword, sizeof (OrigPassword));
+ return FALSE;
+ }
+
+ burn (tempChar, sizeof (tempChar));
+ burn (OrigPassword, sizeof (OrigPassword));
+ return TRUE;
+}
+
+wchar_t *GetTranslatedPassword ()
+{
+ return TranslatedPassword;
+}
+
+void WipeTranslatedPassword ()
+{
+ burn (TranslatedPassword, sizeof (TranslatedPassword));
+}
+
+BOOL CheckKeyboardLayout ()
+{
+ GetKeyboardLayoutName (DefaultKeyboardLayout);
+ if ((wcscmp (DefaultKeyboardLayout, TEXT ("00000409")) != 0) || (wcscmp (DefaultKeyboardLayout, TEXT ("00000409")) != 0))
+ return TRUE;
+ return FALSE;
+}
// Protects an input field from having its content updated by a Paste action. Used for pre-boot password
// input fields (only the US keyboard layout is supported in pre-boot environment so we must prevent the
@@ -1300,6 +1578,24 @@ void ToBootPwdField (HWND hwndDlg, UINT ctrlId)
WNDPROC originalwp = (WNDPROC) GetWindowLongPtrW (hwndCtrl, GWLP_USERDATA);
SendMessage (hwndCtrl, EM_LIMITTEXT, MAX_LEGACY_PASSWORD, 0);
+
+ GetKeyboardLayoutName (DefaultKeyboardLayout);
+
+ if (CheckKeyboardLayout ())
+ {
+ // Load US keyboard layout into the system
+ hklUSKeyboardLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_NOTELLSHELL);
+
+ if (hklUSKeyboardLayout == NULL)
+ AbortProcess ("ERROR_KEYB_LAYOUT_NOT_LOADED");
+
+ hklDefaultKeyboardLayout = LoadKeyboardLayout (DefaultKeyboardLayout, KLF_ACTIVATE);
+
+ /* If US keyboard layout is not availabe, LoadKeyboardLayout will return default system layout */
+
+ if (hklUSKeyboardLayout == hklDefaultKeyboardLayout)
+ AbortProcess ("ERROR_KEYB_LAYOUT_NOT_LOADED");
+ }
// if ToNormalPwdField has been called before, GWLP_USERDATA already contains original WNDPROC
if (!originalwp)
@@ -1309,6 +1605,12 @@ void ToBootPwdField (HWND hwndDlg, UINT ctrlId)
SetWindowLongPtrW (hwndCtrl, GWLP_WNDPROC, (LONG_PTR) BootPwdFieldProc);
}
+BOOL CheckIsIMESupported ()
+{
+ if (himm32dll == NULL)
+ return FALSE;
+ return TRUE;
+}
// Ensures that a warning is displayed when user is pasting a password longer than the maximum
// length which is set to 64 characters
static LRESULT CALLBACK NormalPwdFieldProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
@@ -2138,7 +2440,7 @@ SelectAlgo (HWND hComboBox, int *algo_id)
/* Something went wrong ; couldn't find the requested algo id so we drop
back to a default */
-
+
*algo_id = (int) SendMessage (hComboBox, CB_GETITEMDATA, 0, 0);
SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
@@ -4784,6 +5086,53 @@ BOOL BrowseFiles (HWND hwndDlg, char *stringId, wchar_t *lpszFileName, BOOL keep
return BrowseFilesInDir (hwndDlg, stringId, NULL, lpszFileName, keepHistory, saveMode, browseFilter);
}
+BOOL BrowseFile (HWND hwndDlg, char *stringId, wchar_t *initialDir)
+{
+ OPENFILENAMEW ofn;
+ wchar_t file[TC_MAX_PATH] = { 0 };
+ wchar_t filter[1024];
+ BOOL status = FALSE;
+
+ CoInitialize (NULL);
+
+ ZeroMemory (&ofn, sizeof (ofn));
+
+ if (initialDir)
+ {
+ ofn.lpstrInitialDir = initialDir;
+ }
+
+ ofn.lStructSize = sizeof (ofn);
+ ofn.hwndOwner = hwndDlg;
+ StringCbPrintfW (filter, sizeof(filter), L"%ls (*.*)%c*.*%c",
+ GetString ("ALL_FILES"), 0, 0);
+ ofn.lpstrFilter = filter;
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFile = NULL;
+ ofn.nMaxFile = sizeof (file) / sizeof (file[0]);
+ ofn.lpstrTitle = GetString (stringId);
+ ofn.lpstrDefExt = NULL;
+ ofn.Flags = OFN_HIDEREADONLY
+ | OFN_PATHMUSTEXIST
+ | OFN_DONTADDTORECENT;
+
+ SystemFileSelectorCallerThreadId = GetCurrentThreadId();
+ SystemFileSelectorCallPending = TRUE;
+
+ if (!GetOpenFileNameW (&ofn))
+ goto ret;
+
+ SystemFileSelectorCallPending = FALSE;
+
+ status = TRUE;
+
+ret:
+ SystemFileSelectorCallPending = FALSE;
+ ResetCurrentDirectory();
+ CoUninitialize();
+
+ return status;
+}
BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, wchar_t *initialDir, wchar_t *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter, const wchar_t *initialFileName, const wchar_t *defaultExtension)
{
@@ -9573,8 +9922,6 @@ BOOL PrintHardCopyTextUTF16 (wchar_t *text, wchar_t *title, size_t textByteLen)
return TRUE;
}
-
-
BOOL IsNonInstallMode ()
{
HKEY hkey, hkeybis;
@@ -9673,7 +10020,6 @@ BOOL IsNonInstallMode ()
return TRUE;
}
-
LRESULT SetCheckBox (HWND hwndDlg, int dlgItem, BOOL state)
{
return SendDlgItemMessage (hwndDlg, dlgItem, BM_SETCHECK, state ? BST_CHECKED : BST_UNCHECKED, 0);
@@ -11446,7 +11792,7 @@ BYTE *MapResource (wchar_t *resourceType, int resourceId, PDWORD size)
{
HGLOBAL hResL;
HRSRC hRes;
- HINSTANCE hResInst = NULL;
+ HINSTANCE hResInst = NULL;
#ifdef SETUP_DLL
// In case we're being called from the SetupDLL project, FindResource()
@@ -11458,7 +11804,7 @@ BYTE *MapResource (wchar_t *resourceType, int resourceId, PDWORD size)
hRes = FindResource (hResInst, MAKEINTRESOURCE(resourceId), resourceType);
hResL = LoadResource (hResInst, hRes);
-
+
if (size != NULL)
*size = SizeofResource (hResInst, hRes);