|
|
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: #include "Volume/EncryptionTest.h" ! 11: #include "Main/Main.h" ! 12: #include "Main/Resources.h" ! 13: #include "Main/Application.h" ! 14: #include "Main/GraphicUserInterface.h" ! 15: #include "Main/VolumeHistory.h" ! 16: #include "Main/Xml.h" ! 17: #include "MainFrame.h" ! 18: #include "AboutDialog.h" ! 19: #include "ChangePasswordDialog.h" ! 20: #include "FavoriteVolumesDialog.h" ! 21: #include "LegalNoticesDialog.h" ! 22: #include "PreferencesDialog.h" ! 23: #include "TravelerDiskWizard.h" ! 24: #include "VolumeCreationWizard.h" ! 25: #include "VolumePropertiesDialog.h" ! 26: ! 27: namespace TrueCrypt ! 28: { ! 29: MainFrame::MainFrame (wxWindow* parent) : MainFrameBase (parent), ! 30: SelectedItemIndex (-1), ! 31: SelectedSlotNumber (0) ! 32: { ! 33: wxBusyCursor busy; ! 34: ! 35: SetName (Application::GetName()); ! 36: SetTitle (Application::GetName()); ! 37: SetIcon (Resources::GetTrueCryptIcon()); ! 38: ! 39: InitControls(); ! 40: InitPreferences(); ! 41: InitTaskBarIcon(); ! 42: InitEvents(); ! 43: InitMessageFilter(); ! 44: } ! 45: ! 46: MainFrame::~MainFrame () ! 47: { ! 48: Core->VolumeMountedEvent.Disconnect (this); ! 49: Core->VolumeDismountedEvent.Disconnect (this); ! 50: Gui->PreferencesUpdatedEvent.Disconnect (this); ! 51: ! 52: VolumeHistory::DisconnectComboBox (VolumePathComboBox); ! 53: ! 54: #ifdef TC_WINDOWS ! 55: Hotkey::UnregisterList (this, GetPreferences().Hotkeys); ! 56: #endif ! 57: } ! 58: ! 59: void MainFrame::AddToFavorites (const VolumeInfoList &volumes) ! 60: { ! 61: FavoriteVolumeList newFavorites; ! 62: ! 63: // Delete duplicates ! 64: foreach (shared_ptr <FavoriteVolume> favorite, FavoriteVolume::LoadList()) ! 65: { ! 66: bool mounted = false; ! 67: foreach_ref (const VolumeInfo &volume, volumes) ! 68: { ! 69: if (volume.Path == favorite->Path) ! 70: { ! 71: mounted = true; ! 72: break; ! 73: } ! 74: } ! 75: if (!mounted) ! 76: newFavorites.push_back (favorite); ! 77: } ! 78: ! 79: size_t newItemCount = 0; ! 80: foreach_ref (const VolumeInfo &volume, volumes) ! 81: { ! 82: newFavorites.push_back (shared_ptr <FavoriteVolume> (new FavoriteVolume (volume.Path, volume.MountPoint, volume.SlotNumber))); ! 83: ++newItemCount; ! 84: } ! 85: ! 86: OrganizeFavorites (newFavorites, newItemCount); ! 87: } ! 88: ! 89: bool MainFrame::CanExit () const ! 90: { ! 91: return Gui->IsTheOnlyTopLevelWindow (this); ! 92: } ! 93: ! 94: void MainFrame::ChangePassword (ChangePasswordDialog::Mode::Enum mode) ! 95: { ! 96: if (!CheckVolumePathNotEmpty ()) ! 97: return; ! 98: ! 99: shared_ptr <VolumePath> volumePath = GetSelectedVolumePath(); ! 100: ! 101: if (Core->IsVolumeMounted (*volumePath)) ! 102: { ! 103: Gui->ShowInfo (LangString [mode == ChangePasswordDialog::Mode::ChangePkcs5Prf ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE"]); ! 104: return; ! 105: } ! 106: ! 107: ChangePasswordDialog dialog (this, volumePath, mode); ! 108: dialog.ShowModal(); ! 109: } ! 110: ! 111: void MainFrame::CheckFilesystem (bool repair) ! 112: { ! 113: shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume(); ! 114: if (selectedVolume) ! 115: { ! 116: try ! 117: { ! 118: #ifdef TC_WINDOWS ! 119: string mountPoint = selectedVolume->MountPoint; ! 120: ! 121: wstring args = StringFormatter (repair ? L"/C echo {0} & chkdsk {1} /F /X & pause" : L"/C echo {0} & chkdsk {1} & pause", ! 122: StringFormatter (LangString[repair ? "REPAIRING_FS" : "CHECKING_FS"], mountPoint), mountPoint); ! 123: ! 124: ShellExecute (static_cast <HWND> (GetHandle()), ! 125: L"runas", ! 126: L"cmd.exe", args.c_str(), nullptr, SW_SHOW); ! 127: #else ! 128: Core->CheckFilesystem (selectedVolume, repair); ! 129: UpdateVolumeList(); ! 130: #endif ! 131: } ! 132: catch (exception &e) ! 133: { ! 134: Gui->ShowError (e); ! 135: } ! 136: } ! 137: } ! 138: ! 139: bool MainFrame::CheckVolumePathNotEmpty () const ! 140: { ! 141: if (VolumePathComboBox->GetValue().empty()) ! 142: { ! 143: Gui->ShowInfo ("NO_VOLUME_SELECTED"); ! 144: return false; ! 145: } ! 146: return true; ! 147: } ! 148: ! 149: void MainFrame::DismountVolume (shared_ptr <VolumeInfo> volume) ! 150: { ! 151: try ! 152: { ! 153: if (!volume) ! 154: volume = GetSelectedVolume(); ! 155: ! 156: if (volume) ! 157: Gui->DismountVolume (volume); ! 158: } ! 159: catch (exception &e) ! 160: { ! 161: Gui->ShowError (e); ! 162: } ! 163: } ! 164: ! 165: shared_ptr <VolumeInfo> MainFrame::GetSelectedVolume () const ! 166: { ! 167: return Core->GetMountedVolume (SelectedSlotNumber); ! 168: } ! 169: ! 170: void MainFrame::InitControls () ! 171: { ! 172: LogoBitmap->SetBitmap (Resources::GetLogoBitmap()); ! 173: ! 174: list <int> colPermilles; ! 175: ! 176: #ifndef TC_WINDOWS ! 177: SettingsMenu->Remove (HotkeysMenuItem); ! 178: ToolsMenu->Remove (TravelerDiskWizardMenuItem); ! 179: #endif ! 180: ! 181: #ifdef TC_MACOSX ! 182: SettingsMenu->Remove (PreferencesMenuItem); ! 183: SettingsMenu->AppendSeparator(); ! 184: SettingsMenu->Append (PreferencesMenuItem); ! 185: ! 186: LowStaticBoxSizer->Detach (HigherButtonSizer); ! 187: VolumeStaticBoxSizer->Detach (VolumeGridBagSizer); ! 188: VolumeStaticBoxSizer->Add (VolumeGridBagSizer, 1, wxEXPAND, 0); ! 189: ! 190: ExitButton->SetLabel (_("Close")); ! 191: MountAllDevicesButton->SetLabel (_("Mount All Devices")); ! 192: #endif ! 193: ! 194: #ifdef TC_WINDOWS ! 195: SlotListCtrl->InsertColumn (ColumnSlot, LangString["DRIVE"], wxLIST_FORMAT_LEFT, 1); ! 196: colPermilles.push_back (75); ! 197: #else ! 198: SlotListCtrl->InsertColumn (ColumnSlot, _("Slot"), wxLIST_FORMAT_LEFT, 1); ! 199: colPermilles.push_back (81); ! 200: #endif ! 201: ! 202: SlotListCtrl->InsertColumn (ColumnPath, LangString["VOLUME"], wxLIST_FORMAT_LEFT, 1); ! 203: #ifdef TC_WINDOWS ! 204: colPermilles.push_back (487); ! 205: #else ! 206: colPermilles.push_back (430); ! 207: #endif ! 208: ! 209: SlotListCtrl->InsertColumn (ColumnSize, LangString["SIZE"], wxLIST_FORMAT_RIGHT, 1); ! 210: #ifdef TC_WINDOWS ! 211: colPermilles.push_back (126); ! 212: #else ! 213: colPermilles.push_back (130); ! 214: #endif ! 215: ! 216: #ifdef TC_WINDOWS ! 217: SlotListCtrl->InsertColumn (ColumnEA, LangString["ENCRYPTION_ALGORITHM_LV"], wxLIST_FORMAT_LEFT, 1); ! 218: colPermilles.push_back (233); ! 219: #else ! 220: SlotListCtrl->InsertColumn (ColumnMountPoint, LangString["MOUNT_POINT"], wxLIST_FORMAT_LEFT, 1); ! 221: colPermilles.push_back (259); ! 222: #endif ! 223: ! 224: SlotListCtrl->InsertColumn (ColumnType, LangString["TYPE"], wxLIST_FORMAT_LEFT, 1); ! 225: colPermilles.push_back (100); ! 226: ! 227: wxImageList *imageList = new wxImageList (16, 12, true); ! 228: imageList->Add (Resources::GetDriveIconBitmap(), Resources::GetDriveIconMaskBitmap()); ! 229: SlotListCtrl->AssignImageList (imageList, wxIMAGE_LIST_SMALL); ! 230: ! 231: SetMinSize (wxSize (-1, -1)); ! 232: Gui->SetListCtrlHeight (SlotListCtrl, 12); ! 233: ! 234: #ifdef __WXGTK__ ! 235: if (CreateVolumeButton->GetSize().GetHeight() > 26) ! 236: { ! 237: wxSize size (-1, (int) ((double) Gui->GetCharHeight (this) * 1.53)); ! 238: CreateVolumeButton->SetMinSize (size); ! 239: VolumePropertiesButton->SetMinSize (size); ! 240: WipeCacheButton->SetMinSize (size); ! 241: VolumePathComboBox->SetMinSize (size); ! 242: SelectFileButton->SetMinSize (size); ! 243: SelectDeviceButton->SetMinSize (size); ! 244: VolumeToolsButton->SetMinSize (size); ! 245: size = wxSize (-1, 38); ! 246: VolumeButton->SetMinSize (size); ! 247: } ! 248: #endif ! 249: Fit(); ! 250: Layout(); ! 251: Center(); ! 252: ! 253: VolumePathComboBox->SetMinSize (VolumePathComboBox->GetSize()); ! 254: VolumePathComboBox->SetMaxSize (VolumePathComboBox->GetSize()); ! 255: ! 256: SetMinSize (GetSize()); ! 257: SetMaxSize (GetSize()); ! 258: ! 259: Gui->SetListCtrlColumnWidths (SlotListCtrl, colPermilles); ! 260: ! 261: UpdateVolumeList(); ! 262: UpdateWipeCacheButton(); ! 263: } ! 264: ! 265: void MainFrame::InitEvents () ! 266: { ! 267: Core->VolumeMountedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnVolumeMounted)); ! 268: Core->VolumeDismountedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnVolumeDismounted)); ! 269: Gui->PreferencesUpdatedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnPreferencesUpdated)); ! 270: ! 271: // Drag & drop ! 272: class FileDropTarget : public wxFileDropTarget ! 273: { ! 274: public: ! 275: FileDropTarget (MainFrame *frame) : Frame (frame) { } ! 276: ! 277: wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def) ! 278: { ! 279: wxPoint p; ! 280: wxWindow *w = wxFindWindowAtPointer (p); ! 281: if (w == Frame || wxGetTopLevelParent (w) == Frame) ! 282: return wxDragLink; ! 283: return wxDragNone; ! 284: } ! 285: ! 286: bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames) ! 287: { ! 288: if (!filenames.empty()) ! 289: Frame->SetVolumePath (wstring (filenames.front())); ! 290: return true; ! 291: } ! 292: ! 293: MainFrame *Frame; ! 294: }; ! 295: ! 296: SetDropTarget (new FileDropTarget (this)); ! 297: #ifdef TC_MACOSX ! 298: foreach (wxWindow *c, MainPanel->GetChildren()) ! 299: c->SetDropTarget (new FileDropTarget (this)); ! 300: #endif ! 301: ! 302: // Volume history ! 303: VolumeHistory::ConnectComboBox (VolumePathComboBox); ! 304: ! 305: #ifdef TC_WINDOWS ! 306: // Hotkeys ! 307: Hotkey::RegisterList (this, GetPreferences().Hotkeys); ! 308: Connect (wxEVT_HOTKEY, wxKeyEventHandler (MainFrame::OnHotkey)); ! 309: #endif ! 310: ! 311: // Timer ! 312: class Timer : public wxTimer ! 313: { ! 314: public: ! 315: Timer (MainFrame *frame) : Frame (frame) { } ! 316: ! 317: void Notify() ! 318: { ! 319: Frame->OnTimer(); ! 320: } ! 321: ! 322: MainFrame *Frame; ! 323: }; ! 324: ! 325: mTimer.reset (dynamic_cast <wxTimer *> (new Timer (this))); ! 326: mTimer->Start (1000); ! 327: } ! 328: ! 329: #ifdef TC_WINDOWS ! 330: #include <dbt.h> ! 331: static WNDPROC MainFrameWndProc; ! 332: static LRESULT CALLBACK MainFrameWndProcFilter (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ! 333: { ! 334: if (message == WM_DEVICECHANGE && !Core->IsDeviceChangeInProgress()) ! 335: { ! 336: MainFrame *frame = dynamic_cast <MainFrame *> (Gui->GetMainFrame()); ! 337: PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR) lParam; ! 338: ! 339: if (wParam == DBT_DEVICEREMOVECOMPLETE && hdr->dbch_devicetype == DBT_DEVTYP_VOLUME) ! 340: { ! 341: PDEV_BROADCAST_VOLUME vol = (PDEV_BROADCAST_VOLUME) lParam; ! 342: for (wchar_t driveNo = 0; driveNo < 26; ++driveNo) ! 343: { ! 344: if (vol->dbcv_unitmask & (1 << driveNo)) ! 345: frame->OnDeviceChange (wstring (StringFormatter (L"{0}:\\", wchar_t (L'A' + driveNo)))); ! 346: } ! 347: } ! 348: else ! 349: { ! 350: frame->OnDeviceChange (); ! 351: } ! 352: } ! 353: ! 354: return CallWindowProc (MainFrameWndProc, hwnd, message, wParam, lParam); ! 355: } ! 356: #endif ! 357: ! 358: void MainFrame::InitMessageFilter () ! 359: { ! 360: #ifdef TC_WINDOWS ! 361: HWND mainFrameHwnd = static_cast <HWND> (GetHandle()); ! 362: MainFrameWndProc = (WNDPROC) GetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC); ! 363: SetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC, (LONG_PTR) MainFrameWndProcFilter); ! 364: #endif ! 365: } ! 366: ! 367: void MainFrame::InitPreferences () ! 368: { ! 369: try ! 370: { ! 371: LoadPreferences(); ! 372: ! 373: VolumeSlotNumber lastSelectedSlotNumber = GetPreferences().LastSelectedSlotNumber; ! 374: if (Core->IsSlotNumberValid (lastSelectedSlotNumber)) ! 375: { ! 376: long slotIndex = SlotNumberToItemIndex (lastSelectedSlotNumber); ! 377: if (slotIndex >= 0) ! 378: { ! 379: SlotListCtrl->SetItemState (slotIndex, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); ! 380: SlotListCtrl->EnsureVisible (slotIndex); ! 381: } ! 382: } ! 383: ! 384: LoadFavoriteVolumes(); ! 385: VolumeHistory::Load(); ! 386: } ! 387: catch (exception &e) ! 388: { ! 389: Gui->ShowError (e); ! 390: Gui->ShowError (_("Error while loading configuration files located in ") + wstring (Application::GetConfigFilePath (L""))); ! 391: } ! 392: } ! 393: ! 394: void MainFrame::InitTaskBarIcon () ! 395: { ! 396: class TaskBarIcon : public wxTaskBarIcon ! 397: { ! 398: public: ! 399: TaskBarIcon (MainFrame *frame) : Busy (false), Frame (frame) ! 400: { ! 401: Connect (wxEVT_TASKBAR_LEFT_DOWN, wxTaskBarIconEventHandler (TaskBarIcon::OnLeftButtonDown)); ! 402: } ! 403: ! 404: wxMenu *CreatePopupMenu () ! 405: { ! 406: auto_ptr <wxMenu> popup (new wxMenu); ! 407: ! 408: Gui->AppendToMenu (*popup, LangString[Gui->IsInBackgroundMode() ? "SHOW_TC" : "HIDE_TC"], this, wxCommandEventHandler (TaskBarIcon::OnShowHideMenuItemSelected)); ! 409: ! 410: popup->AppendSeparator(); ! 411: Gui->AppendToMenu (*popup, _("Mount All Favorite Volumes"), this, wxCommandEventHandler (TaskBarIcon::OnMountAllFavoritesMenuItemSelected))->Enable (!Busy); ! 412: Gui->AppendToMenu (*popup, _("Dismount All Mounted Volumes"), this, wxCommandEventHandler (TaskBarIcon::OnDismountAllMenuItemSelected))->Enable (!Busy); ! 413: ! 414: // Favorite volumes ! 415: if (Gui->GetPreferences().BackgroundTaskMenuMountItemsEnabled && !Frame->FavoriteVolumesMenuMap.empty()) ! 416: { ! 417: popup->AppendSeparator(); ! 418: typedef pair <int, FavoriteVolume> FavMapPair; ! 419: foreach (FavMapPair fp, Frame->FavoriteVolumesMenuMap) ! 420: { ! 421: Gui->AppendToMenu (*popup, LangString["MOUNT"] + L" " + wstring (fp.second.Path) + (fp.second.MountPoint.IsEmpty() ? L"" : L" " + wstring (fp.second.MountPoint)), ! 422: this, wxCommandEventHandler (TaskBarIcon::OnFavoriteVolumeMenuItemSelected), fp.first)->Enable (!Busy); ! 423: } ! 424: } ! 425: ! 426: // Mounted volumes ! 427: VolumeInfoList mountedVolumes = Core->GetMountedVolumes(); ! 428: if (!mountedVolumes.empty()) ! 429: { ! 430: if (Gui->GetPreferences().BackgroundTaskMenuOpenItemsEnabled) ! 431: { ! 432: popup->AppendSeparator(); ! 433: OpenMap.clear(); ! 434: foreach (shared_ptr <VolumeInfo> volume, mountedVolumes) ! 435: { ! 436: if (!volume->MountPoint.IsEmpty()) ! 437: { ! 438: wxString label = LangString["OPEN"] + L" " + wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")"; ! 439: wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnOpenMenuItemSelected)); ! 440: OpenMap[item->GetId()] = volume; ! 441: } ! 442: } ! 443: } ! 444: ! 445: if (Gui->GetPreferences().BackgroundTaskMenuDismountItemsEnabled) ! 446: { ! 447: popup->AppendSeparator(); ! 448: DismountMap.clear(); ! 449: foreach (shared_ptr <VolumeInfo> volume, mountedVolumes) ! 450: { ! 451: wxString label = LangString["DISMOUNT"] + L" "; ! 452: ! 453: if (!volume->MountPoint.IsEmpty()) ! 454: label += wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")"; ! 455: else ! 456: label += wstring (volume->Path); ! 457: ! 458: wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnDismountMenuItemSelected)); ! 459: item->Enable (!Busy); ! 460: DismountMap[item->GetId()] = volume; ! 461: } ! 462: } ! 463: } ! 464: ! 465: popup->AppendSeparator(); ! 466: Gui->AppendToMenu (*popup, _("Preferences..."), this, wxCommandEventHandler (TaskBarIcon::OnPreferencesMenuItemSelected))->Enable (!Busy); ! 467: #ifndef TC_MACOSX ! 468: popup->AppendSeparator(); ! 469: Gui->AppendToMenu (*popup, _("Exit"), this, wxCommandEventHandler (TaskBarIcon::OnExitMenuItemSelected))->Enable (!Busy && Frame->CanExit()); ! 470: #endif ! 471: return popup.release(); ! 472: } ! 473: ! 474: void OnDismountAllMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnDismountAllButtonClick (event); Busy = false; } ! 475: void OnDismountMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->DismountVolume (DismountMap[event.GetId()]); Busy = false; } ! 476: void OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnFavoriteVolumeMenuItemSelected (event); Busy = false; } ! 477: void OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->MountAllFavorites (); Busy = false; } ! 478: ! 479: void OnExitMenuItemSelected (wxCommandEvent& event) ! 480: { ! 481: Busy = true; ! 482: if (Core->GetMountedVolumes().empty() || Gui->AskYesNo (LangString ["CONFIRM_EXIT"], false, true)) ! 483: Frame->Close (true); ! 484: Busy = false; ! 485: } ! 486: ! 487: void OnLeftButtonDown (wxTaskBarIconEvent& event) { Gui->SetBackgroundMode (false); } ! 488: void OnOpenMenuItemSelected (wxCommandEvent& event) { Gui->OpenExplorerWindow (OpenMap[event.GetId()]->MountPoint); } ! 489: void OnPreferencesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnPreferencesMenuItemSelected (event); Busy = false; } ! 490: void OnShowHideMenuItemSelected (wxCommandEvent& event) { Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); } ! 491: ! 492: bool Busy; ! 493: map < int, shared_ptr <VolumeInfo> > DismountMap; ! 494: MainFrame *Frame; ! 495: map < int, shared_ptr <VolumeInfo> > OpenMap; ! 496: }; ! 497: ! 498: mTaskBarIcon.reset (new TaskBarIcon (this)); ! 499: ShowTaskBarIcon (GetPreferences().BackgroundTaskEnabled); ! 500: } ! 501: ! 502: void MainFrame::LoadFavoriteVolumes () ! 503: { ! 504: typedef pair <int, FavoriteVolume> FavMapPair; ! 505: foreach (FavMapPair p, FavoriteVolumesMenuMap) ! 506: { ! 507: FavoritesMenu->Delete (p.first); ! 508: } ! 509: FavoriteVolumesMenuMap.clear(); ! 510: ! 511: foreach_ref (const FavoriteVolume &favorite, FavoriteVolume::LoadList()) ! 512: { ! 513: wstring label = wstring (favorite.Path); ! 514: if (!favorite.MountPoint.IsEmpty()) ! 515: label += wstring (L" ") + wstring (favorite.MountPoint); ! 516: ! 517: wxMenuItem *item = Gui->AppendToMenu (*FavoritesMenu, label, this, wxCommandEventHandler (MainFrame::OnFavoriteVolumeMenuItemSelected)); ! 518: FavoriteVolumesMenuMap[item->GetId()] = favorite; ! 519: } ! 520: } ! 521: ! 522: void MainFrame::LoadPreferences () ! 523: { ! 524: UserPreferences prefs; ! 525: prefs.Load(); ! 526: Gui->SetPreferences (prefs); ! 527: NoHistoryCheckBox->SetValue (!prefs.SaveHistory); ! 528: } ! 529: ! 530: void MainFrame::MountAllDevices () ! 531: { ! 532: try ! 533: { ! 534: MountOptions mountOptions (GetPreferences().DefaultMountOptions); ! 535: ! 536: if (SlotListCtrl->GetSelectedItemCount() == 1) ! 537: mountOptions.SlotNumber = SelectedSlotNumber; ! 538: ! 539: Gui->MountAllDeviceHostedVolumes (mountOptions); ! 540: } ! 541: catch (exception &e) ! 542: { ! 543: Gui->ShowError (e); ! 544: } ! 545: } ! 546: ! 547: void MainFrame::MountAllFavorites () ! 548: { ! 549: MountOptions mountOptions (GetPreferences().DefaultMountOptions); ! 550: Gui->MountAllFavoriteVolumes (mountOptions); ! 551: } ! 552: ! 553: void MainFrame::MountVolume () ! 554: { ! 555: if (!IsFreeSlotSelected()) ! 556: { ! 557: Gui->ShowWarning (_("Please select a free drive slot from the list.")); ! 558: return; ! 559: } ! 560: ! 561: if (!CheckVolumePathNotEmpty()) ! 562: return; ! 563: ! 564: MountOptions mountOptions (GetPreferences().DefaultMountOptions); ! 565: mountOptions.SlotNumber = SelectedSlotNumber; ! 566: mountOptions.Path = GetSelectedVolumePath(); ! 567: ! 568: try ! 569: { ! 570: if (Gui->MountVolume (mountOptions) && GetPreferences().SaveHistory) ! 571: VolumeHistory::Add (*mountOptions.Path); ! 572: } ! 573: catch (exception &e) ! 574: { ! 575: Gui->ShowError (e); ! 576: } ! 577: } ! 578: ! 579: void MainFrame::OnAboutMenuItemSelected (wxCommandEvent& event) ! 580: { ! 581: AboutDialog dialog (this); ! 582: dialog.ShowModal(); ! 583: } ! 584: ! 585: void MainFrame::OnActivate (wxActivateEvent& event) ! 586: { ! 587: #ifdef TC_MACOSX ! 588: if (event.GetActive() && Gui->IsInBackgroundMode()) ! 589: Gui->SetBackgroundMode (false); ! 590: #endif ! 591: event.Skip(); ! 592: } ! 593: ! 594: void MainFrame::OnAddAllMountedToFavoritesMenuItemSelected (wxCommandEvent& event) ! 595: { ! 596: AddToFavorites (MountedVolumes); ! 597: } ! 598: ! 599: void MainFrame::OnAddToFavoritesMenuItemSelected (wxCommandEvent& event) ! 600: { ! 601: shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume(); ! 602: if (selectedVolume) ! 603: { ! 604: VolumeInfoList volumes; ! 605: volumes.push_back (selectedVolume); ! 606: AddToFavorites (volumes); ! 607: } ! 608: } ! 609: ! 610: void MainFrame::OnBackupVolumeHeadersMenuItemSelected (wxCommandEvent& event) ! 611: { ! 612: if (!CheckVolumePathNotEmpty ()) ! 613: return; ! 614: ! 615: shared_ptr <VolumePath> volumePath = GetSelectedVolumePath(); ! 616: ! 617: if (Core->IsVolumeMounted (*volumePath)) ! 618: { ! 619: Gui->ShowInfo ("DISMOUNT_FIRST"); ! 620: return; ! 621: } ! 622: ! 623: wxString confirmMsg = LangString["CONFIRM_VOL_HEADER_BAK"]; ! 624: confirmMsg.Replace (L"%hs", L"%s"); ! 625: ! 626: if (!Gui->AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true)) ! 627: return; ! 628: ! 629: FilePathList files = Gui->SelectFiles (this, wxEmptyString, true, false); ! 630: if (files.empty()) ! 631: return; ! 632: ! 633: try ! 634: { ! 635: Core->BackupVolumeHeaders (*volumePath, *files.front()); ! 636: Gui->ShowWarning ("VOL_HEADER_BACKED_UP"); ! 637: } ! 638: catch (Exception &e) ! 639: { ! 640: Gui->ShowError (e); ! 641: } ! 642: } ! 643: ! 644: void MainFrame::OnClearSlotSelectionMenuItemSelected (wxCommandEvent& event) ! 645: { ! 646: Gui->ClearListCtrlSelection (SlotListCtrl); ! 647: UpdateControls(); ! 648: } ! 649: ! 650: void MainFrame::OnClose (wxCloseEvent& event) ! 651: { ! 652: if (GetPreferences().WipeCacheOnClose) ! 653: Core->WipePasswordCache(); ! 654: ! 655: if (!Gui->IsTheOnlyTopLevelWindow (this)) ! 656: { ! 657: // Bring first frame to foreground ! 658: wxFrame *frame = nullptr; ! 659: foreach (wxWindow *window, wxTopLevelWindows) ! 660: { ! 661: if (window != this ! 662: && dynamic_cast <wxFrame *> (window) ! 663: && StringConverter::GetTypeName (typeid (*window)).find ("wxTaskBarIcon") == string::npos) ! 664: { ! 665: frame = dynamic_cast <wxFrame *> (window); ! 666: if (window->IsShown()) ! 667: break; ! 668: } ! 669: } ! 670: ! 671: if (frame) ! 672: { ! 673: frame->Show(); ! 674: if (frame->IsIconized()) ! 675: frame->Iconize(false); ! 676: frame->Raise(); ! 677: } ! 678: } ! 679: else if (event.CanVeto() && GetPreferences().BackgroundTaskEnabled ! 680: && (!GetPreferences().CloseBackgroundTaskOnNoVolumes || !MountedVolumes.empty())) ! 681: { ! 682: // Enter background mode ! 683: if (!Gui->IsInBackgroundMode()) ! 684: Gui->SetBackgroundMode (true); ! 685: } ! 686: else ! 687: { ! 688: #ifdef __WXGTK__ ! 689: Show(); ! 690: #endif ! 691: SavePreferences(); ! 692: ! 693: Destroy(); ! 694: } ! 695: ! 696: // Cancel close - veto is not used to prevent aborting log off procedure on Windows ! 697: return; ! 698: } ! 699: ! 700: void MainFrame::OnCreateVolumeButtonClick (wxCommandEvent& event) ! 701: { ! 702: (new VolumeCreationWizard (nullptr))->Show(); ! 703: } ! 704: ! 705: void MainFrame::OnDefaultKeyfilesMenuItemSelected (wxCommandEvent& event) ! 706: { ! 707: PreferencesDialog dialog (this); ! 708: dialog.SelectPage (dialog.DefaultKeyfilesPage); ! 709: dialog.ShowModal(); ! 710: } ! 711: ! 712: void MainFrame::OnDeviceChange (const DirectoryPath &mountPoint) ! 713: { ! 714: // Check if any host device has been removed and force dismount of volumes accordingly ! 715: VolumeInfoList removedVolumes; ! 716: foreach (shared_ptr <VolumeInfo> volume, Core->GetMountedVolumes()) ! 717: { ! 718: // File-hosted volumes ! 719: if (!volume->Path.IsDevice() && !mountPoint.IsEmpty()) ! 720: { ! 721: if (wxString (volume->Path).Upper().StartsWith (wstring (mountPoint).c_str())) ! 722: { ! 723: removedVolumes.push_back (volume); ! 724: continue; ! 725: } ! 726: } ! 727: ! 728: // Device-hosted volumes ! 729: if (volume->Path.IsDevice() && !Core->IsDevicePresent (volume->Path)) ! 730: removedVolumes.push_back (volume); ! 731: } ! 732: ! 733: if (!removedVolumes.empty()) ! 734: Gui->AutoDismountVolumes (removedVolumes, true); ! 735: } ! 736: ! 737: void MainFrame::OnDismountAllButtonClick (wxCommandEvent& event) ! 738: { ! 739: Gui->DismountAllVolumes(); ! 740: } ! 741: ! 742: void MainFrame::OnEncryptionTestMenuItemSelected (wxCommandEvent& event) ! 743: { ! 744: try ! 745: { ! 746: EncryptionTest::TestAll(); ! 747: Gui->ShowInfo ("TESTS_PASSED"); ! 748: } ! 749: catch (Exception &e) ! 750: { ! 751: Gui->ShowError (e); ! 752: Gui->ShowError ("TESTS_FAILED"); ! 753: } ! 754: } ! 755: ! 756: void MainFrame::OnExitButtonClick (wxCommandEvent& event) ! 757: { ! 758: Close(); ! 759: } ! 760: ! 761: void MainFrame::OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event) ! 762: { ! 763: FavoriteVolume favorite = FavoriteVolumesMenuMap[event.GetId()]; ! 764: if (!favorite.Path.IsEmpty()) ! 765: { ! 766: SetVolumePath (favorite.Path); ! 767: ! 768: MountOptions mountOptions (GetPreferences().DefaultMountOptions); ! 769: favorite.ToMountOptions (mountOptions); ! 770: ! 771: shared_ptr <VolumeInfo> volume = Gui->MountVolume (mountOptions); ! 772: if (volume) ! 773: SlotListCtrl->EnsureVisible (SlotNumberToItemIndex (volume->SlotNumber)); ! 774: } ! 775: } ! 776: ! 777: void MainFrame::OnHiddenVolumeProtectionTriggered (shared_ptr <VolumeInfo> protectedVolume) ! 778: { ! 779: Gui->ShowWarningTopMost (StringFormatter (LangString["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"], wstring (protectedVolume->Path))); ! 780: } ! 781: ! 782: void MainFrame::OnHotkey (wxKeyEvent& event) ! 783: { ! 784: #ifdef TC_WINDOWS ! 785: switch (event.GetId()) ! 786: { ! 787: case Hotkey::Id::DismountAll: ! 788: { ! 789: size_t mountedCount = Core->GetMountedVolumes().size(); ! 790: Gui->DismountAllVolumes(); ! 791: size_t newMountedCount = Core->GetMountedVolumes().size(); ! 792: ! 793: if (newMountedCount < mountedCount) ! 794: { ! 795: if (newMountedCount == 0 && GetPreferences().DisplayMessageAfterHotkeyDismount) ! 796: Gui->ShowInfo ("MOUNTED_VOLUMES_DISMOUNTED"); ! 797: else if (GetPreferences().BeepAfterHotkeyMountDismount) ! 798: MessageBeep((UINT) -1); ! 799: } ! 800: } ! 801: break; ! 802: ! 803: case Hotkey::Id::ForceDismountAllWipeCache: ! 804: case Hotkey::Id::ForceDismountAllWipeCacheExit: ! 805: { ! 806: bool mounted = !Core->GetMountedVolumes().empty(); ! 807: ! 808: WipeCache(); ! 809: Gui->DismountAllVolumes (true, true); ! 810: ! 811: if (mounted && GetPreferences().DisplayMessageAfterHotkeyDismount) ! 812: Gui->ShowInfo ("VOLUMES_DISMOUNTED_CACHE_WIPED"); ! 813: else if (mounted && GetPreferences().BeepAfterHotkeyMountDismount) ! 814: MessageBeep((UINT) -1); ! 815: ! 816: if (event.GetId() == Hotkey::Id::ForceDismountAllWipeCacheExit) ! 817: Close (true); ! 818: } ! 819: break; ! 820: ! 821: case Hotkey::Id::MountAllDevices: ! 822: case Hotkey::Id::MountAllFavorites: ! 823: { ! 824: size_t mountedCount = Core->GetMountedVolumes().size(); ! 825: ! 826: if (event.GetId() == Hotkey::Id::MountAllDevices) ! 827: MountAllDevices(); ! 828: else ! 829: MountAllFavorites(); ! 830: ! 831: if (Core->GetMountedVolumes().size() > mountedCount && GetPreferences().BeepAfterHotkeyMountDismount) ! 832: MessageBeep((UINT) -1); ! 833: } ! 834: break; ! 835: ! 836: case Hotkey::Id::ShowHideApplication: ! 837: Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); ! 838: break; ! 839: ! 840: case Hotkey::Id::WipeCache: ! 841: WipeCache(); ! 842: Gui->ShowInfo ("WIPE_CACHE"); ! 843: break; ! 844: ! 845: default: ! 846: assert (false); ! 847: break; ! 848: } ! 849: #endif // TC_WINDOWS ! 850: } ! 851: ! 852: void MainFrame::OnHotkeysMenuItemSelected (wxCommandEvent& event) ! 853: { ! 854: PreferencesDialog dialog (this); ! 855: dialog.SelectPage (dialog.HotkeysPage); ! 856: dialog.ShowModal(); ! 857: } ! 858: ! 859: void MainFrame::OnLegalNoticesMenuItemSelected (wxCommandEvent& event) ! 860: { ! 861: LegalNoticesDialog dialog (this); ! 862: dialog.ShowModal(); ! 863: } ! 864: ! 865: void MainFrame::OnListChanged () ! 866: { ! 867: OnListItemSelectionChanged(); ! 868: UpdateControls(); ! 869: } ! 870: ! 871: void MainFrame::OnListItemActivated (wxListEvent& event) ! 872: { ! 873: if (IsMountedSlotSelected()) ! 874: OpenSelectedVolume(); ! 875: else ! 876: MountVolume(); ! 877: } ! 878: ! 879: void MainFrame::OnListItemDeleted (long itemIndex) ! 880: { ! 881: if (SelectedItemIndex > itemIndex) ! 882: --SelectedItemIndex; ! 883: } ! 884: ! 885: void MainFrame::OnListItemDeselected (wxListEvent& event) ! 886: { ! 887: OnListItemSelectionChanged(); ! 888: } ! 889: ! 890: void MainFrame::OnListItemInserted (long itemIndex) ! 891: { ! 892: if (SelectedItemIndex >= itemIndex) ! 893: ++SelectedItemIndex; ! 894: } ! 895: ! 896: void MainFrame::OnListItemRightClick (wxListEvent& event) ! 897: { ! 898: #ifdef TC_MACOSX ! 899: if (SelectedItemIndex != event.GetIndex()) ! 900: { ! 901: SelectedItemIndex = event.GetIndex(); ! 902: OnListItemSelectionChanged(); ! 903: } ! 904: #endif ! 905: wxMenu popup; ! 906: if (IsMountedSlotSelected()) ! 907: { ! 908: Gui->AppendToMenu (popup, LangString["DISMOUNT"], this, wxCommandEventHandler (MainFrame::OnDismountVolumeMenuItemSelected)); ! 909: Gui->AppendToMenu (popup, LangString["OPEN"], this, wxCommandEventHandler (MainFrame::OnOpenVolumeMenuItemSelected)); ! 910: Gui->AppendToMenu (popup, _("Deselect"), this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected)); ! 911: ! 912: popup.AppendSeparator(); ! 913: Gui->AppendToMenu (popup, _("Add to Favorites..."), this, wxCommandEventHandler (MainFrame::OnAddToFavoritesMenuItemSelected)); ! 914: ! 915: #if defined (TC_WINDOWS) || defined (TC_LINUX) ! 916: popup.AppendSeparator(); ! 917: Gui->AppendToMenu (popup, LangString["IDPM_CHECK_FILESYS"], this, wxCommandEventHandler (MainFrame::OnCheckFilesystemMenuItemSelected)); ! 918: Gui->AppendToMenu (popup, LangString["IDPM_REPAIR_FILESYS"], this, wxCommandEventHandler (MainFrame::OnRepairFilesystemMenuItemSelected)); ! 919: #endif ! 920: popup.AppendSeparator(); ! 921: Gui->AppendToMenu (popup, LangString["IDPM_PROPERTIES"], this, wxCommandEventHandler (MainFrame::OnVolumePropertiesButtonClick)); ! 922: ! 923: PopupMenu (&popup); ! 924: } ! 925: else if (IsFreeSlotSelected()) ! 926: { ! 927: Gui->AppendToMenu (popup, _("Mount Volume"), this, wxCommandEventHandler (MainFrame::OnMountVolumeMenuItemSelected)); ! 928: Gui->AppendToMenu (popup, _("Deselect"), this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected)); ! 929: ! 930: PopupMenu (&popup); ! 931: } ! 932: ! 933: event.Skip(); ! 934: } ! 935: ! 936: void MainFrame::OnListItemSelected (wxListEvent& event) ! 937: { ! 938: SelectedItemIndex = event.GetIndex(); ! 939: OnListItemSelectionChanged(); ! 940: } ! 941: ! 942: void MainFrame::OnListItemSelectionChanged () ! 943: { ! 944: if (SlotListCtrl->GetSelectedItemCount() < 1) ! 945: SelectedItemIndex = -1; ! 946: ! 947: if (SelectedItemIndex >= 0) ! 948: SelectedSlotNumber = (VolumeSlotNumber) SlotListCtrl->GetItemData (SelectedItemIndex); ! 949: else ! 950: SelectedSlotNumber = 0; ! 951: ! 952: UpdateControls(); ! 953: } ! 954: ! 955: void MainFrame::OnMountAllDevicesButtonClick (wxCommandEvent& event) ! 956: { ! 957: MountAllDevices(); ! 958: } ! 959: ! 960: void MainFrame::OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event) ! 961: { ! 962: MountAllFavorites(); ! 963: } ! 964: ! 965: void MainFrame::OnNoHistoryCheckBoxClick (wxCommandEvent& event) ! 966: { ! 967: UserPreferences prefs = GetPreferences(); ! 968: prefs.SaveHistory = !event.IsChecked(); ! 969: Gui->SetPreferences (prefs); ! 970: ! 971: if (event.IsChecked()) ! 972: { ! 973: VolumeHistory::Clear(); ! 974: } ! 975: } ! 976: ! 977: void MainFrame::OnOrganizeFavoritesMenuItemSelected (wxCommandEvent& event) ! 978: { ! 979: OrganizeFavorites (FavoriteVolume::LoadList()); ! 980: } ! 981: ! 982: void MainFrame::OnPreferencesMenuItemSelected (wxCommandEvent& event) ! 983: { ! 984: PreferencesDialog dialog (this); ! 985: dialog.ShowModal(); ! 986: } ! 987: ! 988: void MainFrame::OnPreferencesUpdated (EventArgs &args) ! 989: { ! 990: const UserPreferences &prefs = GetPreferences(); ! 991: ! 992: NoHistoryCheckBox->SetValue (!prefs.SaveHistory); ! 993: ! 994: ShowTaskBarIcon (prefs.BackgroundTaskEnabled); ! 995: if (Gui->IsInBackgroundMode() && !prefs.BackgroundTaskEnabled) ! 996: Close (true); ! 997: ! 998: prefs.Save(); ! 999: } ! 1000: ! 1001: void MainFrame::OnRestoreVolumeHeaderMenuItemSelected (wxCommandEvent& event) ! 1002: { ! 1003: if (!CheckVolumePathNotEmpty ()) ! 1004: return; ! 1005: ! 1006: shared_ptr <VolumePath> volumePath = GetSelectedVolumePath(); ! 1007: ! 1008: if (Core->IsVolumeMounted (*volumePath)) ! 1009: { ! 1010: Gui->ShowInfo ("DISMOUNT_FIRST"); ! 1011: return; ! 1012: } ! 1013: ! 1014: wxString confirmMsg = LangString["CONFIRM_VOL_HEADER_RESTORE"]; ! 1015: confirmMsg.Replace (L"%hs", L"%s"); ! 1016: ! 1017: if (!Gui->AskYesNo (wxString::Format (confirmMsg, wstring (*volumePath).c_str()), true, true)) ! 1018: return; ! 1019: ! 1020: FilePathList files = Gui->SelectFiles (this, wxEmptyString, false, false); ! 1021: if (files.empty()) ! 1022: return; ! 1023: ! 1024: wxArrayString choices; ! 1025: choices.Add (LangString["RESTORE_NORMAL_VOLUME_HEADER"]); ! 1026: choices.Add (LangString["RESTORE_HIDDEN_VOLUME_HEADER"]); ! 1027: ! 1028: wxSingleChoiceDialog choiceDialog (this, LangString["HEADER_RESTORE_TYPE"], Application::GetName(), choices); ! 1029: choiceDialog.SetSelection (-1); ! 1030: ! 1031: if (choiceDialog.ShowModal() != wxID_OK) ! 1032: return; ! 1033: ! 1034: VolumeType::Enum volumeType; ! 1035: ! 1036: switch (choiceDialog.GetSelection()) ! 1037: { ! 1038: case 0: ! 1039: volumeType = VolumeType::Normal; ! 1040: break; ! 1041: ! 1042: case 1: ! 1043: volumeType = VolumeType::Hidden; ! 1044: break; ! 1045: ! 1046: default: ! 1047: return; ! 1048: } ! 1049: ! 1050: try ! 1051: { ! 1052: Core->RestoreVolumeHeaders (*volumePath, volumeType, *files.front()); ! 1053: Gui->ShowInfo ("VOL_HEADER_RESTORED"); ! 1054: } ! 1055: catch (Exception &e) ! 1056: { ! 1057: Gui->ShowError (e); ! 1058: } ! 1059: } ! 1060: ! 1061: void MainFrame::OnSelectDeviceButtonClick (wxCommandEvent& event) ! 1062: { ! 1063: DevicePath path = Gui->SelectDevice (this); ! 1064: ! 1065: if (!path.IsEmpty()) ! 1066: SetVolumePath (path); ! 1067: } ! 1068: ! 1069: void MainFrame::OnSelectFileButtonClick (wxCommandEvent& event) ! 1070: { ! 1071: FilePath path = Gui->SelectVolumeFile (this); ! 1072: if (!path.IsEmpty()) ! 1073: SetVolumePath (path); ! 1074: } ! 1075: ! 1076: void MainFrame::OnTimer () ! 1077: { ! 1078: UpdateVolumeList(); ! 1079: UpdateWipeCacheButton(); ! 1080: ! 1081: if (GetPreferences().BackgroundTaskEnabled) ! 1082: { ! 1083: // Inactivity auto-dismount ! 1084: if (GetPreferences().DismountOnInactivity) ! 1085: { ! 1086: VolumeInfoList inactiveVolumes; ! 1087: wxLongLong currentTime = wxGetLocalTimeMillis().GetValue(); ! 1088: ! 1089: map <wstring, VolumeActivityMapEntry> newActivityTimeMap; ! 1090: ! 1091: foreach (shared_ptr <VolumeInfo> volume, MountedVolumes) ! 1092: { ! 1093: if (VolumeActivityMap.find (volume->Path) != VolumeActivityMap.end() ! 1094: && VolumeActivityMap[volume->Path].SerialInstanceNumber == volume->SerialInstanceNumber) ! 1095: { ! 1096: VolumeActivityMapEntry ae = VolumeActivityMap[volume->Path]; ! 1097: ! 1098: if (volume->TotalDataRead != ae.TotalDataRead || volume->TotalDataWritten != ae.TotalDataWritten) ! 1099: { ! 1100: ae.LastActivityTime = currentTime; ! 1101: ae.TotalDataRead = volume->TotalDataRead; ! 1102: ae.TotalDataWritten = volume->TotalDataWritten; ! 1103: } ! 1104: else if ((currentTime - ae.LastActivityTime) > GetPreferences().MaxVolumeIdleTime * 1000LL * 60) ! 1105: { ! 1106: inactiveVolumes.push_back (volume); ! 1107: } ! 1108: ! 1109: newActivityTimeMap[volume->Path] = ae; ! 1110: } ! 1111: else ! 1112: { ! 1113: newActivityTimeMap[volume->Path] = VolumeActivityMapEntry (*volume, currentTime); ! 1114: } ! 1115: } ! 1116: ! 1117: VolumeActivityMap = newActivityTimeMap; ! 1118: ! 1119: if (!inactiveVolumes.empty()) ! 1120: Gui->AutoDismountVolumes (inactiveVolumes); ! 1121: } ! 1122: ! 1123: // Screen saver auto-dismount ! 1124: if (GetPreferences().DismountOnScreenSaver) ! 1125: { ! 1126: #ifdef TC_WINDOWS ! 1127: bool running; ! 1128: if (SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0) != 0) ! 1129: { ! 1130: static bool previousState = false; ! 1131: if (running && !previousState) ! 1132: { ! 1133: previousState = true; ! 1134: Gui->OnAutoDismountAllEvent(); ! 1135: } ! 1136: else ! 1137: { ! 1138: previousState = running; ! 1139: } ! 1140: } ! 1141: #endif ! 1142: } ! 1143: } ! 1144: ! 1145: if (Gui->IsInBackgroundMode()) ! 1146: { ! 1147: if (!GetPreferences().BackgroundTaskEnabled) ! 1148: { ! 1149: Close (true); ! 1150: } ! 1151: else if (MountedVolumes.empty() && (GetPreferences().CloseBackgroundTaskOnNoVolumes || Core->IsInTravelMode())) ! 1152: { ! 1153: Close (true); ! 1154: } ! 1155: } ! 1156: } ! 1157: ! 1158: void MainFrame::OnTravelerDiskWizardMenuItemSelected (wxCommandEvent& event) ! 1159: { ! 1160: #ifdef TC_WINDOWS ! 1161: (new TravelerDiskWizard (this))->Show(); ! 1162: #endif ! 1163: } ! 1164: ! 1165: void MainFrame::OnVolumeButtonClick (wxCommandEvent& event) ! 1166: { ! 1167: if (IsMountedSlotSelected()) ! 1168: DismountVolume(); ! 1169: else ! 1170: MountVolume(); ! 1171: } ! 1172: ! 1173: void MainFrame::OnVolumePropertiesButtonClick (wxCommandEvent& event) ! 1174: { ! 1175: shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume(); ! 1176: if (selectedVolume) ! 1177: { ! 1178: VolumePropertiesDialog dialog (this, *selectedVolume); ! 1179: dialog.ShowModal(); ! 1180: } ! 1181: } ! 1182: ! 1183: void MainFrame::OnVolumeToolsButtonClick (wxCommandEvent& event) ! 1184: { ! 1185: if (!CheckVolumePathNotEmpty()) ! 1186: return; ! 1187: ! 1188: wxMenu popup; ! 1189: ! 1190: Gui->AppendToMenu (popup, _("Change Volume Password..."), this, wxCommandEventHandler (MainFrame::OnChangePasswordMenuItemSelected)); ! 1191: ! 1192: popup.AppendSeparator (); ! 1193: ! 1194: Gui->AppendToMenu (popup, _("Add/Remove Keyfiles to/from Volume..."), this, wxCommandEventHandler (MainFrame::OnChangeKeyfilesMenuItemSelected)); ! 1195: Gui->AppendToMenu (popup, _("Remove All Keyfiles from Volume..."), this, wxCommandEventHandler (MainFrame::OnRemoveKeyfilesMenuItemSelected)); ! 1196: ! 1197: popup.AppendSeparator (); ! 1198: ! 1199: Gui->AppendToMenu (popup, _("Change Header Key Derivation Algorithm..."), this, wxCommandEventHandler (MainFrame::OnChangePkcs5PrfMenuItemSelected)); ! 1200: ! 1201: popup.AppendSeparator (); ! 1202: ! 1203: Gui->AppendToMenu (popup, _("Backup Volume Header..."), this, wxCommandEventHandler (MainFrame::OnBackupVolumeHeadersMenuItemSelected)); ! 1204: Gui->AppendToMenu (popup, _("Restore Volume Header..."), this, wxCommandEventHandler (MainFrame::OnRestoreVolumeHeaderMenuItemSelected)); ! 1205: ! 1206: PopupMenu (&popup, VolumeToolsButton->GetPosition().x + 2, VolumeToolsButton->GetPosition().y + 2); ! 1207: } ! 1208: ! 1209: void MainFrame::OnWipeCacheButtonClick (wxCommandEvent& event) ! 1210: { ! 1211: WipeCache(); ! 1212: Gui->ShowInfo ("WIPE_CACHE"); ! 1213: } ! 1214: ! 1215: void MainFrame::OpenSelectedVolume () const ! 1216: { ! 1217: shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume(); ! 1218: if (selectedVolume) ! 1219: { ! 1220: try ! 1221: { ! 1222: wxBusyCursor busy; ! 1223: Gui->OpenExplorerWindow (selectedVolume->MountPoint); ! 1224: } ! 1225: catch (exception &e) ! 1226: { ! 1227: Gui->ShowError (e); ! 1228: } ! 1229: } ! 1230: } ! 1231: ! 1232: void MainFrame::OrganizeFavorites (const FavoriteVolumeList &favorites, size_t newItemCount) ! 1233: { ! 1234: FavoriteVolumesDialog dialog (this, favorites, newItemCount); ! 1235: ! 1236: if (dialog.ShowModal() == wxID_OK) ! 1237: { ! 1238: FavoriteVolume::SaveList (dialog.GetFavorites()); ! 1239: LoadFavoriteVolumes(); ! 1240: } ! 1241: } ! 1242: ! 1243: void MainFrame::SavePreferences () const ! 1244: { ! 1245: try ! 1246: { ! 1247: UserPreferences prefs = GetPreferences(); ! 1248: prefs.LastSelectedSlotNumber = SelectedSlotNumber; ! 1249: prefs.Save(); ! 1250: ! 1251: VolumeHistory::Save(); ! 1252: } ! 1253: catch (exception &e) ! 1254: { ! 1255: if (!Core->IsInTravelMode()) ! 1256: Gui->ShowError (e); ! 1257: } ! 1258: } ! 1259: ! 1260: void MainFrame::ShowTaskBarIcon (bool show) ! 1261: { ! 1262: if (!show && mTaskBarIcon->IsIconInstalled()) ! 1263: { ! 1264: mTaskBarIcon->RemoveIcon(); ! 1265: } ! 1266: else if (show && !mTaskBarIcon->IsIconInstalled()) ! 1267: { ! 1268: #ifndef TC_MACOSX ! 1269: mTaskBarIcon->SetIcon (Resources::GetTrueCryptIcon(), L"TrueCrypt"); ! 1270: #endif ! 1271: } ! 1272: } ! 1273: ! 1274: long MainFrame::SlotNumberToItemIndex (uint32 slotNumber) const ! 1275: { ! 1276: for (long itemIndex = 0; itemIndex < SlotListCtrl->GetItemCount(); itemIndex++) ! 1277: { ! 1278: wxListItem item; ! 1279: item.SetId (itemIndex); ! 1280: if (slotNumber == SlotListCtrl->GetItemData (item)) ! 1281: return itemIndex; ! 1282: } ! 1283: return -1; ! 1284: } ! 1285: ! 1286: void MainFrame::UpdateControls () ! 1287: { ! 1288: bool mounted = IsMountedSlotSelected(); ! 1289: ! 1290: VolumeButton->SetLabel (mounted ? LangString["DISMOUNT"] : wxString (_("Mount"))); ! 1291: VolumePropertiesButton->Enable (mounted); ! 1292: ! 1293: DismountVolumeMenuItem->Enable (mounted); ! 1294: MountVolumeMenuItem->Enable (!mounted); ! 1295: VolumePropertiesMenuItem->Enable (mounted); ! 1296: AddToFavoritesMenuItem->Enable (mounted); ! 1297: AddAllMountedToFavoritesMenuItem->Enable (!MountedVolumes.empty()); ! 1298: UpdateWipeCacheButton(); ! 1299: } ! 1300: ! 1301: void MainFrame::UpdateVolumeList () ! 1302: { ! 1303: static Mutex mutex; ! 1304: ScopeLock lock (mutex); ! 1305: ! 1306: bool listChanged = false; ! 1307: ! 1308: MountedVolumes = Core->GetMountedVolumes(); ! 1309: ! 1310: map < VolumeSlotNumber, shared_ptr <VolumeInfo> > mountedVolumesMap; ! 1311: foreach (shared_ptr <VolumeInfo> volume, MountedVolumes) ! 1312: { ! 1313: mountedVolumesMap[volume->SlotNumber] = volume; ! 1314: } ! 1315: ! 1316: VolumeInfoList protectionTriggeredVolumes; ! 1317: ! 1318: // Update list ! 1319: long prevItemIndex = -1; ! 1320: for (VolumeSlotNumber slotNumber = Core->GetFirstSlotNumber(); slotNumber <= Core->GetLastSlotNumber(); ++slotNumber) ! 1321: { ! 1322: long itemIndex = SlotNumberToItemIndex (slotNumber); ! 1323: vector <wstring> fields (SlotListCtrl->GetColumnCount()); ! 1324: ! 1325: if (mountedVolumesMap.find (slotNumber) != mountedVolumesMap.end()) ! 1326: { ! 1327: shared_ptr <VolumeInfo> volume = mountedVolumesMap[slotNumber]; ! 1328: ! 1329: #ifdef TC_WINDOWS ! 1330: fields[ColumnSlot] = volume->MountPoint; ! 1331: fields[ColumnEA] = volume->EncryptionAlgorithmName; ! 1332: #else ! 1333: fields[ColumnSlot] = StringConverter::FromNumber (slotNumber); ! 1334: fields[ColumnMountPoint] = volume->MountPoint; ! 1335: #endif ! 1336: fields[ColumnPath] = volume->Path; ! 1337: fields[ColumnSize] = Gui->SizeToString (volume->Size); ! 1338: fields[ColumnType] = Gui->VolumeTypeToString (volume->Type, volume->Protection); ! 1339: ! 1340: if (volume->HiddenVolumeProtectionTriggered) ! 1341: { ! 1342: fields[ColumnType] += L"(!)"; ! 1343: } ! 1344: ! 1345: bool slotUpdated = false; ! 1346: if (itemIndex == -1) ! 1347: { ! 1348: Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) volume->SlotNumber); ! 1349: OnListItemInserted (prevItemIndex); ! 1350: ! 1351: listChanged |= true; ! 1352: slotUpdated = true; ! 1353: } ! 1354: else ! 1355: { ! 1356: if (Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields)) ! 1357: { ! 1358: listChanged = true; ! 1359: slotUpdated = true; ! 1360: } ! 1361: prevItemIndex = itemIndex; ! 1362: } ! 1363: ! 1364: if (slotUpdated && volume->HiddenVolumeProtectionTriggered) ! 1365: protectionTriggeredVolumes.push_back (volume); ! 1366: } ! 1367: else ! 1368: { ! 1369: #ifdef TC_WINDOWS ! 1370: fields[ColumnSlot] = Core->SlotNumberToMountPoint (slotNumber); ! 1371: #else ! 1372: fields[ColumnSlot] = StringConverter::FromNumber (slotNumber); ! 1373: #endif ! 1374: ! 1375: #ifdef TC_WINDOWS ! 1376: if (Core->IsMountPointAvailable (fields[ColumnSlot])) ! 1377: #else ! 1378: if (true) ! 1379: #endif ! 1380: { ! 1381: if (itemIndex == -1) ! 1382: { ! 1383: Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) slotNumber); ! 1384: OnListItemInserted (prevItemIndex); ! 1385: listChanged |= true; ! 1386: } ! 1387: else ! 1388: { ! 1389: listChanged |= Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields); ! 1390: prevItemIndex = itemIndex; ! 1391: } ! 1392: } ! 1393: else if (itemIndex != -1) ! 1394: { ! 1395: SlotListCtrl->DeleteItem (itemIndex); ! 1396: OnListItemDeleted (itemIndex); ! 1397: listChanged = true; ! 1398: } ! 1399: } ! 1400: } ! 1401: ! 1402: if (listChanged) ! 1403: OnListChanged(); ! 1404: ! 1405: foreach (shared_ptr <VolumeInfo> volume, protectionTriggeredVolumes) ! 1406: OnHiddenVolumeProtectionTriggered (volume); ! 1407: } ! 1408: ! 1409: void MainFrame::UpdateWipeCacheButton () ! 1410: { ! 1411: bool enabled = WipeCacheButton->IsEnabled(); ! 1412: bool empty = Core->IsPasswordCacheEmpty(); ! 1413: ! 1414: if (empty && enabled) ! 1415: { ! 1416: WipeCacheButton->Disable(); ! 1417: WipeCachedPasswordsMenuItem->Enable (false); ! 1418: } ! 1419: else if (!empty && !enabled) ! 1420: { ! 1421: WipeCacheButton->Enable(); ! 1422: WipeCachedPasswordsMenuItem->Enable(); ! 1423: } ! 1424: } ! 1425: ! 1426: void MainFrame::WipeCache () ! 1427: { ! 1428: Core->WipePasswordCache(); ! 1429: UpdateWipeCacheButton(); ! 1430: } ! 1431: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.