mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-05-21 21:30:48 -05:00
Linux/macOS: show volume creation finalization stages
Report explicit progress stages while writing volume data, writing backup headers, and flushing data to disk so the wizard does not appear stuck at 100%. Keep the wizard in progress during Unix post-creation formatting and show status for temporary mount/device setup, mkfs invocation, and dismount.
This commit is contained in:
@@ -1672,6 +1672,16 @@
|
||||
<entry lang="en" key="LINUX_PREF_MOUNT_NTFS_WITH_NTFS3_HELP">Linux only. When enabled, VeraCrypt probes the decrypted virtual device with blkid -p and mounts detected NTFS filesystems with ntfs3 instead of the default NTFS backend. If NTFS detection fails, VeraCrypt uses the normal automatic filesystem selection. If ntfs3 is unavailable or blocked by the distribution, mounting may fail. This opt-in option can avoid suspend or hibernate hangs caused by frozen user-space FUSE filesystems.</entry>
|
||||
<entry lang="en" key="LINUX_EMERGENCY_UNMOUNT_WARNING">Normal unmount of volume {0} failed. This can happen when applications still have files or directories open on the volume, or when the backing device was disconnected and the mount became stale.\n\nIf the device is still connected, choose No, close applications using the volume, and try unmounting again.\n\nIf the device was disconnected or the mount is stale, VeraCrypt can attempt emergency cleanup by lazy-detaching the filesystem and removing or scheduling removal of VeraCrypt kernel objects. Pending writes may have failed, data may be lost, and cleanup may remain pending until applications close open files. Check the filesystem with fsck or the appropriate repair tool before using it again.\n\nContinue?</entry>
|
||||
<entry lang="en" key="LINUX_EMERGENCY_UNMOUNTED">Emergency cleanup for volume {0} has been initiated. If the volume was disconnected, the mount was stale, or there were pending writes, check the filesystem with fsck or the appropriate repair tool before using it again.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_WRITING_DATA">Creating volume data. Please wait.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_WRITING_BACKUP_HEADER">Finalizing volume creation: writing backup header.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_FLUSHING_DATA">Finalizing volume creation: flushing data to disk. This can take several minutes on large volumes or slow/USB storage.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_FINISHED">Finalizing volume creation.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_ABORTED">Volume creation has been aborted.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_ERROR">Volume creation failed.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_PREPARING_TEMP_VOLUME">Finalizing volume creation: mounting temporary volume.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_PREPARING_TEMP_DEVICE">Finalizing volume creation: preparing temporary device.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_CREATING_FILESYSTEM">Finalizing volume creation: creating filesystem using {0}.</entry>
|
||||
<entry lang="en" key="FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME">Finalizing volume creation: dismounting temporary volume.</entry>
|
||||
</localization>
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="VeraCrypt">
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
namespace VeraCrypt
|
||||
{
|
||||
VolumeCreator::VolumeCreator ()
|
||||
: SizeDone (0)
|
||||
: SizeDone (0),
|
||||
Stage (ProgressStage::NotStarted),
|
||||
mProgressInfo {false, 0, 0, ProgressStage::NotStarted}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,6 +60,7 @@ namespace VeraCrypt
|
||||
if (filesystemSize < 1)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
Stage.Set (ProgressStage::WritingData);
|
||||
DataStart = Layout->GetDataOffset (HostSize);
|
||||
WriteOffset = DataStart;
|
||||
endOffset = DataStart + Layout->GetDataSize (HostSize);
|
||||
@@ -137,6 +140,8 @@ namespace VeraCrypt
|
||||
{
|
||||
SizeDone.Set (Options->Size);
|
||||
|
||||
Stage.Set (ProgressStage::WritingBackupHeader);
|
||||
|
||||
// Backup header
|
||||
SecureBuffer backupHeader (Layout->GetHeaderSize());
|
||||
|
||||
@@ -191,19 +196,26 @@ namespace VeraCrypt
|
||||
VolumeFile->Write (backupHeader);
|
||||
}
|
||||
|
||||
Stage.Set (ProgressStage::FlushingData);
|
||||
VolumeFile->Flush();
|
||||
Stage.Set (ProgressStage::Finished);
|
||||
}
|
||||
else
|
||||
Stage.Set (ProgressStage::Aborted);
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
Stage.Set (ProgressStage::Error);
|
||||
ThreadException.reset (e.CloneNew());
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
Stage.Set (ProgressStage::Error);
|
||||
ThreadException.reset (new ExternalException (SRC_POS, StringConverter::ToExceptionString (e)));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Stage.Set (ProgressStage::Error);
|
||||
ThreadException.reset (new UnknownException (SRC_POS));
|
||||
}
|
||||
|
||||
@@ -214,6 +226,9 @@ namespace VeraCrypt
|
||||
void VolumeCreator::CreateVolume (shared_ptr <VolumeCreationOptions> options)
|
||||
{
|
||||
EncryptionTest::TestAll();
|
||||
SizeDone.Set (0);
|
||||
Stage.Set (ProgressStage::NotStarted);
|
||||
ThreadException.reset();
|
||||
|
||||
{
|
||||
#ifdef TC_UNIX
|
||||
@@ -379,6 +394,9 @@ namespace VeraCrypt
|
||||
Options = options;
|
||||
AbortRequested = false;
|
||||
|
||||
mProgressInfo.TotalSize = options->Size;
|
||||
mProgressInfo.SizeDone = 0;
|
||||
mProgressInfo.Stage = ProgressStage::NotStarted;
|
||||
mProgressInfo.CreationInProgress = true;
|
||||
|
||||
struct ThreadFunctor : public Functor
|
||||
@@ -412,6 +430,7 @@ namespace VeraCrypt
|
||||
VolumeCreator::ProgressInfo VolumeCreator::GetProgressInfo ()
|
||||
{
|
||||
mProgressInfo.SizeDone = SizeDone.Get();
|
||||
mProgressInfo.Stage = static_cast <ProgressStage::Enum> (Stage.Get());
|
||||
return mProgressInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,11 +144,26 @@ namespace VeraCrypt
|
||||
{
|
||||
public:
|
||||
|
||||
struct ProgressStage
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
NotStarted = 0,
|
||||
WritingData,
|
||||
WritingBackupHeader,
|
||||
FlushingData,
|
||||
Finished,
|
||||
Aborted,
|
||||
Error
|
||||
};
|
||||
};
|
||||
|
||||
struct ProgressInfo
|
||||
{
|
||||
bool CreationInProgress;
|
||||
uint64 TotalSize;
|
||||
uint64 SizeDone;
|
||||
ProgressStage::Enum Stage;
|
||||
};
|
||||
|
||||
struct KeyInfo
|
||||
@@ -180,6 +195,7 @@ namespace VeraCrypt
|
||||
shared_ptr <VolumeLayout> Layout;
|
||||
shared_ptr <File> VolumeFile;
|
||||
SharedVal <uint64> SizeDone;
|
||||
SharedVal <int> Stage;
|
||||
uint64 WriteOffset;
|
||||
ProgressInfo mProgressInfo;
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ namespace VeraCrypt
|
||||
ProgressBarRange (1),
|
||||
RealProgressBarRange (1),
|
||||
VolumeCreatorRunning (false),
|
||||
MouseEventsCounter (0)
|
||||
MouseEventsCounter (0),
|
||||
CurrentProgressStage (VolumeCreator::ProgressStage::NotStarted),
|
||||
MaxStaticTextWidth (-1)
|
||||
{
|
||||
DisplayKeysCheckBox->SetValue (displayKeyInfo);
|
||||
#ifdef TC_WINDOWS
|
||||
@@ -170,9 +172,61 @@ namespace VeraCrypt
|
||||
|
||||
void VolumeCreationProgressWizardPage::SetMaxStaticTextWidth (int width)
|
||||
{
|
||||
MaxStaticTextWidth = width;
|
||||
InfoStaticText->Wrap (width);
|
||||
}
|
||||
|
||||
void VolumeCreationProgressWizardPage::SetPageText (const wxString &text)
|
||||
{
|
||||
InfoStaticText->SetLabel (text);
|
||||
|
||||
if (MaxStaticTextWidth > 0)
|
||||
InfoStaticText->Wrap (MaxStaticTextWidth);
|
||||
|
||||
Layout();
|
||||
if (GetParent())
|
||||
GetParent()->Layout();
|
||||
}
|
||||
|
||||
void VolumeCreationProgressWizardPage::SetProgressStage (VolumeCreator::ProgressStage::Enum stage)
|
||||
{
|
||||
if (stage == CurrentProgressStage)
|
||||
return;
|
||||
|
||||
CurrentProgressStage = stage;
|
||||
|
||||
switch (stage)
|
||||
{
|
||||
case VolumeCreator::ProgressStage::WritingData:
|
||||
SetPageText (LangString["FORMAT_STAGE_WRITING_DATA"]);
|
||||
break;
|
||||
|
||||
case VolumeCreator::ProgressStage::WritingBackupHeader:
|
||||
SetPageText (LangString["FORMAT_STAGE_WRITING_BACKUP_HEADER"]);
|
||||
break;
|
||||
|
||||
case VolumeCreator::ProgressStage::FlushingData:
|
||||
SetPageText (LangString["FORMAT_STAGE_FLUSHING_DATA"]);
|
||||
break;
|
||||
|
||||
case VolumeCreator::ProgressStage::Finished:
|
||||
SetPageText (LangString["FORMAT_STAGE_FINISHED"]);
|
||||
break;
|
||||
|
||||
case VolumeCreator::ProgressStage::Aborted:
|
||||
SetPageText (LangString["FORMAT_STAGE_ABORTED"]);
|
||||
break;
|
||||
|
||||
case VolumeCreator::ProgressStage::Error:
|
||||
SetPageText (LangString["FORMAT_STAGE_ERROR"]);
|
||||
break;
|
||||
|
||||
case VolumeCreator::ProgressStage::NotStarted:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeCreationProgressWizardPage::SetProgressState (bool volumeCreatorRunning)
|
||||
{
|
||||
if (volumeCreatorRunning)
|
||||
|
||||
@@ -30,8 +30,9 @@ namespace VeraCrypt
|
||||
void OnRandomPoolTimer ();
|
||||
void SetKeyInfo (const VolumeCreator::KeyInfo &keyInfo);
|
||||
void SetMaxStaticTextWidth (int width);
|
||||
void SetPageText (const wxString &text) { InfoStaticText->SetLabel (text); }
|
||||
void SetPageText (const wxString &text);
|
||||
void SetProgressRange (uint64 progressBarRange);
|
||||
void SetProgressStage (VolumeCreator::ProgressStage::Enum stage);
|
||||
void SetProgressValue (uint64 value);
|
||||
void SetProgressState (bool volumeCreatorRunning);
|
||||
void IncrementEntropyProgress ();
|
||||
@@ -54,6 +55,8 @@ namespace VeraCrypt
|
||||
bool VolumeCreatorRunning;
|
||||
int MouseEventsCounter;
|
||||
Mutex AccessMutex;
|
||||
VolumeCreator::ProgressStage::Enum CurrentProgressStage;
|
||||
int MaxStaticTextWidth;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -429,11 +429,14 @@ namespace VeraCrypt
|
||||
VolumeCreator::ProgressInfo progress = Creator->GetProgressInfo();
|
||||
|
||||
VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
|
||||
page->SetProgressValue (progress.SizeDone);
|
||||
if (page)
|
||||
{
|
||||
page->SetProgressStage (progress.Stage);
|
||||
page->SetProgressValue (progress.SizeDone);
|
||||
}
|
||||
|
||||
if (!progress.CreationInProgress && !AbortConfirmationPending)
|
||||
{
|
||||
SetWorkInProgress (false);
|
||||
OnVolumeCreatorFinished ();
|
||||
}
|
||||
}
|
||||
@@ -447,16 +450,29 @@ namespace VeraCrypt
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeCreationWizard::SetCreationProgressText (const wxString &text)
|
||||
{
|
||||
VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
|
||||
if (!page)
|
||||
return;
|
||||
|
||||
page->SetPageText (text);
|
||||
page->Refresh();
|
||||
page->Update();
|
||||
Gui->Yield();
|
||||
}
|
||||
|
||||
void VolumeCreationWizard::OnVolumeCreatorFinished ()
|
||||
{
|
||||
VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
|
||||
|
||||
ProgressTimer.reset();
|
||||
page->SetProgressState (false);
|
||||
|
||||
Gui->EndInteractiveBusyState (this);
|
||||
SetWorkInProgress (false);
|
||||
UpdateControls();
|
||||
if (page)
|
||||
{
|
||||
page->SetProgressState (false);
|
||||
page->EnableAbort (false);
|
||||
}
|
||||
bool workInProgressCleared = false;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -472,6 +488,8 @@ namespace VeraCrypt
|
||||
{
|
||||
wxBusyCursor busy;
|
||||
|
||||
SetCreationProgressText (LangString["FORMAT_STAGE_PREPARING_TEMP_VOLUME"]);
|
||||
|
||||
MountOptions mountOptions (Gui->GetPreferences().DefaultMountOptions);
|
||||
mountOptions.Path = make_shared <VolumePath> (SelectedVolumePath);
|
||||
mountOptions.NoFilesystem = true;
|
||||
@@ -483,10 +501,11 @@ namespace VeraCrypt
|
||||
|
||||
shared_ptr <VolumeInfo> volume = Core->MountVolume (mountOptions);
|
||||
finally_do_arg (shared_ptr <VolumeInfo>, volume, { Core->DismountVolume (finally_arg, true); });
|
||||
|
||||
|
||||
shared_ptr <VolumeLayout> layout((volume->Type == VolumeType::Normal)? (VolumeLayout*) new VolumeLayoutV2Normal() : (VolumeLayout*) new VolumeLayoutV2Hidden());
|
||||
uint64 filesystemSize = layout->GetMaxDataSize (VolumeSize);
|
||||
|
||||
SetCreationProgressText (LangString["FORMAT_STAGE_PREPARING_TEMP_DEVICE"]);
|
||||
Thread::Sleep (2000); // Try to prevent race conditions caused by OS
|
||||
|
||||
// Temporarily take ownership of the device if the user is not an administrator
|
||||
@@ -540,10 +559,16 @@ namespace VeraCrypt
|
||||
|
||||
args.push_back (string (virtualDevice));
|
||||
|
||||
SetCreationProgressText (StringFormatter (LangString["FORMAT_STAGE_CREATING_FILESYSTEM"], fsFormatter));
|
||||
Process::Execute (fsFormatter, args);
|
||||
SetCreationProgressText (LangString["FORMAT_STAGE_DISMOUNTING_TEMP_VOLUME"]);
|
||||
}
|
||||
#endif // TC_UNIX
|
||||
|
||||
Gui->EndInteractiveBusyState (this);
|
||||
SetWorkInProgress (false);
|
||||
workInProgressCleared = true;
|
||||
|
||||
if (OuterVolume)
|
||||
{
|
||||
SetStep (Step::OuterVolumeContents);
|
||||
@@ -559,10 +584,24 @@ namespace VeraCrypt
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
if (!workInProgressCleared)
|
||||
{
|
||||
Gui->EndInteractiveBusyState (this);
|
||||
SetWorkInProgress (false);
|
||||
workInProgressCleared = true;
|
||||
}
|
||||
Gui->ShowError (e);
|
||||
}
|
||||
|
||||
page->SetProgressValue (0);
|
||||
if (!workInProgressCleared)
|
||||
{
|
||||
Gui->EndInteractiveBusyState (this);
|
||||
SetWorkInProgress (false);
|
||||
}
|
||||
|
||||
if (page)
|
||||
page->SetProgressValue (0);
|
||||
|
||||
if (SelectedVolumeType == VolumeType::Normal && !SelectedVolumePath.IsDevice())
|
||||
{
|
||||
try
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace VeraCrypt
|
||||
void OnThreadExiting (wxCommandEvent& event);
|
||||
void OnVolumeCreatorFinished ();
|
||||
WizardStep ProcessPageChangeRequest (bool forward);
|
||||
void SetCreationProgressText (const wxString &text);
|
||||
|
||||
volatile bool AbortConfirmationPending;
|
||||
volatile bool AbortRequested;
|
||||
|
||||
Reference in New Issue
Block a user