1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-12 03:18: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

@@ -223,12 +223,12 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
EDITTEXT IDC_PASSWORD_DIRECT,50,2,149,14,ES_PASSWORD | ES_AUTOHSCROLL
COMBOBOX IDC_PKCS5_PRF_ID,50,17,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
CONTROL "&Display password",IDC_SHOW_PASSWORD_SINGLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,31,84,11,WS_EX_TRANSPARENT
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,42,82,11
PUSHBUTTON "&Keyfiles...",IDC_KEY_FILES,142,39,64,14
LTEXT "",IDC_BOX_HELP,0,57,225,94
RTEXT "Password:",IDT_PASSWORD,0,6,48,8
COMBOBOX IDC_PKCS5_PRF_ID,50,17,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
RTEXT "PKCS-5 PRF:",IDT_PKCS5_PRF,0,17,48,8
END
@@ -419,6 +419,15 @@ BEGIN
LISTBOX IDC_LIST_BOX,0,3,222,100,LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | WS_VSCROLL
END
IDD_DRIVE_LETTER_SELECTION_PAGE DIALOGEX 0, 0, 226, 152
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_BOX_HELP,0,40,225,95
COMBOBOX IDC_DRIVE_LETTER_LIST,94,15,38,69,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
RTEXT "Drive letter:",IDT_DRIVE_LETTER,5,17,86,8
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@@ -662,6 +671,14 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 145
END
IDD_DRIVE_LETTER_SELECTION_PAGE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 219
TOPMARGIN, 7
BOTTOMMARGIN, 145
END
END
#endif // APSTUDIO_INVOKED

View File

