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:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user