|
|
1.1 root 1: /*
1.1.1.3 ! root 2: Copyright (c) 2004-2006 TrueCrypt Foundation. All rights reserved.
1.1 root 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:
1.1.1.2 root 273: SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
1.1 root 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");
1.1.1.2 root 280: col.cx = 341;
1.1 root 281: col.fmt = LVCFMT_LEFT;
282: SendMessageW (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&col);
283:
284: col.pszText = GetString ("SHORTCUT");
1.1.1.2 root 285: col.cx = 190;
1.1 root 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.