@@ -40,6 +40,18 @@ IMPORTANT: Due to this issue, functions in this file must not directly interact
using namespace std;
using namespace VeraCrypt;
#if TC_VOLUME_DATA_OFFSET != 131072
# error TC_VOLUME_DATA_OFFSET != 131072
#endif
#if TC_VOLUME_HEADER_EFFECTIVE_SIZE != 512
# error TC_VOLUME_HEADER_EFFECTIVE_SIZE != 512
#endif
#if TC_TOTAL_VOLUME_HEADERS_SIZE != 262144
# error TC_TOTAL_VOLUME_HEADERS_SIZE != 262144
#endif
#define TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE (2048 * BYTES_PER_KB)
#define TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE (2 * TC_MAX_VOLUME_SECTOR_SIZE)
#define TC_NTFS_CONCEAL_CONSTANT 0xFF
@@ -312,6 +324,42 @@ BOOL CheckRequirementsForNonSysInPlaceEnc (HWND hwndDlg, const char *devicePath,
return TRUE;
}
BOOL CheckRequirementsForNonSysInPlaceDec (HWND hwndDlg, const char *devicePath, BOOL silent)
{
int partitionNumber = -1, driveNumber = -1;
/* ---------- Checks that do not require admin rights ----------- */
/* Volume type (must be a partition or a dynamic volume) */
if ((sscanf (devicePath, "\\Device\\HarddiskVolume%d", &partitionNumber) != 1
&& sscanf (devicePath, "\\Device\\Harddisk%d\\Partition%d", &driveNumber, &partitionNumber) != 2)
|| partitionNumber == 0)
{
if (!silent)
Error ("INPLACE_ENC_INVALID_PATH", hwndDlg);
return FALSE;
}
/* Admin rights */
if (!IsAdmin())
{
// We rely on the wizard process to call us only when the whole wizard process has been elevated (so UAC
// status can be ignored). In case the IsAdmin() detection somehow fails, we allow the user to continue.
if (!silent)
Warning ("ADMIN_PRIVILEGES_WARN_DEVICES", hwndDlg);
}
/* ---------- Checks that may require admin rights ----------- */
// [Currently none]
return TRUE;
}
int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, volatile HANDLE *outHandle, WipeAlgorithmId wipeAlgorithm)
{
@@ -606,7 +654,7 @@ int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, vol
// In the config file, increase the number of partitions where in-place encryption is in progress
SaveNonSysInPlaceEncSettings (1, wipeAlgorithm);
SaveNonSysInPlaceEncSettings (1, wipeAlgorithm, FALSE);
// Add the wizard to the system startup sequence if appropriate
@@ -1033,7 +1081,7 @@ inplace_enc_read:
// Update the configuration files
SaveNonSysInPlaceEncSettings (-1, wipeAlgorithm);
SaveNonSysInPlaceEncSettings (-1, wipeAlgorithm, FALSE);
@@ -1126,6 +1174,513 @@ closing_seq:
return nStatus;
}
int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile BOOL *DiscardUnreadableEncryptedSectors)
{
HANDLE dev = INVALID_HANDLE_VALUE;
PCRYPTO_INFO masterCryptoInfo = NULL, headerCryptoInfo = NULL;
UINT64_STRUCT unitNo;
char *buf = NULL;
byte *tmpSectorBuf = NULL;
char dosDev[TC_MAX_PATH] = {0};
char devName[MAX_PATH] = {0};
WCHAR deviceName[MAX_PATH];
int nStatus = ERR_SUCCESS;
__int64 deviceSize;
uint64 remainingBytes, workChunkStartByteOffset, lastHeaderUpdateDistance = 0, skippedBadSectorCount = 0;
uint32 workChunkSize;
DWORD dwError, dwResult;
BOOL bPause = FALSE, bEncryptedAreaSizeChanged = FALSE;
LARGE_INTEGER offset;
int sectorSize;
int i;
DWORD n;
char *devicePath = volParams->volumePath;
Password *password = volParams->password;
HWND hwndDlg = volParams->hwndDlg;
int pkcs5_prf = volParams->pkcs5;
DISK_GEOMETRY driveGeometry;
buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);
if (!buf)
{
nStatus = ERR_OUTOFMEMORY;
goto closing_seq;
}
headerCryptoInfo = crypto_open();
if (headerCryptoInfo == NULL)
{
nStatus = ERR_OUTOFMEMORY;
goto closing_seq;
}
deviceSize = GetDeviceSize (devicePath);
if (deviceSize < 0)
{
// Cannot determine the size of the partition
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
// The wizard should have dismounted the TC volume if it was mounted, but for extra safety we will check this again.
if (IsMountedVolume (devicePath))
{
int driveLetter = GetMountedVolumeDriveNo (devicePath);
if (driveLetter == -1
|| !UnmountVolume (hwndDlg, driveLetter, TRUE))
{
handleWin32Error (hwndDlg);
AbortProcess ("CANT_DISMOUNT_VOLUME");
}
}
StringCbCopyA ((char *)deviceName, sizeof(deviceName), devicePath);
ToUNICODE ((char *)deviceName, sizeof(deviceName));
if (FakeDosNameForDevice (devicePath, dosDev, sizeof(dosDev), devName, sizeof(devName), FALSE) != 0)
{
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
dev = OpenPartitionVolume (hwndDlg, devName,
TRUE, // Require exclusive access
FALSE, // Do not require shared access
TRUE, // Ask the user to confirm shared access (if exclusive fails)
FALSE, // Do not append alternative instructions how to encrypt the data (to applicable error messages)
FALSE); // Non-silent mode
if (dev == INVALID_HANDLE_VALUE)
{
nStatus = ERR_DONT_REPORT;
goto closing_seq;
}
// This should never be needed, but is still performed for extra safety (without checking the result)
DeviceIoControl (dev,
FSCTL_ALLOW_EXTENDED_DASD_IO,
NULL,
0,
NULL,
0,
&dwResult,
NULL);
if (!DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveGeometry, sizeof (driveGeometry), &dwResult, NULL))
{
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
sectorSize = driveGeometry.BytesPerSector;
tmpSectorBuf = (byte *) TCalloc (sectorSize);
if (!tmpSectorBuf)
{
nStatus = ERR_OUTOFMEMORY;
goto closing_seq;
}
nStatus = OpenBackupHeader (dev, devicePath, password, pkcs5_prf, &masterCryptoInfo, headerCryptoInfo, deviceSize);
if (nStatus != ERR_SUCCESS)
goto closing_seq;
if (masterCryptoInfo->LegacyVolume)
{
Error ("NONSYS_INPLACE_DECRYPTION_BAD_VOL_FORMAT", hwndDlg);
nStatus = ERR_DONT_REPORT;
goto closing_seq;
}
if (masterCryptoInfo->hiddenVolume)
{
Error ("NONSYS_INPLACE_DECRYPTION_CANT_DECRYPT_HID_VOL", hwndDlg);
nStatus = ERR_DONT_REPORT;
goto closing_seq;
}
if (!bInPlaceEncNonSysResumed
&& masterCryptoInfo->VolumeSize.Value == masterCryptoInfo->EncryptedAreaLength.Value)
{
/* Decryption started (not resumed) */
if ((masterCryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0)
{
// The volume has not been encrypted in-place so it may contain a hidden volume.
// Ask the user to confirm it does not.
char *tmpStr[] = {0,
"CONFIRM_VOL_CONTAINS_NO_HIDDEN_VOL",
"VOL_CONTAINS_NO_HIDDEN_VOL",
"VOL_CONTAINS_A_HIDDEN_VOL",
0};
switch (AskMultiChoice ((void **) tmpStr, FALSE, hwndDlg))
{
case 1:
// NOP
break;
case 2:
default:
// Cancel
nStatus = ERR_DONT_REPORT;
goto closing_seq;
}
}
// Update config files and app data
// In the config file, increase the number of partitions where in-place decryption is in progress
SaveNonSysInPlaceEncSettings (1, TC_WIPE_NONE, TRUE);
// Add the wizard to the system startup sequence if appropriate
if (!IsNonInstallMode ())
ManageStartupSeqWiz (FALSE, "/prinplace");
}
bInPlaceEncNonSysResumed = TRUE;
bFirstNonSysInPlaceEncResumeDone = TRUE;
remainingBytes = masterCryptoInfo->EncryptedAreaLength.Value;
lastHeaderUpdateDistance = 0;
ExportProgressStats (masterCryptoInfo->EncryptedAreaLength.Value, masterCryptoInfo->VolumeSize.Value);
SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_DECRYPTING);
/* The in-place decryption core */
while (remainingBytes > 0)
{
workChunkSize = (uint32) min (remainingBytes, TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE);
if (workChunkSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
{
nStatus = ERR_PARAMETER_INCORRECT;
goto closing_seq;
}
workChunkStartByteOffset = masterCryptoInfo->EncryptedAreaStart.Value;
unitNo.Value = workChunkStartByteOffset / ENCRYPTION_DATA_UNIT_SIZE;
// Read the ciphertext into RAM
offset.QuadPart = workChunkStartByteOffset;
if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0)
{
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
if (ReadFile (dev, buf, workChunkSize, &n, NULL) == 0)
{
// Read error
DWORD dwTmpErr = GetLastError ();
if (IsDiskReadError (dwTmpErr) && !bVolTransformThreadCancel)
{
// Physical defect or data corruption
if (!*DiscardUnreadableEncryptedSectors)
{
*DiscardUnreadableEncryptedSectors = (AskWarnYesNo ("DISCARD_UNREADABLE_ENCRYPTED_SECTORS", hwndDlg) == IDYES);
}
if (*DiscardUnreadableEncryptedSectors)
{
// Read the work chunk again, but this time each sector individually and skiping each bad sector
LARGE_INTEGER tmpSectorOffset;
uint64 tmpSectorCount;
uint64 tmpBufOffset = 0;
DWORD tmpNbrReadBytes = 0;
tmpSectorOffset.QuadPart = offset.QuadPart;
for (tmpSectorCount = workChunkSize / sectorSize; tmpSectorCount > 0; --tmpSectorCount)
{
if (SetFilePointerEx (dev, tmpSectorOffset, NULL, FILE_BEGIN) == 0)
{
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
if (ReadFile (dev, tmpSectorBuf, sectorSize, &tmpNbrReadBytes, NULL) == 0
|| tmpNbrReadBytes != (DWORD) sectorSize)
{
// Read error
// Clear the buffer so the content of each unreadable sector is replaced with decrypted all-zero blocks (producing pseudorandom data)
memset (tmpSectorBuf, 0, sectorSize);
skippedBadSectorCount++;
}
memcpy (buf + tmpBufOffset, tmpSectorBuf, sectorSize);
tmpSectorOffset.QuadPart += sectorSize;
tmpBufOffset += sectorSize;
}
}
else
{
SetLastError (dwTmpErr); // Preserve the original error code
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
}
else
{
SetLastError (dwTmpErr); // Preserve the original error code
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
}
// Decrypt the ciphertext in RAM
DecryptDataUnits ((byte *) buf, &unitNo, workChunkSize / ENCRYPTION_DATA_UNIT_SIZE, masterCryptoInfo);
// Conceal initial portion of the filesystem
if (workChunkStartByteOffset - TC_VOLUME_DATA_OFFSET < TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE)
{
// We are decrypting the initial TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE bytes of the filesystem. We will
// conceal this portion to prevent Windows and applications from interfering with the volume.
for (i = 0; i < min (TC_INITIAL_NTFS_CONCEAL_PORTION_SIZE, workChunkStartByteOffset - TC_VOLUME_DATA_OFFSET + workChunkSize); i++)
buf[i] ^= TC_NTFS_CONCEAL_CONSTANT;
}
// Write the plaintext
offset.QuadPart = workChunkStartByteOffset - TC_VOLUME_DATA_OFFSET;
if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0)
{
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
if (WriteFile (dev, buf, workChunkSize, &n, NULL) == 0)
{
// Write error
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
masterCryptoInfo->EncryptedAreaStart.Value += workChunkSize;
masterCryptoInfo->EncryptedAreaLength.Value -= workChunkSize;
remainingBytes -= workChunkSize;
lastHeaderUpdateDistance += workChunkSize;
bEncryptedAreaSizeChanged = TRUE;
if (lastHeaderUpdateDistance >= TC_NONSYS_INPLACE_ENC_HEADER_UPDATE_INTERVAL)
{
nStatus = FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize);
if (nStatus != ERR_SUCCESS)
{
// Possible write error
goto closing_seq;
}
lastHeaderUpdateDistance = 0;
}
ExportProgressStats (masterCryptoInfo->EncryptedAreaLength.Value, masterCryptoInfo->VolumeSize.Value);
if (bVolTransformThreadCancel)
{
bPause = TRUE;
break;
}
}
nStatus = FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize);
if (nStatus != ERR_SUCCESS)
{
// Possible write error
goto closing_seq;
}
if (!bPause)
{
/* Volume has been fully decrypted. */
// Prevent attempts to update volume header during the closing sequence
bEncryptedAreaSizeChanged = FALSE;
SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_FINALIZING);
/* Undo concealing of the filesystem */
nStatus = ConcealNTFS (dev);
if (nStatus != ERR_SUCCESS)
goto closing_seq;
/* Ovewrite the backup header and the remaining ciphertext with all-zero blocks (the primary header was overwritten with the decrypted data). */
memset (tmpSectorBuf, 0, sectorSize);
for (offset.QuadPart = masterCryptoInfo->VolumeSize.Value;
offset.QuadPart <= deviceSize - sectorSize;
offset.QuadPart += sectorSize)
{
if (SetFilePointerEx (dev, offset, NULL, FILE_BEGIN) == 0)
{
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
if (WriteFile (dev, tmpSectorBuf, sectorSize, &n, NULL) == 0)
{
// Write error
dwError = GetLastError();
SetLastError (dwError);
nStatus = ERR_OS_ERROR;
goto closing_seq;
}
}
/* Update the configuration files */
SaveNonSysInPlaceEncSettings (-1, TC_WIPE_NONE, TRUE);
SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_FINISHED);
nStatus = ERR_SUCCESS;
}
else
{
// The process has been paused by the user or aborted by the wizard (e.g. on app exit)
nStatus = ERR_USER_ABORT;
SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PAUSED);
}
if (dev != INVALID_HANDLE_VALUE)
{
CloseHandle (dev);
dev = INVALID_HANDLE_VALUE;
}
closing_seq:
dwError = GetLastError();
if (bEncryptedAreaSizeChanged
&& dev != INVALID_HANDLE_VALUE
&& masterCryptoInfo != NULL
&& headerCryptoInfo != NULL
&& deviceSize > 0)
{
// Execution of the core loop may have been interrupted due to an error or user action without updating the header
FastVolumeHeaderUpdate (dev, headerCryptoInfo, masterCryptoInfo, deviceSize);
}
if (dev != INVALID_HANDLE_VALUE)
{
CloseHandle (dev);
dev = INVALID_HANDLE_VALUE;
}
if (masterCryptoInfo != NULL)
{
crypto_close (masterCryptoInfo);
masterCryptoInfo = NULL;
}
if (headerCryptoInfo != NULL)
{
crypto_close (headerCryptoInfo);
headerCryptoInfo = NULL;
}
if (dosDev[0])
RemoveFakeDosName (devicePath, dosDev);
if (buf != NULL)
{
TCfree (buf);
buf = NULL;
}
if (tmpSectorBuf != NULL)
{
TCfree (tmpSectorBuf);
tmpSectorBuf = NULL;
}
if (skippedBadSectorCount > 0)
{
wchar_t msg[30000] = {0};
wchar_t sizeStr[500] = {0};
GetSizeString (skippedBadSectorCount * sectorSize, sizeStr, sizeof(sizeStr));
StringCbPrintfW (msg, sizeof(msg),
GetString ("SKIPPED_BAD_SECTOR_COUNT"),
skippedBadSectorCount,
sizeStr);
WarningDirect (msg, hwndDlg);
}
if (nStatus != ERR_SUCCESS && nStatus != ERR_USER_ABORT)
SetLastError (dwError);
return nStatus;
}
int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_INFO *masterCryptoInfo, __int64 deviceSize)
{
@@ -1168,6 +1723,13 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
mputInt64 (fieldPos, (masterCryptoInfo->EncryptedAreaStart.Value));
mputInt64 (fieldPos, (masterCryptoInfo->EncryptedAreaLength.Value));
// We need to ensure the TC_HEADER_FLAG_NONSYS_INPLACE_ENC flag bit is set, because if volumes created by TC-format
// were decrypted in place, it would be possible to mount them partially encrypted and it wouldn't be possible
// to resume interrupted decryption after the wizard exits.
masterCryptoInfo->HeaderFlags |= TC_HEADER_FLAG_NONSYS_INPLACE_ENC;
fieldPos = (byte *) header + TC_HEADER_OFFSET_FLAGS;
mputLong (fieldPos, (masterCryptoInfo->HeaderFlags));
headerCrc32 = GetCrc32 (header + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
fieldPos = (byte *) header + TC_HEADER_OFFSET_HEADER_CRC;
@@ -1419,7 +1981,7 @@ void SetNonSysInplaceEncUIStatus (int nonSysInplaceEncStatus)
}
BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm)
BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm, BOOL bDecrypt)
{
int count;
char str[32];
@@ -1435,7 +1997,7 @@ BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm)
RemoveNonSysInPlaceEncNotifications();
return TRUE;
}
else
else if (!bDecrypt)
{
if (newWipeAlgorithm != TC_WIPE_NONE)
{
@@ -1447,11 +2009,11 @@ BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm)
{
remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE));
}
StringCbPrintfA (str, sizeof(str), "%d", count);
return SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), strlen(str), FALSE);
}
StringCbPrintfA (str, sizeof(str), "%d", count);
return SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), strlen(str), FALSE);
}

