|
|
1.1 ! root 1: /* ! 2: Copyright (c) 2004-2005 TrueCrypt Foundation. All rights reserved. ! 3: ! 4: Covered by TrueCrypt License 2.0 the full text of which is contained in the file ! 5: License.txt included in TrueCrypt binary and source code distribution archives. ! 6: */ ! 7: ! 8: #include <windows.h> ! 9: #include "Dlgcode.h" ! 10: #include "Hotkeys.h" ! 11: #include "Language.h" ! 12: #include "Mount.h" ! 13: #include "Resource.h" ! 14: ! 15: #define MAX_KEY_COMB_NAME_LEN 260 ! 16: ! 17: TCHOTKEY Hotkeys [NBR_HOTKEYS]; ! 18: static TCHOTKEY tmpHotkeys [NBR_HOTKEYS]; ! 19: ! 20: static int nSelectedHotkeyId; ! 21: static UINT currentVKeyCode; ! 22: ! 23: ! 24: static void ScanAndProcessKey (UINT *vKeyCode, wchar_t *keyName) ! 25: { ! 26: UINT vKey; ! 27: *vKeyCode = 0; ! 28: ! 29: for (vKey = 0; vKey <= 0xFF; vKey++) ! 30: { ! 31: if (GetAsyncKeyState (vKey) < 0) ! 32: { ! 33: if (GetKeyName (vKey, keyName)) // If the key is allowed and its name has been resolved ! 34: *vKeyCode = vKey; ! 35: } ! 36: } ! 37: } ! 38: ! 39: ! 40: /* Returns TRUE if the key is allowed and its name is resolved. */ ! 41: BOOL GetKeyName (UINT vKey, wchar_t *keyName) ! 42: { ! 43: BOOL result = TRUE; ! 44: ! 45: if (vKey >= 0x30 && vKey <= 0x5a) ! 46: { ! 47: // ASCII characters ! 48: wsprintfW (keyName, L"%hc", (char) vKey); ! 49: } ! 50: else if (vKey >= 0xE9 && vKey <= 0xF5) ! 51: { ! 52: // OEM-specific ! 53: wsprintfW (keyName, L"OEM-%d", vKey); ! 54: } ! 55: else if (vKey >= VK_F1 && vKey <= VK_F24) ! 56: { ! 57: // F1-F24 ! 58: wsprintfW (keyName, L"F%d", vKey - VK_F1 + 1); ! 59: } ! 60: else if (vKey >= VK_NUMPAD0 && vKey <= VK_NUMPAD9) ! 61: { ! 62: // Numpad numbers ! 63: wsprintfW (keyName, L"%s %d", GetString ("VK_NUMPAD"), vKey - VK_NUMPAD0); ! 64: } ! 65: else ! 66: { ! 67: switch (vKey) ! 68: { ! 69: case VK_MULTIPLY: wsprintfW (keyName, L"%s *", GetString ("VK_NUMPAD")); break; ! 70: case VK_ADD: wsprintfW (keyName, L"%s +", GetString ("VK_NUMPAD")); break; ! 71: case VK_SEPARATOR: wsprintfW (keyName, L"%s Separator", GetString ("VK_NUMPAD")); break; ! 72: case VK_SUBTRACT: wsprintfW (keyName, L"%s -", GetString ("VK_NUMPAD")); break; ! 73: case VK_DECIMAL: wsprintfW (keyName, L"%s .", GetString ("VK_NUMPAD")); break; ! 74: case VK_DIVIDE: wsprintfW (keyName, L"%s /", GetString ("VK_NUMPAD")); break; ! 75: case VK_OEM_1: wcscpy (keyName, L"OEM 1 (';')"); break; ! 76: case VK_OEM_PLUS: wcscpy (keyName, L"+"); break; ! 77: case VK_OEM_COMMA: wcscpy (keyName, L","); break; ! 78: case VK_OEM_MINUS: wcscpy (keyName, L"-"); break; ! 79: case VK_OEM_PERIOD: wcscpy (keyName, L"."); break; ! 80: case VK_OEM_2: wcscpy (keyName, L"OEM 2 ('/')"); break; ! 81: case VK_OEM_3: wcscpy (keyName, L"OEM 3 (`)"); break; ! 82: case VK_OEM_4: wcscpy (keyName, L"OEM 4 ('[')"); break; ! 83: case VK_OEM_5: wcscpy (keyName, L"OEM 5 ('\\')"); break; ! 84: case VK_OEM_6: wcscpy (keyName, L"OEM 6 (']')"); break; ! 85: case VK_OEM_7: wcscpy (keyName, L"OEM 7 (')"); break; ! 86: case VK_OEM_8: wcscpy (keyName, L"OEM 8"); break; ! 87: case VK_OEM_AX: wcscpy (keyName, L"OEM AX"); break; ! 88: case VK_OEM_102: wcscpy (keyName, L"OEM 102"); break; ! 89: case VK_ICO_HELP: wcscpy (keyName, L"ICO_HELP"); break; ! 90: case VK_ICO_00: wcscpy (keyName, L"ICO_00"); break; ! 91: case VK_ICO_CLEAR: wcscpy (keyName, L"ICO_CLEAR"); break; ! 92: case VK_ATTN: wcscpy (keyName, L"Attn"); break; ! 93: case VK_CRSEL: wcscpy (keyName, L"CrSel"); break; ! 94: case VK_EXSEL: wcscpy (keyName, L"ExSel"); break; ! 95: case VK_EREOF: wcscpy (keyName, L"Erase EOF"); break; ! 96: case VK_PA1: wcscpy (keyName, L"PA1"); break; ! 97: case VK_OEM_CLEAR: wcscpy (keyName, L"OEM Clear"); break; ! 98: ! 99: case 0: ! 100: case 1: ! 101: case 0xFF: ! 102: result = FALSE; ! 103: break; ! 104: ! 105: default: ! 106: { ! 107: char key[16]; ! 108: wchar_t *desc; ! 109: sprintf (key, "VKEY_%02X", vKey); ! 110: desc = GetString (key); ! 111: if (desc == UnknownString) ! 112: result = FALSE; ! 113: else ! 114: wcsncpy (keyName, desc, MAX_KEY_COMB_NAME_LEN); ! 115: } ! 116: } ! 117: } ! 118: return result; ! 119: } ! 120: ! 121: ! 122: static BOOL ShortcutInUse (UINT vKeyCode, UINT modifiers, TCHOTKEY hotkeys[]) ! 123: { ! 124: int i; ! 125: ! 126: for (i = 0; i < NBR_HOTKEYS; i++) ! 127: { ! 128: if (hotkeys[i].vKeyCode == vKeyCode && hotkeys[i].vKeyModifiers == modifiers) ! 129: return TRUE; ! 130: } ! 131: return FALSE; ! 132: } ! 133: ! 134: ! 135: void UnregisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[]) ! 136: { ! 137: int i; ! 138: ! 139: for (i = 0; i < NBR_HOTKEYS; i++) ! 140: { ! 141: if (hotkeys[i].vKeyCode != 0) ! 142: UnregisterHotKey (hwndDlg, i); ! 143: ! 144: } ! 145: } ! 146: ! 147: ! 148: void RegisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[]) ! 149: { ! 150: int i; ! 151: ! 152: for (i = 0; i < NBR_HOTKEYS; i++) ! 153: { ! 154: if (hotkeys[i].vKeyCode != 0) ! 155: RegisterHotKey (hwndDlg, i, hotkeys[i].vKeyModifiers, hotkeys[i].vKeyCode); ! 156: } ! 157: } ! 158: ! 159: ! 160: static void DisplayHotkeyList (HWND hwndDlg) ! 161: { ! 162: LVITEMW item; ! 163: HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST); ! 164: int i; ! 165: wchar_t ShortcutMod [MAX_KEY_COMB_NAME_LEN]; ! 166: wchar_t ShortcutFinal [MAX_KEY_COMB_NAME_LEN*2]; ! 167: wchar_t Shortcut [MAX_KEY_COMB_NAME_LEN]; ! 168: ! 169: SendMessage (hList, LVM_DELETEALLITEMS,0, (LPARAM)&item); ! 170: ! 171: for (i = 0; i < NBR_HOTKEYS; i++) ! 172: { ! 173: memset (&item,0,sizeof(item)); ! 174: item.mask = LVIF_TEXT; ! 175: item.iItem = i; ! 176: item.iSubItem = 0; ! 177: ! 178: switch (i) ! 179: { ! 180: ! 181: case HK_AUTOMOUNT_DEVICES: ! 182: item.pszText = GetString ("HK_AUTOMOUNT_DEVICES"); ! 183: break; ! 184: ! 185: case HK_DISMOUNT_ALL: ! 186: item.pszText = GetString ("HK_DISMOUNT_ALL"); ! 187: break; ! 188: ! 189: case HK_FORCE_DISMOUNT_ALL_AND_WIPE: ! 190: item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE"); ! 191: break; ! 192: ! 193: case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT: ! 194: item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT"); ! 195: break; ! 196: ! 197: case HK_MOUNT_FAVORITE_VOLUMES: ! 198: item.pszText = GetString ("HK_MOUNT_FAVORITE_VOLUMES"); ! 199: break; ! 200: ! 201: case HK_SHOW_HIDE_MAIN_WINDOW: ! 202: item.pszText = GetString ("HK_SHOW_HIDE_MAIN_WINDOW"); ! 203: break; ! 204: ! 205: default: ! 206: item.pszText = L"[?]"; ! 207: } ! 208: ! 209: SendMessageW (hList,LVM_INSERTITEMW,0,(LPARAM)&item); ! 210: ! 211: item.iSubItem = 1; ! 212: wcscpy (Shortcut, L""); ! 213: wcscpy (ShortcutMod, L""); ! 214: ! 215: if (GetKeyName (tmpHotkeys[i].vKeyCode, Shortcut)) ! 216: { ! 217: if (tmpHotkeys[i].vKeyModifiers & MOD_CONTROL) ! 218: { ! 219: wcscat (ShortcutMod, GetString ("VK_CONTROL")); ! 220: wcscat (ShortcutMod, L"+"); ! 221: } ! 222: ! 223: if (tmpHotkeys[i].vKeyModifiers & MOD_SHIFT) ! 224: { ! 225: wcscat (ShortcutMod, GetString ("VK_SHIFT")); ! 226: wcscat (ShortcutMod, L"+"); ! 227: } ! 228: ! 229: if (tmpHotkeys[i].vKeyModifiers & MOD_ALT) ! 230: { ! 231: wcscat (ShortcutMod, GetString ("VK_ALT")); ! 232: wcscat (ShortcutMod, L"+"); ! 233: } ! 234: ! 235: if (tmpHotkeys[i].vKeyModifiers & MOD_WIN) ! 236: { ! 237: wcscat (ShortcutMod, GetString ("VK_WIN")); ! 238: wcscat (ShortcutMod, L"+"); ! 239: } ! 240: ! 241: wsprintfW (ShortcutFinal, L"%s%s", ShortcutMod, Shortcut); ! 242: item.pszText = ShortcutFinal; ! 243: } ! 244: else ! 245: item.pszText = L""; ! 246: ! 247: SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&item); ! 248: } ! 249: } ! 250: ! 251: ! 252: ! 253: BOOL WINAPI HotkeysDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) ! 254: { ! 255: HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST); ! 256: WORD lw = LOWORD (wParam); ! 257: WORD hw = HIWORD (wParam); ! 258: static BOOL bKeyScanOn; ! 259: static BOOL bTPlaySoundOnHotkeyMountDismount; ! 260: static BOOL bTDisplayMsgBoxOnHotkeyDismount; ! 261: ! 262: switch (msg) ! 263: { ! 264: case WM_INITDIALOG: ! 265: { ! 266: LVCOLUMNW col; ! 267: ! 268: bKeyScanOn = FALSE; ! 269: nSelectedHotkeyId = -1; ! 270: currentVKeyCode = 0; ! 271: memcpy (tmpHotkeys, Hotkeys, sizeof(tmpHotkeys)); ! 272: ! 273: SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0, ! 274: LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP ! 275: ); ! 276: ! 277: memset (&col,0,sizeof(col)); ! 278: col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; ! 279: col.pszText = GetString ("ACTION"); ! 280: col.cx = 220; ! 281: col.fmt = LVCFMT_LEFT; ! 282: SendMessageW (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&col); ! 283: ! 284: col.pszText = GetString ("SHORTCUT"); ! 285: col.cx = 210; ! 286: col.fmt = LVCFMT_LEFT; ! 287: SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&col); ! 288: ! 289: LocalizeDialog (hwndDlg, "IDD_HOTKEYS_DLG"); ! 290: ! 291: SetCheckBox (hwndDlg, IDC_HK_MOD_CTRL, TRUE); ! 292: SetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT, FALSE); ! 293: SetCheckBox (hwndDlg, IDC_HK_MOD_ALT, TRUE); ! 294: SetCheckBox (hwndDlg, IDC_HK_MOD_WIN, FALSE); ! 295: ! 296: SetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_PLAY_SOUND, bPlaySoundOnHotkeyMountDismount); ! 297: SetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_MSG_BOX, bDisplayMsgBoxOnHotkeyDismount); ! 298: ! 299: bTPlaySoundOnHotkeyMountDismount = bPlaySoundOnHotkeyMountDismount; ! 300: bTDisplayMsgBoxOnHotkeyDismount = bDisplayMsgBoxOnHotkeyDismount; ! 301: ! 302: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); ! 303: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); ! 304: ! 305: DisplayHotkeyList(hwndDlg); ! 306: ! 307: SetTimer (hwndDlg, 0xfe, 10, NULL); ! 308: return 1; ! 309: } ! 310: ! 311: case WM_TIMER: ! 312: { ! 313: if (nSelectedHotkeyId > -1) ! 314: { ! 315: wchar_t keyName [MAX_KEY_COMB_NAME_LEN]; ! 316: UINT tmpVKeyCode; ! 317: ! 318: keyName[0] = 0; ! 319: ! 320: ScanAndProcessKey (&tmpVKeyCode, &keyName[0]); ! 321: ! 322: if (keyName[0] != 0) ! 323: { ! 324: currentVKeyCode = tmpVKeyCode; ! 325: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName); ! 326: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), TRUE); ! 327: } ! 328: } ! 329: return 1; ! 330: } ! 331: ! 332: case WM_COMMAND: ! 333: case WM_NOTIFY: ! 334: ! 335: if (lw == IDC_HOTKEY_KEY && hw == EN_CHANGE) ! 336: { ! 337: if (!bKeyScanOn && nSelectedHotkeyId < 0 && GetWindowTextLengthW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY))) ! 338: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); ! 339: } ! 340: ! 341: if (msg == WM_NOTIFY && wParam == IDC_HOTKEY_LIST) ! 342: { ! 343: if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE ! 344: || ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED)) ! 345: { ! 346: LVITEM item; ! 347: memset(&item,0,sizeof(item)); ! 348: nSelectedHotkeyId = ((LPNMLISTVIEW) lParam)->iItem; ! 349: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), GetString ("PRESS_A_KEY_TO_ASSIGN")); ! 350: ! 351: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), (tmpHotkeys[nSelectedHotkeyId].vKeyCode > 0)); ! 352: ! 353: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); ! 354: bKeyScanOn = TRUE; ! 355: return 1; ! 356: } ! 357: } ! 358: ! 359: if (lw == IDC_HOTKEY_ASSIGN) ! 360: { ! 361: if (nSelectedHotkeyId >= 0 && currentVKeyCode != 0) ! 362: { ! 363: UINT modifiers = 0; ! 364: if (GetCheckBox (hwndDlg, IDC_HK_MOD_CTRL)) ! 365: modifiers = MOD_CONTROL; ! 366: ! 367: if (GetCheckBox (hwndDlg, IDC_HK_MOD_ALT)) ! 368: modifiers |= MOD_ALT; ! 369: ! 370: if (GetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT)) ! 371: modifiers |= MOD_SHIFT; ! 372: ! 373: if (GetCheckBox (hwndDlg, IDC_HK_MOD_WIN)) ! 374: modifiers |= MOD_WIN; ! 375: ! 376: // Check if it's not already assigned ! 377: if (ShortcutInUse (currentVKeyCode, modifiers, tmpHotkeys)) ! 378: { ! 379: Error ("SHORTCUT_ALREADY_IN_USE"); ! 380: return 1; ! 381: } ! 382: ! 383: // Check for reserved system keys ! 384: switch (currentVKeyCode) ! 385: { ! 386: case VK_F1: ! 387: case VK_F12: ! 388: /* F1 is help and F12 is reserved for use by the debugger at all times */ ! 389: if (modifiers == 0) ! 390: { ! 391: Error ("CANNOT_USE_RESERVED_KEY"); ! 392: return 1; ! 393: } ! 394: break; ! 395: } ! 396: ! 397: // Test if the shortcut can be assigned without errors ! 398: if (!RegisterHotKey (hwndDlg, nSelectedHotkeyId, modifiers, currentVKeyCode)) ! 399: { ! 400: handleWin32Error(hwndDlg); ! 401: return 1; ! 402: } ! 403: else ! 404: { ! 405: if (!UnregisterHotKey (hwndDlg, nSelectedHotkeyId)) ! 406: handleWin32Error(hwndDlg); ! 407: ! 408: tmpHotkeys[nSelectedHotkeyId].vKeyCode = currentVKeyCode; ! 409: tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = modifiers; ! 410: ! 411: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); ! 412: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); ! 413: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); ! 414: nSelectedHotkeyId = -1; ! 415: bKeyScanOn = FALSE; ! 416: } ! 417: } ! 418: DisplayHotkeyList(hwndDlg); ! 419: return 1; ! 420: } ! 421: ! 422: if (lw == IDC_HOTKEY_REMOVE) ! 423: { ! 424: if (nSelectedHotkeyId >= 0) ! 425: { ! 426: tmpHotkeys[nSelectedHotkeyId].vKeyCode = 0; ! 427: tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = 0; ! 428: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); ! 429: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); ! 430: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); ! 431: nSelectedHotkeyId = -1; ! 432: bKeyScanOn = FALSE; ! 433: DisplayHotkeyList(hwndDlg); ! 434: } ! 435: return 1; ! 436: } ! 437: ! 438: if (lw == IDC_RESET_HOTKEYS) ! 439: { ! 440: int i; ! 441: ! 442: for (i = 0; i < NBR_HOTKEYS; i++) ! 443: { ! 444: tmpHotkeys[i].vKeyCode = 0; ! 445: tmpHotkeys[i].vKeyModifiers = 0; ! 446: } ! 447: SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); ! 448: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); ! 449: EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); ! 450: nSelectedHotkeyId = -1; ! 451: bKeyScanOn = FALSE; ! 452: DisplayHotkeyList(hwndDlg); ! 453: return 1; ! 454: } ! 455: ! 456: if (lw == IDC_DISMOUNT_CONFIRM_PLAY_SOUND) ! 457: { ! 458: bTPlaySoundOnHotkeyMountDismount = GetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_PLAY_SOUND); ! 459: } ! 460: ! 461: if (lw == IDC_DISMOUNT_CONFIRM_MSG_BOX) ! 462: { ! 463: bTDisplayMsgBoxOnHotkeyDismount = GetCheckBox (hwndDlg, IDC_DISMOUNT_CONFIRM_MSG_BOX); ! 464: } ! 465: ! 466: if (lw == IDCANCEL || lw == IDCLOSE) ! 467: { ! 468: KillTimer (hwndDlg, 0xfe); ! 469: EndDialog (hwndDlg, IDCANCEL); ! 470: return 1; ! 471: } ! 472: ! 473: if (lw == IDOK) ! 474: { ! 475: UnregisterAllHotkeys (GetParent (hwndDlg), Hotkeys); ! 476: memcpy (Hotkeys, tmpHotkeys, sizeof(Hotkeys)); ! 477: RegisterAllHotkeys (GetParent (hwndDlg), Hotkeys); ! 478: KillTimer (hwndDlg, 0xfe); ! 479: bPlaySoundOnHotkeyMountDismount = bTPlaySoundOnHotkeyMountDismount; ! 480: bDisplayMsgBoxOnHotkeyDismount = bTDisplayMsgBoxOnHotkeyDismount; ! 481: ! 482: SaveSettings (hwndDlg); ! 483: EndDialog (hwndDlg, IDCANCEL); ! 484: return 1; ! 485: } ! 486: return 0; ! 487: ! 488: case WM_CLOSE: ! 489: ! 490: KillTimer (hwndDlg, 0xfe); ! 491: EndDialog (hwndDlg, IDCANCEL); ! 492: return 1; ! 493: } ! 494: return 0; ! 495: } ! 496: ! 497:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.