From d90d9f0c401a21c85a525aaca0b97df8f7955db8 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 25 Dec 2014 22:54:14 +0100 Subject: Linux/MacOSX: Implement waiting dialog for lengthy operations in order to have a better user experience. --- src/Core/Core.h | 132 ++++++++++++++++++ src/Core/CoreBase.h | 1 + src/Main/Forms/ChangePasswordDialog.cpp | 5 +- src/Main/Forms/Forms.cpp | 35 +++++ src/Main/Forms/Forms.h | 23 +++ src/Main/Forms/MainFrame.cpp | 31 ++++- src/Main/Forms/MainFrame.h | 15 +- src/Main/Forms/TrueCrypt.fbp | 239 ++++++++++++++++++++++++++++++++ src/Main/Forms/VolumeCreationWizard.cpp | 5 +- src/Main/Forms/VolumeCreationWizard.h | 2 +- src/Main/Forms/WaitDialog.cpp | 94 +++++++++++++ src/Main/Forms/WaitDialog.h | 90 ++++++++++++ src/Main/GraphicUserInterface.cpp | 57 ++++++-- src/Main/GraphicUserInterface.h | 2 + src/Main/Main.make | 1 + src/Main/UserInterface.cpp | 73 +++++++++- src/Main/UserInterface.h | 4 + 17 files changed, 791 insertions(+), 18 deletions(-) mode change 100644 => 100755 src/Main/Forms/Forms.cpp mode change 100644 => 100755 src/Main/Forms/Forms.h mode change 100644 => 100755 src/Main/Forms/TrueCrypt.fbp create mode 100755 src/Main/Forms/WaitDialog.cpp create mode 100755 src/Main/Forms/WaitDialog.h diff --git a/src/Core/Core.h b/src/Core/Core.h index 5f218775..1a7a1611 100644 --- a/src/Core/Core.h +++ b/src/Core/Core.h @@ -15,6 +15,138 @@ namespace VeraCrypt { extern auto_ptr Core; extern auto_ptr CoreDirect; + + class WaitThreadRoutine + { + public: + Exception* m_pException; + WaitThreadRoutine() : m_pException(NULL) {} + virtual ~WaitThreadRoutine() {if (m_pException) delete m_pException;} + bool HasException () { return m_pException != NULL;} + Exception* GetException () const { return m_pException;} + void Execute(void) + { + try + { + ExecutionCode(); + } + catch(Exception& ex) + { + m_pException = ex.CloneNew(); + } + catch(...) + { + m_pException = new UnknownException (SRC_POS); + } + } + virtual void ExecutionCode(void) = 0; + }; + + class MountThreadRoutine : public WaitThreadRoutine + { + public: + MountOptions& m_options; + shared_ptr m_pVolume; + MountThreadRoutine(MountOptions &options) : m_options(options) {} + virtual ~MountThreadRoutine() { } + virtual void ExecutionCode(void) { m_pVolume = Core->MountVolume(m_options); } + }; + + class VolumeCreatorThreadRoutine : public WaitThreadRoutine + { + public: + shared_ptr m_options; + shared_ptr m_pCreator; + VolumeCreatorThreadRoutine(shared_ptr options, shared_ptr pCreator) + : m_options(options), m_pCreator(pCreator) {} + virtual ~VolumeCreatorThreadRoutine() { } + virtual void ExecutionCode(void) { m_pCreator->CreateVolume (m_options); } + }; + + class ChangePasswordThreadRoutine : public WaitThreadRoutine + { + public: + shared_ptr m_volumePath; + bool m_preserveTimestamps; + shared_ptr m_password; + shared_ptr m_kdf; + shared_ptr m_keyfiles; + shared_ptr m_newPassword; + shared_ptr m_newKeyfiles; + shared_ptr m_newPkcs5Kdf; + int m_wipeCount; + ChangePasswordThreadRoutine(shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr kdf, shared_ptr keyfiles, shared_ptr newPassword, shared_ptr newKeyfiles, shared_ptr newPkcs5Kdf, int wipeCount) : m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_kdf(kdf), m_keyfiles(keyfiles), m_newPassword(newPassword), m_newKeyfiles(newKeyfiles), m_newPkcs5Kdf(newPkcs5Kdf), m_wipeCount(wipeCount) {} + virtual ~ChangePasswordThreadRoutine() { } + virtual void ExecutionCode(void) { Core->ChangePassword(m_volumePath, m_preserveTimestamps, m_password, m_kdf, m_keyfiles, m_newPassword, m_newKeyfiles, m_newPkcs5Kdf, m_wipeCount); } + }; + + class OpenVolumeThreadRoutine : public WaitThreadRoutine + { + public: + shared_ptr m_volumePath; + bool m_preserveTimestamps; + shared_ptr m_password; + shared_ptr m_Kdf; + shared_ptr m_keyfiles; + VolumeProtection::Enum m_protection; + shared_ptr m_protectionPassword; + shared_ptr m_protectionKdf; + shared_ptr m_protectionKeyfiles; + bool m_sharedAccessAllowed; + VolumeType::Enum m_volumeType; + bool m_useBackupHeaders; + bool m_partitionInSystemEncryptionScope; + shared_ptr m_pVolume; + + OpenVolumeThreadRoutine(shared_ptr volumePath, bool preserveTimestamps, shared_ptr password, shared_ptr Kdf, shared_ptr keyfiles, VolumeProtection::Enum protection = VolumeProtection::None, shared_ptr protectionPassword = shared_ptr (), shared_ptr protectionKdf = shared_ptr (), shared_ptr protectionKeyfiles = shared_ptr (), bool sharedAccessAllowed = false, VolumeType::Enum volumeType = VolumeType::Unknown, bool useBackupHeaders = false, bool partitionInSystemEncryptionScope = false): + m_volumePath(volumePath), m_preserveTimestamps(preserveTimestamps), m_password(password), m_Kdf(Kdf), m_keyfiles(keyfiles), + m_protection(protection), m_protectionPassword(protectionPassword), m_protectionKdf(protectionKdf), m_protectionKeyfiles(protectionKeyfiles), m_sharedAccessAllowed(sharedAccessAllowed), m_volumeType(volumeType),m_useBackupHeaders(useBackupHeaders), + m_partitionInSystemEncryptionScope(partitionInSystemEncryptionScope) {} + + ~OpenVolumeThreadRoutine() {} + + virtual void ExecutionCode(void) { m_pVolume = Core->OpenVolume(m_volumePath,m_preserveTimestamps,m_password,m_Kdf,m_keyfiles, m_protection,m_protectionPassword,m_protectionKdf, m_protectionKeyfiles,m_sharedAccessAllowed,m_volumeType,m_useBackupHeaders, m_partitionInSystemEncryptionScope); } + + }; + + class ReEncryptHeaderThreadRoutine : public WaitThreadRoutine + { + public: + const BufferPtr &m_newHeaderBuffer; + shared_ptr m_header; + shared_ptr m_password; + shared_ptr m_keyfiles; + ReEncryptHeaderThreadRoutine(const BufferPtr &newHeaderBuffer, shared_ptr header, shared_ptr password, shared_ptr keyfiles) + : m_newHeaderBuffer(newHeaderBuffer), m_header(header), m_password(password), m_keyfiles(keyfiles) {} + virtual ~ReEncryptHeaderThreadRoutine() { } + virtual void ExecutionCode(void) { Core->ReEncryptVolumeHeaderWithNewSalt (m_newHeaderBuffer, m_header, m_password, m_keyfiles); } + }; + + class DecryptThreadRoutine : public WaitThreadRoutine + { + public: + shared_ptr m_pHeader; + const ConstBufferPtr &m_encryptedData; + const VolumePassword &m_password; + shared_ptr m_kdf; + const Pkcs5KdfList &m_keyDerivationFunctions; + const EncryptionAlgorithmList &m_encryptionAlgorithms; + const EncryptionModeList &m_encryptionModes; + bool m_bResult; + DecryptThreadRoutine(shared_ptr header, const ConstBufferPtr &encryptedData, const VolumePassword &password, shared_ptr kdf, const Pkcs5KdfList &keyDerivationFunctions, const EncryptionAlgorithmList &encryptionAlgorithms, const EncryptionModeList &encryptionModes) + : m_pHeader(header), m_encryptedData(encryptedData), m_password(password), m_kdf(kdf), m_keyDerivationFunctions(keyDerivationFunctions), m_encryptionAlgorithms(encryptionAlgorithms), m_encryptionModes(encryptionModes), m_bResult(false){} + virtual ~DecryptThreadRoutine() { } + virtual void ExecutionCode(void) { m_bResult = m_pHeader->Decrypt(m_encryptedData, m_password, m_kdf, m_keyDerivationFunctions, m_encryptionAlgorithms, m_encryptionModes); } + }; + + class WaitThreadUI + { + public: + WaitThreadUI(WaitThreadRoutine* pRoutine): m_pRoutine(pRoutine) {} + virtual ~WaitThreadUI() {} + virtual void Run(void) { m_pRoutine->ExecutionCode();} + WaitThreadRoutine* m_pRoutine; + }; } #endif // TC_HEADER_Core_Core diff --git a/src/Core/CoreBase.h b/src/Core/CoreBase.h index 0d52e5b9..d7dbcd0e 100755 --- a/src/Core/CoreBase.h +++ b/src/Core/CoreBase.h @@ -20,6 +20,7 @@ #include "CoreException.h" #include "HostDevice.h" #include "MountOptions.h" +#include "VolumeCreator.h" namespace VeraCrypt { diff --git a/src/Main/Forms/ChangePasswordDialog.cpp b/src/Main/Forms/ChangePasswordDialog.cpp index e07b7d3b..75fe717c 100755 --- a/src/Main/Forms/ChangePasswordDialog.cpp +++ b/src/Main/Forms/ChangePasswordDialog.cpp @@ -10,6 +10,7 @@ #include "Main/Main.h" #include "Main/GraphicUserInterface.h" #include "ChangePasswordDialog.h" +#include "WaitDialog.h" namespace VeraCrypt { @@ -124,9 +125,11 @@ namespace VeraCrypt }); #endif wxBusyCursor busy; - Core->ChangePassword (Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps, + ChangePasswordThreadRoutine routine(Path, Gui->GetPreferences().DefaultMountOptions.PreserveTimestamps, CurrentPasswordPanel->GetPassword(), CurrentPasswordPanel->GetPkcs5Kdf(), CurrentPasswordPanel->GetKeyfiles(), newPassword, newKeyfiles, NewPasswordPanel->GetPkcs5Kdf(), NewPasswordPanel->GetHeaderWipeCount()); + WaitDialog dlg(this, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); } switch (DialogMode) diff --git a/src/Main/Forms/Forms.cpp b/src/Main/Forms/Forms.cpp old mode 100644 new mode 100755 index ad732534..1c536b31 --- a/src/Main/Forms/Forms.cpp +++ b/src/Main/Forms/Forms.cpp @@ -3349,3 +3349,38 @@ VolumeSizeWizardPageBase::~VolumeSizeWizardPageBase() VolumeSizePrefixChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( VolumeSizeWizardPageBase::OnVolumeSizePrefixSelected ), NULL, this ); } + +WaitDialogBase::WaitDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer( wxVERTICAL ); + + WaitStaticText = new wxStaticText( this, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE ); + WaitStaticText->Wrap( -1 ); + bSizer160->Add( WaitStaticText, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5 ); + + WaitProgessBar = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL|wxGA_SMOOTH ); + WaitProgessBar->SetValue( 0 ); + bSizer160->Add( WaitProgessBar, 0, wxALL|wxEXPAND, 5 ); + + + this->SetSizer( bSizer160 ); + this->Layout(); + bSizer160->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( WaitDialogBase::OnWaitDialogClose ) ); + this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( WaitDialogBase::OnWaitDialogInit ) ); +} + +WaitDialogBase::~WaitDialogBase() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( WaitDialogBase::OnWaitDialogClose ) ); + this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( WaitDialogBase::OnWaitDialogInit ) ); + +} diff --git a/src/Main/Forms/Forms.h b/src/Main/Forms/Forms.h old mode 100644 new mode 100755 index a59a9bf7..b0579219 --- a/src/Main/Forms/Forms.h +++ b/src/Main/Forms/Forms.h @@ -1025,6 +1025,29 @@ namespace VeraCrypt }; + /////////////////////////////////////////////////////////////////////////////// + /// Class WaitDialogBase + /////////////////////////////////////////////////////////////////////////////// + class WaitDialogBase : public wxDialog + { + private: + + protected: + wxStaticText* WaitStaticText; + wxGauge* WaitProgessBar; + + // Virtual event handlers, overide them in your derived class + virtual void OnWaitDialogClose( wxCloseEvent& event ) { event.Skip(); } + virtual void OnWaitDialogInit( wxInitDialogEvent& event ) { event.Skip(); } + + + public: + + WaitDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("VeraCrypt"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION ); + ~WaitDialogBase(); + + }; + } // namespace VeraCrypt #endif //__FORMS_H__ diff --git a/src/Main/Forms/MainFrame.cpp b/src/Main/Forms/MainFrame.cpp index b48f3718..fbf20537 100644 --- a/src/Main/Forms/MainFrame.cpp +++ b/src/Main/Forms/MainFrame.cpp @@ -36,6 +36,10 @@ 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) + MainFrame::MainFrame (wxWindow* parent) : MainFrameBase (parent), ListItemRightClickEventPending (false), SelectedItemIndex (-1), @@ -84,6 +88,11 @@ namespace VeraCrypt Gui->ShowError (e); } } + + 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 ) ); + } MainFrame::~MainFrame () @@ -100,6 +109,9 @@ namespace VeraCrypt } #endif + 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 ) ); Core->VolumeMountedEvent.Disconnect (this); Core->VolumeDismountedEvent.Disconnect (this); Gui->OpenVolumeSystemRequestEvent.Disconnect (this); @@ -343,7 +355,7 @@ namespace VeraCrypt Core->VolumeMountedEvent.Connect (EventConnector (this, &MainFrame::OnVolumeMounted)); Core->VolumeDismountedEvent.Connect (EventConnector (this, &MainFrame::OnVolumeDismounted)); Gui->OpenVolumeSystemRequestEvent.Connect (EventConnector (this, &MainFrame::OnOpenVolumeSystemRequestEvent)); - Gui->PreferencesUpdatedEvent.Connect (EventConnector (this, &MainFrame::OnPreferencesUpdated)); + Gui->PreferencesUpdatedEvent.Connect (EventConnector (this, &MainFrame::OnPreferencesUpdatedEvent)); // Drag & drop class FileDropTarget : public wxFileDropTarget @@ -1139,7 +1151,22 @@ namespace VeraCrypt dialog.ShowModal(); } - void MainFrame::OnPreferencesUpdated (EventArgs &args) + 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 (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(); diff --git a/src/Main/Forms/MainFrame.h b/src/Main/Forms/MainFrame.h index a759cfcd..b31128cb 100644 --- a/src/Main/Forms/MainFrame.h +++ b/src/Main/Forms/MainFrame.h @@ -16,6 +16,10 @@ namespace VeraCrypt { struct FavoriteVolume; + DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_UPDATE_VOLUME_LIST, -1); + DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_PREF_UPDATED, -1); + DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_OPEN_VOLUME_REQUEST, -1); + class MainFrame : public MainFrameBase { public: @@ -109,10 +113,12 @@ namespace VeraCrypt void OnNoHistoryCheckBoxClick (wxCommandEvent& event); void OnOnlineHelpMenuItemSelected (wxCommandEvent& event) { Gui->OpenOnlineHelp (this); } void OnOpenVolumeMenuItemSelected (wxCommandEvent& event) { OpenSelectedVolume(); } - void OnOpenVolumeSystemRequestEvent (EventArgs &args) { SetVolumePath (wstring (dynamic_cast (args).mVolumePath)); } + void OnOpenVolumeSystemRequest (wxCommandEvent& event); + void OnOpenVolumeSystemRequestEvent (EventArgs &args); void OnOrganizeFavoritesMenuItemSelected (wxCommandEvent& event); void OnPreferencesMenuItemSelected (wxCommandEvent& event); - void OnPreferencesUpdated (EventArgs &args); + void OnPreferencesUpdated (wxCommandEvent& event); + void OnPreferencesUpdatedEvent (EventArgs &args) { wxQueueEvent (this, new wxCommandEvent( wxEVT_COMMAND_PREF_UPDATED,0)); } void OnRemoveKeyfilesMenuItemSelected (wxCommandEvent& event) { ChangePassword (ChangePasswordDialog::Mode::RemoveAllKeyfiles); } void OnRepairFilesystemMenuItemSelected( wxCommandEvent& event ) { CheckFilesystem (true); } void OnRestoreVolumeHeaderMenuItemSelected (wxCommandEvent& event); @@ -126,8 +132,9 @@ namespace VeraCrypt void OnVolumePropertiesButtonClick (wxCommandEvent& event); void OnVolumeToolsButtonClick (wxCommandEvent& event); void OnVolumeButtonClick (wxCommandEvent& event); - void OnVolumeDismounted (EventArgs &args) { UpdateVolumeList(); } - void OnVolumeMounted (EventArgs &args) { UpdateVolumeList(); } + void OnUpdateVolumeList (wxCommandEvent& event) { UpdateVolumeList(); } + void OnVolumeDismounted (EventArgs &args) { wxQueueEvent (this, new wxCommandEvent( wxEVT_COMMAND_UPDATE_VOLUME_LIST,0)); } + void OnVolumeMounted (EventArgs &args) { wxQueueEvent (this, new wxCommandEvent( wxEVT_COMMAND_UPDATE_VOLUME_LIST,0)); } void OnUserGuideMenuItemSelected (wxCommandEvent& event) { Gui->OpenUserGuide (this); } void OnWebsiteMenuItemSelected (wxCommandEvent& event) { Gui->OpenHomepageLink (this, L"website"); } void OnWipeCacheButtonClick (wxCommandEvent& event); diff --git a/src/Main/Forms/TrueCrypt.fbp b/src/Main/Forms/TrueCrypt.fbp old mode 100644 new mode 100755 index 0e14502d..998b00d1 --- a/src/Main/Forms/TrueCrypt.fbp +++ b/src/Main/Forms/TrueCrypt.fbp @@ -26918,5 +26918,244 @@ + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + WaitDialogBase + + -1,-1 + wxCAPTION + + VeraCrypt + + + + + + + + + + + + + + OnWaitDialogClose + + + + + + OnWaitDialogInit + + + + + + + + + + + + + + + + + + + + + + + bSizer160 + wxVERTICAL + none + + 5 + wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + MyLabel + + 0 + + + 0 + + 1 + WaitStaticText + 1 + + + protected + 1 + + Resizable + 1 + + wxALIGN_CENTRE + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + WaitProgessBar + 1 + + + protected + 1 + + 100 + Resizable + 1 + + wxGA_HORIZONTAL|wxGA_SMOOTH + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index 1dac1315..01fa8450 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -27,6 +27,7 @@ #include "VolumeLocationWizardPage.h" #include "VolumePasswordWizardPage.h" #include "VolumeSizeWizardPage.h" +#include "WaitDialog.h" namespace VeraCrypt { @@ -865,7 +866,9 @@ namespace VeraCrypt options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*SelectedHash); Creator.reset (new VolumeCreator); - Creator->CreateVolume (options); + VolumeCreatorThreadRoutine routine(options, Creator); + WaitDialog dlg(this, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); page->SetKeyInfo (Creator->GetKeyInfo()); diff --git a/src/Main/Forms/VolumeCreationWizard.h b/src/Main/Forms/VolumeCreationWizard.h index 3a87c4cb..09bc1c34 100644 --- a/src/Main/Forms/VolumeCreationWizard.h +++ b/src/Main/Forms/VolumeCreationWizard.h @@ -54,7 +54,7 @@ namespace VeraCrypt volatile bool AbortConfirmationPending; volatile bool AbortRequested; volatile bool CreationAborted; - auto_ptr Creator; + shared_ptr Creator; bool CrossPlatformSupport; static bool DeviceWarningConfirmed; bool DisplayKeyInfo; diff --git a/src/Main/Forms/WaitDialog.cpp b/src/Main/Forms/WaitDialog.cpp new file mode 100755 index 00000000..a8290d10 --- /dev/null +++ b/src/Main/Forms/WaitDialog.cpp @@ -0,0 +1,94 @@ +/* + Copyright (c) 2014 IDRIX. All rights reserved. + + Governed by the VeraCrypt License the full text of which is contained in + the file License.txt included in VeraCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include "Volume/EncryptionModeXTS.h" +#include "Main/GraphicUserInterface.h" +#include "Common/SecurityToken.h" +#include "WaitDialog.h" + +namespace VeraCrypt +{ + DEFINE_EVENT_TYPE(wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED) + + wxThread::ExitCode WaitThread::Entry() + { + wxCommandEvent finishEvent( wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED,0); + + m_pRoutine->Execute(); + wxQueueEvent (m_pHandler, new wxCommandEvent( wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED,0)); + return (wxThread::ExitCode)0; // success + } + + void WaitDialog::ThrowException(Exception* ex) + { + #define VC_CONVERT_EXCEPTION(NAME) if (dynamic_cast (ex)) throw (NAME&) *ex; + VC_CONVERT_EXCEPTION (PasswordIncorrect); + VC_CONVERT_EXCEPTION (PasswordKeyfilesIncorrect); + VC_CONVERT_EXCEPTION (PasswordOrKeyboardLayoutIncorrect); + VC_CONVERT_EXCEPTION (PasswordOrMountOptionsIncorrect); + VC_CONVERT_EXCEPTION (ProtectionPasswordIncorrect); + VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); + VC_CONVERT_EXCEPTION (PasswordEmpty); + VC_CONVERT_EXCEPTION (PasswordTooLong); + VC_CONVERT_EXCEPTION (UnportablePassword); + VC_CONVERT_EXCEPTION (ElevationFailed); + VC_CONVERT_EXCEPTION (RootDeviceUnavailable); + VC_CONVERT_EXCEPTION (DriveLetterUnavailable); + VC_CONVERT_EXCEPTION (DriverError); + VC_CONVERT_EXCEPTION (EncryptedSystemRequired); + VC_CONVERT_EXCEPTION (HigherFuseVersionRequired); + VC_CONVERT_EXCEPTION (KernelCryptoServiceTestFailed); + VC_CONVERT_EXCEPTION (LoopDeviceSetupFailed); + VC_CONVERT_EXCEPTION (MountPointRequired); + VC_CONVERT_EXCEPTION (MountPointUnavailable); + VC_CONVERT_EXCEPTION (NoDriveLetterAvailable); + VC_CONVERT_EXCEPTION (TemporaryDirectoryFailure); + VC_CONVERT_EXCEPTION (UnsupportedSectorSizeHiddenVolumeProtection); + VC_CONVERT_EXCEPTION (UnsupportedSectorSizeNoKernelCrypto); + VC_CONVERT_EXCEPTION (VolumeAlreadyMounted); + VC_CONVERT_EXCEPTION (VolumeSlotUnavailable); + VC_CONVERT_EXCEPTION (UserInterfaceException); + VC_CONVERT_EXCEPTION (MissingArgument); + VC_CONVERT_EXCEPTION (NoItemSelected); + VC_CONVERT_EXCEPTION (StringFormatterException); + VC_CONVERT_EXCEPTION (ExecutedProcessFailed); + VC_CONVERT_EXCEPTION (AlreadyInitialized); + VC_CONVERT_EXCEPTION (AssertionFailed); + VC_CONVERT_EXCEPTION (ExternalException); + VC_CONVERT_EXCEPTION (InsufficientData); + VC_CONVERT_EXCEPTION (NotApplicable); + VC_CONVERT_EXCEPTION (NotImplemented); + VC_CONVERT_EXCEPTION (NotInitialized); + VC_CONVERT_EXCEPTION (ParameterIncorrect); + VC_CONVERT_EXCEPTION (ParameterTooLarge); + VC_CONVERT_EXCEPTION (PartitionDeviceRequired); + VC_CONVERT_EXCEPTION (StringConversionFailed); + VC_CONVERT_EXCEPTION (TestFailed); + VC_CONVERT_EXCEPTION (TimeOut); + VC_CONVERT_EXCEPTION (UnknownException); + VC_CONVERT_EXCEPTION (UserAbort) + VC_CONVERT_EXCEPTION (CipherInitError); + VC_CONVERT_EXCEPTION (WeakKeyDetected); + VC_CONVERT_EXCEPTION (HigherVersionRequired); + VC_CONVERT_EXCEPTION (KeyfilePathEmpty); + VC_CONVERT_EXCEPTION (MissingVolumeData); + VC_CONVERT_EXCEPTION (MountedVolumeInUse); + VC_CONVERT_EXCEPTION (UnsupportedSectorSize); + VC_CONVERT_EXCEPTION (VolumeEncryptionNotCompleted); + VC_CONVERT_EXCEPTION (VolumeHostInUse); + VC_CONVERT_EXCEPTION (VolumeProtected); + VC_CONVERT_EXCEPTION (VolumeReadOnly); + VC_CONVERT_EXCEPTION (Pkcs11Exception); + VC_CONVERT_EXCEPTION (InvalidSecurityTokenKeyfilePath); + VC_CONVERT_EXCEPTION (SecurityTokenLibraryNotInitialized); + VC_CONVERT_EXCEPTION (SecurityTokenKeyfileAlreadyExists); + VC_CONVERT_EXCEPTION (SecurityTokenKeyfileNotFound); + throw *ex; + } +} diff --git a/src/Main/Forms/WaitDialog.h b/src/Main/Forms/WaitDialog.h new file mode 100755 index 00000000..c9e0d56e --- /dev/null +++ b/src/Main/Forms/WaitDialog.h @@ -0,0 +1,90 @@ +/* + Copyright (c) 2014 IDRIX. All rights reserved. + + Governed by the VeraCrypt License the full text of which is contained in + the file License.txt included in VeraCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Main_Forms_WaitDialog +#define TC_HEADER_Main_Forms_WaitDialog + +#include "Forms.h" +#include "Main/Main.h" + +namespace VeraCrypt +{ + + DECLARE_LOCAL_EVENT_TYPE(wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED, -1); + + class WaitDialog; + + + + class WaitThread : public wxThread + { + public: + WaitThread(WaitDialog *handler, WaitThreadRoutine* pRoutine) : wxThread(wxTHREAD_DETACHED), m_pRoutine(pRoutine) + { + m_pHandler = handler; + } + ~WaitThread() + { + } + + protected: + virtual ExitCode Entry(); + WaitDialog *m_pHandler; + WaitThreadRoutine* m_pRoutine; + }; + + class WaitDialog : public WaitDialogBase, public WaitThreadUI + { + public: + WaitDialog (wxWindow *parent, const wxString& label, WaitThreadRoutine* pRoutine) + : WaitDialogBase(parent), WaitThreadUI(pRoutine), m_timer (this) + { + WaitStaticText->SetLabel (label); + WaitProgessBar->Pulse(); + Layout(); + GetSizer()->Fit( this ); + Centre( wxBOTH ); + Connect( wxID_ANY, wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED, wxCommandEventHandler( WaitDialog::OnThreadCompletion ) ); + Connect( wxEVT_TIMER, wxTimerEventHandler( WaitDialog::OnProgressTimer ), NULL, this ); + m_thread = new WaitThread(this, pRoutine); + } + + ~WaitDialog() + { + Disconnect( wxEVT_TIMER, wxTimerEventHandler( WaitDialog::OnProgressTimer )); + Disconnect( wxID_ANY, wxEVT_COMMAND_WAITDIALOGTHREAD_COMPLETED, wxCommandEventHandler( WaitDialog::OnThreadCompletion ) ); + } + + virtual void OnWaitDialogInit( wxInitDialogEvent& event ) + { + m_thread->Run(); + m_timer.Start(100); + } + + // virtual void OnWaitDialogClose( wxCloseEvent& event ) { } + void OnThreadCompletion(wxCommandEvent &) + { + EndModal(0); + } + + void OnProgressTimer(wxTimerEvent& event) + { + WaitProgessBar->Pulse(); + } + + virtual void Run(void) { ShowModal(); if (m_pRoutine->HasException()) ThrowException(m_pRoutine->m_pException); } + + void ThrowException(Exception* ex); + + protected: + WaitThread* m_thread; + wxTimer m_timer; + }; +} + +#endif // TC_HEADER_Main_Forms_WaitDialog diff --git a/src/Main/GraphicUserInterface.cpp b/src/Main/GraphicUserInterface.cpp index 78e0e34d..5ddcfa61 100755 --- a/src/Main/GraphicUserInterface.cpp +++ b/src/Main/GraphicUserInterface.cpp @@ -30,6 +30,7 @@ #include "Forms/MountOptionsDialog.h" #include "Forms/RandomPoolEnrichmentDialog.h" #include "Forms/SecurityTokenKeyfilesDialog.h" +#include "Forms/WaitDialog.h" namespace VeraCrypt { @@ -173,7 +174,7 @@ namespace VeraCrypt try { wxBusyCursor busy; - volume = Core->OpenVolume ( + OpenVolumeThreadRoutine routine( options->Path, options->PreserveTimestamps, options->Password, @@ -187,6 +188,10 @@ namespace VeraCrypt volumeType, options->UseBackupHeaders ); + WaitDialog dlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); + + volume = routine.m_pVolume; } catch (PasswordException &e) { @@ -263,14 +268,18 @@ namespace VeraCrypt // Re-encrypt volume header SecureBuffer newHeaderBuffer (normalVolume->GetLayout()->GetHeaderSize()); - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Keyfiles); + ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, normalVolume->GetHeader(), normalVolumeMountOptions.Password, normalVolumeMountOptions.Keyfiles); + WaitDialog dlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); backupFile.Write (newHeaderBuffer); if (hiddenVolume) { // Re-encrypt hidden volume header - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Keyfiles); + ReEncryptHeaderThreadRoutine hiddenRoutine(newHeaderBuffer, hiddenVolume->GetHeader(), hiddenVolumeMountOptions.Password, hiddenVolumeMountOptions.Keyfiles); + WaitDialog hiddenDlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &hiddenRoutine); + hiddenDlg.Run(); } else { @@ -1259,7 +1268,7 @@ namespace VeraCrypt try { wxBusyCursor busy; - volume = Core->OpenVolume ( + OpenVolumeThreadRoutine routine( options.Path, options.PreserveTimestamps, options.Password, @@ -1273,6 +1282,10 @@ namespace VeraCrypt VolumeType::Unknown, true ); + WaitDialog dlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); + + volume = routine.m_pVolume; } catch (PasswordException &e) { @@ -1293,7 +1306,9 @@ namespace VeraCrypt // Re-encrypt volume header wxBusyCursor busy; SecureBuffer newHeaderBuffer (volume->GetLayout()->GetHeaderSize()); - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, volume->GetHeader(), options.Password, options.Keyfiles); + ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, volume->GetHeader(), options.Password, options.Keyfiles); + WaitDialog dlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); // Write volume header int headerOffset = volume->GetLayout()->GetHeaderOffset(); @@ -1377,7 +1392,15 @@ namespace VeraCrypt // Decrypt header shared_ptr passwordKey = Keyfile::ApplyListToPassword (options.Keyfiles, options.Password); - if (layout->GetHeader()->Decrypt (headerBuffer, *passwordKey, options.Kdf, layout->GetSupportedKeyDerivationFunctions(), layout->GetSupportedEncryptionAlgorithms(), layout->GetSupportedEncryptionModes())) + Pkcs5KdfList keyDerivationFunctions = layout->GetSupportedKeyDerivationFunctions(); + EncryptionAlgorithmList encryptionAlgorithms = layout->GetSupportedEncryptionAlgorithms(); + EncryptionModeList encryptionModes = layout->GetSupportedEncryptionModes(); + + DecryptThreadRoutine decryptRoutine(layout->GetHeader(), headerBuffer, *passwordKey, options.Kdf, keyDerivationFunctions, encryptionAlgorithms, encryptionModes); + WaitDialog decryptDlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &decryptRoutine); + decryptDlg.Run(); + + if (decryptRoutine.m_bResult) { decryptedLayout = layout; break; @@ -1402,7 +1425,9 @@ namespace VeraCrypt // Re-encrypt volume header wxBusyCursor busy; SecureBuffer newHeaderBuffer (decryptedLayout->GetHeaderSize()); - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + ReEncryptHeaderThreadRoutine routine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + WaitDialog dlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); // Write volume header int headerOffset = decryptedLayout->GetHeaderOffset(); @@ -1416,7 +1441,9 @@ namespace VeraCrypt if (decryptedLayout->HasBackupHeader()) { // Re-encrypt backup volume header - Core->ReEncryptVolumeHeaderWithNewSalt (newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + ReEncryptHeaderThreadRoutine backupRoutine(newHeaderBuffer, decryptedLayout->GetHeader(), options.Password, options.Keyfiles); + WaitDialog backupDlg(parent, LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &backupRoutine); + backupDlg.Run(); // Write backup volume header headerOffset = decryptedLayout->GetBackupHeaderOffset(); @@ -1758,6 +1785,20 @@ namespace VeraCrypt #endif } + WaitThreadUI* GraphicUserInterface::GetWaitThreadUI(WaitThreadRoutine *pRoutine) const + { + return new WaitDialog(GetTopWindow(), LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], pRoutine); + } + + shared_ptr GraphicUserInterface::MountVolumeThread (MountOptions &options) const + { + MountThreadRoutine routine(options); + WaitDialog dlg(GetTopWindow(), LangString["IDT_STATIC_MODAL_WAIT_DLG_INFO"], &routine); + dlg.Run(); + + return routine.m_pVolume; + } + DEFINE_EVENT_TYPE (TC_EVENT_THREAD_EXITING); GraphicUserInterface *Gui = nullptr; diff --git a/src/Main/GraphicUserInterface.h b/src/Main/GraphicUserInterface.h index 890ab5d6..f7d6d709 100755 --- a/src/Main/GraphicUserInterface.h +++ b/src/Main/GraphicUserInterface.h @@ -88,6 +88,8 @@ namespace VeraCrypt virtual bool UpdateListCtrlItem (wxListCtrl *listCtrl, long itemIndex, const vector &itemFields) const; virtual void UserEnrichRandomPool (wxWindow *parent, shared_ptr hash = shared_ptr ()) const; virtual void Yield () const; + virtual WaitThreadUI* GetWaitThreadUI(WaitThreadRoutine *pRoutine) const; + virtual shared_ptr MountVolumeThread (MountOptions &options) const; #ifdef TC_MACOSX virtual void MacOpenFile (const wxString &fileName); diff --git a/src/Main/Main.make b/src/Main/Main.make index f373debd..02577d8d 100644 --- a/src/Main/Main.make +++ b/src/Main/Main.make @@ -52,6 +52,7 @@ OBJS += Forms/VolumeFormatOptionsWizardPage.o OBJS += Forms/VolumeLocationWizardPage.o OBJS += Forms/VolumePasswordWizardPage.o OBJS += Forms/VolumeSizeWizardPage.o +OBJS += Forms/WaitDialog.o OBJS += Forms/WizardFrame.o endif diff --git a/src/Main/UserInterface.cpp b/src/Main/UserInterface.cpp index 4306dec2..73db03dc 100755 --- a/src/Main/UserInterface.cpp +++ b/src/Main/UserInterface.cpp @@ -17,6 +17,7 @@ #include "Platform/Unix/Process.h" #endif #include "Platform/SystemInfo.h" +#include "Platform/SystemException.h" #include "Common/SecurityToken.h" #include "Volume/EncryptionTest.h" #include "Application.h" @@ -729,7 +730,8 @@ namespace VeraCrypt try { - volume = Core->MountVolume (options); + volume = MountVolumeThread (options); + } catch (VolumeHostInUse&) { @@ -1496,4 +1498,73 @@ namespace VeraCrypt return L"?"; } } + + #define VC_CONVERT_EXCEPTION(NAME) if (dynamic_cast (ex)) throw (NAME&) *ex; + + void UserInterface::ThrowException (Exception* ex) + { + VC_CONVERT_EXCEPTION (PasswordIncorrect); + VC_CONVERT_EXCEPTION (PasswordKeyfilesIncorrect); + VC_CONVERT_EXCEPTION (PasswordOrKeyboardLayoutIncorrect); + VC_CONVERT_EXCEPTION (PasswordOrMountOptionsIncorrect); + VC_CONVERT_EXCEPTION (ProtectionPasswordIncorrect); + VC_CONVERT_EXCEPTION (ProtectionPasswordKeyfilesIncorrect); + VC_CONVERT_EXCEPTION (PasswordEmpty); + VC_CONVERT_EXCEPTION (PasswordTooLong); + VC_CONVERT_EXCEPTION (UnportablePassword); + VC_CONVERT_EXCEPTION (ElevationFailed); + VC_CONVERT_EXCEPTION (RootDeviceUnavailable); + VC_CONVERT_EXCEPTION (DriveLetterUnavailable); + VC_CONVERT_EXCEPTION (DriverError); + VC_CONVERT_EXCEPTION (EncryptedSystemRequired); + VC_CONVERT_EXCEPTION (HigherFuseVersionRequired); + VC_CONVERT_EXCEPTION (KernelCryptoServiceTestFailed); + VC_CONVERT_EXCEPTION (LoopDeviceSetupFailed); + VC_CONVERT_EXCEPTION (MountPointRequired); + VC_CONVERT_EXCEPTION (MountPointUnavailable); + VC_CONVERT_EXCEPTION (NoDriveLetterAvailable); + VC_CONVERT_EXCEPTION (TemporaryDirectoryFailure); + VC_CONVERT_EXCEPTION (UnsupportedSectorSizeHiddenVolumeProtection); + VC_CONVERT_EXCEPTION (UnsupportedSectorSizeNoKernelCrypto); + VC_CONVERT_EXCEPTION (VolumeAlreadyMounted); + VC_CONVERT_EXCEPTION (VolumeSlotUnavailable); + VC_CONVERT_EXCEPTION (UserInterfaceException); + VC_CONVERT_EXCEPTION (MissingArgument); + VC_CONVERT_EXCEPTION (NoItemSelected); + VC_CONVERT_EXCEPTION (StringFormatterException); + VC_CONVERT_EXCEPTION (ExecutedProcessFailed); + VC_CONVERT_EXCEPTION (AlreadyInitialized); + VC_CONVERT_EXCEPTION (AssertionFailed); + VC_CONVERT_EXCEPTION (ExternalException); + VC_CONVERT_EXCEPTION (InsufficientData); + VC_CONVERT_EXCEPTION (NotApplicable); + VC_CONVERT_EXCEPTION (NotImplemented); + VC_CONVERT_EXCEPTION (NotInitialized); + VC_CONVERT_EXCEPTION (ParameterIncorrect); + VC_CONVERT_EXCEPTION (ParameterTooLarge); + VC_CONVERT_EXCEPTION (PartitionDeviceRequired); + VC_CONVERT_EXCEPTION (StringConversionFailed); + VC_CONVERT_EXCEPTION (TestFailed); + VC_CONVERT_EXCEPTION (TimeOut); + VC_CONVERT_EXCEPTION (UnknownException); + VC_CONVERT_EXCEPTION (UserAbort) + VC_CONVERT_EXCEPTION (CipherInitError); + VC_CONVERT_EXCEPTION (WeakKeyDetected); + VC_CONVERT_EXCEPTION (HigherVersionRequired); + VC_CONVERT_EXCEPTION (KeyfilePathEmpty); + VC_CONVERT_EXCEPTION (MissingVolumeData); + VC_CONVERT_EXCEPTION (MountedVolumeInUse); + VC_CONVERT_EXCEPTION (UnsupportedSectorSize); + VC_CONVERT_EXCEPTION (VolumeEncryptionNotCompleted); + VC_CONVERT_EXCEPTION (VolumeHostInUse); + VC_CONVERT_EXCEPTION (VolumeProtected); + VC_CONVERT_EXCEPTION (VolumeReadOnly); + VC_CONVERT_EXCEPTION (Pkcs11Exception); + VC_CONVERT_EXCEPTION (InvalidSecurityTokenKeyfilePath); + VC_CONVERT_EXCEPTION (SecurityTokenLibraryNotInitialized); + VC_CONVERT_EXCEPTION (SecurityTokenKeyfileAlreadyExists); + VC_CONVERT_EXCEPTION (SecurityTokenKeyfileNotFound); + VC_CONVERT_EXCEPTION (SystemException); + throw *ex; + } } diff --git a/src/Main/UserInterface.h b/src/Main/UserInterface.h index ae74ae99..a280bcc2 100755 --- a/src/Main/UserInterface.h +++ b/src/Main/UserInterface.h @@ -54,6 +54,7 @@ namespace VeraCrypt virtual void ListMountedVolumes (const VolumeInfoList &volumes) const; virtual void ListSecurityTokenKeyfiles () const = 0; virtual shared_ptr MountVolume (MountOptions &options) const; + virtual shared_ptr MountVolumeThread (MountOptions &options) const { return Core->MountVolume (options);} virtual VolumeInfoList MountAllDeviceHostedVolumes (MountOptions &options) const; virtual VolumeInfoList MountAllFavoriteVolumes (MountOptions &options); virtual void OpenExplorerWindow (const DirectoryPath &path); @@ -75,6 +76,7 @@ namespace VeraCrypt virtual wxString TimeSpanToString (uint64 seconds) const; virtual bool VolumeHasUnrecommendedExtension (const VolumePath &path) const; virtual void Yield () const = 0; + virtual WaitThreadUI* GetWaitThreadUI(WaitThreadRoutine *pRoutine) const { return new WaitThreadUI(pRoutine);} virtual wxDateTime VolumeTimeToDateTime (VolumeTime volumeTime) const { return wxDateTime ((time_t) (volumeTime / 1000ULL / 1000 / 10 - 134774ULL * 24 * 3600)); } virtual wxString VolumeTimeToString (VolumeTime volumeTime) const; virtual wxString VolumeTypeToString (VolumeType::Enum type, VolumeProtection::Enum protection) const; @@ -88,6 +90,8 @@ namespace VeraCrypt const UserInterface *UI; }; + static void ThrowException (Exception* ex); + protected: UserInterface (); virtual bool OnExceptionInMainLoop () { throw; } -- cgit v1.2.3