View File

@@ -18,6 +18,7 @@ enum nonsys_inplace_enc_status
NONSYS_INPLACE_ENC_STATUS_PREPARING,
NONSYS_INPLACE_ENC_STATUS_RESIZING,
NONSYS_INPLACE_ENC_STATUS_ENCRYPTING,
NONSYS_INPLACE_ENC_STATUS_DECRYPTING,
NONSYS_INPLACE_ENC_STATUS_FINALIZING,
NONSYS_INPLACE_ENC_STATUS_PAUSED,
NONSYS_INPLACE_ENC_STATUS_FINISHED,
@@ -25,8 +26,10 @@ enum nonsys_inplace_enc_status
};
BOOL CheckRequirementsForNonSysInPlaceEnc (HWND hwndDlg, const char *devicePath, BOOL silent);
BOOL CheckRequirementsForNonSysInPlaceDec (HWND hwndDlg, const char *devicePath, BOOL silent);
int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, volatile HANDLE *outHandle, WipeAlgorithmId wipeAlgorithm);
int EncryptPartitionInPlaceResume (HANDLE dev, volatile FORMAT_VOL_PARAMETERS *volParams, WipeAlgorithmId wipeAlgorithm, volatile BOOL *bTryToCorrectReadErrors);
int DecryptPartitionInPlace (volatile FORMAT_VOL_PARAMETERS *volParams, volatile BOOL *DiscardUnreadableEncryptedSectors);
void ShowInPlaceEncErrMsgWAltSteps (HWND hwndDlg, char *iniStrId, BOOL bErr);
void SetNonSysInplaceEncUIStatus (int nonSysInplaceEncStatus);
int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_INFO *masterCryptoInfo, __int64 deviceSize);
@@ -34,7 +37,7 @@ int FastVolumeHeaderUpdate (HANDLE dev, CRYPTO_INFO *headerCryptoInfo, CRYPTO_IN
static HANDLE OpenPartitionVolume (HWND hwndDlg, const char *devName, BOOL bExclusiveRequired, BOOL bSharedRequired, BOOL bSharedRequiresConfirmation, BOOL bShowAlternativeSteps, BOOL bSilent);
static int DismountFileSystem (HWND hwndDlg, HANDLE dev, int driveLetter, BOOL bForcedAllowed, BOOL bForcedRequiresConfirmation, BOOL bSilent);
static int ConcealNTFS (HANDLE dev);
BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId wipeAlgorithm);
BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId wipeAlgorithm, BOOL bDecrypting);
static void ExportProgressStats (__int64 bytesDone, __int64 totalSize);
int ZeroUnreadableSectors (HANDLE dev, LARGE_INTEGER startOffset, int64 size, int sectorSize, uint64 *zeroedSectorCount);
static int OpenBackupHeader (HANDLE dev, const char *devicePath, Password *password, int pkcs5, PCRYPTO_INFO *retCryptoInfo, CRYPTO_INFO *headerCryptoInfo, __int64 deviceSize);

