mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-14 08:31:29 +00:00
Veracrypt currently appears in screenshots and screen captures, which can unintentionally expose sensitive information, such as the fact that Veracrypt is running or the location of your volumes. Both Windows and macOS offer mechanisms to exclude specific windows from being captured. While not foolproof, this is a useful preventative measure. The method is a no-op for Linux/FreeBSD. For more details on the wxWidgets API, see: https://docs.wxwidgets.org/3.2/classwx_top_level_window.html#a337b9cec62b0cbd3b1b1545a83270f64
1813 lines
49 KiB
C++
1813 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();
|
|
InitWindowPrivacy();
|
|
|
|
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::InitWindowPrivacy ()
|
|
{
|
|
Gui->SetContentProtection(!CmdLine->ArgAllowScreencapture);
|
|
}
|
|
|
|
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->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
|
|
}
|
|
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->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
|
|
}
|
|
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->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
|
|
}
|
|
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);
|
|
EnsureVisible();
|
|
#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->ArgHash)
|
|
{
|
|
mountOptions.Kdf = Pkcs5Kdf::GetAlgorithm (*CmdLine->ArgHash);
|
|
}
|
|
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::OnLanguageMenuItemSelected (wxCommandEvent& event)
|
|
{
|
|
#ifdef TC_MACOSX
|
|
if (Gui->IsInBackgroundMode())
|
|
Gui->SetBackgroundMode (false);
|
|
#endif
|
|
PreferencesDialog dialog (this);
|
|
dialog.SelectPage (dialog.LanguagesPage);
|
|
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
|
|
{
|
|
uint8 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->Protection);
|
|
|
|
if (volume->HiddenVolumeProtectionTriggered)
|
|
{
|
|
fields[ColumnType] += L"(!)";
|
|
}
|
|
|
|
bool slotUpdated = false;
|
|
if (itemIndex == -1)
|
|
{
|
|
Gui->InsertToListCtrl (SlotListCtrl, ++prevItemIndex, fields, 0, (void *)(intptr_t) 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 *)(intptr_t) 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
|
|
}
|