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