mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Windows: First implementation of non-system volumes decryption.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user