1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 19:08:26 -06:00

Windows: First implementation of non-system volumes decryption.

This commit is contained in:
Mounir IDRASSI
2015-05-17 12:14:58 +02:00
parent 4695920b41
commit f72125ea71
16 changed files with 1557 additions and 116 deletions

View File

@@ -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);
SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString (bInPlaceEncNonSysResumed ? "DEFER" : "CANCEL"));
if (lastbVolTransformThreadRunning != bVolTransformThreadRunning
|| lastbVolTransformThreadToRun != bVolTransformThreadToRun)
{
SetWindowTextW (GetDlgItem (hCurPage, IDC_PAUSE),
GetString ((bVolTransformThreadRunning || bVolTransformThreadToRun) ? "IDC_PAUSE" : "RESUME"));
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)
{
SwitchWizardToNonSysInplaceEncResumeMode();
SwitchWizardToNonSysInplaceDecStartMode (szFileName);
return;
}
else if (DirectNonSysInplaceEncResumeMode || DirectNonSysInplaceDecResumeMode)
{
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;
}