VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Mount/Hotkeys.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mount/Hotkeys.c')
-rw-r--r--src/Mount/Hotkeys.c1222
1 files changed, 611 insertions, 611 deletions
diff --git a/src/Mount/Hotkeys.c b/src/Mount/Hotkeys.c
index 59fa1093..0403c634 100644
--- a/src/Mount/Hotkeys.c
+++ b/src/Mount/Hotkeys.c
@@ -1,611 +1,611 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include <windows.h>
-#include "Dlgcode.h"
-#include "Hotkeys.h"
-#include "Language.h"
-#include "Mount.h"
-#include "Resource.h"
-
-#include <Strsafe.h>
-
-#ifndef SRC_POS
-#define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__))
-#endif
-
-#define MAX_KEY_COMB_NAME_LEN 260
-
-TCHOTKEY Hotkeys [NBR_HOTKEYS];
-static TCHOTKEY tmpHotkeys [NBR_HOTKEYS];
-
-static int nSelectedHotkeyId;
-static UINT currentVKeyCode;
-static BYTE vkeysDown[256];
-
-
-static void ScanAndProcessKey (UINT *vKeyCode, wchar_t *keyName)
-{
- UINT vKey;
- *vKeyCode = 0;
-
- for (vKey = 0; vKey <= 0xFF; vKey++)
- {
- if (GetAsyncKeyState (vKey) < 0)
- {
- if (!vkeysDown [vKey])
- {
- vkeysDown [vKey] = 1;
- if (GetKeyName (vKey, keyName)) // If the key is allowed and its name has been resolved
- *vKeyCode = vKey;
- }
- }
- else
- vkeysDown [vKey] = 0;
- }
-}
-
-
-/* Returns TRUE if the key is allowed and its name is resolved. */
-BOOL GetKeyName (UINT vKey, wchar_t *keyName)
-{
- BOOL result = TRUE;
-
- if (vKey >= 0x30 && vKey <= 0x5a)
- {
- // ASCII characters
- StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%hc", (char) vKey);
- }
- else if (vKey >= 0xE9 && vKey <= 0xF5)
- {
- // OEM-specific
- StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM-%d", vKey);
-
- // mapping taken from:
- // http://www.hotkeynet.com/ref/keynames.html
- // https://mojoware.googlecode.com/svn-history/r3/trunk/mojo_engine/cKeyboard.cpp
- // http://www.screenio.com/gui_screenio/gs_htmlhelp_subweb/download/SIMKEYS.cob
- //
- // These values seem to come from Nokia/Ericsson mobile device keys
-
- switch (vKey)
- {
- case 0xE9: // OEMReset = 0xE9
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMReset)");
- break;
- case 0xEA: // OEMJump = 0xEA
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMJump)");
- break;
- case 0xEB: // OEMPA1 = 0xEB
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMPA1)");
- break;
- case 0xEC: // OEMPA2 = 0xEC
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMPA2)");
- break;
- case 0xED: // OEMPA3 = 0xED
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMPA3)");
- break;
- case 0xEE: // OEMWSCtrl = 0xEE
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMWSCtrl)");
- break;
- case 0xEF: // OEMCUSel = 0xEF
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMCUSel)");
- break;
- case 0xF0: // OEMATTN = 0xF0
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMATTN)");
- break;
- case 0xF1: // OEMFinish = 0xF1
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMFinish)");
- break;
- case 0xF2: // OEMCopy = 0xF2
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMCopy)");
- break;
- case 0xF3: // OEMAuto = 0xF3
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMAuto)");
- break;
- case 0xF4: // OEMENLW = 0xF4
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMENLW)");
- break;
- case 0xF5: // OEMBackTab = 0xF5
- StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMBackTab)");
- break;
- }
- }
- else if (vKey >= VK_F1 && vKey <= VK_F24)
- {
- // F1-F24
- StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"F%d", vKey - VK_F1 + 1);
- }
- else if (vKey >= VK_NUMPAD0 && vKey <= VK_NUMPAD9)
- {
- // Numpad numbers
- StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s %d", GetString ("VK_NUMPAD"), vKey - VK_NUMPAD0);
- }
- else
- {
- switch (vKey)
- {
- case VK_MULTIPLY: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s *", GetString ("VK_NUMPAD")); break;
- case VK_ADD: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s +", GetString ("VK_NUMPAD")); break;
- case VK_SEPARATOR: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s Separator", GetString ("VK_NUMPAD")); break;
- case VK_SUBTRACT: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s -", GetString ("VK_NUMPAD")); break;
- case VK_DECIMAL: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s .", GetString ("VK_NUMPAD")); break;
- case VK_DIVIDE: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s /", GetString ("VK_NUMPAD")); break;
- case VK_OEM_1: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 1 (';')"); break;
- case VK_OEM_PLUS: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"+"); break;
- case VK_OEM_COMMA: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L","); break;
- case VK_OEM_MINUS: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"-"); break;
- case VK_OEM_PERIOD: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"."); break;
- case VK_OEM_2: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 2 ('/')"); break;
- case VK_OEM_3: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 3 (`)"); break;
- case VK_OEM_4: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 4 ('[')"); break;
- case VK_OEM_5: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 5 ('\\')"); break;
- case VK_OEM_6: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 6 (']')"); break;
- case VK_OEM_7: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 7 (')"); break;
- case VK_OEM_8: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 8"); break;
- case VK_OEM_AX: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM AX"); break;
- case VK_OEM_102: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 102"); break;
- case VK_ICO_HELP: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ICO_HELP"); break;
- case VK_ICO_00: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ICO_00"); break;
- case VK_ICO_CLEAR: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ICO_CLEAR"); break;
- case VK_ATTN: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"Attn"); break;
- case VK_CRSEL: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"CrSel"); break;
- case VK_EXSEL: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ExSel"); break;
- case VK_EREOF: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"Erase EOF"); break;
- case VK_PA1: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"PA1"); break;
- case VK_OEM_CLEAR: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM Clear"); break;
-
- case 0:
- case 1:
- case 0xFF:
- result = FALSE;
- break;
-
- default:
- {
- char key[16];
- wchar_t *desc;
- StringCbPrintfA (key, sizeof(key),"VKEY_%02X", vKey);
- desc = GetString (key);
- if (desc == UnknownString)
- result = FALSE;
- else
- StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, desc);
- }
- }
- }
- return result;
-}
-
-
-static BOOL ShortcutInUse (UINT vKeyCode, UINT modifiers, TCHOTKEY hotkeys[])
-{
- int i;
-
- for (i = 0; i < NBR_HOTKEYS; i++)
- {
- if (hotkeys[i].vKeyCode == vKeyCode && hotkeys[i].vKeyModifiers == modifiers)
- return TRUE;
- }
- return FALSE;
-}
-
-
-void UnregisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[])
-{
- int i;
-
- for (i = 0; i < NBR_HOTKEYS; i++)
- {
- if (hotkeys[i].vKeyCode != 0)
- UnregisterHotKey (hwndDlg, i);
-
- }
-}
-
-
-BOOL RegisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[])
-{
- BOOL result = TRUE;
- int i;
-
- for (i = 0; i < NBR_HOTKEYS; i++)
- {
- if (hotkeys[i].vKeyCode != 0
- && !RegisterHotKey (hwndDlg, i, hotkeys[i].vKeyModifiers, hotkeys[i].vKeyCode))
- result = FALSE;
- }
-
- return result;
-}
-
-
-static void DisplayHotkeyList (HWND hwndDlg)
-{
- LVITEMW item;
- HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST);
- int i;
- wchar_t ShortcutMod [MAX_KEY_COMB_NAME_LEN];
- wchar_t ShortcutFinal [MAX_KEY_COMB_NAME_LEN*2];
- wchar_t Shortcut [MAX_KEY_COMB_NAME_LEN];
-
- SendMessage (hList, LVM_DELETEALLITEMS,0, (LPARAM)&item);
-
- for (i = 0; i < NBR_HOTKEYS; i++)
- {
- memset (&item,0,sizeof(item));
- item.mask = LVIF_TEXT;
- item.iItem = i;
- item.iSubItem = 0;
-
- switch (i)
- {
-
- case HK_AUTOMOUNT_DEVICES:
- item.pszText = GetString ("HK_AUTOMOUNT_DEVICES");
- break;
-
- case HK_DISMOUNT_ALL:
- item.pszText = GetString ("HK_DISMOUNT_ALL");
- break;
-
- case HK_WIPE_CACHE:
- item.pszText = GetString ("HK_WIPE_CACHE");
- break;
-
- case HK_DISMOUNT_ALL_AND_WIPE:
- item.pszText = GetString ("HK_DISMOUNT_ALL_AND_WIPE");
- break;
-
- case HK_FORCE_DISMOUNT_ALL_AND_WIPE:
- item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE");
- break;
-
- case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT:
- item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT");
- break;
-
- case HK_MOUNT_FAVORITE_VOLUMES:
- item.pszText = GetString ("HK_MOUNT_FAVORITE_VOLUMES");
- break;
-
- case HK_SHOW_HIDE_MAIN_WINDOW:
- item.pszText = GetString ("HK_SHOW_HIDE_MAIN_WINDOW");
- break;
-
- case HK_CLOSE_SECURITY_TOKEN_SESSIONS:
- item.pszText = GetString ("IDM_CLOSE_ALL_TOKEN_SESSIONS");
- break;
-
- default:
- item.pszText = L"[?]";
- }
-
- SendMessageW (hList,LVM_INSERTITEMW,0,(LPARAM)&item);
-
- item.iSubItem = 1;
- Shortcut[0] = 0;
- ShortcutMod[0] = 0;
-
- if (GetKeyName (tmpHotkeys[i].vKeyCode, Shortcut))
- {
- if (tmpHotkeys[i].vKeyModifiers & MOD_CONTROL)
- {
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_CONTROL"));
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
- }
-
- if (tmpHotkeys[i].vKeyModifiers & MOD_SHIFT)
- {
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_SHIFT"));
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
- }
-
- if (tmpHotkeys[i].vKeyModifiers & MOD_ALT)
- {
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_ALT"));
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
- }
-
- if (tmpHotkeys[i].vKeyModifiers & MOD_WIN)
- {
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_WIN"));
- StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
- }
-
- StringCbPrintfW (ShortcutFinal, sizeof(ShortcutFinal), L"%s%s", ShortcutMod, Shortcut);
- item.pszText = ShortcutFinal;
- }
- else
- item.pszText = L"";
-
- SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&item);
- }
-}
-
-
-
-BOOL CALLBACK HotkeysDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- WORD lw = LOWORD (wParam);
- WORD hw = HIWORD (wParam);
- static BOOL bKeyScanOn;
- static BOOL bTPlaySoundOnSuccessfulHkDismount;
- static BOOL bTDisplayBalloonOnSuccessfulHkDismount;
-
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- LVCOLUMNW col;
- HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST);
-
- bKeyScanOn = FALSE;
- nSelectedHotkeyId = -1;
- currentVKeyCode = 0;
- memcpy (tmpHotkeys, Hotkeys, sizeof(tmpHotkeys));
- memset (vkeysDown, 0, sizeof(vkeysDown));
-
- SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
- LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP
- );
-
- memset (&col,0,sizeof(col));
- col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
- col.pszText = GetString ("ACTION");
- col.cx = CompensateXDPI (341);
- col.fmt = LVCFMT_LEFT;
- SendMessageW (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&col);
-
- col.pszText = GetString ("SHORTCUT");
- col.cx = CompensateXDPI (190);
- col.fmt = LVCFMT_LEFT;
- SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&col);
-
- LocalizeDialog (hwndDlg, "IDD_HOTKEYS_DLG");
-
- SetCheckBox (hwndDlg, IDC_HK_MOD_CTRL, TRUE);
- SetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT, FALSE);
- SetCheckBox (hwndDlg, IDC_HK_MOD_ALT, TRUE);
- SetCheckBox (hwndDlg, IDC_HK_MOD_WIN, FALSE);
-
- SetCheckBox (hwndDlg, IDC_HK_DISMOUNT_PLAY_SOUND, bPlaySoundOnSuccessfulHkDismount);
- SetCheckBox (hwndDlg, IDC_HK_DISMOUNT_BALLOON_TOOLTIP, bDisplayBalloonOnSuccessfulHkDismount);
-
- bTPlaySoundOnSuccessfulHkDismount = bPlaySoundOnSuccessfulHkDismount;
- bTDisplayBalloonOnSuccessfulHkDismount = bDisplayBalloonOnSuccessfulHkDismount;
-
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
-
- DisplayHotkeyList(hwndDlg);
-
- if (SetTimer (hwndDlg, 0xfe, 10, NULL) == 0)
- {
- Error ("CANNOT_SET_TIMER", MainDlg);
- EndDialog (hwndDlg, IDCANCEL);
- return 1;
- }
- return 1;
- }
-
- case WM_TIMER:
- {
- if ((nSelectedHotkeyId > -1) && (GetFocus () == GetDlgItem (hwndDlg, IDC_HOTKEY_KEY)))
- {
- wchar_t keyName [MAX_KEY_COMB_NAME_LEN];
- UINT tmpVKeyCode;
-
- keyName[0] = 0;
-
- ScanAndProcessKey (&tmpVKeyCode, &keyName[0]);
-
- if (keyName[0] != 0)
- {
- currentVKeyCode = tmpVKeyCode;
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName);
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), TRUE);
- }
- else if ((currentVKeyCode != 0) && GetKeyName (currentVKeyCode, keyName))
- {
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName);
- }
- }
- return 1;
- }
-
- case WM_NOTIFY:
- if (wParam == IDC_HOTKEY_LIST)
- {
- if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE
- || ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED))
- {
- LVITEM item;
- memset(&item,0,sizeof(item));
- nSelectedHotkeyId = ((LPNMLISTVIEW) lParam)->iItem;
- currentVKeyCode = 0;
- memset (vkeysDown, 0, sizeof(vkeysDown));
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), GetString ("PRESS_A_KEY_TO_ASSIGN"));
-
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), (tmpHotkeys[nSelectedHotkeyId].vKeyCode > 0));
-
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
- bKeyScanOn = TRUE;
- return 1;
- }
- }
-
- return 0;
-
- case WM_COMMAND:
- if (lw == IDC_HOTKEY_KEY && hw == EN_CHANGE)
- {
- if (!bKeyScanOn && nSelectedHotkeyId < 0 && GetWindowTextLengthW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY)))
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
- }
-
- if (lw == IDC_HOTKEY_ASSIGN)
- {
- BOOL bOwnActiveShortcut = FALSE;
-
- if (nSelectedHotkeyId >= 0 && currentVKeyCode != 0)
- {
- UINT modifiers = 0;
- if (GetCheckBox (hwndDlg, IDC_HK_MOD_CTRL))
- modifiers = MOD_CONTROL;
-
- if (GetCheckBox (hwndDlg, IDC_HK_MOD_ALT))
- modifiers |= MOD_ALT;
-
- if (GetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT))
- modifiers |= MOD_SHIFT;
-
- if (GetCheckBox (hwndDlg, IDC_HK_MOD_WIN))
- modifiers |= MOD_WIN;
-
- // Check if it's not already assigned
- if (ShortcutInUse (currentVKeyCode, modifiers, tmpHotkeys))
- {
- Error ("SHORTCUT_ALREADY_IN_USE", hwndDlg);
- return 1;
- }
-
- // Check for reserved system keys
- switch (currentVKeyCode)
- {
- case VK_F1:
- case VK_F12:
- /* F1 is help and F12 is reserved for use by the debugger at all times */
- if (modifiers == 0)
- {
- Error ("CANNOT_USE_RESERVED_KEY", hwndDlg);
- return 1;
- }
- break;
- }
-
- bOwnActiveShortcut = ShortcutInUse (currentVKeyCode, modifiers, Hotkeys);
-
- // Test if the shortcut can be assigned without errors
- if (!bOwnActiveShortcut
- && !RegisterHotKey (hwndDlg, nSelectedHotkeyId, modifiers, currentVKeyCode))
- {
- handleWin32Error(hwndDlg, SRC_POS);
- return 1;
- }
- else
- {
- if (!bOwnActiveShortcut && !UnregisterHotKey (hwndDlg, nSelectedHotkeyId))
- handleWin32Error(hwndDlg, SRC_POS);
-
- tmpHotkeys[nSelectedHotkeyId].vKeyCode = currentVKeyCode;
- tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = modifiers;
-
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
- nSelectedHotkeyId = -1;
- bKeyScanOn = FALSE;
- currentVKeyCode = 0;
- memset (vkeysDown, 0, sizeof(vkeysDown));
- }
- }
- DisplayHotkeyList(hwndDlg);
- return 1;
- }
-
- if (lw == IDC_HOTKEY_REMOVE)
- {
- if (nSelectedHotkeyId >= 0)
- {
- tmpHotkeys[nSelectedHotkeyId].vKeyCode = 0;
- tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = 0;
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
- nSelectedHotkeyId = -1;
- bKeyScanOn = FALSE;
- currentVKeyCode = 0;
- memset (vkeysDown, 0, sizeof(vkeysDown));
- DisplayHotkeyList(hwndDlg);
- }
- return 1;
- }
-
- if (lw == IDC_RESET_HOTKEYS)
- {
- int i;
-
- for (i = 0; i < NBR_HOTKEYS; i++)
- {
- tmpHotkeys[i].vKeyCode = 0;
- tmpHotkeys[i].vKeyModifiers = 0;
- }
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
- EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
- nSelectedHotkeyId = -1;
- bKeyScanOn = FALSE;
- currentVKeyCode = 0;
- memset (vkeysDown, 0, sizeof(vkeysDown));
- DisplayHotkeyList(hwndDlg);
- return 1;
- }
-
- if (lw == IDC_HK_DISMOUNT_PLAY_SOUND)
- {
- bTPlaySoundOnSuccessfulHkDismount = GetCheckBox (hwndDlg, IDC_HK_DISMOUNT_PLAY_SOUND);
- }
-
- if (lw == IDC_HK_DISMOUNT_BALLOON_TOOLTIP)
- {
- bTDisplayBalloonOnSuccessfulHkDismount = GetCheckBox (hwndDlg, IDC_HK_DISMOUNT_BALLOON_TOOLTIP);
- }
-
- if (lw == IDCANCEL || lw == IDCLOSE)
- {
- KillTimer (hwndDlg, 0xfe);
- EndDialog (hwndDlg, IDCANCEL);
- return 1;
- }
-
- if (lw == IDOK)
- {
- HWND hwndMainDlg = hwndDlg;
-
- while (GetParent (hwndMainDlg) != NULL)
- {
- hwndMainDlg = GetParent (hwndMainDlg);
- }
- UnregisterAllHotkeys (hwndMainDlg, Hotkeys);
- memcpy (Hotkeys, tmpHotkeys, sizeof(Hotkeys));
- RegisterAllHotkeys (hwndMainDlg, Hotkeys);
- KillTimer (hwndDlg, 0xfe);
- bPlaySoundOnSuccessfulHkDismount = bTPlaySoundOnSuccessfulHkDismount;
- bDisplayBalloonOnSuccessfulHkDismount = bTDisplayBalloonOnSuccessfulHkDismount;
-
- SaveSettings (hwndDlg);
- EndDialog (hwndDlg, IDCANCEL);
- return 1;
- }
- return 0;
-
- case WM_CLOSE:
-
- KillTimer (hwndDlg, 0xfe);
- EndDialog (hwndDlg, IDCANCEL);
- return 1;
- }
- return 0;
-}
-
-
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include <windows.h>
+#include "Dlgcode.h"
+#include "Hotkeys.h"
+#include "Language.h"
+#include "Mount.h"
+#include "Resource.h"
+
+#include <Strsafe.h>
+
+#ifndef SRC_POS
+#define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__))
+#endif
+
+#define MAX_KEY_COMB_NAME_LEN 260
+
+TCHOTKEY Hotkeys [NBR_HOTKEYS];
+static TCHOTKEY tmpHotkeys [NBR_HOTKEYS];
+
+static int nSelectedHotkeyId;
+static UINT currentVKeyCode;
+static BYTE vkeysDown[256];
+
+
+static void ScanAndProcessKey (UINT *vKeyCode, wchar_t *keyName)
+{
+ UINT vKey;
+ *vKeyCode = 0;
+
+ for (vKey = 0; vKey <= 0xFF; vKey++)
+ {
+ if (GetAsyncKeyState (vKey) < 0)
+ {
+ if (!vkeysDown [vKey])
+ {
+ vkeysDown [vKey] = 1;
+ if (GetKeyName (vKey, keyName)) // If the key is allowed and its name has been resolved
+ *vKeyCode = vKey;
+ }
+ }
+ else
+ vkeysDown [vKey] = 0;
+ }
+}
+
+
+/* Returns TRUE if the key is allowed and its name is resolved. */
+BOOL GetKeyName (UINT vKey, wchar_t *keyName)
+{
+ BOOL result = TRUE;
+
+ if (vKey >= 0x30 && vKey <= 0x5a)
+ {
+ // ASCII characters
+ StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%hc", (char) vKey);
+ }
+ else if (vKey >= 0xE9 && vKey <= 0xF5)
+ {
+ // OEM-specific
+ StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM-%d", vKey);
+
+ // mapping taken from:
+ // http://www.hotkeynet.com/ref/keynames.html
+ // https://mojoware.googlecode.com/svn-history/r3/trunk/mojo_engine/cKeyboard.cpp
+ // http://www.screenio.com/gui_screenio/gs_htmlhelp_subweb/download/SIMKEYS.cob
+ //
+ // These values seem to come from Nokia/Ericsson mobile device keys
+
+ switch (vKey)
+ {
+ case 0xE9: // OEMReset = 0xE9
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMReset)");
+ break;
+ case 0xEA: // OEMJump = 0xEA
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMJump)");
+ break;
+ case 0xEB: // OEMPA1 = 0xEB
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMPA1)");
+ break;
+ case 0xEC: // OEMPA2 = 0xEC
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMPA2)");
+ break;
+ case 0xED: // OEMPA3 = 0xED
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMPA3)");
+ break;
+ case 0xEE: // OEMWSCtrl = 0xEE
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMWSCtrl)");
+ break;
+ case 0xEF: // OEMCUSel = 0xEF
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMCUSel)");
+ break;
+ case 0xF0: // OEMATTN = 0xF0
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMATTN)");
+ break;
+ case 0xF1: // OEMFinish = 0xF1
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMFinish)");
+ break;
+ case 0xF2: // OEMCopy = 0xF2
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMCopy)");
+ break;
+ case 0xF3: // OEMAuto = 0xF3
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMAuto)");
+ break;
+ case 0xF4: // OEMENLW = 0xF4
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMENLW)");
+ break;
+ case 0xF5: // OEMBackTab = 0xF5
+ StringCbCatW (keyName, MAX_KEY_COMB_NAME_LEN, L" (OEMBackTab)");
+ break;
+ }
+ }
+ else if (vKey >= VK_F1 && vKey <= VK_F24)
+ {
+ // F1-F24
+ StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"F%d", vKey - VK_F1 + 1);
+ }
+ else if (vKey >= VK_NUMPAD0 && vKey <= VK_NUMPAD9)
+ {
+ // Numpad numbers
+ StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s %d", GetString ("VK_NUMPAD"), vKey - VK_NUMPAD0);
+ }
+ else
+ {
+ switch (vKey)
+ {
+ case VK_MULTIPLY: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s *", GetString ("VK_NUMPAD")); break;
+ case VK_ADD: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s +", GetString ("VK_NUMPAD")); break;
+ case VK_SEPARATOR: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s Separator", GetString ("VK_NUMPAD")); break;
+ case VK_SUBTRACT: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s -", GetString ("VK_NUMPAD")); break;
+ case VK_DECIMAL: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s .", GetString ("VK_NUMPAD")); break;
+ case VK_DIVIDE: StringCbPrintfW (keyName, MAX_KEY_COMB_NAME_LEN, L"%s /", GetString ("VK_NUMPAD")); break;
+ case VK_OEM_1: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 1 (';')"); break;
+ case VK_OEM_PLUS: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"+"); break;
+ case VK_OEM_COMMA: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L","); break;
+ case VK_OEM_MINUS: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"-"); break;
+ case VK_OEM_PERIOD: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"."); break;
+ case VK_OEM_2: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 2 ('/')"); break;
+ case VK_OEM_3: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 3 (`)"); break;
+ case VK_OEM_4: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 4 ('[')"); break;
+ case VK_OEM_5: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 5 ('\\')"); break;
+ case VK_OEM_6: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 6 (']')"); break;
+ case VK_OEM_7: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 7 (')"); break;
+ case VK_OEM_8: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 8"); break;
+ case VK_OEM_AX: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM AX"); break;
+ case VK_OEM_102: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM 102"); break;
+ case VK_ICO_HELP: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ICO_HELP"); break;
+ case VK_ICO_00: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ICO_00"); break;
+ case VK_ICO_CLEAR: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ICO_CLEAR"); break;
+ case VK_ATTN: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"Attn"); break;
+ case VK_CRSEL: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"CrSel"); break;
+ case VK_EXSEL: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"ExSel"); break;
+ case VK_EREOF: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"Erase EOF"); break;
+ case VK_PA1: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"PA1"); break;
+ case VK_OEM_CLEAR: StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, L"OEM Clear"); break;
+
+ case 0:
+ case 1:
+ case 0xFF:
+ result = FALSE;
+ break;
+
+ default:
+ {
+ char key[16];
+ wchar_t *desc;
+ StringCbPrintfA (key, sizeof(key),"VKEY_%02X", vKey);
+ desc = GetString (key);
+ if (desc == UnknownString)
+ result = FALSE;
+ else
+ StringCbCopyW (keyName, MAX_KEY_COMB_NAME_LEN, desc);
+ }
+ }
+ }
+ return result;
+}
+
+
+static BOOL ShortcutInUse (UINT vKeyCode, UINT modifiers, TCHOTKEY hotkeys[])
+{
+ int i;
+
+ for (i = 0; i < NBR_HOTKEYS; i++)
+ {
+ if (hotkeys[i].vKeyCode == vKeyCode && hotkeys[i].vKeyModifiers == modifiers)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void UnregisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[])
+{
+ int i;
+
+ for (i = 0; i < NBR_HOTKEYS; i++)
+ {
+ if (hotkeys[i].vKeyCode != 0)
+ UnregisterHotKey (hwndDlg, i);
+
+ }
+}
+
+
+BOOL RegisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[])
+{
+ BOOL result = TRUE;
+ int i;
+
+ for (i = 0; i < NBR_HOTKEYS; i++)
+ {
+ if (hotkeys[i].vKeyCode != 0
+ && !RegisterHotKey (hwndDlg, i, hotkeys[i].vKeyModifiers, hotkeys[i].vKeyCode))
+ result = FALSE;
+ }
+
+ return result;
+}
+
+
+static void DisplayHotkeyList (HWND hwndDlg)
+{
+ LVITEMW item;
+ HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST);
+ int i;
+ wchar_t ShortcutMod [MAX_KEY_COMB_NAME_LEN];
+ wchar_t ShortcutFinal [MAX_KEY_COMB_NAME_LEN*2];
+ wchar_t Shortcut [MAX_KEY_COMB_NAME_LEN];
+
+ SendMessage (hList, LVM_DELETEALLITEMS,0, (LPARAM)&item);
+
+ for (i = 0; i < NBR_HOTKEYS; i++)
+ {
+ memset (&item,0,sizeof(item));
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.iSubItem = 0;
+
+ switch (i)
+ {
+
+ case HK_AUTOMOUNT_DEVICES:
+ item.pszText = GetString ("HK_AUTOMOUNT_DEVICES");
+ break;
+
+ case HK_DISMOUNT_ALL:
+ item.pszText = GetString ("HK_DISMOUNT_ALL");
+ break;
+
+ case HK_WIPE_CACHE:
+ item.pszText = GetString ("HK_WIPE_CACHE");
+ break;
+
+ case HK_DISMOUNT_ALL_AND_WIPE:
+ item.pszText = GetString ("HK_DISMOUNT_ALL_AND_WIPE");
+ break;
+
+ case HK_FORCE_DISMOUNT_ALL_AND_WIPE:
+ item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE");
+ break;
+
+ case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT:
+ item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT");
+ break;
+
+ case HK_MOUNT_FAVORITE_VOLUMES:
+ item.pszText = GetString ("HK_MOUNT_FAVORITE_VOLUMES");
+ break;
+
+ case HK_SHOW_HIDE_MAIN_WINDOW:
+ item.pszText = GetString ("HK_SHOW_HIDE_MAIN_WINDOW");
+ break;
+
+ case HK_CLOSE_SECURITY_TOKEN_SESSIONS:
+ item.pszText = GetString ("IDM_CLOSE_ALL_TOKEN_SESSIONS");
+ break;
+
+ default:
+ item.pszText = L"[?]";
+ }
+
+ SendMessageW (hList,LVM_INSERTITEMW,0,(LPARAM)&item);
+
+ item.iSubItem = 1;
+ Shortcut[0] = 0;
+ ShortcutMod[0] = 0;
+
+ if (GetKeyName (tmpHotkeys[i].vKeyCode, Shortcut))
+ {
+ if (tmpHotkeys[i].vKeyModifiers & MOD_CONTROL)
+ {
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_CONTROL"));
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
+ }
+
+ if (tmpHotkeys[i].vKeyModifiers & MOD_SHIFT)
+ {
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_SHIFT"));
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
+ }
+
+ if (tmpHotkeys[i].vKeyModifiers & MOD_ALT)
+ {
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_ALT"));
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
+ }
+
+ if (tmpHotkeys[i].vKeyModifiers & MOD_WIN)
+ {
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),GetString ("VK_WIN"));
+ StringCbCatW (ShortcutMod, sizeof(ShortcutMod),L"+");
+ }
+
+ StringCbPrintfW (ShortcutFinal, sizeof(ShortcutFinal), L"%s%s", ShortcutMod, Shortcut);
+ item.pszText = ShortcutFinal;
+ }
+ else
+ item.pszText = L"";
+
+ SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&item);
+ }
+}
+
+
+
+BOOL CALLBACK HotkeysDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ WORD lw = LOWORD (wParam);
+ WORD hw = HIWORD (wParam);
+ static BOOL bKeyScanOn;
+ static BOOL bTPlaySoundOnSuccessfulHkDismount;
+ static BOOL bTDisplayBalloonOnSuccessfulHkDismount;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ LVCOLUMNW col;
+ HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST);
+
+ bKeyScanOn = FALSE;
+ nSelectedHotkeyId = -1;
+ currentVKeyCode = 0;
+ memcpy (tmpHotkeys, Hotkeys, sizeof(tmpHotkeys));
+ memset (vkeysDown, 0, sizeof(vkeysDown));
+
+ SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
+ LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP
+ );
+
+ memset (&col,0,sizeof(col));
+ col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
+ col.pszText = GetString ("ACTION");
+ col.cx = CompensateXDPI (341);
+ col.fmt = LVCFMT_LEFT;
+ SendMessageW (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&col);
+
+ col.pszText = GetString ("SHORTCUT");
+ col.cx = CompensateXDPI (190);
+ col.fmt = LVCFMT_LEFT;
+ SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&col);
+
+ LocalizeDialog (hwndDlg, "IDD_HOTKEYS_DLG");
+
+ SetCheckBox (hwndDlg, IDC_HK_MOD_CTRL, TRUE);
+ SetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT, FALSE);
+ SetCheckBox (hwndDlg, IDC_HK_MOD_ALT, TRUE);
+ SetCheckBox (hwndDlg, IDC_HK_MOD_WIN, FALSE);
+
+ SetCheckBox (hwndDlg, IDC_HK_DISMOUNT_PLAY_SOUND, bPlaySoundOnSuccessfulHkDismount);
+ SetCheckBox (hwndDlg, IDC_HK_DISMOUNT_BALLOON_TOOLTIP, bDisplayBalloonOnSuccessfulHkDismount);
+
+ bTPlaySoundOnSuccessfulHkDismount = bPlaySoundOnSuccessfulHkDismount;
+ bTDisplayBalloonOnSuccessfulHkDismount = bDisplayBalloonOnSuccessfulHkDismount;
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
+
+ DisplayHotkeyList(hwndDlg);
+
+ if (SetTimer (hwndDlg, 0xfe, 10, NULL) == 0)
+ {
+ Error ("CANNOT_SET_TIMER", MainDlg);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+ return 1;
+ }
+
+ case WM_TIMER:
+ {
+ if ((nSelectedHotkeyId > -1) && (GetFocus () == GetDlgItem (hwndDlg, IDC_HOTKEY_KEY)))
+ {
+ wchar_t keyName [MAX_KEY_COMB_NAME_LEN];
+ UINT tmpVKeyCode;
+
+ keyName[0] = 0;
+
+ ScanAndProcessKey (&tmpVKeyCode, &keyName[0]);
+
+ if (keyName[0] != 0)
+ {
+ currentVKeyCode = tmpVKeyCode;
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), TRUE);
+ }
+ else if ((currentVKeyCode != 0) && GetKeyName (currentVKeyCode, keyName))
+ {
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName);
+ }
+ }
+ return 1;
+ }
+
+ case WM_NOTIFY:
+ if (wParam == IDC_HOTKEY_LIST)
+ {
+ if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE
+ || ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED))
+ {
+ LVITEM item;
+ memset(&item,0,sizeof(item));
+ nSelectedHotkeyId = ((LPNMLISTVIEW) lParam)->iItem;
+ currentVKeyCode = 0;
+ memset (vkeysDown, 0, sizeof(vkeysDown));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), GetString ("PRESS_A_KEY_TO_ASSIGN"));
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), (tmpHotkeys[nSelectedHotkeyId].vKeyCode > 0));
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
+ bKeyScanOn = TRUE;
+ return 1;
+ }
+ }
+
+ return 0;
+
+ case WM_COMMAND:
+ if (lw == IDC_HOTKEY_KEY && hw == EN_CHANGE)
+ {
+ if (!bKeyScanOn && nSelectedHotkeyId < 0 && GetWindowTextLengthW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY)))
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
+ }
+
+ if (lw == IDC_HOTKEY_ASSIGN)
+ {
+ BOOL bOwnActiveShortcut = FALSE;
+
+ if (nSelectedHotkeyId >= 0 && currentVKeyCode != 0)
+ {
+ UINT modifiers = 0;
+ if (GetCheckBox (hwndDlg, IDC_HK_MOD_CTRL))
+ modifiers = MOD_CONTROL;
+
+ if (GetCheckBox (hwndDlg, IDC_HK_MOD_ALT))
+ modifiers |= MOD_ALT;
+
+ if (GetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT))
+ modifiers |= MOD_SHIFT;
+
+ if (GetCheckBox (hwndDlg, IDC_HK_MOD_WIN))
+ modifiers |= MOD_WIN;
+
+ // Check if it's not already assigned
+ if (ShortcutInUse (currentVKeyCode, modifiers, tmpHotkeys))
+ {
+ Error ("SHORTCUT_ALREADY_IN_USE", hwndDlg);
+ return 1;
+ }
+
+ // Check for reserved system keys
+ switch (currentVKeyCode)
+ {
+ case VK_F1:
+ case VK_F12:
+ /* F1 is help and F12 is reserved for use by the debugger at all times */
+ if (modifiers == 0)
+ {
+ Error ("CANNOT_USE_RESERVED_KEY", hwndDlg);
+ return 1;
+ }
+ break;
+ }
+
+ bOwnActiveShortcut = ShortcutInUse (currentVKeyCode, modifiers, Hotkeys);
+
+ // Test if the shortcut can be assigned without errors
+ if (!bOwnActiveShortcut
+ && !RegisterHotKey (hwndDlg, nSelectedHotkeyId, modifiers, currentVKeyCode))
+ {
+ handleWin32Error(hwndDlg, SRC_POS);
+ return 1;
+ }
+ else
+ {
+ if (!bOwnActiveShortcut && !UnregisterHotKey (hwndDlg, nSelectedHotkeyId))
+ handleWin32Error(hwndDlg, SRC_POS);
+
+ tmpHotkeys[nSelectedHotkeyId].vKeyCode = currentVKeyCode;
+ tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = modifiers;
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
+ nSelectedHotkeyId = -1;
+ bKeyScanOn = FALSE;
+ currentVKeyCode = 0;
+ memset (vkeysDown, 0, sizeof(vkeysDown));
+ }
+ }
+ DisplayHotkeyList(hwndDlg);
+ return 1;
+ }
+
+ if (lw == IDC_HOTKEY_REMOVE)
+ {
+ if (nSelectedHotkeyId >= 0)
+ {
+ tmpHotkeys[nSelectedHotkeyId].vKeyCode = 0;
+ tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = 0;
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
+ nSelectedHotkeyId = -1;
+ bKeyScanOn = FALSE;
+ currentVKeyCode = 0;
+ memset (vkeysDown, 0, sizeof(vkeysDown));
+ DisplayHotkeyList(hwndDlg);
+ }
+ return 1;
+ }
+
+ if (lw == IDC_RESET_HOTKEYS)
+ {
+ int i;
+
+ for (i = 0; i < NBR_HOTKEYS; i++)
+ {
+ tmpHotkeys[i].vKeyCode = 0;
+ tmpHotkeys[i].vKeyModifiers = 0;
+ }
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L"");
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE);
+ nSelectedHotkeyId = -1;
+ bKeyScanOn = FALSE;
+ currentVKeyCode = 0;
+ memset (vkeysDown, 0, sizeof(vkeysDown));
+ DisplayHotkeyList(hwndDlg);
+ return 1;
+ }
+
+ if (lw == IDC_HK_DISMOUNT_PLAY_SOUND)
+ {
+ bTPlaySoundOnSuccessfulHkDismount = GetCheckBox (hwndDlg, IDC_HK_DISMOUNT_PLAY_SOUND);
+ }
+
+ if (lw == IDC_HK_DISMOUNT_BALLOON_TOOLTIP)
+ {
+ bTDisplayBalloonOnSuccessfulHkDismount = GetCheckBox (hwndDlg, IDC_HK_DISMOUNT_BALLOON_TOOLTIP);
+ }
+
+ if (lw == IDCANCEL || lw == IDCLOSE)
+ {
+ KillTimer (hwndDlg, 0xfe);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+
+ if (lw == IDOK)
+ {
+ HWND hwndMainDlg = hwndDlg;
+
+ while (GetParent (hwndMainDlg) != NULL)
+ {
+ hwndMainDlg = GetParent (hwndMainDlg);
+ }
+ UnregisterAllHotkeys (hwndMainDlg, Hotkeys);
+ memcpy (Hotkeys, tmpHotkeys, sizeof(Hotkeys));
+ RegisterAllHotkeys (hwndMainDlg, Hotkeys);
+ KillTimer (hwndDlg, 0xfe);
+ bPlaySoundOnSuccessfulHkDismount = bTPlaySoundOnSuccessfulHkDismount;
+ bDisplayBalloonOnSuccessfulHkDismount = bTDisplayBalloonOnSuccessfulHkDismount;
+
+ SaveSettings (hwndDlg);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+ return 0;
+
+ case WM_CLOSE:
+
+ KillTimer (hwndDlg, 0xfe);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+ return 0;
+}
+
+