View File

@@ -34,6 +34,7 @@
#define IDD_DEVICE_WIPE_MODE_PAGE_DLG 129
#define IDD_DEVICE_TRANSFORM_MODE_DLG 130
#define IDD_EXPANDED_LIST_SELECT_PAGE_DLG 131
#define IDD_DRIVE_LETTER_SELECTION_PAGE 132
#define IDC_BOX_TITLE 1000
#define IDC_RESCUE_DISK_ISO_PATH 1001
#define IDC_COMBO_BOX 1002
@@ -137,15 +138,17 @@
#define IDT_PASS 1100
#define IDC_DEVICE_TRANSFORM_MODE_FORMAT 1101
#define IDC_DEVICE_TRANSFORM_MODE_INPLACE 1102
#define IDC_DRIVE_LETTER_LIST 1103
#define IDT_DRIVE_LETTER 1104
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 132
#define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1103
#define _APS_NEXT_CONTROL_VALUE 1105
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

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;
}

View File

@@ -42,6 +42,7 @@ void DisplaySizingErrorText ( HWND hwndTextBox );
void EnableDisableFileNext ( HWND hComboBox , HWND hMainButton );
BOOL QueryFreeSpace ( HWND hwndDlg , HWND hwndTextBox , BOOL display );
static BOOL FinalPreTransformPrompts (void);
void UpdateLastDialogId (void);
void HandleOldAssignedDriveLetter (void);
void AddCipher ( HWND hComboBox , char *lpszCipher , int nCipher );
BOOL CALLBACK PageDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam );
@@ -90,6 +91,7 @@ extern volatile BOOL bVolTransformThreadCancel;
extern volatile BOOL bInPlaceEncNonSysResumed;
extern volatile BOOL bFirstNonSysInPlaceEncResumeDone;
extern volatile BOOL bInPlaceEncNonSys;
extern volatile BOOL bInPlaceDecNonSys;
extern __int64 NonSysInplaceEncBytesDone;
extern __int64 NonSysInplaceEncTotalSize;
extern int nPbar;