|
|
1.1 root 1: /*
2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
3:
4: Governed by the TrueCrypt License 2.4 the full text of which is contained
5: in the file License.txt included in TrueCrypt binary and source code
6: distribution packages.
7: */
8:
9: #include "System.h"
10: #ifdef TC_WINDOWS
11: #include <wx/msw/registry.h>
12: #endif
13: #include "Main/Main.h"
14: #include "Main/Application.h"
15: #include "Main/GraphicUserInterface.h"
16: #include "PreferencesDialog.h"
17:
18: namespace TrueCrypt
19: {
20: PreferencesDialog::PreferencesDialog (wxWindow* parent)
21: : PreferencesDialogBase (parent),
22: LastVirtualKeyPressed (0),
23: Preferences (Gui->GetPreferences()),
24: RestoreValidatorBell (false)
25: {
26: #define TC_CHECK_BOX_VALIDATOR(NAME) (TC_JOIN(NAME,CheckBox))->SetValidator (wxGenericValidator (&Preferences.NAME));
27:
28: // Security
29: TC_CHECK_BOX_VALIDATOR (DismountOnLogOff);
30: TC_CHECK_BOX_VALIDATOR (DismountOnPowerSaving);
31: TC_CHECK_BOX_VALIDATOR (DismountOnScreenSaver);
32: TC_CHECK_BOX_VALIDATOR (DismountOnInactivity);
33: DismountOnInactivitySpinCtrl->SetValidator (wxGenericValidator (&Preferences.MaxVolumeIdleTime));
34: TC_CHECK_BOX_VALIDATOR (ForceAutoDismount);
35: PreserveTimestampsCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.PreserveTimestamps));
36: TC_CHECK_BOX_VALIDATOR (WipeCacheOnAutoDismount);
37: TC_CHECK_BOX_VALIDATOR (WipeCacheOnClose);
38:
39: // Mount options
40: CachePasswordsCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.CachePassword));
41: MountReadOnlyCheckBox->SetValue (Preferences.DefaultMountOptions.Protection == VolumeProtection::ReadOnly);
42: MountRemovableCheckBox->SetValidator (wxGenericValidator (&Preferences.DefaultMountOptions.Removable));
43:
44: FilesystemOptionsTextCtrl->SetValue (Preferences.DefaultMountOptions.FilesystemOptions);
45:
46: // Keyfiles
47: TC_CHECK_BOX_VALIDATOR (UseKeyfiles);
48:
49: DefaultKeyfilesPanel = new KeyfilesPanel (DefaultKeyfilesPage, make_shared <KeyfileList> (Preferences.DefaultKeyfiles));
50: DefaultKeyfilesSizer->Add (DefaultKeyfilesPanel, 1, wxALL | wxEXPAND);
51: DefaultKeyfilesSizer->Layout();
52:
53: // System integration
54: TC_CHECK_BOX_VALIDATOR (BackgroundTaskEnabled);
55: TC_CHECK_BOX_VALIDATOR (CloseBackgroundTaskOnNoVolumes);
56: TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuDismountItemsEnabled);
57: TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuMountItemsEnabled);
58: TC_CHECK_BOX_VALIDATOR (BackgroundTaskMenuOpenItemsEnabled);
59:
60: TC_CHECK_BOX_VALIDATOR (StartOnLogon);
61: TC_CHECK_BOX_VALIDATOR (MountDevicesOnLogon);
62: TC_CHECK_BOX_VALIDATOR (MountFavoritesOnLogon);
63:
64: CloseBackgroundTaskOnNoVolumesCheckBox->Show (!Core->IsInTravelMode());
65: TC_CHECK_BOX_VALIDATOR (CloseExplorerWindowsOnDismount);
66: TC_CHECK_BOX_VALIDATOR (OpenExplorerWindowAfterMount);
67:
68: #ifdef TC_WINDOWS
69: // Hotkeys
70: TC_CHECK_BOX_VALIDATOR (BeepAfterHotkeyMountDismount);
71: TC_CHECK_BOX_VALIDATOR (DisplayMessageAfterHotkeyDismount);
72: #endif
73:
74: TransferDataToWindow(); // Code below relies on TransferDataToWindow() called at this point
75:
76: #if defined (TC_WINDOWS) || defined (TC_MACOSX)
77: FilesystemSizer->Show (false);
78: #else
79: // Auto-dismount is not supported on Linux as dismount may require the user to enter admin password
80: AutoDismountSizer->Show (false);
81: WipeCacheOnAutoDismountCheckBox->Show (false);
82: #endif
83:
84: #ifndef TC_WINDOWS
85: LogOnSizer->Show (false);
86: MountRemovableCheckBox->Show (false);
87: CloseExplorerWindowsOnDismountCheckBox->Show (false);
88: #endif
89:
90: #ifndef wxHAS_POWER_EVENTS
91: DismountOnPowerSavingCheckBox->Show (false);
92: #endif
93:
94: #ifdef TC_MACOSX
95: DismountOnScreenSaverCheckBox->Show (false);
96: FilesystemSecuritySizer->Show (false);
97: DismountOnLogOffCheckBox->SetLabel (_("TrueCrypt quits"));
98: OpenExplorerWindowAfterMountCheckBox->SetLabel (_("Open Finder window for successfully mounted volume"));
99:
100: MountRemovableCheckBox->Show (false);
101: FilesystemSizer->Show (false);
102: LogOnSizer->Show (false);
103: CloseExplorerWindowsOnDismountCheckBox->Show (false);
104: #endif
105:
106: #ifdef TC_WINDOWS
107: // Hotkeys
108: list <int> colPermilles;
109: HotkeyListCtrl->InsertColumn (ColumnHotkeyDescription, LangString["ACTION"], wxLIST_FORMAT_LEFT, 1);
110: colPermilles.push_back (642);
111: HotkeyListCtrl->InsertColumn (ColumnHotkey, LangString["SHORTCUT"], wxLIST_FORMAT_LEFT, 1);
112: colPermilles.push_back (358);
113:
114: vector <wstring> fields (HotkeyListCtrl->GetColumnCount());
115:
116: UnregisteredHotkeys = Preferences.Hotkeys;
117: Hotkey::UnregisterList (Gui->GetMainFrame(), UnregisteredHotkeys);
118:
119: foreach (shared_ptr <Hotkey> hotkey, Preferences.Hotkeys)
120: {
121: fields[ColumnHotkeyDescription] = hotkey->Description;
122: fields[ColumnHotkey] = hotkey->GetShortcutString();
123: Gui->AppendToListCtrl (HotkeyListCtrl, fields, -1, hotkey.get());
124: }
125:
126: Gui->SetListCtrlHeight (HotkeyListCtrl, 5);
127:
128: Layout();
129: Fit();
130: Gui->SetListCtrlColumnWidths (HotkeyListCtrl, colPermilles);
131:
132: RestoreValidatorBell = !wxTextValidator::IsSilent();
133: wxTextValidator::SetBellOnError (true);
134: HotkeyTextCtrl->SetValidator (wxTextValidator (wxFILTER_INCLUDE_CHAR_LIST));
135:
136: UpdateHotkeyButtons();
137: #endif
138:
139: // Page setup
140: for (size_t page = 0; page < PreferencesNotebook->GetPageCount(); page++)
141: {
142: wxNotebookPage *np = PreferencesNotebook->GetPage (page);
143: if (np == HotkeysPage)
144: {
145: #ifndef TC_WINDOWS
146: PreferencesNotebook->RemovePage (page--);
147: continue;
148: #endif
149: }
150:
151: np->Layout();
152: }
153:
154: Layout();
155: Fit();
156: Center();
157:
158: StdButtonsOK->SetDefault();
159:
160: #ifdef TC_WINDOWS
161: // Hotkey timer
162: class Timer : public wxTimer
163: {
164: public:
165: Timer (PreferencesDialog *dialog) : Dialog (dialog) { }
166:
167: void Notify()
168: {
169: Dialog->OnTimer();
170: }
171:
172: PreferencesDialog *Dialog;
173: };
174:
175: mTimer.reset (dynamic_cast <wxTimer *> (new Timer (this)));
176: mTimer->Start (25);
177: #endif
178: }
179:
180: PreferencesDialog::~PreferencesDialog ()
181: {
182: if (RestoreValidatorBell)
183: wxTextValidator::SetBellOnError (false);
184: }
185:
186: void PreferencesDialog::SelectPage (wxPanel *page)
187: {
188: for (size_t pageIndex = 0; pageIndex < PreferencesNotebook->GetPageCount(); pageIndex++)
189: {
190: if (PreferencesNotebook->GetPage (pageIndex) == page)
191: PreferencesNotebook->ChangeSelection (pageIndex);
192: }
193: }
194:
195: void PreferencesDialog::OnAssignHotkeyButtonClick (wxCommandEvent& event)
196: {
197: #ifdef TC_WINDOWS
198: foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl))
199: {
200: Hotkey *hotkey = reinterpret_cast <Hotkey *> (HotkeyListCtrl->GetItemData (item));
201:
202: int mods = 0;
203: mods |= HotkeyShiftCheckBox->IsChecked() ? wxMOD_SHIFT : 0;
204: mods |= HotkeyControlCheckBox->IsChecked() ? wxMOD_CONTROL : 0;
205: mods |= HotkeyAltCheckBox->IsChecked() ? wxMOD_ALT : 0;
206: mods |= HotkeyWinCheckBox->IsChecked() ? wxMOD_WIN : 0;
207:
208: // F1 is help and F12 is reserved for use by the debugger at all times
209: if (mods == 0 && (LastVirtualKeyPressed == VK_F1 || LastVirtualKeyPressed == VK_F12))
210: {
211: Gui->ShowError ("CANNOT_USE_RESERVED_KEY");
212: return;
213: }
214:
215: // Test if the hotkey can be registered
216: if (!this->RegisterHotKey (hotkey->Id, mods, LastVirtualKeyPressed))
217: {
218: Gui->ShowError (SystemException (SRC_POS));
219: return;
220: }
221: UnregisterHotKey (hotkey->Id);
222:
223: foreach_ref (const Hotkey &h, Preferences.Hotkeys)
224: {
225: if (h.Id != hotkey->Id && h.VirtualKeyCode == LastVirtualKeyPressed && h.VirtualKeyModifiers == mods)
226: {
227: Gui->ShowError ("SHORTCUT_ALREADY_IN_USE");
228: return;
229: }
230: }
231:
232: hotkey->VirtualKeyCode = LastVirtualKeyPressed;
233: hotkey->VirtualKeyModifiers = mods;
234:
235: vector <wstring> fields (HotkeyListCtrl->GetColumnCount());
236: fields[ColumnHotkeyDescription] = hotkey->Description;
237: fields[ColumnHotkey] = hotkey->GetShortcutString();
238: Gui->UpdateListCtrlItem (HotkeyListCtrl, item, fields);
239:
240: UpdateHotkeyButtons();
241: }
242: #endif // TC_WINDOWS
243: }
244:
245: void PreferencesDialog::OnBackgroundTaskEnabledCheckBoxClick (wxCommandEvent& event)
246: {
247: if (!event.IsChecked())
248: BackgroundTaskEnabledCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_BACKGROUND_TASK_DISABLED"], false, true));
249: }
250:
251: void PreferencesDialog::OnClose (wxCloseEvent& event)
252: {
253: #ifdef TC_WINDOWS
254: Hotkey::RegisterList (Gui->GetMainFrame(), UnregisteredHotkeys);
255: #endif
256: event.Skip();
257: }
258:
259: void PreferencesDialog::OnDismountOnPowerSavingCheckBoxClick (wxCommandEvent& event)
260: {
261: if (event.IsChecked() && !ForceAutoDismountCheckBox->IsChecked())
262: Gui->ShowWarning ("WARN_PREF_AUTO_DISMOUNT");
263: }
264:
265: void PreferencesDialog::OnDismountOnScreenSaverCheckBoxClick (wxCommandEvent& event)
266: {
267: if (event.IsChecked() && !ForceAutoDismountCheckBox->IsChecked())
268: Gui->ShowWarning ("WARN_PREF_AUTO_DISMOUNT");
269: }
270:
271: void PreferencesDialog::OnForceAutoDismountCheckBoxClick (wxCommandEvent& event)
272: {
273: if (!event.IsChecked())
274: ForceAutoDismountCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_NO_FORCED_AUTODISMOUNT"], false, true));
275: }
276:
277: void PreferencesDialog::OnHotkeyListItemDeselected (wxListEvent& event)
278: {
279: UpdateHotkeyButtons();
280: }
281:
282: void PreferencesDialog::OnHotkeyListItemSelected (wxListEvent& event)
283: {
284: UpdateHotkeyButtons();
285: HotkeyTextCtrl->ChangeValue (LangString ["PRESS_A_KEY_TO_ASSIGN"]);
286: AssignHotkeyButton->Enable (false);
287: }
288:
289: void PreferencesDialog::OnOKButtonClick (wxCommandEvent& event)
290: {
291: #ifdef TC_WINDOWS
292: HotkeyTextCtrl->SetValidator (wxTextValidator (wxFILTER_NONE));
293: #endif
294: if (!Validate())
295: return;
296:
297: TransferDataFromWindow();
298:
299: Preferences.DefaultMountOptions.Protection = MountReadOnlyCheckBox->IsChecked() ? VolumeProtection::ReadOnly : VolumeProtection::None;
300: Preferences.DefaultMountOptions.FilesystemOptions = FilesystemOptionsTextCtrl->GetValue();
301: Preferences.DefaultKeyfiles = *DefaultKeyfilesPanel->GetKeyfiles();
302:
303: Gui->SetPreferences (Preferences);
304:
305: #ifdef TC_WINDOWS
306: // Log on actions
307: wxString logonKey = wxString (L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Curren") + L"tVersion\\Run"; // Splitted to prevent false antivirus heuristic alerts
308: if (Preferences.StartOnLogon || Preferences.MountDevicesOnLogon || Preferences.MountFavoritesOnLogon)
309: {
310: auto_ptr <wxRegKey> regKey (new wxRegKey (logonKey));
311: throw_sys_sub_if (!regKey.get(), wstring (logonKey));
312:
313: wxString cmdLine = wstring (L"\"") + wstring (Application::GetExecutablePath()) + L"\" --load-preferences";
314:
315: wxString autoMount;
316: if (Preferences.MountDevicesOnLogon)
317: autoMount += L"devices";
318: if (Preferences.MountFavoritesOnLogon)
319: {
320: if (!autoMount.empty())
321: autoMount += L",";
322: autoMount += L"favorites";
323: }
324:
325: if (!autoMount.empty())
326: cmdLine += wxString (L" --auto-mount=") + autoMount;
327:
328: if (Preferences.StartOnLogon)
329: cmdLine += L" --background-task";
330:
331: throw_sys_sub_if (!regKey->SetValue (Application::GetName().c_str(), cmdLine), wstring (logonKey));
332: }
333: else
334: {
335: auto_ptr <wxRegKey> regKey (new wxRegKey (logonKey));
336: regKey->DeleteValue (Application::GetName().c_str());
337: }
338:
339: // Hotkeys
340: Hotkey::RegisterList (Gui->GetMainFrame(), Preferences.Hotkeys);
341: #endif
342:
343: EndModal (wxID_OK);
344: }
345:
346: void PreferencesDialog::OnPreserveTimestampsCheckBoxClick (wxCommandEvent& event)
347: {
348: if (!event.IsChecked())
349: PreserveTimestampsCheckBox->SetValue (!Gui->AskYesNo (LangString["CONFIRM_TIMESTAMP_UPDATING"], false, true));
350: }
351:
352: void PreferencesDialog::OnRemoveHotkeyButtonClick (wxCommandEvent& event)
353: {
354: foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl))
355: {
356: Hotkey *hotkey = reinterpret_cast <Hotkey *> (HotkeyListCtrl->GetItemData (item));
357: hotkey->VirtualKeyCode = 0;
358: hotkey->VirtualKeyModifiers = 0;
359:
360: vector <wstring> fields (HotkeyListCtrl->GetColumnCount());
361: fields[ColumnHotkeyDescription] = hotkey->Description;
362: fields[ColumnHotkey] = hotkey->GetShortcutString();
363: Gui->UpdateListCtrlItem (HotkeyListCtrl, item, fields);
364:
365: UpdateHotkeyButtons();
366: }
367: }
368:
369: void PreferencesDialog::OnTimer ()
370: {
371: #ifdef TC_WINDOWS
372: for (UINT vKey = 0; vKey <= 0xFF; vKey++)
373: {
374: if (GetAsyncKeyState (vKey) < 0)
375: {
376: bool shift = wxGetKeyState (WXK_SHIFT);
377: bool control = wxGetKeyState (WXK_CONTROL);
378: bool alt = wxGetKeyState (WXK_ALT);
379: bool win = wxGetKeyState (WXK_WINDOWS_LEFT) || wxGetKeyState (WXK_WINDOWS_RIGHT);
380:
381: if (!Hotkey::GetVirtualKeyCodeString (vKey).empty()) // If the key is allowed and its name has been resolved
382: {
383: LastVirtualKeyPressed = vKey;
384:
385: HotkeyShiftCheckBox->SetValue (shift);
386: HotkeyControlCheckBox->SetValue (control);
387: HotkeyAltCheckBox->SetValue (alt);
388: HotkeyWinCheckBox->SetValue (win);
389:
390: HotkeyTextCtrl->ChangeValue (Hotkey::GetVirtualKeyCodeString (LastVirtualKeyPressed));
391: UpdateHotkeyButtons();
392: return;
393: }
394: }
395: }
396: #endif
397: }
398:
399: void PreferencesDialog::UpdateHotkeyButtons()
400: {
401: AssignHotkeyButton->Enable (!HotkeyTextCtrl->IsEmpty() && HotkeyListCtrl->GetSelectedItemCount() > 0);
402:
403: bool remove = false;
404: foreach (long item, Gui->GetListCtrlSelectedItems (HotkeyListCtrl))
405: {
406: if (reinterpret_cast <Hotkey *> (HotkeyListCtrl->GetItemData (item))->VirtualKeyCode != 0)
407: remove = true;
408: }
409: RemoveHotkeyButton->Enable (remove);
410: }
411: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.