VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Format/Tcformat.c
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2015-05-17 10:14:58 (GMT)
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2015-05-17 10:16:16 (GMT)
commitf72125ea71f98d0147bb742b48d1097844949c9e (patch)
tree836b63959937bb846553f7f851be9e5e405c1ea0 /src/Format/Tcformat.c
parent4695920b41e969bed138bfe2fe0d877b2abb36f6 (diff)
downloadVeraCrypt-f72125ea71f98d0147bb742b48d1097844949c9e.zip
VeraCrypt-f72125ea71f98d0147bb742b48d1097844949c9e.tar.gz
Windows: First implementation of non-system volumes decryption.
Diffstat (limited to 'src/Format/Tcformat.c')
-rw-r--r--src/Format/Tcformat.c488
1 files changed, 430 insertions, 58 deletions
diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c
index ba35c47..a0d9b29 100644
--- a/src/Format/Tcformat.c
+++ b/src/Format/Tcformat.c
@@ -94,8 +94,9 @@ enum wizard_pages
NONSYS_INPLACE_ENC_RESUME_PARTITION_SEL_PAGE,
NONSYS_INPLACE_ENC_RAND_DATA_PAGE,
NONSYS_INPLACE_ENC_WIPE_MODE_PAGE,
- NONSYS_INPLACE_ENC_ENCRYPTION_PAGE,
- NONSYS_INPLACE_ENC_ENCRYPTION_FINISHED_PAGE,
+ NONSYS_INPLACE_ENC_TRANSFORM_PAGE,
+ NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE,
+ NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE,
FORMAT_PAGE,
FORMAT_FINISHED_PAGE,
SYSENC_HIDDEN_OS_INITIAL_INFO_PAGE,
@@ -148,10 +149,13 @@ volatile BOOL bHiddenOS = FALSE; /* If TRUE, we are performing or (or supposed
BOOL bDirectSysEncMode = FALSE;
BOOL bDirectSysEncModeCommand = SYSENC_COMMAND_NONE;
BOOL DirectDeviceEncMode = FALSE;
+BOOL DirectNonSysInplaceDecStartMode = FALSE;
BOOL DirectNonSysInplaceEncResumeMode = FALSE;
+BOOL DirectNonSysInplaceDecResumeMode = FALSE;
BOOL DirectPromptNonSysInplaceEncResumeMode = FALSE;
-volatile BOOL bInPlaceEncNonSys = FALSE; /* If TRUE, existing data on a non-system partition/volume are to be encrypted (for system encryption, this flag is ignored) */
-volatile BOOL bInPlaceEncNonSysResumed = FALSE; /* If TRUE, the wizard is supposed to resume (or has resumed) process of non-system in-place encryption. */
+volatile BOOL bInPlaceEncNonSys = FALSE; /* If TRUE, existing data on a non-system partition/volume are to be encrypted (or decrypted if bInPlaceDecNonSys is TRUE) in place (for system encryption, this flag is ignored) */
+volatile BOOL bInPlaceDecNonSys = FALSE; /* If TRUE, existing data on a non-system partition/volume are to be decrypted in place (for system encryption, this flag is ignored) */
+volatile BOOL bInPlaceEncNonSysResumed = FALSE; /* If TRUE, the wizard is supposed to resume (or has resumed) process of non-system in-place encryption/decryption. */
volatile BOOL bFirstNonSysInPlaceEncResumeDone = FALSE;
__int64 NonSysInplaceEncBytesDone = 0;
__int64 NonSysInplaceEncTotalSize = 0;
@@ -657,7 +661,10 @@ static BOOL ChangeWizardMode (int newWizardMode)
}
if (newWizardMode != WIZARD_MODE_NONSYS_DEVICE)
+ {
bInPlaceEncNonSys = FALSE;
+ bInPlaceDecNonSys = FALSE;
+ }
if (newWizardMode == WIZARD_MODE_NONSYS_DEVICE && !IsAdmin() && IsUacSupported())
{
@@ -666,7 +673,8 @@ static BOOL ChangeWizardMode (int newWizardMode)
}
// The contents of the following items may be inappropriate after a change of mode
- szFileName[0] = 0;
+ if (! (bInPlaceDecNonSys && !bInPlaceEncNonSysResumed)) // If we are starting (but not resuming) decryption of non-system volume, we actually need szFileName as it contains the command line param.
+ szFileName[0] = 0;
szDiskFile[0] = 0;
nUIVolumeSize = 0;
nVolumeSize = 0;
@@ -1067,6 +1075,7 @@ BOOL SwitchWizardToHiddenOSMode (void)
bHiddenVolDirect = FALSE;
bWholeSysDrive = FALSE;
bInPlaceEncNonSys = FALSE;
+ bInPlaceDecNonSys = FALSE;
if (bDirectSysEncModeCommand == SYSENC_COMMAND_CREATE_HIDDEN_OS_ELEV)
{
@@ -1102,11 +1111,11 @@ BOOL SwitchWizardToHiddenOSMode (void)
return TRUE;
}
-void SwitchWizardToNonSysInplaceEncResumeMode (void)
+void SwitchWizardToNonSysInplaceEncResumeMode (BOOL bDecrypt)
{
if (!IsAdmin() && IsUacSupported())
{
- if (!ElevateWholeWizardProcess ("/zinplace"))
+ if (!ElevateWholeWizardProcess (bDecrypt ? "/resumeinplacedec" : "/zinplace"))
AbortProcessSilent ();
}
@@ -1116,6 +1125,7 @@ void SwitchWizardToNonSysInplaceEncResumeMode (void)
CreateNonSysInplaceEncMutex ();
bInPlaceEncNonSys = TRUE;
+ bInPlaceDecNonSys = bDecrypt;
bInPlaceEncNonSysResumed = TRUE;
ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE);
@@ -1123,6 +1133,31 @@ void SwitchWizardToNonSysInplaceEncResumeMode (void)
LoadPage (MainDlg, NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE);
}
+void SwitchWizardToNonSysInplaceDecStartMode (char *volPath)
+{
+ if (!IsAdmin() && IsUacSupported())
+ {
+ if (!ElevateWholeWizardProcess ((string ("/inplacedec \"") + volPath + "\"").c_str()))
+ AbortProcessSilent ();
+ }
+
+ if (!IsAdmin())
+ AbortProcess("ADMIN_PRIVILEGES_WARN_DEVICES");
+
+ if (!CheckRequirementsForNonSysInPlaceDec (MainDlg, volPath, FALSE))
+ AbortProcessSilent ();
+
+ CreateNonSysInplaceEncMutex ();
+
+ bInPlaceEncNonSys = TRUE;
+ bInPlaceDecNonSys = TRUE;
+ bInPlaceEncNonSysResumed = FALSE;
+
+ ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE);
+
+ LoadPage (MainDlg, NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE);
+}
+
// Use this function e.g. if the config file with the system encryption settings was lost or not written
// correctly, and we don't know whether to encrypt or decrypt (but we know that encryption or decryption
// is required). Returns FALSE if failed or cancelled.
@@ -1730,6 +1765,7 @@ static void SysEncResume (void)
return;
}
+ bVolTransformThreadCancel = FALSE;
bSystemEncryptionInProgress = FALSE;
WaitCursor ();
@@ -1906,6 +1942,9 @@ void ShowNonSysInPlaceEncUIStatus (void)
case NONSYS_INPLACE_ENC_STATUS_ENCRYPTING:
StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_ENCRYPTING"));
break;
+ case NONSYS_INPLACE_ENC_STATUS_DECRYPTING:
+ StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_DECRYPTING"));
+ break;
case NONSYS_INPLACE_ENC_STATUS_FINALIZING:
StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_FINALIZING"));
break;
@@ -1925,12 +1964,28 @@ void ShowNonSysInPlaceEncUIStatus (void)
void UpdateNonSysInPlaceEncControls (void)
{
- EnableWindow (GetDlgItem (hCurPage, IDC_WIPE_MODE), !(bVolTransformThreadRunning || bVolTransformThreadToRun));
+ // Reduce flickering by updating a GUI element only when a relevant change affects it
+ static BOOL lastbVolTransformThreadRunning = !bVolTransformThreadRunning;
+ static BOOL lastbVolTransformThreadToRun = !bVolTransformThreadToRun;
+ static BOOL lastbInPlaceEncNonSysResumed = !bInPlaceEncNonSysResumed;
- SetWindowTextW (GetDlgItem (hCurPage, IDC_PAUSE),
- GetString ((bVolTransformThreadRunning || bVolTransformThreadToRun) ? "IDC_PAUSE" : "RESUME"));
+ EnableWindow (GetDlgItem (hCurPage, IDC_WIPE_MODE), !(bVolTransformThreadRunning || bVolTransformThreadToRun) && !bInPlaceDecNonSys);
+
+ if (lastbVolTransformThreadRunning != bVolTransformThreadRunning
+ || lastbVolTransformThreadToRun != bVolTransformThreadToRun)
+ {
+ SetWindowTextW (GetDlgItem (hCurPage, IDC_PAUSE),
+ GetString ((bVolTransformThreadRunning || bVolTransformThreadToRun) ? "IDC_PAUSE" : "RESUME"));
- SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString (bInPlaceEncNonSysResumed ? "DEFER" : "CANCEL"));
+ lastbVolTransformThreadRunning = bVolTransformThreadRunning;
+ lastbVolTransformThreadToRun = bVolTransformThreadToRun;
+ }
+
+ if (lastbInPlaceEncNonSysResumed != bInPlaceEncNonSysResumed)
+ {
+ SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString (bInPlaceEncNonSysResumed ? "DEFER" : "CANCEL"));
+ lastbInPlaceEncNonSysResumed = bInPlaceEncNonSysResumed;
+ }
EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), bFirstNonSysInPlaceEncResumeDone
&& NonSysInplaceEncStatus != NONSYS_INPLACE_ENC_STATUS_FINALIZING
@@ -1995,11 +2050,12 @@ static void UpdateNonSysInplaceEncProgressBar (void)
if (bVolTransformThreadRunning
&& (nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_ENCRYPTING
+ || nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_DECRYPTING
|| nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINALIZING
|| nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED))
{
if (lastNonSysInplaceEncStatus != nonSysInplaceEncStatus
- && nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_ENCRYPTING)
+ && (nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_ENCRYPTING || nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_DECRYPTING))
{
InitNonSysInplaceEncProgressBar ();
}
@@ -2033,7 +2089,7 @@ static void InitNonSysInplaceEncProgressBar (void)
InitProgressBar (totalSize,
NonSysInplaceEncBytesDone,
- FALSE,
+ bInPlaceDecNonSys,
TRUE,
TRUE,
TRUE);
@@ -2436,7 +2492,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
volParams->hiddenVolHostSize = nHiddenVolHostSize;
volParams->ea = nVolumeEA;
volParams->pkcs5 = hash_algo;
- volParams->headerFlags = CreatingHiddenSysVol() ? TC_HEADER_FLAG_ENCRYPTED_SYSTEM : 0;
+ volParams->headerFlags = (CreatingHiddenSysVol() ? TC_HEADER_FLAG_ENCRYPTED_SYSTEM : 0);
volParams->fileSystem = fileSystem;
volParams->clusterSize = clusterSize;
volParams->sparseFileSwitch = bSparseFileSwitch;
@@ -2446,8 +2502,19 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
volParams->password = &volumePassword;
volParams->hwndDlg = hwndDlg;
- if (bInPlaceEncNonSys)
+ if (bInPlaceDecNonSys)
{
+ // In-place decryption of non-system volume
+
+ if (!bInPlaceEncNonSysResumed)
+ DiscardUnreadableEncryptedSectors = FALSE;
+
+ nStatus = DecryptPartitionInPlace (volParams, &DiscardUnreadableEncryptedSectors);
+ }
+ else if (bInPlaceEncNonSys)
+ {
+ // In-place encryption of non-system volume
+
HANDLE hPartition = INVALID_HANDLE_VALUE;
SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PREPARING);
@@ -2475,6 +2542,8 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
}
else
{
+ // Format-encryption
+
InitProgressBar (GetVolumeDataAreaSize (bHidden, nVolumeSize), 0, FALSE, FALSE, FALSE, TRUE);
nStatus = TCFormatVolume (volParams);
@@ -2492,7 +2561,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
&& nStatus == ERR_USER_ABORT
&& NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED)
{
- // Ignore user abort if non-system in-place encryption successfully finished
+ // Ignore user abort if non-system in-place encryption/decryption successfully finished
nStatus = ERR_SUCCESS;
}
@@ -2519,7 +2588,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
SetLastError (dwWin32FormatError);
if ((bVolTransformThreadCancel || nStatus == ERR_USER_ABORT)
- && !(bInPlaceEncNonSys && NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED)) // Ignore user abort if non-system in-place encryption successfully finished.
+ && !(bInPlaceEncNonSys && NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED)) // Ignore user abort if non-system in-place encryption/decryption successfully finished.
{
if (!bDevice && !(bHiddenVol && !bHiddenVolHost)) // If we're not creating a hidden volume and if it's a file container
{
@@ -2549,7 +2618,11 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
else
{
SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_ERROR);
- ShowInPlaceEncErrMsgWAltSteps (hwndDlg, "INPLACE_ENC_GENERIC_ERR_ALT_STEPS", TRUE);
+
+ if (bInPlaceDecNonSys)
+ Error ("INPLACE_DEC_GENERIC_ERR", hwndDlg);
+ else
+ ShowInPlaceEncErrMsgWAltSteps (hwndDlg, "INPLACE_ENC_GENERIC_ERR_ALT_STEPS", TRUE);
}
}
else if (!(bHiddenVolHost && hiddenVolHostDriveNo < 0)) // If the error was not that the hidden volume host could not be mounted (this error has already been reported to the user)
@@ -2589,9 +2662,16 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
}
else if (bInPlaceEncNonSys)
{
- Warning ("NONSYS_INPLACE_ENC_FINISHED_INFO", hwndDlg);
+ if (!bInPlaceDecNonSys)
+ {
+ Warning ("NONSYS_INPLACE_ENC_FINISHED_INFO", hwndDlg);
- HandleOldAssignedDriveLetter ();
+ HandleOldAssignedDriveLetter ();
+ }
+ else
+ {
+ // NOP - Final steps for in-place decryption are handled with the TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED message.
+ }
}
else
{
@@ -2868,16 +2948,21 @@ static void LoadPage (HWND hwndDlg, int nPageNo)
(DLGPROC) PageDialogProc);
break;
- case NONSYS_INPLACE_ENC_ENCRYPTION_PAGE:
+ case NONSYS_INPLACE_ENC_TRANSFORM_PAGE:
hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INPLACE_ENCRYPTION_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
break;
- case NONSYS_INPLACE_ENC_ENCRYPTION_FINISHED_PAGE:
+ case NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE:
hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
break;
+ case NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_DRIVE_LETTER_SELECTION_PAGE), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
case FORMAT_PAGE:
hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_FORMAT_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
@@ -3272,7 +3357,7 @@ static BOOL FinalPreTransformPrompts (void)
if (bHiddenOS && bHiddenVolHost)
StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("OVERWRITEPROMPT_DEVICE_HIDDEN_OS_PARTITION"), szFileName, drive);
else
- StringCbPrintfW (szTmp, sizeof(szTmp), GetString (bInPlaceEncNonSys ? "NONSYS_INPLACE_ENC_CONFIRM" : "OVERWRITEPROMPT_DEVICE"), type, szFileName, drive);
+ StringCbPrintfW (szTmp, sizeof(szTmp), GetString (bInPlaceEncNonSys ? (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_CONFIRM" : "NONSYS_INPLACE_ENC_CONFIRM") : "OVERWRITEPROMPT_DEVICE"), type, szFileName, drive);
x = MessageBoxW (MainDlg, szTmp, lpszTitle, YES_NO | MB_ICONWARNING | (bInPlaceEncNonSys ? MB_DEFBUTTON1 : MB_DEFBUTTON2));
@@ -3339,6 +3424,15 @@ static BOOL FinalPreTransformPrompts (void)
return TRUE;
}
+void UpdateLastDialogId (void)
+{
+ static char PageDebugId[128];
+
+ StringCbPrintfA (PageDebugId, sizeof(PageDebugId), "FORMAT_PAGE_%d", nCurPageNo);
+ LastDialogId = PageDebugId;
+}
+
+
void HandleOldAssignedDriveLetter (void)
{
if (bDevice)
@@ -3381,7 +3475,6 @@ static BOOL FileSize4GBLimitQuestionNeeded (void)
not. - see DialogProc */
BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- static char PageDebugId[128];
WORD lw = LOWORD (wParam);
WORD hw = HIWORD (wParam);
@@ -3392,8 +3485,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
case WM_INITDIALOG:
LocalizeDialog (hwndDlg, "IDD_VOL_CREATION_WIZARD_DLG");
- StringCbPrintfA (PageDebugId, sizeof(PageDebugId), "FORMAT_PAGE_%d", nCurPageNo);
- LastDialogId = PageDebugId;
+ UpdateLastDialogId ();
switch (nCurPageNo)
{
@@ -3974,7 +4066,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceEncNonSys ? "NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE_HELP" : "PASSWORD_HIDDENVOL_HOST_DIRECT_HELP"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceEncNonSys ? (bInPlaceEncNonSysResumed ? "NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE_HELP" : "NONSYS_INPLACE_DEC_PASSWORD_PAGE_HELP") : "PASSWORD_HIDDENVOL_HOST_DIRECT_HELP"));
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bInPlaceEncNonSys ? "PASSWORD" : "PASSWORD_HIDVOL_HOST_TITLE"));
@@ -4367,7 +4459,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
break;
- case NONSYS_INPLACE_ENC_ENCRYPTION_PAGE:
+ case NONSYS_INPLACE_ENC_TRANSFORM_PAGE:
if (bInPlaceEncNonSysResumed)
{
@@ -4377,19 +4469,19 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
nWipeMode = savedWipeAlgorithm;
}
- SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("ENCRYPTION"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bInPlaceDecNonSys ? "DECRYPTION" : "ENCRYPTION"));
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("NONSYS_INPLACE_ENC_ENCRYPTION_PAGE_INFO"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_DECRYPTION_PAGE_INFO" : "NONSYS_INPLACE_ENC_ENCRYPTION_PAGE_INFO"));
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString (bInPlaceEncNonSysResumed ? "DEFER" : "CANCEL"));
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
- SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString (bInPlaceEncNonSysResumed ? "RESUME" : "ENCRYPT"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString (bInPlaceEncNonSysResumed ? "RESUME" : (bInPlaceDecNonSys ? "DECRYPT" : "ENCRYPT")));
SetWindowTextW (GetDlgItem (hwndDlg, IDC_PAUSE), GetString ("IDC_PAUSE"));
- EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), !bInPlaceEncNonSysResumed);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), !bInPlaceEncNonSysResumed && !bInPlaceDecNonSys);
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
@@ -4397,19 +4489,28 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
ShowWindow (GetDlgItem (hwndDlg, IDC_MORE_INFO_SYS_ENCRYPTION), SW_HIDE);
- EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_MODE), TRUE);
- PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, TRUE, FALSE);
- SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &nWipeMode);
+ if (bInPlaceDecNonSys)
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDT_FORMAT_OPTIONS), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDT_WIPE_MODE), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_WIPE_MODE), SW_HIDE);
+ }
+ else
+ {
+ EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_MODE), TRUE);
+ PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, TRUE, FALSE);
+ SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &nWipeMode);
+ }
break;
- case NONSYS_INPLACE_ENC_ENCRYPTION_FINISHED_PAGE:
+ case NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE:
bConfirmQuit = FALSE;
- SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("NONSYS_INPLACE_ENC_FINISHED_TITLE"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_FINISHED_TITLE" : "NONSYS_INPLACE_ENC_FINISHED_TITLE"));
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("NONSYS_INPLACE_ENC_FINISHED_INFO"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_FINISHED_INFO" : "NONSYS_INPLACE_ENC_FINISHED_INFO"));
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("FINALIZE"));
@@ -4421,6 +4522,54 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
break;
+ case NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE:
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("NONSYS_INPLACE_DEC_FINISHED_TITLE"));
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("NONSYS_INPLACE_DEC_FINISHED_DRIVE_LETTER_SEL_INFO"));
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("FINALIZE"));
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
+
+ // The Cancel button and the X button must be disabled to prevent the user from forgetting to assign a drive letter to the partition by closing
+ // the window accidentally or clicking Cancel. The user is forced to click Finish to assign at least the pre-selected free drive letter.
+ // This is critical because inexperienced users would not know how to access data on the decrypted volume without a drive letter.
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), FALSE);
+ DisableCloseButton (MainDlg);
+ bConfirmQuit = TRUE; // Alt-F4 will still work but the user will be prompted to confirm the action.
+
+ // Decryption of non-system volume finished, no drive letter is assigned to the decrypted volume, and free drive letters are available.
+ // This is critical because inexperienced users would not know how to access data on the decrypted volume. We cannot allow exit
+ // until a drive letter is freed up and assigned to the decrypted volume.
+
+ while (GetFirstAvailableDrive () == -1)
+ {
+ Error ("NONSYS_INPLACE_DEC_FINISHED_NO_DRIVE_LETTER_AVAILABLE", hwndDlg);
+ }
+
+ // Populate the combobox with free drive letters
+ {
+ DWORD dwUsedDrives = GetLogicalDrives();
+ char szDriveLetter[] = {' ', ':', 0 };
+ int i;
+
+ for (i = 0; i < 26; i++)
+ {
+ if (!(dwUsedDrives & 1 << i))
+ {
+ // Add
+ szDriveLetter [0] = (char) (i + 'A');
+ AddComboPair (GetDlgItem (hCurPage, IDC_DRIVE_LETTER_LIST), szDriveLetter, i);
+ }
+ }
+ }
+ SendMessage (GetDlgItem (hwndDlg, IDC_DRIVE_LETTER_LIST), CB_SETCURSEL, 0, 0);
+ break;
+
case FORMAT_PAGE:
{
BOOL bNTFSallowed = FALSE;
@@ -4967,7 +5116,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
break;
- case NONSYS_INPLACE_ENC_ENCRYPTION_PAGE:
+ case NONSYS_INPLACE_ENC_TRANSFORM_PAGE:
{
switch (lw)
{
@@ -5664,6 +5813,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
KillTimer (hwndDlg, TIMER_ID_SYSENC_PROGRESS);
+ UpdateLastDialogId ();
+
try
{
if (BootEncStatus.DriveMounted) // If we had been really encrypting/decrypting (not just proceeding to deinstall)
@@ -5788,6 +5939,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (!bVolTransformThreadRunning && !bVolTransformThreadToRun)
{
KillTimer (hwndDlg, TIMER_ID_NONSYS_INPLACE_ENC_PROGRESS);
+
+ UpdateLastDialogId ();
}
UpdateNonSysInPlaceEncControls ();
@@ -5927,6 +6080,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
// The driver stopped wiping
KillTimer (hwndDlg, TIMER_ID_WIPE_PROGRESS);
+ UpdateLastDialogId ();
try
{
@@ -6010,8 +6164,29 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
KillTimer (hwndDlg, TIMER_ID_NONSYS_INPLACE_ENC_PROGRESS);
- LoadPage (hwndDlg, NONSYS_INPLACE_ENC_ENCRYPTION_FINISHED_PAGE);
+ if (bInPlaceDecNonSys)
+ {
+ // Decryption of non-system volume finished and free drive letters are available. Check if a drive letter is assigned to the decrypted volume.
+
+ WCHAR deviceName[MAX_PATH + 1];
+ StringCbCopyA ((char *)deviceName, sizeof(deviceName), szDiskFile);
+ ToUNICODE ((char *)deviceName, sizeof(deviceName));
+
+ if (GetDiskDeviceDriveLetter (deviceName) < 0)
+ {
+ // No drive letter is assigned to the device
+ MessageBeep (MB_OK);
+ LoadPage (hwndDlg, NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE);
+ return 1;
+ }
+ else
+ {
+ Info ("NONSYS_INPLACE_DEC_FINISHED_INFO", hwndDlg);
+ }
+ }
+
+ LoadPage (hwndDlg, NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE);
return 1;
case TC_APPMSG_VOL_TRANSFORM_THREAD_ENDED:
@@ -6050,7 +6225,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
case TC_APPMSG_FORMAT_USER_QUIT:
- if (nCurPageNo == NONSYS_INPLACE_ENC_ENCRYPTION_PAGE
+ if (nCurPageNo == NONSYS_INPLACE_ENC_TRANSFORM_PAGE
&& (bVolTransformThreadRunning || bVolTransformThreadToRun || bInPlaceEncNonSysResumed))
{
// Non-system encryption in progress
@@ -6970,10 +7145,10 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
}
}
- else
+ else if (bInPlaceEncNonSysResumed)
{
/* Scan all available partitions to discover all partitions where non-system in-place
- encryption has been interrupted. */
+ encryption/decryption has been interrupted. */
BOOL tmpbDevice;
@@ -7002,12 +7177,115 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
return 1;
}
- nNewPageNo = NONSYS_INPLACE_ENC_ENCRYPTION_PAGE - 1; // Skip irrelevant pages
+ nNewPageNo = NONSYS_INPLACE_ENC_TRANSFORM_PAGE - 1; // Skip irrelevant pages
}
NormalCursor();
}
+ else
+ {
+ /* Try to mount the non-system volume to decrypt in place (the process has not started yet, we are NOT trying to resume it).
+ We will try to mount it using the backup header, which we require to work (i.e. be non-damaged) before we start writing
+ to the volume (the primary header will be overwritten by decrypted data soon after the decryption process begins, so the
+ backup header will contain the only copy of the master key). */
+
+ int driveNo = -1;
+
+ // The volume may already be mounted. We need to dismount it first in order to verify the supplied password/keyfile(s) is/are correct.
+ if (IsMountedVolume (szFileName))
+ {
+ driveNo = GetMountedVolumeDriveNo (szFileName);
+
+ if (driveNo == -1
+ || !UnmountVolume (hwndDlg, driveNo, TRUE))
+ {
+ handleWin32Error (MainDlg);
+ AbortProcess ("CANT_DISMOUNT_VOLUME");
+ }
+ }
+
+ driveNo = GetLastAvailableDrive ();
+
+ if (driveNo < 0)
+ AbortProcess ("NO_FREE_DRIVES");
+
+ MountOptions mountOptions;
+ ZeroMemory (&mountOptions, sizeof (mountOptions));
+
+ mountOptions.UseBackupHeader = FALSE; // This must be FALSE at this point because otherwise we wouldn't be able to detect a legacy volume
+ mountOptions.ReadOnly = TRUE;
+ mountOptions.Removable = ConfigReadInt ("MountVolumesRemovable", FALSE);
+
+ // Check that it is not a hidden or legacy volume
+
+ if (MountVolume (hwndDlg, driveNo, szFileName, &volumePassword, hash_algo, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
+ {
+ NormalCursor();
+ return 1;
+ }
+
+ {
+ DWORD dwResult;
+ VOLUME_PROPERTIES_STRUCT volProp;
+
+ memset (&volProp, 0, sizeof(volProp));
+ volProp.driveNo = driveNo;
+ if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &volProp, sizeof (volProp), &volProp, sizeof (volProp), &dwResult, NULL) || dwResult == 0)
+ {
+ handleWin32Error (hwndDlg);
+ UnmountVolume (hwndDlg, driveNo, TRUE);
+ AbortProcess ("CANT_GET_VOL_INFO");
+ }
+
+ if (volProp.volFormatVersion == TC_VOLUME_FORMAT_VERSION_PRE_6_0)
+ {
+ UnmountVolume (hwndDlg, driveNo, TRUE);
+ AbortProcess ("NONSYS_INPLACE_DECRYPTION_BAD_VOL_FORMAT");
+ }
+
+ if (volProp.hiddenVolume)
+ {
+ UnmountVolume (hwndDlg, driveNo, TRUE);
+ AbortProcess ("NONSYS_INPLACE_DECRYPTION_CANT_DECRYPT_HID_VOL");
+ }
+ }
+
+ // Remount the volume using the backup header to verify it is working
+
+ if (!UnmountVolume (hwndDlg, driveNo, TRUE))
+ {
+ handleWin32Error (MainDlg);
+ AbortProcess ("CANT_DISMOUNT_VOLUME");
+ }
+
+ mountOptions.UseBackupHeader = TRUE; // This must be TRUE at this point (we won't be using the regular header, which will be lost soon after the decryption process starts)
+
+ if (MountVolume (hwndDlg, driveNo, szFileName, &volumePassword, hash_algo, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
+ {
+ NormalCursor();
+ return 1;
+ }
+
+ if (!UnmountVolume (hwndDlg, driveNo, TRUE))
+ {
+ handleWin32Error (MainDlg);
+ AbortProcess ("CANT_DISMOUNT_VOLUME");
+ }
+
+ BOOL tmpbDevice;
+
+ CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), szFileName, &tmpbDevice);
+
+ nVolumeSize = GetDeviceSize (szDiskFile);
+ if (nVolumeSize == -1)
+ {
+ handleWin32Error (MainDlg);
+ AbortProcessSilent ();
+ }
+ nNewPageNo = NONSYS_INPLACE_ENC_TRANSFORM_PAGE - 1; // Skip irrelevant pages
+ NormalCursor();
+ }
}
else if (nCurPageNo == FILESYS_PAGE)
@@ -7312,20 +7590,76 @@ retryCDDriveCheck:
}
else if (nCurPageNo == NONSYS_INPLACE_ENC_RESUME_PARTITION_SEL_PAGE)
{
- nNewPageNo = NONSYS_INPLACE_ENC_ENCRYPTION_PAGE - 1; // Skip irrelevant pages
+ nNewPageNo = NONSYS_INPLACE_ENC_TRANSFORM_PAGE - 1; // Skip irrelevant pages
}
- else if (nCurPageNo == NONSYS_INPLACE_ENC_ENCRYPTION_PAGE)
+ else if (nCurPageNo == NONSYS_INPLACE_ENC_TRANSFORM_PAGE)
{
/* In-place encryption start (the 'Next' button has been clicked) */
+ if (bInPlaceDecNonSys
+ && !bInPlaceEncNonSysResumed
+ && AskWarnYesNo ("NONSYS_INPLACE_ENC_CONFIRM_BACKUP", hwndDlg) == IDNO)
+ {
+ // Cancel
+ return 1;
+ }
NonSysInplaceEncResume ();
return 1;
}
- else if (nCurPageNo == NONSYS_INPLACE_ENC_ENCRYPTION_FINISHED_PAGE)
+ else if (nCurPageNo == NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE)
{
PostMessage (hwndDlg, TC_APPMSG_FORMAT_USER_QUIT, 0, 0);
return 1;
}
+ else if (nCurPageNo == NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE)
+ {
+ BOOL bDrvLetterAssignResult = FALSE;
+
+ int tmpDriveLetter = (int) SendMessage (GetDlgItem (hCurPage, IDC_DRIVE_LETTER_LIST),
+ CB_GETITEMDATA,
+ SendMessage (GetDlgItem (hCurPage, IDC_DRIVE_LETTER_LIST), CB_GETCURSEL, 0, 0),
+ 0);
+
+ if (tmpDriveLetter < 0)
+ tmpDriveLetter = GetFirstAvailableDrive ();
+
+ do
+ {
+ char szDriveLetter[] = {'A', ':', 0 };
+ char rootPath[] = {'A', ':', '\\', 0 };
+ char uniqVolName[MAX_PATH+1] = { 0 };
+
+ rootPath[0] += (char) tmpDriveLetter;
+ szDriveLetter[0] += (char) tmpDriveLetter;
+
+ if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, szDiskFile))
+ {
+ bDrvLetterAssignResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH);
+
+ DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE,
+ szDriveLetter,
+ szDiskFile);
+
+ if (bDrvLetterAssignResult)
+ {
+ if (SetVolumeMountPoint (rootPath, uniqVolName) == 0)
+ bDrvLetterAssignResult = FALSE;
+ }
+ }
+
+ if (!bDrvLetterAssignResult)
+ {
+ if (AskErrYesNo ("ERR_CANNOT_ASSIGN_DRIVE_LETTER_NONSYS_DEC", hwndDlg) == IDNO)
+ break;
+ }
+
+ } while (bDrvLetterAssignResult == FALSE);
+
+ bConfirmQuit = FALSE;
+
+ PostMessage (hwndDlg, TC_APPMSG_FORMAT_USER_QUIT, 0, 0);
+ return 1;
+ }
else if (nCurPageNo == FORMAT_PAGE)
{
/* Format start (the 'Next' button has been clicked on the Format page) */
@@ -7906,26 +8240,33 @@ void ExtractCommandLine (HWND hwndDlg, char *lpszCommandLine)
CommandDecryptSysEnc,
CommandEncDev,
CommandHiddenSys,
- CommandResumeInplaceLogOn,
+ CommandResumeNonSysInplaceLogOn,
CommandResumeHiddenSys,
CommandSysEnc,
+ CommandInplaceDec,
+ CommandResumeInplaceDec,
CommandResumeInplace,
};
argument args[]=
{
+ // Public
{ OptionHistory, "/history", "/h", FALSE },
{ OptionNoIsoCheck, "/noisocheck", "/n", FALSE },
{ OptionTokenLib, "/tokenlib", NULL, FALSE },
{ OptionQuit, "/quit", "/q", FALSE },
+
+ // Internal
{ CommandResumeSysEncLogOn, "/acsysenc", "/a", TRUE },
{ CommandResumeSysEnc, "/csysenc", "/c", TRUE },
{ CommandDecryptSysEnc, "/dsysenc", "/d", TRUE },
{ CommandEncDev, "/encdev", "/e", TRUE },
{ CommandHiddenSys, "/isysenc", "/i", TRUE },
- { CommandResumeInplaceLogOn, "/prinplace", "/p", TRUE },
+ { CommandResumeNonSysInplaceLogOn, "/prinplace", "/p", TRUE },
{ CommandResumeHiddenSys, "/risysenc", "/r", TRUE },
{ CommandSysEnc, "/sysenc", "/s", TRUE },
+ { CommandInplaceDec, "/inplacedec", NULL, TRUE },
+ { CommandResumeInplaceDec, "/resumeinplacedec",NULL, TRUE },
{ CommandResumeInplace, "/zinplace", "/z", TRUE }
};
@@ -8053,12 +8394,36 @@ void ExtractCommandLine (HWND hwndDlg, char *lpszCommandLine)
DirectDeviceEncMode = TRUE;
break;
+ case CommandInplaceDec:
+ // Start (not resume) decrypting the specified non-system volume in place
+ {
+ char szTmp [TC_MAX_PATH + 8000] = {0};
+
+ GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, sizeof (szTmp));
+
+ if (strlen (szTmp) < 1)
+ {
+ // No valid volume path specified as command-line parameter
+ AbortProcess ("ERR_PARAMETER_INCORRECT");
+ }
+
+ memset (szFileName, 0, sizeof (szFileName));
+ StringCbCopyA (szFileName, sizeof (szFileName), szTmp);
+ DirectNonSysInplaceDecStartMode = TRUE;
+ }
+ break;
+
case CommandResumeInplace:
// Resume interrupted process of non-system in-place encryption of a partition
DirectNonSysInplaceEncResumeMode = TRUE;
break;
- case CommandResumeInplaceLogOn:
+ case CommandResumeInplaceDec:
+ // Resume interrupted process of non-system in-place decryption of a partition
+ DirectNonSysInplaceDecResumeMode = TRUE;
+ break;
+
+ case CommandResumeNonSysInplaceLogOn:
// Ask the user whether to resume interrupted process of non-system in-place encryption of a partition
// This switch is passed only by the system (from the startup sequence).
DirectPromptNonSysInplaceEncResumeMode = TRUE;
@@ -8641,7 +9006,7 @@ static void AfterWMInitTasks (HWND hwndDlg)
else
{
// Nothing to resume
- Warning ("NOTHING_TO_RESUME", hwndDlg);
+ Warning ("NO_SYS_ENC_PROCESS_TO_RESUME", hwndDlg);
EndMainDlg (MainDlg);
return;
@@ -8985,7 +9350,7 @@ static void AfterWMInitTasks (HWND hwndDlg)
&& !bInPlaceEncNonSysPending)
{
// This instance of the wizard has been launched via the system startup sequence to prompt for resume of
- // a non-system in-place encryption process. However, no config file indicates that any such process
+ // a non-system in-place encryption/decryption process. However, no config file indicates that any such process
// has been interrupted. This inconsistency may occur, for example, when the process is finished
// but the wizard is not removed from the startup sequence because system encryption is in progress.
// Therefore, we remove it from the startup sequence now if possible.
@@ -8996,9 +9361,16 @@ static void AfterWMInitTasks (HWND hwndDlg)
AbortProcessSilent ();
}
- if (DirectNonSysInplaceEncResumeMode)
+ BOOL bDecrypt = FALSE;
+
+ if (DirectNonSysInplaceDecStartMode)
+ {
+ SwitchWizardToNonSysInplaceDecStartMode (szFileName);
+ return;
+ }
+ else if (DirectNonSysInplaceEncResumeMode || DirectNonSysInplaceDecResumeMode)
{
- SwitchWizardToNonSysInplaceEncResumeMode();
+ SwitchWizardToNonSysInplaceEncResumeMode (DirectNonSysInplaceDecResumeMode);
return;
}
else if (DirectPromptNonSysInplaceEncResumeMode)
@@ -9006,8 +9378,8 @@ static void AfterWMInitTasks (HWND hwndDlg)
if (NonSysInplaceEncInProgressElsewhere ())
AbortProcessSilent ();
- if (AskNonSysInPlaceEncryptionResume(hwndDlg) == IDYES)
- SwitchWizardToNonSysInplaceEncResumeMode();
+ if (AskNonSysInPlaceEncryptionResume(hwndDlg, &bDecrypt) == IDYES)
+ SwitchWizardToNonSysInplaceEncResumeMode(bDecrypt);
else
AbortProcessSilent ();
@@ -9015,9 +9387,9 @@ static void AfterWMInitTasks (HWND hwndDlg)
}
else if (bInPlaceEncNonSysPending
&& !NonSysInplaceEncInProgressElsewhere ()
- && AskNonSysInPlaceEncryptionResume(hwndDlg) == IDYES)
+ && AskNonSysInPlaceEncryptionResume(hwndDlg, &bDecrypt) == IDYES)
{
- SwitchWizardToNonSysInplaceEncResumeMode();
+ SwitchWizardToNonSysInplaceEncResumeMode(bDecrypt);
return;
}