Annotation of truecrypt/main/forms/mainframe.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.