1810 lines
49 KiB
C++
1810 lines
49 KiB
C++
/*
|
|
Derived from source code of TrueCrypt 7.1a, which is
|
|
Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
|
|
by the TrueCrypt License 3.0.
|
|
|
|
Modifications and additions to the original source code (contained in this file)
|
|
and all other portions of this file are Copyright (c) 2013-2017 IDRIX
|
|
and are governed by the Apache License 2.0 the full text of which is
|
|
contained in the file License.txt included in VeraCrypt binary and source
|
|
code distribution packages.
|
|
*/
|
|
|
|
#include "System.h"
|
|
|
|
#ifdef TC_UNIX
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#endif
|
|
|
|
#include "Common/SecurityToken.h"
|
|
#include "Main/Main.h"
|
|
#include "Main/Resources.h"
|
|
#include "Main/Application.h"
|
|
#include "Main/GraphicUserInterface.h"
|
|
#include "Main/VolumeHistory.h"
|
|
#include "Main/Xml.h"
|
|
#include "MainFrame.h"
|
|
#include "AboutDialog.h"
|
|
#include "BenchmarkDialog.h"
|
|
#include "ChangePasswordDialog.h"
|
|
#include "EncryptionTestDialog.h"
|
|
#include "FavoriteVolumesDialog.h"
|
|
#include "LegalNoticesDialog.h"
|
|
#include "PreferencesDialog.h"
|
|
#include "SecurityTokenKeyfilesDialog.h"
|
|
#include "VolumeCreationWizard.h"
|
|
#include "VolumePropertiesDialog.h"
|
|
|
|
namespace VeraCrypt
|
|
{
|
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_UPDATE_VOLUME_LIST)
|
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_PREF_UPDATED)
|
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_OPEN_VOLUME_REQUEST)
|
|
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SHOW_WARNING)
|
|
|
|
MainFrame::MainFrame (wxWindow* parent) : MainFrameBase (parent),
|
|
#ifdef HAVE_INDICATORS
|
|
indicator (NULL),
|
|
#endif
|
|
ListItemRightClickEventPending (false),
|
|
SelectedItemIndex (-1),
|
|
SelectedSlotNumber (0),
|
|
ShowRequestFifo (-1)
|
|
{
|
|
wxBusyCursor busy;
|
|
|
|
SetName (Application::GetName());
|
|
SetTitle (Application::GetName());
|
|
SetIcon (Resources::GetVeraCryptIcon());
|
|
|
|
#if defined(TC_UNIX) && !defined(TC_MACOSX)
|
|
try
|
|
{
|
|
string fifoPath = GetShowRequestFifoPath();
|
|
|
|
remove (fifoPath.c_str());
|
|
throw_sys_if (mkfifo (fifoPath.c_str(), S_IRUSR | S_IWUSR) == -1);
|
|
|
|
ShowRequestFifo = open (fifoPath.c_str(), O_RDONLY | O_NONBLOCK);
|
|
throw_sys_if (ShowRequestFifo == -1);
|
|
}
|
|
catch (...)
|
|
{
|
|
#ifdef DEBUG
|
|
throw;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
InitControls();
|
|
InitPreferences();
|
|
InitTaskBarIcon();
|
|
InitEvents();
|
|
InitMessageFilter();
|
|
|
|
if (!GetPreferences().SecurityTokenModule.IsEmpty() && !SecurityToken::IsInitialized())
|
|
{
|
|
try
|
|
{
|
|
Gui->InitSecurityTokenLibrary();
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
Connect( wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnQuit ) );
|
|
Connect( wxID_ANY, wxEVT_COMMAND_UPDATE_VOLUME_LIST, wxCommandEventHandler( MainFrame::OnUpdateVolumeList ) );
|
|
Connect( wxID_ANY, wxEVT_COMMAND_PREF_UPDATED, wxCommandEventHandler( MainFrame::OnPreferencesUpdated ) );
|
|
Connect( wxID_ANY, wxEVT_COMMAND_OPEN_VOLUME_REQUEST, wxCommandEventHandler( MainFrame::OnOpenVolumeSystemRequest ) );
|
|
|
|
#ifdef TC_MACOSX
|
|
Connect( wxID_ANY, wxEVT_MOVE, wxMoveEventHandler( MainFrame::OnMoveHandler ) );
|
|
#endif
|
|
}
|
|
|
|
MainFrame::~MainFrame ()
|
|
{
|
|
#if defined(TC_UNIX) && !defined(TC_MACOSX)
|
|
if (ShowRequestFifo != -1)
|
|
{
|
|
try
|
|
{
|
|
close (ShowRequestFifo);
|
|
remove (string (GetShowRequestFifoPath()).c_str());
|
|
}
|
|
catch (...) { }
|
|
}
|
|
#endif
|
|
|
|
Disconnect( wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnQuit ) );
|
|
Disconnect( wxID_ANY, wxEVT_COMMAND_UPDATE_VOLUME_LIST, wxCommandEventHandler( MainFrame::OnUpdateVolumeList ) );
|
|
Disconnect( wxID_ANY, wxEVT_COMMAND_PREF_UPDATED, wxCommandEventHandler( MainFrame::OnPreferencesUpdated ) );
|
|
Disconnect( wxID_ANY, wxEVT_COMMAND_OPEN_VOLUME_REQUEST, wxCommandEventHandler( MainFrame::OnOpenVolumeSystemRequest ) );
|
|
#ifdef TC_MACOSX
|
|
Disconnect( wxID_ANY, wxEVT_MOVE, wxMoveEventHandler( MainFrame::OnMoveHandler ) );
|
|
#endif
|
|
Core->VolumeMountedEvent.Disconnect (this);
|
|
Core->VolumeDismountedEvent.Disconnect (this);
|
|
Gui->OpenVolumeSystemRequestEvent.Disconnect (this);
|
|
Gui->PreferencesUpdatedEvent.Disconnect (this);
|
|
|
|
VolumeHistory::DisconnectComboBox (VolumePathComboBox);
|
|
|
|
#ifdef TC_WINDOWS
|
|
Hotkey::UnregisterList (this, GetPreferences().Hotkeys);
|
|
#endif
|
|
}
|
|
|
|
void MainFrame::AddToFavorites (const VolumeInfoList &volumes)
|
|
{
|
|
try
|
|
{
|
|
FavoriteVolumeList newFavorites;
|
|
|
|
// Delete duplicates
|
|
foreach (shared_ptr <FavoriteVolume> favorite, FavoriteVolume::LoadList())
|
|
{
|
|
bool mounted = false;
|
|
foreach_ref (const VolumeInfo &volume, volumes)
|
|
{
|
|
if (volume.Path == favorite->Path)
|
|
{
|
|
mounted = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!mounted)
|
|
newFavorites.push_back (favorite);
|
|
}
|
|
|
|
size_t newItemCount = 0;
|
|
foreach_ref (const VolumeInfo &volume, volumes)
|
|
{
|
|
newFavorites.push_back (shared_ptr <FavoriteVolume> (new FavoriteVolume (volume.Path, volume.MountPoint, volume.SlotNumber, volume.Protection == VolumeProtection::ReadOnly, volume.SystemEncryption)));
|
|
++newItemCount;
|
|
}
|
|
|
|
OrganizeFavorites (newFavorites, newItemCount);
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
bool MainFrame::CanExit () const
|
|
{
|
|
return Gui->IsTheOnlyTopLevelWindow (this);
|
|
}
|
|
|
|
void MainFrame::ChangePassword (ChangePasswordDialog::Mode::Enum mode)
|
|
{
|
|
if (!CheckVolumePathNotEmpty ())
|
|
return;
|
|
|
|
shared_ptr <VolumePath> volumePath = GetSelectedVolumePath();
|
|
|
|
#ifdef TC_WINDOWS
|
|
if (Core->IsVolumeMounted (*volumePath))
|
|
{
|
|
Gui->ShowInfo (LangString [mode == ChangePasswordDialog::Mode::ChangePkcs5Prf ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE"]);
|
|
return;
|
|
}
|
|
#endif
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
ChangePasswordDialog dialog (this, volumePath, mode);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::CheckFilesystem (bool repair)
|
|
{
|
|
shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
|
|
if (selectedVolume)
|
|
{
|
|
try
|
|
{
|
|
#ifdef TC_WINDOWS
|
|
string mountPoint = selectedVolume->MountPoint;
|
|
|
|
wstring args = StringFormatter (repair ? L"/C echo {0} & chkdsk {1} /F /X & pause" : L"/C echo {0} & chkdsk {1} & pause",
|
|
StringFormatter (LangString[repair ? "REPAIRING_FS" : "CHECKING_FS"], mountPoint), mountPoint);
|
|
|
|
ShellExecute (static_cast <HWND> (GetHandle()),
|
|
L"runas",
|
|
L"cmd.exe", args.c_str(), nullptr, SW_SHOW);
|
|
#else
|
|
# ifdef TC_MACOSX
|
|
Gui->ShowInfo (LangString["LINUX_FIRST_AID"]);
|
|
# endif
|
|
Core->CheckFilesystem (selectedVolume, repair);
|
|
UpdateVolumeList();
|
|
#endif
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool MainFrame::CheckVolumePathNotEmpty () const
|
|
{
|
|
if (VolumePathComboBox->GetValue().empty())
|
|
{
|
|
Gui->ShowInfo ("NO_VOLUME_SELECTED");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void MainFrame::DismountVolume (shared_ptr <VolumeInfo> volume)
|
|
{
|
|
try
|
|
{
|
|
if (!volume)
|
|
volume = GetSelectedVolume();
|
|
|
|
if (volume)
|
|
Gui->DismountVolume (volume);
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
shared_ptr <VolumeInfo> MainFrame::GetSelectedVolume () const
|
|
{
|
|
return Core->GetMountedVolume (SelectedSlotNumber);
|
|
}
|
|
|
|
void MainFrame::InitControls ()
|
|
{
|
|
LogoBitmap->SetBitmap (Resources::GetLogoBitmap());
|
|
|
|
list <int> colPermilles;
|
|
|
|
#ifndef TC_WINDOWS
|
|
SettingsMenu->Remove (HotkeysMenuItem);
|
|
#endif
|
|
|
|
#ifdef TC_MACOSX
|
|
SettingsMenu->Remove (PreferencesMenuItem);
|
|
SettingsMenu->AppendSeparator();
|
|
SettingsMenu->Append (PreferencesMenuItem);
|
|
|
|
LowStaticBoxSizer->Detach (HigherButtonSizer);
|
|
VolumeStaticBoxSizer->Detach (VolumeGridBagSizer);
|
|
VolumeStaticBoxSizer->Add (VolumeGridBagSizer, 1, wxEXPAND, 0);
|
|
|
|
ExitButton->SetLabel (LangString["IDCLOSE"]);
|
|
MountAllDevicesButton->SetLabel (LangString["LINUX_MOUNT_ALL_DEV"]);
|
|
#endif
|
|
|
|
#ifdef TC_WINDOWS
|
|
SlotListCtrl->InsertColumn (ColumnSlot, LangString["DRIVE"], wxLIST_FORMAT_LEFT, 1);
|
|
colPermilles.push_back (75);
|
|
#else
|
|
SlotListCtrl->InsertColumn (ColumnSlot, LangString["TOKEN_SLOT_ID"], wxLIST_FORMAT_LEFT, 1);
|
|
colPermilles.push_back (82);
|
|
#endif
|
|
|
|
SlotListCtrl->InsertColumn (ColumnPath, LangString["VOLUME"], wxLIST_FORMAT_LEFT, 1);
|
|
#ifdef TC_WINDOWS
|
|
colPermilles.push_back (487);
|
|
#else
|
|
colPermilles.push_back (429);
|
|
#endif
|
|
|
|
SlotListCtrl->InsertColumn (ColumnSize, LangString["SIZE"], wxLIST_FORMAT_RIGHT, 1);
|
|
#ifdef TC_WINDOWS
|
|
colPermilles.push_back (126);
|
|
#else
|
|
colPermilles.push_back (130);
|
|
#endif
|
|
|
|
#ifdef TC_WINDOWS
|
|
SlotListCtrl->InsertColumn (ColumnEA, LangString["ENCRYPTION_ALGORITHM_LV"], wxLIST_FORMAT_LEFT, 1);
|
|
colPermilles.push_back (233);
|
|
#else
|
|
SlotListCtrl->InsertColumn (ColumnMountPoint, LangString["MOUNT_POINT"], wxLIST_FORMAT_LEFT, 1);
|
|
colPermilles.push_back (259);
|
|
#endif
|
|
|
|
SlotListCtrl->InsertColumn (ColumnType, LangString["TYPE"], wxLIST_FORMAT_LEFT, 1);
|
|
colPermilles.push_back (100);
|
|
|
|
wxImageList *imageList = new wxImageList (16, 12, true);
|
|
imageList->Add (Resources::GetDriveIconBitmap(), Resources::GetDriveIconMaskBitmap());
|
|
SlotListCtrl->AssignImageList (imageList, wxIMAGE_LIST_SMALL);
|
|
|
|
SetMinSize (wxSize (-1, -1));
|
|
|
|
size_t slotListRowCount = 12;
|
|
|
|
#ifndef TC_WINDOWS
|
|
int screenHeight = wxSystemSettings::GetMetric (wxSYS_SCREEN_Y);
|
|
|
|
if (screenHeight < 480)
|
|
slotListRowCount = 1;
|
|
else if (screenHeight <= 600)
|
|
slotListRowCount = slotListRowCount * screenHeight / 1000;
|
|
#endif
|
|
|
|
Gui->SetListCtrlHeight (SlotListCtrl, slotListRowCount);
|
|
|
|
#ifdef __WXGTK__
|
|
wxSize size (-1, (int) ((double) Gui->GetCharHeight (this) * 1.53));
|
|
CreateVolumeButton->SetMinSize (size);
|
|
VolumePropertiesButton->SetMinSize (size);
|
|
WipeCacheButton->SetMinSize (size);
|
|
VolumePathComboBox->SetMinSize (size);
|
|
SelectFileButton->SetMinSize (size);
|
|
SelectDeviceButton->SetMinSize (size);
|
|
VolumeToolsButton->SetMinSize (size);
|
|
size = wxSize (-1, 38);
|
|
VolumeButton->SetMinSize (size);
|
|
#endif
|
|
Fit();
|
|
Layout();
|
|
Center();
|
|
|
|
VolumePathComboBox->SetMinSize (VolumePathComboBox->GetSize());
|
|
VolumePathComboBox->SetMaxSize (VolumePathComboBox->GetSize());
|
|
|
|
SetMinSize (GetSize());
|
|
SetMaxSize (GetSize());
|
|
|
|
Gui->SetListCtrlColumnWidths (SlotListCtrl, colPermilles);
|
|
|
|
UpdateVolumeList();
|
|
UpdateWipeCacheButton();
|
|
}
|
|
|
|
void MainFrame::InitEvents ()
|
|
{
|
|
Core->VolumeMountedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnVolumeMounted));
|
|
Core->VolumeDismountedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnVolumeDismounted));
|
|
Gui->OpenVolumeSystemRequestEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnOpenVolumeSystemRequestEvent));
|
|
Gui->PreferencesUpdatedEvent.Connect (EventConnector <MainFrame> (this, &MainFrame::OnPreferencesUpdatedEvent));
|
|
|
|
// Drag & drop
|
|
class FileDropTarget : public wxFileDropTarget
|
|
{
|
|
public:
|
|
FileDropTarget (MainFrame *frame) : Frame (frame) { }
|
|
|
|
wxDragResult OnDragOver (wxCoord x, wxCoord y, wxDragResult def)
|
|
{
|
|
wxPoint p;
|
|
wxWindow *w = wxFindWindowAtPointer (p);
|
|
if (w == Frame || wxGetTopLevelParent (w) == Frame)
|
|
return wxDragLink;
|
|
return wxDragNone;
|
|
}
|
|
|
|
bool OnDropFiles (wxCoord x, wxCoord y, const wxArrayString &filenames)
|
|
{
|
|
if (!filenames.empty())
|
|
Frame->SetVolumePath (wstring (filenames.front()));
|
|
return true;
|
|
}
|
|
|
|
MainFrame *Frame;
|
|
};
|
|
|
|
SetDropTarget (new FileDropTarget (this));
|
|
foreach (wxWindow *c, MainPanel->GetChildren())
|
|
c->SetDropTarget (new FileDropTarget (this));
|
|
|
|
// Volume history
|
|
VolumeHistory::ConnectComboBox (VolumePathComboBox);
|
|
|
|
#ifdef TC_WINDOWS
|
|
// Hotkeys
|
|
Hotkey::RegisterList (this, GetPreferences().Hotkeys);
|
|
Connect (wxEVT_HOTKEY, wxKeyEventHandler (MainFrame::OnHotkey));
|
|
#endif
|
|
|
|
// Timer
|
|
class Timer : public wxTimer
|
|
{
|
|
public:
|
|
Timer (MainFrame *frame) : Frame (frame) { }
|
|
|
|
void Notify()
|
|
{
|
|
Frame->OnTimer();
|
|
}
|
|
|
|
MainFrame *Frame;
|
|
};
|
|
|
|
mTimer.reset (dynamic_cast <wxTimer *> (new Timer (this)));
|
|
mTimer->Start (2000);
|
|
}
|
|
|
|
#ifdef TC_WINDOWS
|
|
#include <dbt.h>
|
|
static WNDPROC MainFrameWndProc;
|
|
static LRESULT CALLBACK MainFrameWndProcFilter (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (message == WM_DEVICECHANGE && !Core->IsDeviceChangeInProgress())
|
|
{
|
|
MainFrame *frame = dynamic_cast <MainFrame *> (Gui->GetMainFrame());
|
|
PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR) lParam;
|
|
|
|
if (wParam == DBT_DEVICEREMOVECOMPLETE && hdr->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
|
{
|
|
PDEV_BROADCAST_VOLUME vol = (PDEV_BROADCAST_VOLUME) lParam;
|
|
for (wchar_t driveNo = 0; driveNo < 26; ++driveNo)
|
|
{
|
|
if (vol->dbcv_unitmask & (1 << driveNo))
|
|
frame->OnDeviceChange (wstring (StringFormatter (L"{0}:\\", wchar_t (L'A' + driveNo))));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
frame->OnDeviceChange ();
|
|
}
|
|
}
|
|
|
|
return CallWindowProc (MainFrameWndProc, hwnd, message, wParam, lParam);
|
|
}
|
|
#endif
|
|
|
|
void MainFrame::InitMessageFilter ()
|
|
{
|
|
#ifdef TC_WINDOWS
|
|
HWND mainFrameHwnd = static_cast <HWND> (GetHandle());
|
|
MainFrameWndProc = (WNDPROC) GetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC);
|
|
SetWindowLongPtr (mainFrameHwnd, GWL_WNDPROC, (LONG_PTR) MainFrameWndProcFilter);
|
|
#endif
|
|
}
|
|
|
|
void MainFrame::InitPreferences ()
|
|
{
|
|
try
|
|
{
|
|
LoadPreferences();
|
|
|
|
VolumeSlotNumber lastSelectedSlotNumber = GetPreferences().LastSelectedSlotNumber;
|
|
if (Core->IsSlotNumberValid (lastSelectedSlotNumber))
|
|
{
|
|
long slotIndex = SlotNumberToItemIndex (lastSelectedSlotNumber);
|
|
if (slotIndex >= 0)
|
|
{
|
|
SlotListCtrl->SetItemState (slotIndex, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
|
|
SlotListCtrl->EnsureVisible (slotIndex);
|
|
}
|
|
}
|
|
|
|
LoadFavoriteVolumes();
|
|
VolumeHistory::Load();
|
|
|
|
if (VolumePathComboBox->GetValue().empty() && !VolumeHistory::Get().empty())
|
|
SetVolumePath (VolumeHistory::Get().front());
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
Gui->ShowError (LangString["LINUX_ERROR_LOADING_CONFIG"] + wstring (Application::GetConfigFilePath (L"")));
|
|
}
|
|
}
|
|
|
|
void MainFrame::InitTaskBarIcon ()
|
|
{
|
|
class TaskBarIcon : public wxTaskBarIcon
|
|
{
|
|
public:
|
|
TaskBarIcon (MainFrame *frame) : Busy (false), Frame (frame)
|
|
{
|
|
Connect (wxEVT_TASKBAR_LEFT_DOWN, wxTaskBarIconEventHandler (TaskBarIcon::OnLeftButtonDown));
|
|
}
|
|
|
|
wxMenu *CreatePopupMenu ()
|
|
{
|
|
unique_ptr <wxMenu> popup (new wxMenu);
|
|
|
|
Gui->AppendToMenu (*popup, LangString[Gui->IsInBackgroundMode() ? "SHOW_TC" : "HIDE_TC"], this, wxCommandEventHandler (TaskBarIcon::OnShowHideMenuItemSelected));
|
|
|
|
popup->AppendSeparator();
|
|
Gui->AppendToMenu (*popup, LangString["IDM_MOUNT_FAVORITE_VOLUMES"], this, wxCommandEventHandler (TaskBarIcon::OnMountAllFavoritesMenuItemSelected))->Enable (!Busy);
|
|
Gui->AppendToMenu (*popup, LangString["HK_DISMOUNT_ALL"], this, wxCommandEventHandler (TaskBarIcon::OnDismountAllMenuItemSelected))->Enable (!Busy);
|
|
|
|
// Favorite volumes
|
|
if (Gui->GetPreferences().BackgroundTaskMenuMountItemsEnabled && !Frame->FavoriteVolumesMenuMap.empty())
|
|
{
|
|
popup->AppendSeparator();
|
|
typedef pair <int, FavoriteVolume> FavMapPair;
|
|
foreach (FavMapPair fp, Frame->FavoriteVolumesMenuMap)
|
|
{
|
|
//TBH Gui->AppendToMenu (*popup, LangString["MOUNT"] + L" " + wstring (fp.second.Path) + (fp.second.MountPoint.IsEmpty() ? L"" : L" " + wstring (fp.second.MountPoint)),
|
|
Gui->AppendToMenu (*popup, LangString["MOUNT_BUTTON"] + L" " + wstring (fp.second.Path) + (fp.second.MountPoint.IsEmpty() ? L"" : L" " + wstring (fp.second.MountPoint)),
|
|
this, wxCommandEventHandler (TaskBarIcon::OnFavoriteVolumeMenuItemSelected), fp.first)->Enable (!Busy);
|
|
}
|
|
}
|
|
|
|
// Mounted volumes
|
|
VolumeInfoList mountedVolumes = Core->GetMountedVolumes();
|
|
if (!mountedVolumes.empty())
|
|
{
|
|
if (Gui->GetPreferences().BackgroundTaskMenuOpenItemsEnabled)
|
|
{
|
|
popup->AppendSeparator();
|
|
OpenMap.clear();
|
|
foreach (shared_ptr <VolumeInfo> volume, mountedVolumes)
|
|
{
|
|
if (!volume->MountPoint.IsEmpty())
|
|
{
|
|
wxString label = LangString["OPEN"] + L" " + wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")";
|
|
wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnOpenMenuItemSelected));
|
|
OpenMap[item->GetId()] = volume;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Gui->GetPreferences().BackgroundTaskMenuDismountItemsEnabled)
|
|
{
|
|
popup->AppendSeparator();
|
|
DismountMap.clear();
|
|
foreach (shared_ptr <VolumeInfo> volume, mountedVolumes)
|
|
{
|
|
wxString label = LangString["DISMOUNT"] + L" ";
|
|
|
|
if (!volume->MountPoint.IsEmpty())
|
|
label += wstring (volume->MountPoint) + L" (" + wstring (volume->Path) + L")";
|
|
else
|
|
label += wstring (volume->Path);
|
|
|
|
wxMenuItem *item = Gui->AppendToMenu (*popup, label, this, wxCommandEventHandler (TaskBarIcon::OnDismountMenuItemSelected));
|
|
item->Enable (!Busy);
|
|
DismountMap[item->GetId()] = volume;
|
|
}
|
|
}
|
|
}
|
|
|
|
popup->AppendSeparator();
|
|
Gui->AppendToMenu (*popup, LangString["IDM_PREFERENCES"], this, wxCommandEventHandler (TaskBarIcon::OnPreferencesMenuItemSelected))->Enable (!Busy);
|
|
#ifndef TC_MACOSX
|
|
popup->AppendSeparator();
|
|
Gui->AppendToMenu (*popup, LangString["EXIT"], this, wxCommandEventHandler (TaskBarIcon::OnExitMenuItemSelected))->Enable (!Busy && Frame->CanExit());
|
|
#endif
|
|
return popup.release();
|
|
}
|
|
|
|
void OnDismountAllMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnDismountAllButtonClick (event); Busy = false; }
|
|
void OnDismountMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->DismountVolume (DismountMap[event.GetId()]); Busy = false; }
|
|
void OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnFavoriteVolumeMenuItemSelected (event); Busy = false; }
|
|
void OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->MountAllFavorites (); Busy = false; }
|
|
|
|
void OnExitMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
Busy = true;
|
|
if (Core->GetMountedVolumes().empty() || Gui->AskYesNo (LangString ["CONFIRM_EXIT"], false, true))
|
|
Frame->Close (true);
|
|
Busy = false;
|
|
}
|
|
|
|
void OnLeftButtonDown (wxTaskBarIconEvent& event) { Gui->SetBackgroundMode (false); }
|
|
void OnOpenMenuItemSelected (wxCommandEvent& event) { Gui->OpenExplorerWindow (OpenMap[event.GetId()]->MountPoint); }
|
|
void OnPreferencesMenuItemSelected (wxCommandEvent& event) { Busy = true; Frame->OnPreferencesMenuItemSelected (event); Busy = false; }
|
|
void OnShowHideMenuItemSelected (wxCommandEvent& event) { Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); }
|
|
|
|
bool Busy;
|
|
map < int, shared_ptr <VolumeInfo> > DismountMap;
|
|
MainFrame *Frame;
|
|
map < int, shared_ptr <VolumeInfo> > OpenMap;
|
|
};
|
|
|
|
mTaskBarIcon.reset (new TaskBarIcon (this));
|
|
ShowTaskBarIcon (GetPreferences().BackgroundTaskEnabled);
|
|
}
|
|
|
|
void MainFrame::LoadFavoriteVolumes ()
|
|
{
|
|
typedef pair <int, FavoriteVolume> FavMapPair;
|
|
foreach (FavMapPair p, FavoriteVolumesMenuMap)
|
|
{
|
|
FavoritesMenu->Delete (p.first);
|
|
}
|
|
FavoriteVolumesMenuMap.clear();
|
|
|
|
foreach_ref (const FavoriteVolume &favorite, FavoriteVolume::LoadList())
|
|
{
|
|
wstring label = wstring (favorite.Path);
|
|
if (!favorite.MountPoint.IsEmpty())
|
|
label += wstring (L" ") + wstring (favorite.MountPoint);
|
|
|
|
wxMenuItem *item = Gui->AppendToMenu (*FavoritesMenu, label, this, wxCommandEventHandler (MainFrame::OnFavoriteVolumeMenuItemSelected));
|
|
FavoriteVolumesMenuMap[item->GetId()] = favorite;
|
|
}
|
|
}
|
|
|
|
void MainFrame::LoadPreferences ()
|
|
{
|
|
UserPreferences prefs;
|
|
prefs.Load();
|
|
Gui->SetPreferences (prefs);
|
|
NoHistoryCheckBox->SetValue (!prefs.SaveHistory);
|
|
}
|
|
|
|
void MainFrame::MountAllDevices ()
|
|
{
|
|
try
|
|
{
|
|
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
|
|
if (CmdLine->ArgTrueCryptMode)
|
|
{
|
|
mountOptions.TrueCryptMode = CmdLine->ArgTrueCryptMode;
|
|
}
|
|
if (CmdLine->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash, mountOptions.TrueCryptMode);
|
|
}
|
|
if (CmdLine->ArgPim > 0)
|
|
{
|
|
mountOptions.Pim = CmdLine->ArgPim;
|
|
}
|
|
|
|
if (SlotListCtrl->GetSelectedItemCount() == 1)
|
|
mountOptions.SlotNumber = SelectedSlotNumber;
|
|
|
|
Gui->MountAllDeviceHostedVolumes (mountOptions);
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::MountAllFavorites ()
|
|
{
|
|
try
|
|
{
|
|
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
|
|
if (CmdLine->ArgTrueCryptMode)
|
|
{
|
|
mountOptions.TrueCryptMode = CmdLine->ArgTrueCryptMode;
|
|
}
|
|
if (CmdLine->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash, mountOptions.TrueCryptMode);
|
|
}
|
|
if (CmdLine->ArgPim > 0)
|
|
{
|
|
mountOptions.Pim = CmdLine->ArgPim;
|
|
}
|
|
mountOptions.EMVSupportEnabled = GetPreferences().EMVSupportEnabled;
|
|
Gui->MountAllFavoriteVolumes (mountOptions);
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::MountVolume ()
|
|
{
|
|
if (!IsFreeSlotSelected())
|
|
{
|
|
Gui->ShowWarning (LangString["LINUX_SELECT_FREE_SLOT"]);
|
|
return;
|
|
}
|
|
|
|
if (!CheckVolumePathNotEmpty())
|
|
return;
|
|
|
|
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
|
|
mountOptions.SlotNumber = SelectedSlotNumber;
|
|
mountOptions.Path = GetSelectedVolumePath();
|
|
if (CmdLine->ArgTrueCryptMode)
|
|
{
|
|
mountOptions.TrueCryptMode = CmdLine->ArgTrueCryptMode;
|
|
}
|
|
if (CmdLine->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash, mountOptions.TrueCryptMode);
|
|
}
|
|
if (CmdLine->ArgPim > 0)
|
|
{
|
|
mountOptions.Pim = CmdLine->ArgPim;
|
|
}
|
|
mountOptions.EMVSupportEnabled = GetPreferences().EMVSupportEnabled;
|
|
|
|
try
|
|
{
|
|
if (Gui->MountVolume (mountOptions) && GetPreferences().SaveHistory)
|
|
VolumeHistory::Add (*mountOptions.Path);
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnAboutMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
EnsureVisible ();
|
|
#endif
|
|
AboutDialog dialog (this);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnActivate (wxActivateEvent& event)
|
|
{
|
|
Gui->SetActiveFrame (this);
|
|
|
|
#ifdef TC_MACOSX
|
|
if (event.GetActive() && Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
event.Skip();
|
|
}
|
|
|
|
void MainFrame::OnAddAllMountedToFavoritesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
AddToFavorites (MountedVolumes);
|
|
}
|
|
|
|
void MainFrame::OnAddToFavoritesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
|
|
if (selectedVolume)
|
|
{
|
|
VolumeInfoList volumes;
|
|
volumes.push_back (selectedVolume);
|
|
AddToFavorites (volumes);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnBackupVolumeHeadersMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
if (!CheckVolumePathNotEmpty ())
|
|
return;
|
|
|
|
try
|
|
{
|
|
Gui->BackupVolumeHeaders (GetSelectedVolumePath());
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnBenchmarkMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
BenchmarkDialog dialog (this);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnClearSlotSelectionMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
Gui->ClearListCtrlSelection (SlotListCtrl);
|
|
UpdateControls();
|
|
}
|
|
|
|
void MainFrame::OnClose (wxCloseEvent& event)
|
|
{
|
|
if (GetPreferences().WipeCacheOnClose)
|
|
Core->WipePasswordCache();
|
|
|
|
#ifdef TC_MACOSX
|
|
if (!event.CanVeto() && GetPreferences().DismountOnLogOff)
|
|
{
|
|
try
|
|
{
|
|
Gui->DismountVolumes (Core->GetMountedVolumes(), GetPreferences().ForceAutoDismount, false);
|
|
}
|
|
catch (...) { }
|
|
}
|
|
#endif
|
|
|
|
if (!Gui->IsTheOnlyTopLevelWindow (this))
|
|
{
|
|
// Bring first frame to foreground
|
|
wxFrame *frame = nullptr;
|
|
foreach (wxWindow *window, wxTopLevelWindows)
|
|
{
|
|
if (window != this
|
|
&& dynamic_cast <wxFrame *> (window)
|
|
&& StringConverter::GetTypeName (typeid (*window)).find ("wxTaskBarIcon") == string::npos)
|
|
{
|
|
frame = dynamic_cast <wxFrame *> (window);
|
|
if (window->IsShown())
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (frame)
|
|
{
|
|
frame->Show();
|
|
if (frame->IsIconized())
|
|
frame->Iconize(false);
|
|
frame->Raise();
|
|
}
|
|
}
|
|
else if (event.CanVeto() && GetPreferences().BackgroundTaskEnabled
|
|
&& (!GetPreferences().CloseBackgroundTaskOnNoVolumes || !MountedVolumes.empty()))
|
|
{
|
|
// Enter background mode
|
|
if (!Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (true);
|
|
}
|
|
else
|
|
{
|
|
#ifdef __WXGTK__
|
|
Show();
|
|
#endif
|
|
SavePreferences();
|
|
|
|
Destroy();
|
|
}
|
|
|
|
// Cancel close - veto is not used to prevent aborting log off procedure on Windows
|
|
return;
|
|
}
|
|
|
|
void MainFrame::OnCloseAllSecurityTokenSessionsMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
try
|
|
{
|
|
{
|
|
wxBusyCursor busy;
|
|
SecurityToken::CloseAllSessions();
|
|
}
|
|
Gui->ShowInfo ("ALL_TOKEN_SESSIONS_CLOSED");
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnCreateVolumeButtonClick (wxCommandEvent& event)
|
|
{
|
|
try
|
|
{
|
|
(new VolumeCreationWizard (nullptr))->Show();
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnDefaultKeyfilesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
PreferencesDialog dialog (this);
|
|
dialog.SelectPage (dialog.DefaultKeyfilesPage);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnDefaultMountParametersMenuItemSelected(wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
PreferencesDialog dialog (this);
|
|
dialog.SelectPage (dialog.DefaultMountOptionsPage);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnDeviceChange (const DirectoryPath &mountPoint)
|
|
{
|
|
// Check if any host device has been removed and force dismount of volumes accordingly
|
|
VolumeInfoList removedVolumes;
|
|
foreach (shared_ptr <VolumeInfo> volume, Core->GetMountedVolumes())
|
|
{
|
|
// File-hosted volumes
|
|
if (!volume->Path.IsDevice() && !mountPoint.IsEmpty())
|
|
{
|
|
if (wxString (wstring(volume->Path)).Upper().StartsWith (wstring (mountPoint).c_str()))
|
|
{
|
|
removedVolumes.push_back (volume);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Device-hosted volumes
|
|
if (volume->Path.IsDevice() && !Core->IsDevicePresent (volume->Path))
|
|
removedVolumes.push_back (volume);
|
|
}
|
|
|
|
if (!removedVolumes.empty())
|
|
Gui->AutoDismountVolumes (removedVolumes, true);
|
|
}
|
|
|
|
void MainFrame::OnDismountAllButtonClick (wxCommandEvent& event)
|
|
{
|
|
Gui->DismountAllVolumes();
|
|
}
|
|
|
|
void MainFrame::OnEncryptionTestMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
EncryptionTestDialog dialog (this);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnExitButtonClick (wxCommandEvent& event)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
void MainFrame::OnFavoriteVolumeMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
FavoriteVolume favorite = FavoriteVolumesMenuMap[event.GetId()];
|
|
if (!favorite.Path.IsEmpty())
|
|
{
|
|
SetVolumePath (favorite.Path);
|
|
|
|
MountOptions mountOptions (GetPreferences().DefaultMountOptions);
|
|
if (CmdLine->ArgTrueCryptMode)
|
|
{
|
|
mountOptions.TrueCryptMode = CmdLine->ArgTrueCryptMode;
|
|
}
|
|
if (CmdLine->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash, mountOptions.TrueCryptMode);
|
|
}
|
|
if (CmdLine->ArgPim > 0)
|
|
{
|
|
mountOptions.Pim = CmdLine->ArgPim;
|
|
}
|
|
favorite.ToMountOptions (mountOptions);
|
|
|
|
shared_ptr <VolumeInfo> volume = Gui->MountVolume (mountOptions);
|
|
if (volume)
|
|
SlotListCtrl->EnsureVisible (SlotNumberToItemIndex (volume->SlotNumber));
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnHiddenVolumeProtectionTriggered (shared_ptr <VolumeInfo> protectedVolume)
|
|
{
|
|
Gui->ShowWarningTopMost (StringFormatter (LangString["DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"], wstring (protectedVolume->Path)));
|
|
}
|
|
|
|
void MainFrame::OnHotkey (wxKeyEvent& event)
|
|
{
|
|
#ifdef TC_WINDOWS
|
|
switch (event.GetId())
|
|
{
|
|
case Hotkey::Id::CloseAllSecurityTokenSessions:
|
|
try
|
|
{
|
|
SecurityToken::CloseAllSessions();
|
|
Gui->ShowInfo ("ALL_TOKEN_SESSIONS_CLOSED");
|
|
}
|
|
catch (exception &e) { Gui->ShowError (e); }
|
|
break;
|
|
|
|
case Hotkey::Id::DismountAll:
|
|
case Hotkey::Id::DismountAllWipeCache:
|
|
{
|
|
if (event.GetId() == Hotkey::Id::DismountAllWipeCache)
|
|
WipeCache();
|
|
|
|
size_t mountedCount = Core->GetMountedVolumes().size();
|
|
Gui->DismountAllVolumes();
|
|
size_t newMountedCount = Core->GetMountedVolumes().size();
|
|
|
|
if (newMountedCount < mountedCount)
|
|
{
|
|
if (newMountedCount == 0 && GetPreferences().DisplayMessageAfterHotkeyDismount)
|
|
Gui->ShowInfo ("MOUNTED_VOLUMES_DISMOUNTED");
|
|
else if (GetPreferences().BeepAfterHotkeyMountDismount)
|
|
MessageBeep((UINT) -1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Hotkey::Id::ForceDismountAllWipeCache:
|
|
case Hotkey::Id::ForceDismountAllWipeCacheExit:
|
|
{
|
|
bool mounted = !Core->GetMountedVolumes().empty();
|
|
|
|
WipeCache();
|
|
Gui->DismountAllVolumes (true, true);
|
|
|
|
if (mounted && GetPreferences().DisplayMessageAfterHotkeyDismount)
|
|
Gui->ShowInfo ("VOLUMES_DISMOUNTED_CACHE_WIPED");
|
|
else if (mounted && GetPreferences().BeepAfterHotkeyMountDismount)
|
|
MessageBeep((UINT) -1);
|
|
|
|
if (event.GetId() == Hotkey::Id::ForceDismountAllWipeCacheExit)
|
|
Close (true);
|
|
}
|
|
break;
|
|
|
|
case Hotkey::Id::MountAllDevices:
|
|
case Hotkey::Id::MountAllFavorites:
|
|
{
|
|
size_t mountedCount = Core->GetMountedVolumes().size();
|
|
|
|
if (event.GetId() == Hotkey::Id::MountAllDevices)
|
|
MountAllDevices();
|
|
else
|
|
MountAllFavorites();
|
|
|
|
if (Core->GetMountedVolumes().size() > mountedCount && GetPreferences().BeepAfterHotkeyMountDismount)
|
|
MessageBeep((UINT) -1);
|
|
}
|
|
break;
|
|
|
|
case Hotkey::Id::ShowHideApplication:
|
|
Gui->SetBackgroundMode (!Gui->IsInBackgroundMode());
|
|
break;
|
|
|
|
case Hotkey::Id::WipeCache:
|
|
WipeCache();
|
|
Gui->ShowInfo ("PASSWORD_CACHE_WIPED");
|
|
break;
|
|
|
|
default:
|
|
assert (false);
|
|
break;
|
|
}
|
|
#endif // TC_WINDOWS
|
|
}
|
|
|
|
void MainFrame::OnHotkeysMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
PreferencesDialog dialog (this);
|
|
dialog.SelectPage (dialog.HotkeysPage);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnLegalNoticesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
LegalNoticesDialog dialog (this);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnListChanged ()
|
|
{
|
|
OnListItemSelectionChanged();
|
|
UpdateControls();
|
|
}
|
|
|
|
void MainFrame::OnListItemActivated (wxListEvent& event)
|
|
{
|
|
if (IsMountedSlotSelected())
|
|
OpenSelectedVolume();
|
|
else
|
|
MountVolume();
|
|
}
|
|
|
|
void MainFrame::OnListItemDeleted (long itemIndex)
|
|
{
|
|
if (SelectedItemIndex > itemIndex)
|
|
--SelectedItemIndex;
|
|
}
|
|
|
|
void MainFrame::OnListItemDeselected (wxListEvent& event)
|
|
{
|
|
OnListItemSelectionChanged();
|
|
}
|
|
|
|
void MainFrame::OnListItemInserted (long itemIndex)
|
|
{
|
|
if (SelectedItemIndex >= itemIndex)
|
|
++SelectedItemIndex;
|
|
}
|
|
|
|
void MainFrame::OnListItemRightClick (wxListEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (SelectedItemIndex != event.GetIndex())
|
|
{
|
|
SelectedItemIndex = event.GetIndex();
|
|
OnListItemSelectionChanged();
|
|
}
|
|
|
|
if (!ListItemRightClickEventPending)
|
|
{
|
|
ListItemRightClickEventPending = true;
|
|
SlotListCtrl->GetEventHandler()->AddPendingEvent (event);
|
|
return;
|
|
}
|
|
|
|
ListItemRightClickEventPending = false;
|
|
#endif
|
|
|
|
wxMenu popup;
|
|
if (IsMountedSlotSelected())
|
|
{
|
|
Gui->AppendToMenu (popup, LangString["DISMOUNT"], this, wxCommandEventHandler (MainFrame::OnDismountVolumeMenuItemSelected));
|
|
Gui->AppendToMenu (popup, LangString["OPEN"], this, wxCommandEventHandler (MainFrame::OnOpenVolumeMenuItemSelected));
|
|
Gui->AppendToMenu (popup, LangString["LINUX_DESELECT"], this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected));
|
|
|
|
popup.AppendSeparator();
|
|
Gui->AppendToMenu (popup, LangString["IDPM_ADD_TO_FAVORITES"], this, wxCommandEventHandler (MainFrame::OnAddToFavoritesMenuItemSelected));
|
|
|
|
popup.AppendSeparator();
|
|
Gui->AppendToMenu (popup, LangString["IDPM_CHECK_FILESYS"], this, wxCommandEventHandler (MainFrame::OnCheckFilesystemMenuItemSelected));
|
|
Gui->AppendToMenu (popup, LangString["IDPM_REPAIR_FILESYS"], this, wxCommandEventHandler (MainFrame::OnRepairFilesystemMenuItemSelected));
|
|
|
|
popup.AppendSeparator();
|
|
Gui->AppendToMenu (popup, LangString["IDPM_PROPERTIES"], this, wxCommandEventHandler (MainFrame::OnVolumePropertiesButtonClick));
|
|
|
|
PopupMenu (&popup);
|
|
}
|
|
else if (IsFreeSlotSelected())
|
|
{
|
|
Gui->AppendToMenu (popup, LangString["IDM_MOUNT_VOLUME"], this, wxCommandEventHandler (MainFrame::OnMountVolumeMenuItemSelected));
|
|
|
|
popup.AppendSeparator();
|
|
|
|
Gui->AppendToMenu (popup, LangString["SELECT_FILE_AND_MOUNT"], this, wxCommandEventHandler (MainFrame::OnSelectFileAndMountMenuItemSelected));
|
|
Gui->AppendToMenu (popup, LangString["SELECT_DEVICE_AND_MOUNT"], this, wxCommandEventHandler (MainFrame::OnSelectDeviceAndMountMenuItemSelected));
|
|
|
|
popup.AppendSeparator();
|
|
|
|
Gui->AppendToMenu (popup, LangString["LINUX_DESELECT"], this, wxCommandEventHandler (MainFrame::OnClearSlotSelectionMenuItemSelected));
|
|
|
|
PopupMenu (&popup);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnListItemSelected (wxListEvent& event)
|
|
{
|
|
SelectedItemIndex = event.GetIndex();
|
|
OnListItemSelectionChanged();
|
|
}
|
|
|
|
void MainFrame::OnListItemSelectionChanged ()
|
|
{
|
|
if (SlotListCtrl->GetSelectedItemCount() < 1)
|
|
SelectedItemIndex = -1;
|
|
|
|
if (SelectedItemIndex >= 0)
|
|
SelectedSlotNumber = (VolumeSlotNumber) SlotListCtrl->GetItemData (SelectedItemIndex);
|
|
else
|
|
SelectedSlotNumber = 0;
|
|
|
|
UpdateControls();
|
|
}
|
|
|
|
void MainFrame::OnManageSecurityTokenKeyfilesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
try
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
SecurityTokenKeyfilesDialog dialog (this, false);
|
|
dialog.ShowModal();
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnMountAllDevicesButtonClick (wxCommandEvent& event)
|
|
{
|
|
MountAllDevices();
|
|
}
|
|
|
|
void MainFrame::OnMountAllFavoritesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
MountAllFavorites();
|
|
}
|
|
|
|
void MainFrame::OnNoHistoryCheckBoxClick (wxCommandEvent& event)
|
|
{
|
|
UserPreferences prefs = GetPreferences();
|
|
prefs.SaveHistory = !event.IsChecked();
|
|
Gui->SetPreferences (prefs);
|
|
|
|
if (event.IsChecked())
|
|
{
|
|
try
|
|
{
|
|
VolumeHistory::Clear();
|
|
}
|
|
catch (exception &e) { Gui->ShowError (e); }
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnOrganizeFavoritesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
try
|
|
{
|
|
OrganizeFavorites (FavoriteVolume::LoadList());
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnPreferencesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
PreferencesDialog dialog (this);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
void MainFrame::OnOpenVolumeSystemRequest (wxCommandEvent& event)
|
|
{
|
|
wstring* eventPath = (wstring*) event.GetClientData();
|
|
SetVolumePath (*eventPath);
|
|
delete eventPath;
|
|
}
|
|
|
|
void MainFrame::OnOpenVolumeSystemRequestEvent (EventArgs &args)
|
|
{
|
|
wstring* eventPath = new wstring (dynamic_cast <OpenVolumeSystemRequestEventArgs &> (args).mVolumePath);
|
|
wxCommandEvent* pEvent = new wxCommandEvent( wxEVT_COMMAND_OPEN_VOLUME_REQUEST,0);
|
|
pEvent->SetClientData(eventPath);
|
|
wxQueueEvent (this, pEvent);
|
|
}
|
|
|
|
void MainFrame::OnPreferencesUpdated (wxCommandEvent& event)
|
|
{
|
|
const UserPreferences &prefs = GetPreferences();
|
|
|
|
NoHistoryCheckBox->SetValue (!prefs.SaveHistory);
|
|
|
|
ShowTaskBarIcon (prefs.BackgroundTaskEnabled);
|
|
if (Gui->IsInBackgroundMode() && !prefs.BackgroundTaskEnabled)
|
|
Close (true);
|
|
|
|
SavePreferences();
|
|
}
|
|
|
|
void MainFrame::OnRestoreVolumeHeaderMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
if (!CheckVolumePathNotEmpty ())
|
|
return;
|
|
|
|
try
|
|
{
|
|
Gui->RestoreVolumeHeaders (GetSelectedVolumePath());
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnSecurityTokenPreferencesMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
PreferencesDialog dialog (this);
|
|
dialog.SelectPage (dialog.SecurityTokensPage);
|
|
dialog.ShowModal();
|
|
}
|
|
|
|
|
|
void MainFrame::OnSelectDeviceAndMountMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
DevicePath path = Gui->SelectDevice (this);
|
|
|
|
if (!path.IsEmpty())
|
|
{
|
|
SetVolumePath (path);
|
|
OnMountVolumeMenuItemSelected (event);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnSelectDeviceButtonClick (wxCommandEvent& event)
|
|
{
|
|
DevicePath path = Gui->SelectDevice (this);
|
|
|
|
if (!path.IsEmpty())
|
|
SetVolumePath (path);
|
|
}
|
|
|
|
void MainFrame::OnSelectFileAndMountMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
FilePath path = Gui->SelectVolumeFile (this);
|
|
|
|
if (!path.IsEmpty())
|
|
{
|
|
SetVolumePath (path);
|
|
OnMountVolumeMenuItemSelected (event);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnSelectFileButtonClick (wxCommandEvent& event)
|
|
{
|
|
FilePath path = Gui->SelectVolumeFile (this);
|
|
if (!path.IsEmpty())
|
|
SetVolumePath (path);
|
|
}
|
|
|
|
void MainFrame::OnTimer ()
|
|
{
|
|
try
|
|
{
|
|
UpdateVolumeList();
|
|
UpdateWipeCacheButton();
|
|
|
|
if (GetPreferences().BackgroundTaskEnabled)
|
|
{
|
|
// Inactivity auto-dismount
|
|
if (GetPreferences().DismountOnInactivity)
|
|
{
|
|
VolumeInfoList inactiveVolumes;
|
|
wxLongLong currentTime = wxGetLocalTimeMillis().GetValue();
|
|
|
|
map <wstring, VolumeActivityMapEntry> newActivityTimeMap;
|
|
|
|
foreach (shared_ptr <VolumeInfo> volume, MountedVolumes)
|
|
{
|
|
if (VolumeActivityMap.find (volume->Path) != VolumeActivityMap.end()
|
|
&& VolumeActivityMap[volume->Path].SerialInstanceNumber == volume->SerialInstanceNumber)
|
|
{
|
|
VolumeActivityMapEntry ae = VolumeActivityMap[volume->Path];
|
|
|
|
if (volume->TotalDataRead != ae.TotalDataRead || volume->TotalDataWritten != ae.TotalDataWritten)
|
|
{
|
|
ae.LastActivityTime = currentTime;
|
|
ae.TotalDataRead = volume->TotalDataRead;
|
|
ae.TotalDataWritten = volume->TotalDataWritten;
|
|
}
|
|
else if ((currentTime - ae.LastActivityTime) > GetPreferences().MaxVolumeIdleTime * 1000LL * 60)
|
|
{
|
|
inactiveVolumes.push_back (volume);
|
|
}
|
|
|
|
newActivityTimeMap[volume->Path] = ae;
|
|
}
|
|
else
|
|
{
|
|
newActivityTimeMap[volume->Path] = VolumeActivityMapEntry (*volume, currentTime);
|
|
}
|
|
}
|
|
|
|
VolumeActivityMap = newActivityTimeMap;
|
|
|
|
if (!inactiveVolumes.empty())
|
|
Gui->AutoDismountVolumes (inactiveVolumes);
|
|
}
|
|
|
|
// Screen saver auto-dismount
|
|
if (GetPreferences().DismountOnScreenSaver)
|
|
{
|
|
#ifdef TC_WINDOWS
|
|
bool running;
|
|
if (SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0) != 0)
|
|
{
|
|
static bool previousState = false;
|
|
if (running && !previousState)
|
|
{
|
|
previousState = true;
|
|
Gui->OnAutoDismountAllEvent();
|
|
}
|
|
else
|
|
{
|
|
previousState = running;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (Gui->IsInBackgroundMode())
|
|
{
|
|
if (!GetPreferences().BackgroundTaskEnabled)
|
|
{
|
|
Close (true);
|
|
}
|
|
else if (MountedVolumes.empty() && (GetPreferences().CloseBackgroundTaskOnNoVolumes || Core->IsInPortableMode()))
|
|
{
|
|
Close (true);
|
|
}
|
|
}
|
|
|
|
#if defined(TC_UNIX) && !defined(TC_MACOSX)
|
|
try
|
|
{
|
|
byte buf[128];
|
|
if (read (ShowRequestFifo, buf, sizeof (buf)) > 0 && Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
}
|
|
catch (...)
|
|
{
|
|
#ifdef DEBUG
|
|
throw;
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnVolumeButtonClick (wxCommandEvent& event)
|
|
{
|
|
if (IsMountedSlotSelected())
|
|
DismountVolume();
|
|
else
|
|
MountVolume();
|
|
}
|
|
|
|
void MainFrame::OnVolumePropertiesButtonClick (wxCommandEvent& event)
|
|
{
|
|
shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
|
|
if (selectedVolume)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
VolumePropertiesDialog dialog (this, *selectedVolume);
|
|
dialog.ShowModal();
|
|
}
|
|
}
|
|
|
|
void MainFrame::OnVolumeToolsButtonClick (wxCommandEvent& event)
|
|
{
|
|
if (!CheckVolumePathNotEmpty())
|
|
return;
|
|
|
|
wxMenu popup;
|
|
|
|
Gui->AppendToMenu (popup, LangString["IDM_CHANGE_PASSWORD"], this, wxCommandEventHandler (MainFrame::OnChangePasswordMenuItemSelected));
|
|
|
|
popup.AppendSeparator ();
|
|
|
|
Gui->AppendToMenu (popup, LangString["IDM_ADD_REMOVE_VOL_KEYFILES"], this, wxCommandEventHandler (MainFrame::OnChangeKeyfilesMenuItemSelected));
|
|
Gui->AppendToMenu (popup, LangString["IDM_REMOVE_ALL_KEYFILES_FROM_VOL"], this, wxCommandEventHandler (MainFrame::OnRemoveKeyfilesMenuItemSelected));
|
|
|
|
popup.AppendSeparator ();
|
|
|
|
Gui->AppendToMenu (popup, LangString["IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO"], this, wxCommandEventHandler (MainFrame::OnChangePkcs5PrfMenuItemSelected));
|
|
|
|
popup.AppendSeparator ();
|
|
|
|
Gui->AppendToMenu (popup, LangString["IDM_BACKUP_VOL_HEADER"], this, wxCommandEventHandler (MainFrame::OnBackupVolumeHeadersMenuItemSelected));
|
|
Gui->AppendToMenu (popup, LangString["IDM_RESTORE_VOL_HEADER"], this, wxCommandEventHandler (MainFrame::OnRestoreVolumeHeaderMenuItemSelected));
|
|
|
|
PopupMenu (&popup, VolumeToolsButton->GetPosition().x + 2, VolumeToolsButton->GetPosition().y + 2);
|
|
}
|
|
|
|
void MainFrame::OnWipeCacheButtonClick (wxCommandEvent& event)
|
|
{
|
|
WipeCache();
|
|
Gui->ShowInfo ("PASSWORD_CACHE_WIPED");
|
|
}
|
|
|
|
void MainFrame::OpenSelectedVolume () const
|
|
{
|
|
shared_ptr <VolumeInfo> selectedVolume = GetSelectedVolume();
|
|
if (selectedVolume)
|
|
{
|
|
try
|
|
{
|
|
wxBusyCursor busy;
|
|
Gui->OpenExplorerWindow (selectedVolume->MountPoint);
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainFrame::OrganizeFavorites (const FavoriteVolumeList &favorites, size_t newItemCount)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
FavoriteVolumesDialog dialog (this, favorites, newItemCount);
|
|
|
|
if (dialog.ShowModal() == wxID_OK)
|
|
{
|
|
FavoriteVolume::SaveList (dialog.GetFavorites());
|
|
LoadFavoriteVolumes();
|
|
}
|
|
}
|
|
|
|
void MainFrame::SavePreferences () const
|
|
{
|
|
try
|
|
{
|
|
UserPreferences prefs = GetPreferences();
|
|
prefs.LastSelectedSlotNumber = SelectedSlotNumber;
|
|
prefs.Save();
|
|
|
|
VolumeHistory::Save();
|
|
}
|
|
catch (exception &e)
|
|
{
|
|
if (!Core->IsInPortableMode())
|
|
Gui->ShowError (e);
|
|
}
|
|
}
|
|
|
|
#ifdef HAVE_INDICATORS
|
|
void MainFrame::SetBusy (bool busy)
|
|
{
|
|
gtk_widget_set_sensitive(indicator_item_mountfavorites, !busy);
|
|
gtk_widget_set_sensitive(indicator_item_dismountall, !busy);
|
|
gtk_widget_set_sensitive(indicator_item_prefs, !busy);
|
|
gtk_widget_set_sensitive(indicator_item_exit, !busy /*&& CanExit()*/);
|
|
}
|
|
|
|
static void IndicatorOnShowHideMenuItemSelected (GtkWidget *widget, MainFrame *self) { Gui->SetBackgroundMode (!Gui->IsInBackgroundMode()); }
|
|
static void IndicatorOnMountAllFavoritesMenuItemSelected (GtkWidget *widget, MainFrame *self) { self->SetBusy(true); self->MountAllFavorites (); self->SetBusy(false); }
|
|
static void IndicatorOnDismountAllMenuItemSelected (GtkWidget *widget, MainFrame *self) { self->SetBusy(true); Gui->DismountAllVolumes(); self->SetBusy(false); }
|
|
static void IndicatorOnPreferencesMenuItemSelected (GtkWidget *widget, MainFrame *self) {
|
|
self->SetBusy(true);
|
|
PreferencesDialog dialog (self);
|
|
dialog.ShowModal();
|
|
self->SetBusy(false);
|
|
}
|
|
static void IndicatorOnExitMenuItemSelected (GtkWidget *widget, MainFrame *self) {
|
|
self->SetBusy(true);
|
|
if (Core->GetMountedVolumes().empty() || Gui->AskYesNo (LangString ["CONFIRM_EXIT"], false, true))
|
|
self->Close (true);
|
|
self->SetBusy(false);
|
|
}
|
|
|
|
#endif
|
|
void MainFrame::ShowTaskBarIcon (bool show)
|
|
{
|
|
if (!show && mTaskBarIcon->IsIconInstalled())
|
|
{
|
|
mTaskBarIcon->RemoveIcon();
|
|
}
|
|
else if (show && !mTaskBarIcon->IsIconInstalled())
|
|
{
|
|
#ifndef TC_MACOSX
|
|
#ifndef HAVE_INDICATORS
|
|
mTaskBarIcon->SetIcon (Resources::GetVeraCryptIcon(), L"VeraCrypt");
|
|
#endif
|
|
#endif
|
|
#ifdef HAVE_INDICATORS
|
|
if (indicator == NULL) {
|
|
indicator = app_indicator_new ("veracrypt", "veracrypt", APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
|
|
app_indicator_set_status (indicator, APP_INDICATOR_STATUS_ACTIVE);
|
|
|
|
GtkWidget *menu = gtk_menu_new();
|
|
|
|
indicator_item_showhide = gtk_menu_item_new_with_label (LangString[Gui->IsInBackgroundMode() ? "SHOW_TC" : "HIDE_TC"].mb_str());
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), indicator_item_showhide);
|
|
g_signal_connect (indicator_item_showhide, "activate", G_CALLBACK (IndicatorOnShowHideMenuItemSelected), this);
|
|
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
|
|
|
|
indicator_item_mountfavorites = gtk_menu_item_new_with_label (LangString["IDM_MOUNT_FAVORITE_VOLUMES"]);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), indicator_item_mountfavorites);
|
|
g_signal_connect (indicator_item_mountfavorites, "activate", G_CALLBACK (IndicatorOnMountAllFavoritesMenuItemSelected), this);
|
|
|
|
indicator_item_dismountall = gtk_menu_item_new_with_label (LangString["HK_DISMOUNT_ALL"]);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), indicator_item_dismountall);
|
|
g_signal_connect (indicator_item_dismountall, "activate", G_CALLBACK (IndicatorOnDismountAllMenuItemSelected), this);
|
|
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
|
|
|
|
indicator_item_prefs = gtk_menu_item_new_with_label (LangString["IDM_PREFERENCES"]);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), indicator_item_prefs);
|
|
g_signal_connect (indicator_item_prefs, "activate", G_CALLBACK (IndicatorOnPreferencesMenuItemSelected), this);
|
|
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
|
|
|
|
indicator_item_exit = gtk_menu_item_new_with_label (LangString["EXIT"]);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), indicator_item_exit);
|
|
g_signal_connect (indicator_item_exit, "activate", G_CALLBACK (IndicatorOnExitMenuItemSelected), this);
|
|
|
|
gtk_widget_show_all (menu);
|
|
app_indicator_set_menu (indicator, GTK_MENU (menu));
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
long MainFrame::SlotNumberToItemIndex (uint32 slotNumber) const
|
|
{
|
|
for (long itemIndex = 0; itemIndex < SlotListCtrl->GetItemCount(); itemIndex++)
|
|
{
|
|
wxListItem item;
|
|
item.SetId (itemIndex);
|
|
if (slotNumber == (uint32) SlotListCtrl->GetItemData (item))
|
|
return itemIndex;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void MainFrame::UpdateControls ()
|
|
{
|
|
bool mounted = IsMountedSlotSelected();
|
|
|
|
VolumeButton->SetLabel (mounted ? LangString["UNMOUNT_BUTTON"] : LangString["MOUNT_BUTTON"]);
|
|
VolumePropertiesButton->Enable (mounted);
|
|
|
|
DismountVolumeMenuItem->Enable (mounted);
|
|
MountVolumeMenuItem->Enable (!mounted);
|
|
VolumePropertiesMenuItem->Enable (mounted);
|
|
AddToFavoritesMenuItem->Enable (mounted);
|
|
AddAllMountedToFavoritesMenuItem->Enable (!MountedVolumes.empty());
|
|
UpdateWipeCacheButton();
|
|
}
|
|
|
|
void MainFrame::UpdateVolumeList ()
|
|
{
|
|
static Mutex mutex;
|
|
ScopeLock lock (mutex);
|
|
|
|
bool listChanged = false;
|
|
|
|
MountedVolumes = Core->GetMountedVolumes();
|
|
|
|
map < VolumeSlotNumber, shared_ptr <VolumeInfo> > mountedVolumesMap;
|
|
foreach (shared_ptr <VolumeInfo> volume, MountedVolumes)
|
|
{
|
|
mountedVolumesMap[volume->SlotNumber] = volume;
|
|
}
|
|
|
|
VolumeInfoList protectionTriggeredVolumes;
|
|
SlotListCtrl->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
|
|
|
// Update list
|
|
long prevItemIndex = -1;
|
|
for (VolumeSlotNumber slotNumber = Core->GetFirstSlotNumber(); slotNumber <= Core->GetLastSlotNumber(); ++slotNumber)
|
|
{
|
|
long itemIndex = SlotNumberToItemIndex (slotNumber);
|
|
vector <wstring> fields (SlotListCtrl->GetColumnCount());
|
|
|
|
if (mountedVolumesMap.find (slotNumber) != mountedVolumesMap.end())
|
|
{
|
|
shared_ptr <VolumeInfo> volume = mountedVolumesMap[slotNumber];
|
|
|
|
#ifdef TC_WINDOWS
|
|
fields[ColumnSlot] = volume->MountPoint;
|
|
fields[ColumnEA] = volume->EncryptionAlgorithmName;
|
|
#else
|
|
fields[ColumnSlot] = StringConverter::FromNumber (slotNumber);
|
|
fields[ColumnMountPoint] = volume->MountPoint;
|
|
#endif
|
|
fields[ColumnPath] = volume->Path;
|
|
fields[ColumnSize] = Gui->SizeToString (volume->Size);
|
|
fields[ColumnType] = Gui->VolumeTypeToString (volume->Type, volume->TrueCryptMode, volume->Protection);
|
|
|
|
if (volume->HiddenVolumeProtectionTriggered)
|
|
{
|
|
fields[ColumnType] += L"(!)";
|
|
}
|
|
|
|
bool slotUpdated = false;
|
|
if (itemIndex == -1)
|
|
{
|
|
Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) volume->SlotNumber);
|
|
OnListItemInserted (prevItemIndex);
|
|
|
|
listChanged |= true;
|
|
slotUpdated = true;
|
|
}
|
|
else
|
|
{
|
|
if (Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields))
|
|
{
|
|
listChanged = true;
|
|
slotUpdated = true;
|
|
}
|
|
prevItemIndex = itemIndex;
|
|
}
|
|
|
|
if (slotUpdated && volume->HiddenVolumeProtectionTriggered)
|
|
protectionTriggeredVolumes.push_back (volume);
|
|
}
|
|
else
|
|
{
|
|
#ifdef TC_WINDOWS
|
|
fields[ColumnSlot] = Core->SlotNumberToMountPoint (slotNumber);
|
|
#else
|
|
fields[ColumnSlot] = StringConverter::FromNumber (slotNumber);
|
|
#endif
|
|
|
|
#ifdef TC_WINDOWS
|
|
if (Core->IsMountPointAvailable (fields[ColumnSlot]))
|
|
#else
|
|
if (true)
|
|
#endif
|
|
{
|
|
if (itemIndex == -1)
|
|
{
|
|
Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *) slotNumber);
|
|
OnListItemInserted (prevItemIndex);
|
|
listChanged |= true;
|
|
}
|
|
else
|
|
{
|
|
listChanged |= Gui->UpdateListCtrlItem (SlotListCtrl, itemIndex, fields);
|
|
prevItemIndex = itemIndex;
|
|
}
|
|
}
|
|
else if (itemIndex != -1)
|
|
{
|
|
SlotListCtrl->DeleteItem (itemIndex);
|
|
OnListItemDeleted (itemIndex);
|
|
listChanged = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (listChanged)
|
|
OnListChanged();
|
|
|
|
foreach (shared_ptr <VolumeInfo> volume, protectionTriggeredVolumes)
|
|
OnHiddenVolumeProtectionTriggered (volume);
|
|
}
|
|
|
|
void MainFrame::UpdateWipeCacheButton ()
|
|
{
|
|
bool enabled = WipeCacheButton->IsEnabled();
|
|
bool empty = Core->IsPasswordCacheEmpty();
|
|
|
|
if (empty && enabled)
|
|
{
|
|
WipeCacheButton->Disable();
|
|
WipeCachedPasswordsMenuItem->Enable (false);
|
|
}
|
|
else if (!empty && !enabled)
|
|
{
|
|
WipeCacheButton->Enable();
|
|
WipeCachedPasswordsMenuItem->Enable();
|
|
}
|
|
}
|
|
|
|
void MainFrame::WipeCache ()
|
|
{
|
|
Core->WipePasswordCache();
|
|
UpdateWipeCacheButton();
|
|
}
|
|
|
|
#ifdef TC_MACOSX
|
|
void MainFrame::OnMoveHandler(wxMoveEvent& event)
|
|
{
|
|
EnsureVisible (true);
|
|
}
|
|
#endif
|
|
}
|