From fc37cc4a02ed13d1a73b941a9f80975600fd1b99 Mon Sep 17 00:00:00 2001 From: David Foerster Date: Tue, 10 May 2016 20:20:14 +0200 Subject: Normalize all line terminators --- src/Common/Format.c | 2108 +++++++++++++++++++++++++-------------------------- 1 file changed, 1054 insertions(+), 1054 deletions(-) (limited to 'src/Common/Format.c') diff --git a/src/Common/Format.c b/src/Common/Format.c index fe12c041..43a96d04 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -1,810 +1,810 @@ -/* - Legal Notice: Some portions of the source code contained in this file were - derived from the source code of TrueCrypt 7.1a, which is - Copyright (c) 2003-2012 TrueCrypt Developers Association and which is - governed by the TrueCrypt License 3.0, also from the source code of - Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux - and which is governed by the 'License Agreement for Encryption for the Masses' - Modifications and additions to the original source code (contained in this file) - and all other portions of this file are Copyright (c) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. */ - -#include -#include - -#include "Tcdefs.h" - -#include "Common.h" -#include "Crypto.h" -#include "Fat.h" -#include "Format.h" -#include "Random.h" -#include "Volumes.h" - -#include "Apidrvr.h" -#include "Dlgcode.h" -#include "Language.h" -#include "Progress.h" -#include "Resource.h" -#include "Format/FormatCom.h" -#include "Format/Tcformat.h" - -#include - -#ifndef SRC_POS -#define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__)) -#endif - -int FormatWriteBufferSize = 1024 * 1024; -static uint32 FormatSectorSize = 0; - - -uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize) -{ - uint64 reservedSize; - - if (hiddenVolume) - { - // Reserve free space at the end of the host filesystem. FAT file system fills the last sector with - // zeroes (marked as free; observed when quick format was performed using the OS format tool). - // Therefore, when the outer volume is mounted with hidden volume protection, such write operations - // (e.g. quick formatting the outer volume filesystem as FAT) would needlessly trigger hidden volume - // protection. - -#if TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE > 4096 -# error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE too large for very small volumes. Revise the code. -#endif - -#if TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH < TC_MAX_VOLUME_SECTOR_SIZE -# error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH too small. -#endif - - if (volumeSize < TC_VOLUME_SMALL_SIZE_THRESHOLD) - reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE; - else - reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH; // Ensure size of a hidden volume larger than TC_VOLUME_SMALL_SIZE_THRESHOLD is a multiple of the maximum supported sector size - } - else - { - reservedSize = TC_TOTAL_VOLUME_HEADERS_SIZE; - } - - if (volumeSize < reservedSize) - return 0; - - return volumeSize - reservedSize; -} - - -int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) -{ - int nStatus; - PCRYPTO_INFO cryptoInfo = NULL; - HANDLE dev = INVALID_HANDLE_VALUE; - DWORD dwError; - char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; - unsigned __int64 num_sectors, startSector; - fatparams ft; - FILETIME ftCreationTime; - FILETIME ftLastWriteTime; - FILETIME ftLastAccessTime; - BOOL bTimeStampValid = FALSE; - BOOL bInstantRetryOtherFilesys = FALSE; - WCHAR dosDev[TC_MAX_PATH] = { 0 }; - WCHAR devName[MAX_PATH] = { 0 }; - int driveLetter = -1; - WCHAR deviceName[MAX_PATH]; - uint64 dataOffset, dataAreaSize; - LARGE_INTEGER offset; - BOOL bFailedRequiredDASD = FALSE; - HWND hwndDlg = volParams->hwndDlg; - - FormatSectorSize = volParams->sectorSize; - - if (FormatSectorSize < TC_MIN_VOLUME_SECTOR_SIZE - || FormatSectorSize > TC_MAX_VOLUME_SECTOR_SIZE - || FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) - { - Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); - return ERR_DONT_REPORT; - } - - /* WARNING: Note that if Windows fails to format the volume as NTFS and the volume size is - less than the maximum FAT size, the user is asked within this function whether he wants to instantly - retry FAT format instead (to avoid having to re-create the whole container again). If the user - answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed - and some destructive operations that were performed during the first attempt must be (and are) skipped. - Therefore, whenever adding or modifying any potentially destructive operations below 'begin_format', - determine whether they (or their portions) need to be skipped during such a second attempt; if so, - use the 'bInstantRetryOtherFilesys' flag to skip them. */ - - if (volParams->hiddenVol) - { - dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size; - } - else - { - if (volParams->size <= TC_TOTAL_VOLUME_HEADERS_SIZE) - return ERR_VOL_SIZE_WRONG; - - dataOffset = TC_VOLUME_DATA_OFFSET; - } - - dataAreaSize = GetVolumeDataAreaSize (volParams->hiddenVol, volParams->size); - - num_sectors = dataAreaSize / FormatSectorSize; - - if (volParams->bDevice) - { - StringCchCopyW (deviceName, ARRAYSIZE(deviceName), volParams->volumePath); - - driveLetter = GetDiskDeviceDriveLetter (deviceName); - } - - VirtualLock (header, sizeof (header)); - - nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, - header, - volParams->ea, - FIRST_MODE_OF_OPERATION_ID, - volParams->password, - volParams->pkcs5, - volParams->pim, - NULL, - &cryptoInfo, - dataAreaSize, - volParams->hiddenVol ? dataAreaSize : 0, - dataOffset, - dataAreaSize, - 0, - volParams->headerFlags, - FormatSectorSize, - FALSE); - - if (nStatus != 0) - { - burn (header, sizeof (header)); - VirtualUnlock (header, sizeof (header)); - return nStatus; - } - -begin_format: - - if (volParams->bDevice) - { - /* Device-hosted volume */ - - DWORD dwResult; - int nPass; - - if (FakeDosNameForDevice (volParams->volumePath, dosDev, sizeof(dosDev), devName, sizeof(devName), FALSE) != 0) - return ERR_OS_ERROR; - - if (IsDeviceMounted (devName)) - { - if ((dev = DismountDrive (devName, volParams->volumePath)) == INVALID_HANDLE_VALUE) - { - Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); - nStatus = ERR_DONT_REPORT; - goto error; - } - - /* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver - would otherwise prevent us from writing to hidden sectors). */ - - if (!DeviceIoControl (dev, - FSCTL_ALLOW_EXTENDED_DASD_IO, - NULL, - 0, - NULL, - 0, - &dwResult, - NULL)) - { - bFailedRequiredDASD = TRUE; - } - } - else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1) - { - // Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition - // to which no drive letter has been assigned under the system. This problem can be worked - // around by assigning a drive letter to the partition temporarily. - - wchar_t szDriveLetter[] = { L'A', L':', 0 }; - wchar_t rootPath[] = { L'A', L':', L'\\', 0 }; - wchar_t uniqVolName[MAX_PATH+1] = { 0 }; - int tmpDriveLetter = -1; - BOOL bResult = FALSE; - - tmpDriveLetter = GetFirstAvailableDrive (); - - if (tmpDriveLetter != -1) - { - rootPath[0] += (wchar_t) tmpDriveLetter; - szDriveLetter[0] += (wchar_t) tmpDriveLetter; - - if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, volParams->volumePath)) - { - bResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH); - - DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE, - szDriveLetter, - volParams->volumePath); - - if (bResult - && SetVolumeMountPoint (rootPath, uniqVolName)) - { - // The drive letter can be removed now - DeleteVolumeMountPoint (rootPath); - } - } - } - } - - // For extra safety, we will try to gain "raw" access to the partition. Note that this should actually be - // redundant because if the filesystem was mounted, we already tried to obtain DASD above. If we failed, - // bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, - // for extra safety, in case IsDeviceMounted() failed to detect a live filesystem, we will blindly - // send FSCTL_ALLOW_EXTENDED_DASD_IO (possibly for a second time) without checking the result. - - DeviceIoControl (dev, - FSCTL_ALLOW_EXTENDED_DASD_IO, - NULL, - 0, - NULL, - 0, - &dwResult, - NULL); - - - // If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open - // so that the filesystem driver does not prevent us from formatting hidden sectors. - for (nPass = (bFailedRequiredDASD ? 0 : 1); nPass < 2; nPass++) - { - int retryCount; - - retryCount = 0; - - // Try exclusive access mode first - // Note that when exclusive access is denied, it is worth retrying (usually succeeds after a few tries). - while (dev == INVALID_HANDLE_VALUE && retryCount++ < EXCL_ACCESS_MAX_AUTO_RETRIES) - { - dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - - if (retryCount > 1) - Sleep (EXCL_ACCESS_AUTO_RETRY_DELAY); - } - - if (dev == INVALID_HANDLE_VALUE) - { - // Exclusive access denied -- retry in shared mode - dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (dev != INVALID_HANDLE_VALUE) - { - if (!volParams->bForceOperation && (Silent || (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2)))) - { - nStatus = ERR_DONT_REPORT; - goto error; - } - } - else - { - handleWin32Error (volParams->hwndDlg, SRC_POS); - Error ("CANT_ACCESS_VOL", hwndDlg); - nStatus = ERR_DONT_REPORT; - goto error; - } - } - - if (volParams->hiddenVol || bInstantRetryOtherFilesys) - break; // The following "quick format" operation would damage the outer volume - - if (nPass == 0) - { - char buf [2 * TC_MAX_VOLUME_SECTOR_SIZE]; - DWORD bw; - - // Perform pseudo "quick format" so that the filesystem driver does not prevent us from - // formatting hidden sectors - memset (buf, 0, sizeof (buf)); - - if (!WriteFile (dev, buf, sizeof (buf), &bw, NULL)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - FlushFileBuffers (dev); - CloseHandle (dev); - dev = INVALID_HANDLE_VALUE; - } - } - - if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL)) - { - Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); - nStatus = ERR_DONT_REPORT; - goto error; - } - } - else - { - /* File-hosted volume */ - - dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE, - (volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0, - NULL, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL); - - if (dev == INVALID_HANDLE_VALUE) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - DisableFileCompression (dev); - - if (!volParams->hiddenVol && !bInstantRetryOtherFilesys) - { - LARGE_INTEGER volumeSize; - volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE; - - if (volParams->sparseFileSwitch && volParams->quickFormat) - { - // Create as sparse file container - DWORD tmp; - if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - } - - // Preallocate the file - if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN) - || !SetEndOfFile (dev) - || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0) - { - nStatus = ERR_OS_ERROR; - goto error; - } - } - } - - if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp) - { - if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0) - bTimeStampValid = FALSE; - else - bTimeStampValid = TRUE; - } - - if (volParams->hwndDlg && volParams->bGuiMode) KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW); - - /* Volume header */ - - // Hidden volume setup - if (volParams->hiddenVol) - { - LARGE_INTEGER headerOffset; - - // Check hidden volume size - if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE) - { - nStatus = ERR_VOL_SIZE_WRONG; - goto error; - } - - // Seek to hidden volume header location - - headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET; - - if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - } - else if (bInstantRetryOtherFilesys) - { - // The previous file system format failed and the user wants to try again with a different file system. - // The volume header had been written successfully so we need to seek to the byte after the header. - - LARGE_INTEGER offset; - offset.QuadPart = TC_VOLUME_DATA_OFFSET; - if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - } - - if (!bInstantRetryOtherFilesys) - { - // Write the volume header - if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - // To prevent fragmentation, write zeroes to reserved header sectors which are going to be filled with random data - if (!volParams->bDevice && !volParams->hiddenVol) - { - byte buf[TC_VOLUME_HEADER_GROUP_SIZE - TC_VOLUME_HEADER_EFFECTIVE_SIZE]; - DWORD bytesWritten; - ZeroMemory (buf, sizeof (buf)); - - if (!WriteFile (dev, buf, sizeof (buf), &bytesWritten, NULL)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - if (bytesWritten != sizeof (buf)) - { - nStatus = ERR_PARAMETER_INCORRECT; - goto error; - } - } - } - - if (volParams->hiddenVol) - { - // Calculate data area position of hidden volume - cryptoInfo->hiddenVolumeOffset = dataOffset; - - // Validate the offset - if (dataOffset % FormatSectorSize != 0) - { - nStatus = ERR_VOL_SIZE_WRONG; - goto error; - } - - volParams->quickFormat = TRUE; // To entirely format a hidden volume would be redundant - } - - /* Data area */ - startSector = dataOffset / FormatSectorSize; - - // Format filesystem - - switch (volParams->fileSystem) - { - case FILESYS_NONE: - case FILESYS_NTFS: - case FILESYS_EXFAT: - - if (volParams->bDevice && !StartFormatWriteThread()) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat); - - if (volParams->bDevice) - StopFormatWriteThread(); - - break; - - case FILESYS_FAT: - if (num_sectors > 0xFFFFffff) - { - nStatus = ERR_VOL_SIZE_WRONG; - goto error; - } - - // Calculate the fats, root dir etc - ft.num_sectors = (unsigned int) (num_sectors); - -#if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF -#error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF -#endif - - ft.sector_size = (uint16) FormatSectorSize; - ft.cluster_size = volParams->clusterSize; - memcpy (ft.volume_name, "NO NAME ", 11); - GetFatParams (&ft); - *(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize; - - if (volParams->bDevice && !StartFormatWriteThread()) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat); - - if (volParams->bDevice) - StopFormatWriteThread(); - - break; - - default: - nStatus = ERR_PARAMETER_INCORRECT; - goto error; - } - - if (nStatus != ERR_SUCCESS) - goto error; - - // Write header backup - offset.QuadPart = volParams->hiddenVol ? volParams->hiddenVolHostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET : dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE; - - if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, - header, - volParams->ea, - FIRST_MODE_OF_OPERATION_ID, - volParams->password, - volParams->pkcs5, - volParams->pim, - cryptoInfo->master_keydata, - &cryptoInfo, - dataAreaSize, - volParams->hiddenVol ? dataAreaSize : 0, - dataOffset, - dataAreaSize, - 0, - volParams->headerFlags, - FormatSectorSize, - FALSE); - - if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - // Fill reserved header sectors (including the backup header area) with random data - if (!volParams->hiddenVol) - { - nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE); - - if (nStatus != ERR_SUCCESS) - goto error; - } - -#ifndef DEBUG - if (volParams->quickFormat && volParams->fileSystem != FILESYS_NTFS && volParams->fileSystem != FILESYS_EXFAT) - Sleep (500); // User-friendly GUI -#endif - -error: - dwError = GetLastError(); - - burn (header, sizeof (header)); - VirtualUnlock (header, sizeof (header)); - - if (dev != INVALID_HANDLE_VALUE) - { - if (!volParams->bDevice && !volParams->hiddenVol && nStatus != 0) - { - // Remove preallocated part before closing file handle if format failed - if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0) - SetEndOfFile (dev); - } - - FlushFileBuffers (dev); - - if (bTimeStampValid) - SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime); - - CloseHandle (dev); - dev = INVALID_HANDLE_VALUE; - } - - if (nStatus != 0) - { - SetLastError(dwError); - goto fv_end; - } - - if (volParams->fileSystem == FILESYS_NTFS || volParams->fileSystem == FILESYS_EXFAT) - { - // Quick-format volume as NTFS - int driveNo = GetLastAvailableDrive (); - MountOptions mountOptions; - int retCode; - int fsType = (volParams->fileSystem == FILESYS_EXFAT)? FILESYS_EXFAT: FILESYS_NTFS; - - ZeroMemory (&mountOptions, sizeof (mountOptions)); - - if (driveNo == -1) - { - if (!Silent) - { - MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND); - MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); - } - - nStatus = ERR_NO_FREE_DRIVES; - goto fv_end; - } - - mountOptions.ReadOnly = FALSE; - mountOptions.Removable = FALSE; - mountOptions.ProtectHiddenVolume = FALSE; - mountOptions.PreserveTimestamp = bPreserveTimestamp; - mountOptions.PartitionInInactiveSysEncScope = FALSE; - mountOptions.UseBackupHeader = FALSE; - - if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1) - { - if (!Silent) - { - MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND); - MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); - } - nStatus = ERR_VOL_MOUNT_FAILED; - goto fv_end; - } - - if (!Silent && !IsAdmin () && IsUacSupported ()) - retCode = UacFormatFs (volParams->hwndDlg, driveNo, volParams->clusterSize, fsType); - else - retCode = FormatFs (driveNo, volParams->clusterSize, fsType); - - if (retCode != TRUE) - { - if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) - MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); - - if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize) - { - if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT", hwndDlg) == IDYES) - { - // NTFS format failed and the user wants to try FAT format immediately - volParams->fileSystem = FILESYS_FAT; - bInstantRetryOtherFilesys = TRUE; - volParams->quickFormat = TRUE; // Volume has already been successfully TC-formatted - volParams->clusterSize = 0; // Default cluster size - goto begin_format; - } - } - else - Error ("FORMAT_NTFS_FAILED", hwndDlg); - - nStatus = ERR_DONT_REPORT; - goto fv_end; - } - - if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) - MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); - } - -fv_end: - dwError = GetLastError(); - - if (dosDev[0]) - RemoveFakeDosName (volParams->volumePath, dosDev); - - crypto_close (cryptoInfo); - - SetLastError (dwError); - return nStatus; -} - - -int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat) -{ - int write_buf_cnt = 0; - char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf; - unsigned __int64 nSecNo = startSector; - int retVal = 0; - DWORD err; - char temporaryKey[MASTER_KEYDATA_SIZE]; - char originalK2[MASTER_KEYDATA_SIZE]; - - LARGE_INTEGER startOffset; - LARGE_INTEGER newOffset; - - // Seek to start sector - startOffset.QuadPart = startSector * FormatSectorSize; - if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN) - || newOffset.QuadPart != startOffset.QuadPart) - { - return ERR_OS_ERROR; - } - - write_buf = (char *)TCalloc (FormatWriteBufferSize); - if (!write_buf) - return ERR_OUTOFMEMORY; - - VirtualLock (temporaryKey, sizeof (temporaryKey)); - VirtualLock (originalK2, sizeof (originalK2)); - - memset (sector, 0, sizeof (sector)); - - // Remember the original secondary key (XTS mode) before generating a temporary one - memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2)); - - /* Fill the rest of the data area with random data */ - - if(!quickFormat) - { - /* Generate a random temporary key set to be used for "dummy" encryption that will fill - the free disk space (data area) with random data. This is necessary for plausible - deniability of hidden volumes. */ - - // Temporary master key - if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)) - goto fail; - - // Temporary secondary key (XTS mode) - if (!RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE)) - goto fail; - - retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks); - if (retVal != ERR_SUCCESS) - goto fail; - - if (!EAInitMode (cryptoInfo)) - { - retVal = ERR_MODE_INIT_FAILED; - goto fail; - } - - while (num_sectors--) - { - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, - cryptoInfo) == FALSE) - goto fail; - } - - if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) - goto fail; - } - else - nSecNo = num_sectors; - - UpdateProgressBar (nSecNo * FormatSectorSize); - - // Restore the original secondary key (XTS mode) in case NTFS format fails and the user wants to try FAT immediately - memcpy (cryptoInfo->k2, originalK2, sizeof (cryptoInfo->k2)); - - // Reinitialize the encryption algorithm and mode in case NTFS format fails and the user wants to try FAT immediately - retVal = EAInit (cryptoInfo->ea, cryptoInfo->master_keydata, cryptoInfo->ks); - if (retVal != ERR_SUCCESS) - goto fail; - if (!EAInitMode (cryptoInfo)) - { - retVal = ERR_MODE_INIT_FAILED; - goto fail; - } - - burn (temporaryKey, sizeof(temporaryKey)); - burn (originalK2, sizeof(originalK2)); - VirtualUnlock (temporaryKey, sizeof (temporaryKey)); - VirtualUnlock (originalK2, sizeof (originalK2)); - TCfree (write_buf); - - return 0; - -fail: - err = GetLastError(); - - burn (temporaryKey, sizeof(temporaryKey)); - burn (originalK2, sizeof(originalK2)); - VirtualUnlock (temporaryKey, sizeof (temporaryKey)); - VirtualUnlock (originalK2, sizeof (originalK2)); - TCfree (write_buf); - - SetLastError (err); - return (retVal ? retVal : ERR_OS_ERROR); -} - - -volatile BOOLEAN FormatExError; - -BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter) +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + governed by the TrueCrypt License 3.0, also from the source code of + Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux + and which is governed by the 'License Agreement for Encryption for the Masses' + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. */ + +#include +#include + +#include "Tcdefs.h" + +#include "Common.h" +#include "Crypto.h" +#include "Fat.h" +#include "Format.h" +#include "Random.h" +#include "Volumes.h" + +#include "Apidrvr.h" +#include "Dlgcode.h" +#include "Language.h" +#include "Progress.h" +#include "Resource.h" +#include "Format/FormatCom.h" +#include "Format/Tcformat.h" + +#include + +#ifndef SRC_POS +#define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__)) +#endif + +int FormatWriteBufferSize = 1024 * 1024; +static uint32 FormatSectorSize = 0; + + +uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize) +{ + uint64 reservedSize; + + if (hiddenVolume) + { + // Reserve free space at the end of the host filesystem. FAT file system fills the last sector with + // zeroes (marked as free; observed when quick format was performed using the OS format tool). + // Therefore, when the outer volume is mounted with hidden volume protection, such write operations + // (e.g. quick formatting the outer volume filesystem as FAT) would needlessly trigger hidden volume + // protection. + +#if TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE > 4096 +# error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE too large for very small volumes. Revise the code. +#endif + +#if TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH < TC_MAX_VOLUME_SECTOR_SIZE +# error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH too small. +#endif + + if (volumeSize < TC_VOLUME_SMALL_SIZE_THRESHOLD) + reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE; + else + reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH; // Ensure size of a hidden volume larger than TC_VOLUME_SMALL_SIZE_THRESHOLD is a multiple of the maximum supported sector size + } + else + { + reservedSize = TC_TOTAL_VOLUME_HEADERS_SIZE; + } + + if (volumeSize < reservedSize) + return 0; + + return volumeSize - reservedSize; +} + + +int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) +{ + int nStatus; + PCRYPTO_INFO cryptoInfo = NULL; + HANDLE dev = INVALID_HANDLE_VALUE; + DWORD dwError; + char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + unsigned __int64 num_sectors, startSector; + fatparams ft; + FILETIME ftCreationTime; + FILETIME ftLastWriteTime; + FILETIME ftLastAccessTime; + BOOL bTimeStampValid = FALSE; + BOOL bInstantRetryOtherFilesys = FALSE; + WCHAR dosDev[TC_MAX_PATH] = { 0 }; + WCHAR devName[MAX_PATH] = { 0 }; + int driveLetter = -1; + WCHAR deviceName[MAX_PATH]; + uint64 dataOffset, dataAreaSize; + LARGE_INTEGER offset; + BOOL bFailedRequiredDASD = FALSE; + HWND hwndDlg = volParams->hwndDlg; + + FormatSectorSize = volParams->sectorSize; + + if (FormatSectorSize < TC_MIN_VOLUME_SECTOR_SIZE + || FormatSectorSize > TC_MAX_VOLUME_SECTOR_SIZE + || FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) + { + Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); + return ERR_DONT_REPORT; + } + + /* WARNING: Note that if Windows fails to format the volume as NTFS and the volume size is + less than the maximum FAT size, the user is asked within this function whether he wants to instantly + retry FAT format instead (to avoid having to re-create the whole container again). If the user + answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed + and some destructive operations that were performed during the first attempt must be (and are) skipped. + Therefore, whenever adding or modifying any potentially destructive operations below 'begin_format', + determine whether they (or their portions) need to be skipped during such a second attempt; if so, + use the 'bInstantRetryOtherFilesys' flag to skip them. */ + + if (volParams->hiddenVol) + { + dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size; + } + else + { + if (volParams->size <= TC_TOTAL_VOLUME_HEADERS_SIZE) + return ERR_VOL_SIZE_WRONG; + + dataOffset = TC_VOLUME_DATA_OFFSET; + } + + dataAreaSize = GetVolumeDataAreaSize (volParams->hiddenVol, volParams->size); + + num_sectors = dataAreaSize / FormatSectorSize; + + if (volParams->bDevice) + { + StringCchCopyW (deviceName, ARRAYSIZE(deviceName), volParams->volumePath); + + driveLetter = GetDiskDeviceDriveLetter (deviceName); + } + + VirtualLock (header, sizeof (header)); + + nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, + header, + volParams->ea, + FIRST_MODE_OF_OPERATION_ID, + volParams->password, + volParams->pkcs5, + volParams->pim, + NULL, + &cryptoInfo, + dataAreaSize, + volParams->hiddenVol ? dataAreaSize : 0, + dataOffset, + dataAreaSize, + 0, + volParams->headerFlags, + FormatSectorSize, + FALSE); + + if (nStatus != 0) + { + burn (header, sizeof (header)); + VirtualUnlock (header, sizeof (header)); + return nStatus; + } + +begin_format: + + if (volParams->bDevice) + { + /* Device-hosted volume */ + + DWORD dwResult; + int nPass; + + if (FakeDosNameForDevice (volParams->volumePath, dosDev, sizeof(dosDev), devName, sizeof(devName), FALSE) != 0) + return ERR_OS_ERROR; + + if (IsDeviceMounted (devName)) + { + if ((dev = DismountDrive (devName, volParams->volumePath)) == INVALID_HANDLE_VALUE) + { + Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); + nStatus = ERR_DONT_REPORT; + goto error; + } + + /* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver + would otherwise prevent us from writing to hidden sectors). */ + + if (!DeviceIoControl (dev, + FSCTL_ALLOW_EXTENDED_DASD_IO, + NULL, + 0, + NULL, + 0, + &dwResult, + NULL)) + { + bFailedRequiredDASD = TRUE; + } + } + else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1) + { + // Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition + // to which no drive letter has been assigned under the system. This problem can be worked + // around by assigning a drive letter to the partition temporarily. + + wchar_t szDriveLetter[] = { L'A', L':', 0 }; + wchar_t rootPath[] = { L'A', L':', L'\\', 0 }; + wchar_t uniqVolName[MAX_PATH+1] = { 0 }; + int tmpDriveLetter = -1; + BOOL bResult = FALSE; + + tmpDriveLetter = GetFirstAvailableDrive (); + + if (tmpDriveLetter != -1) + { + rootPath[0] += (wchar_t) tmpDriveLetter; + szDriveLetter[0] += (wchar_t) tmpDriveLetter; + + if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, volParams->volumePath)) + { + bResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH); + + DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE, + szDriveLetter, + volParams->volumePath); + + if (bResult + && SetVolumeMountPoint (rootPath, uniqVolName)) + { + // The drive letter can be removed now + DeleteVolumeMountPoint (rootPath); + } + } + } + } + + // For extra safety, we will try to gain "raw" access to the partition. Note that this should actually be + // redundant because if the filesystem was mounted, we already tried to obtain DASD above. If we failed, + // bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, + // for extra safety, in case IsDeviceMounted() failed to detect a live filesystem, we will blindly + // send FSCTL_ALLOW_EXTENDED_DASD_IO (possibly for a second time) without checking the result. + + DeviceIoControl (dev, + FSCTL_ALLOW_EXTENDED_DASD_IO, + NULL, + 0, + NULL, + 0, + &dwResult, + NULL); + + + // If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open + // so that the filesystem driver does not prevent us from formatting hidden sectors. + for (nPass = (bFailedRequiredDASD ? 0 : 1); nPass < 2; nPass++) + { + int retryCount; + + retryCount = 0; + + // Try exclusive access mode first + // Note that when exclusive access is denied, it is worth retrying (usually succeeds after a few tries). + while (dev == INVALID_HANDLE_VALUE && retryCount++ < EXCL_ACCESS_MAX_AUTO_RETRIES) + { + dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (retryCount > 1) + Sleep (EXCL_ACCESS_AUTO_RETRY_DELAY); + } + + if (dev == INVALID_HANDLE_VALUE) + { + // Exclusive access denied -- retry in shared mode + dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (dev != INVALID_HANDLE_VALUE) + { + if (!volParams->bForceOperation && (Silent || (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2)))) + { + nStatus = ERR_DONT_REPORT; + goto error; + } + } + else + { + handleWin32Error (volParams->hwndDlg, SRC_POS); + Error ("CANT_ACCESS_VOL", hwndDlg); + nStatus = ERR_DONT_REPORT; + goto error; + } + } + + if (volParams->hiddenVol || bInstantRetryOtherFilesys) + break; // The following "quick format" operation would damage the outer volume + + if (nPass == 0) + { + char buf [2 * TC_MAX_VOLUME_SECTOR_SIZE]; + DWORD bw; + + // Perform pseudo "quick format" so that the filesystem driver does not prevent us from + // formatting hidden sectors + memset (buf, 0, sizeof (buf)); + + if (!WriteFile (dev, buf, sizeof (buf), &bw, NULL)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + FlushFileBuffers (dev); + CloseHandle (dev); + dev = INVALID_HANDLE_VALUE; + } + } + + if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL)) + { + Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); + nStatus = ERR_DONT_REPORT; + goto error; + } + } + else + { + /* File-hosted volume */ + + dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE, + (volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0, + NULL, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL); + + if (dev == INVALID_HANDLE_VALUE) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + DisableFileCompression (dev); + + if (!volParams->hiddenVol && !bInstantRetryOtherFilesys) + { + LARGE_INTEGER volumeSize; + volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE; + + if (volParams->sparseFileSwitch && volParams->quickFormat) + { + // Create as sparse file container + DWORD tmp; + if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + } + + // Preallocate the file + if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN) + || !SetEndOfFile (dev) + || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0) + { + nStatus = ERR_OS_ERROR; + goto error; + } + } + } + + if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp) + { + if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0) + bTimeStampValid = FALSE; + else + bTimeStampValid = TRUE; + } + + if (volParams->hwndDlg && volParams->bGuiMode) KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW); + + /* Volume header */ + + // Hidden volume setup + if (volParams->hiddenVol) + { + LARGE_INTEGER headerOffset; + + // Check hidden volume size + if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE) + { + nStatus = ERR_VOL_SIZE_WRONG; + goto error; + } + + // Seek to hidden volume header location + + headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET; + + if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + } + else if (bInstantRetryOtherFilesys) + { + // The previous file system format failed and the user wants to try again with a different file system. + // The volume header had been written successfully so we need to seek to the byte after the header. + + LARGE_INTEGER offset; + offset.QuadPart = TC_VOLUME_DATA_OFFSET; + if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + } + + if (!bInstantRetryOtherFilesys) + { + // Write the volume header + if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + // To prevent fragmentation, write zeroes to reserved header sectors which are going to be filled with random data + if (!volParams->bDevice && !volParams->hiddenVol) + { + byte buf[TC_VOLUME_HEADER_GROUP_SIZE - TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + DWORD bytesWritten; + ZeroMemory (buf, sizeof (buf)); + + if (!WriteFile (dev, buf, sizeof (buf), &bytesWritten, NULL)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + if (bytesWritten != sizeof (buf)) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + } + } + + if (volParams->hiddenVol) + { + // Calculate data area position of hidden volume + cryptoInfo->hiddenVolumeOffset = dataOffset; + + // Validate the offset + if (dataOffset % FormatSectorSize != 0) + { + nStatus = ERR_VOL_SIZE_WRONG; + goto error; + } + + volParams->quickFormat = TRUE; // To entirely format a hidden volume would be redundant + } + + /* Data area */ + startSector = dataOffset / FormatSectorSize; + + // Format filesystem + + switch (volParams->fileSystem) + { + case FILESYS_NONE: + case FILESYS_NTFS: + case FILESYS_EXFAT: + + if (volParams->bDevice && !StartFormatWriteThread()) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat); + + if (volParams->bDevice) + StopFormatWriteThread(); + + break; + + case FILESYS_FAT: + if (num_sectors > 0xFFFFffff) + { + nStatus = ERR_VOL_SIZE_WRONG; + goto error; + } + + // Calculate the fats, root dir etc + ft.num_sectors = (unsigned int) (num_sectors); + +#if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF +#error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF +#endif + + ft.sector_size = (uint16) FormatSectorSize; + ft.cluster_size = volParams->clusterSize; + memcpy (ft.volume_name, "NO NAME ", 11); + GetFatParams (&ft); + *(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize; + + if (volParams->bDevice && !StartFormatWriteThread()) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat); + + if (volParams->bDevice) + StopFormatWriteThread(); + + break; + + default: + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + if (nStatus != ERR_SUCCESS) + goto error; + + // Write header backup + offset.QuadPart = volParams->hiddenVol ? volParams->hiddenVolHostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET : dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE; + + if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, + header, + volParams->ea, + FIRST_MODE_OF_OPERATION_ID, + volParams->password, + volParams->pkcs5, + volParams->pim, + cryptoInfo->master_keydata, + &cryptoInfo, + dataAreaSize, + volParams->hiddenVol ? dataAreaSize : 0, + dataOffset, + dataAreaSize, + 0, + volParams->headerFlags, + FormatSectorSize, + FALSE); + + if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + // Fill reserved header sectors (including the backup header area) with random data + if (!volParams->hiddenVol) + { + nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE); + + if (nStatus != ERR_SUCCESS) + goto error; + } + +#ifndef DEBUG + if (volParams->quickFormat && volParams->fileSystem != FILESYS_NTFS && volParams->fileSystem != FILESYS_EXFAT) + Sleep (500); // User-friendly GUI +#endif + +error: + dwError = GetLastError(); + + burn (header, sizeof (header)); + VirtualUnlock (header, sizeof (header)); + + if (dev != INVALID_HANDLE_VALUE) + { + if (!volParams->bDevice && !volParams->hiddenVol && nStatus != 0) + { + // Remove preallocated part before closing file handle if format failed + if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0) + SetEndOfFile (dev); + } + + FlushFileBuffers (dev); + + if (bTimeStampValid) + SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime); + + CloseHandle (dev); + dev = INVALID_HANDLE_VALUE; + } + + if (nStatus != 0) + { + SetLastError(dwError); + goto fv_end; + } + + if (volParams->fileSystem == FILESYS_NTFS || volParams->fileSystem == FILESYS_EXFAT) + { + // Quick-format volume as NTFS + int driveNo = GetLastAvailableDrive (); + MountOptions mountOptions; + int retCode; + int fsType = (volParams->fileSystem == FILESYS_EXFAT)? FILESYS_EXFAT: FILESYS_NTFS; + + ZeroMemory (&mountOptions, sizeof (mountOptions)); + + if (driveNo == -1) + { + if (!Silent) + { + MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND); + MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); + } + + nStatus = ERR_NO_FREE_DRIVES; + goto fv_end; + } + + mountOptions.ReadOnly = FALSE; + mountOptions.Removable = FALSE; + mountOptions.ProtectHiddenVolume = FALSE; + mountOptions.PreserveTimestamp = bPreserveTimestamp; + mountOptions.PartitionInInactiveSysEncScope = FALSE; + mountOptions.UseBackupHeader = FALSE; + + if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1) + { + if (!Silent) + { + MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND); + MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); + } + nStatus = ERR_VOL_MOUNT_FAILED; + goto fv_end; + } + + if (!Silent && !IsAdmin () && IsUacSupported ()) + retCode = UacFormatFs (volParams->hwndDlg, driveNo, volParams->clusterSize, fsType); + else + retCode = FormatFs (driveNo, volParams->clusterSize, fsType); + + if (retCode != TRUE) + { + if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) + MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); + + if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize) + { + if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT", hwndDlg) == IDYES) + { + // NTFS format failed and the user wants to try FAT format immediately + volParams->fileSystem = FILESYS_FAT; + bInstantRetryOtherFilesys = TRUE; + volParams->quickFormat = TRUE; // Volume has already been successfully TC-formatted + volParams->clusterSize = 0; // Default cluster size + goto begin_format; + } + } + else + Error ("FORMAT_NTFS_FAILED", hwndDlg); + + nStatus = ERR_DONT_REPORT; + goto fv_end; + } + + if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) + MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); + } + +fv_end: + dwError = GetLastError(); + + if (dosDev[0]) + RemoveFakeDosName (volParams->volumePath, dosDev); + + crypto_close (cryptoInfo); + + SetLastError (dwError); + return nStatus; +} + + +int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat) +{ + int write_buf_cnt = 0; + char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf; + unsigned __int64 nSecNo = startSector; + int retVal = 0; + DWORD err; + char temporaryKey[MASTER_KEYDATA_SIZE]; + char originalK2[MASTER_KEYDATA_SIZE]; + + LARGE_INTEGER startOffset; + LARGE_INTEGER newOffset; + + // Seek to start sector + startOffset.QuadPart = startSector * FormatSectorSize; + if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN) + || newOffset.QuadPart != startOffset.QuadPart) + { + return ERR_OS_ERROR; + } + + write_buf = (char *)TCalloc (FormatWriteBufferSize); + if (!write_buf) + return ERR_OUTOFMEMORY; + + VirtualLock (temporaryKey, sizeof (temporaryKey)); + VirtualLock (originalK2, sizeof (originalK2)); + + memset (sector, 0, sizeof (sector)); + + // Remember the original secondary key (XTS mode) before generating a temporary one + memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2)); + + /* Fill the rest of the data area with random data */ + + if(!quickFormat) + { + /* Generate a random temporary key set to be used for "dummy" encryption that will fill + the free disk space (data area) with random data. This is necessary for plausible + deniability of hidden volumes. */ + + // Temporary master key + if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)) + goto fail; + + // Temporary secondary key (XTS mode) + if (!RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE)) + goto fail; + + retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks); + if (retVal != ERR_SUCCESS) + goto fail; + + if (!EAInitMode (cryptoInfo)) + { + retVal = ERR_MODE_INIT_FAILED; + goto fail; + } + + while (num_sectors--) + { + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + cryptoInfo) == FALSE) + goto fail; + } + + if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) + goto fail; + } + else + nSecNo = num_sectors; + + UpdateProgressBar (nSecNo * FormatSectorSize); + + // Restore the original secondary key (XTS mode) in case NTFS format fails and the user wants to try FAT immediately + memcpy (cryptoInfo->k2, originalK2, sizeof (cryptoInfo->k2)); + + // Reinitialize the encryption algorithm and mode in case NTFS format fails and the user wants to try FAT immediately + retVal = EAInit (cryptoInfo->ea, cryptoInfo->master_keydata, cryptoInfo->ks); + if (retVal != ERR_SUCCESS) + goto fail; + if (!EAInitMode (cryptoInfo)) + { + retVal = ERR_MODE_INIT_FAILED; + goto fail; + } + + burn (temporaryKey, sizeof(temporaryKey)); + burn (originalK2, sizeof(originalK2)); + VirtualUnlock (temporaryKey, sizeof (temporaryKey)); + VirtualUnlock (originalK2, sizeof (originalK2)); + TCfree (write_buf); + + return 0; + +fail: + err = GetLastError(); + + burn (temporaryKey, sizeof(temporaryKey)); + burn (originalK2, sizeof(originalK2)); + VirtualUnlock (temporaryKey, sizeof (temporaryKey)); + VirtualUnlock (originalK2, sizeof (originalK2)); + TCfree (write_buf); + + SetLastError (err); + return (retVal ? retVal : ERR_OS_ERROR); +} + + +volatile BOOLEAN FormatExError; + +BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter) { if (FormatExError) return FALSE; @@ -859,250 +859,250 @@ BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID paramet FormatExError = TRUE; break; } - return (FormatExError? FALSE : TRUE); -} - -BOOL FormatFs (int driveNo, int clusterSize, int fsType) -{ - wchar_t dllPath[MAX_PATH] = {0}; - WCHAR dir[8] = { (WCHAR) driveNo + L'A', 0 }; - PFORMATEX FormatEx; - HMODULE hModule; - int i; - WCHAR szFsFormat[16]; - WCHAR szLabel[2] = {0}; - switch (fsType) - { - case FILESYS_NTFS: - StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"NTFS"); - break; - case FILESYS_EXFAT: - StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"EXFAT"); - break; - default: - return FALSE; - } - - - if (GetSystemDirectory (dllPath, MAX_PATH)) - { - StringCchCatW(dllPath, ARRAYSIZE(dllPath), L"\\fmifs.dll"); - } - else - StringCchCopyW(dllPath, ARRAYSIZE(dllPath), L"C:\\Windows\\System32\\fmifs.dll"); - - hModule = LoadLibrary (dllPath); - - if (hModule == NULL) - return FALSE; - - if (!(FormatEx = (PFORMATEX) GetProcAddress (GetModuleHandle (L"fmifs.dll"), "FormatEx"))) - { - FreeLibrary (hModule); - return FALSE; - } - - StringCchCatW (dir, ARRAYSIZE(dir), L":\\"); - - FormatExError = TRUE; - - // Windows sometimes fails to format a volume (hosted on a removable medium) as NTFS. - // It often helps to retry several times. - for (i = 0; i < 50 && FormatExError; i++) - { - FormatExError = FALSE; - FormatEx (dir, FMIFS_HARDDISK, szFsFormat, szLabel, TRUE, clusterSize * FormatSectorSize, FormatExCallback); - } - - // The device may be referenced for some time after FormatEx() returns - Sleep (4000); - - FreeLibrary (hModule); - return FormatExError? FALSE : TRUE; -} - -BOOL FormatNtfs (int driveNo, int clusterSize) -{ - return FormatFs (driveNo, clusterSize, FILESYS_NTFS); -} - -BOOL WriteSector (void *dev, char *sector, - char *write_buf, int *write_buf_cnt, - __int64 *nSecNo, PCRYPTO_INFO cryptoInfo) -{ - static __int32 updateTime = 0; - - (*nSecNo)++; - - memcpy (write_buf + *write_buf_cnt, sector, FormatSectorSize); - (*write_buf_cnt) += FormatSectorSize; - - if (*write_buf_cnt == FormatWriteBufferSize && !FlushFormatWriteBuffer (dev, write_buf, write_buf_cnt, nSecNo, cryptoInfo)) - return FALSE; - - if (GetTickCount () - updateTime > 25) - { - if (UpdateProgressBar (*nSecNo * FormatSectorSize)) - return FALSE; - - updateTime = GetTickCount (); - } - - return TRUE; - -} - - -static volatile BOOL WriteThreadRunning; -static volatile BOOL WriteThreadExitRequested; -static HANDLE WriteThreadHandle; - -static byte *WriteThreadBuffer; -static HANDLE WriteBufferEmptyEvent; -static HANDLE WriteBufferFullEvent; - -static volatile HANDLE WriteRequestHandle; -static volatile int WriteRequestSize; -static volatile DWORD WriteRequestResult; - - -static void __cdecl FormatWriteThreadProc (void *arg) -{ - DWORD bytesWritten; - - SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - - while (!WriteThreadExitRequested) - { - if (WaitForSingleObject (WriteBufferFullEvent, INFINITE) == WAIT_FAILED) - { - handleWin32Error (NULL, SRC_POS); - break; - } - - if (WriteThreadExitRequested) - break; - - if (!WriteFile (WriteRequestHandle, WriteThreadBuffer, WriteRequestSize, &bytesWritten, NULL)) - WriteRequestResult = GetLastError(); - else - WriteRequestResult = ERROR_SUCCESS; - - if (!SetEvent (WriteBufferEmptyEvent)) - { - handleWin32Error (NULL, SRC_POS); - break; - } - } - - WriteThreadRunning = FALSE; - _endthread(); -} - - -static BOOL StartFormatWriteThread () -{ - DWORD sysErr; - - WriteBufferEmptyEvent = NULL; - WriteBufferFullEvent = NULL; - WriteThreadBuffer = NULL; - - WriteBufferEmptyEvent = CreateEvent (NULL, FALSE, TRUE, NULL); - if (!WriteBufferEmptyEvent) - goto err; - - WriteBufferFullEvent = CreateEvent (NULL, FALSE, FALSE, NULL); - if (!WriteBufferFullEvent) - goto err; - - WriteThreadBuffer = TCalloc (FormatWriteBufferSize); - if (!WriteThreadBuffer) - { - SetLastError (ERROR_OUTOFMEMORY); - goto err; - } - - WriteThreadExitRequested = FALSE; - WriteRequestResult = ERROR_SUCCESS; - - WriteThreadHandle = (HANDLE) _beginthread (FormatWriteThreadProc, 0, NULL); - if ((uintptr_t) WriteThreadHandle == -1L) - goto err; - - WriteThreadRunning = TRUE; - return TRUE; - -err: - sysErr = GetLastError(); - - if (WriteBufferEmptyEvent) - CloseHandle (WriteBufferEmptyEvent); - if (WriteBufferFullEvent) - CloseHandle (WriteBufferFullEvent); - if (WriteThreadBuffer) - TCfree (WriteThreadBuffer); - - SetLastError (sysErr); - return FALSE; -} - - -static void StopFormatWriteThread () -{ - if (WriteThreadRunning) - { - WaitForSingleObject (WriteBufferEmptyEvent, INFINITE); - - WriteThreadExitRequested = TRUE; - SetEvent (WriteBufferFullEvent); - - WaitForSingleObject (WriteThreadHandle, INFINITE); - } - - CloseHandle (WriteBufferEmptyEvent); - CloseHandle (WriteBufferFullEvent); - TCfree (WriteThreadBuffer); -} - - -BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __int64 *nSecNo, PCRYPTO_INFO cryptoInfo) -{ - UINT64_STRUCT unitNo; - DWORD bytesWritten; - - if (*write_buf_cnt == 0) - return TRUE; - - unitNo.Value = (*nSecNo * FormatSectorSize - *write_buf_cnt) / ENCRYPTION_DATA_UNIT_SIZE; - - EncryptDataUnits (write_buf, &unitNo, *write_buf_cnt / ENCRYPTION_DATA_UNIT_SIZE, cryptoInfo); - - if (WriteThreadRunning) - { - if (WaitForSingleObject (WriteBufferEmptyEvent, INFINITE) == WAIT_FAILED) - return FALSE; - - if (WriteRequestResult != ERROR_SUCCESS) - { - SetEvent (WriteBufferEmptyEvent); - SetLastError (WriteRequestResult); - return FALSE; - } - - memcpy (WriteThreadBuffer, write_buf, *write_buf_cnt); - WriteRequestHandle = dev; - WriteRequestSize = *write_buf_cnt; - - if (!SetEvent (WriteBufferFullEvent)) - return FALSE; - } - else - { - if (!WriteFile ((HANDLE) dev, write_buf, *write_buf_cnt, &bytesWritten, NULL)) - return FALSE; - } - - *write_buf_cnt = 0; - return TRUE; -} + return (FormatExError? FALSE : TRUE); +} + +BOOL FormatFs (int driveNo, int clusterSize, int fsType) +{ + wchar_t dllPath[MAX_PATH] = {0}; + WCHAR dir[8] = { (WCHAR) driveNo + L'A', 0 }; + PFORMATEX FormatEx; + HMODULE hModule; + int i; + WCHAR szFsFormat[16]; + WCHAR szLabel[2] = {0}; + switch (fsType) + { + case FILESYS_NTFS: + StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"NTFS"); + break; + case FILESYS_EXFAT: + StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"EXFAT"); + break; + default: + return FALSE; + } + + + if (GetSystemDirectory (dllPath, MAX_PATH)) + { + StringCchCatW(dllPath, ARRAYSIZE(dllPath), L"\\fmifs.dll"); + } + else + StringCchCopyW(dllPath, ARRAYSIZE(dllPath), L"C:\\Windows\\System32\\fmifs.dll"); + + hModule = LoadLibrary (dllPath); + + if (hModule == NULL) + return FALSE; + + if (!(FormatEx = (PFORMATEX) GetProcAddress (GetModuleHandle (L"fmifs.dll"), "FormatEx"))) + { + FreeLibrary (hModule); + return FALSE; + } + + StringCchCatW (dir, ARRAYSIZE(dir), L":\\"); + + FormatExError = TRUE; + + // Windows sometimes fails to format a volume (hosted on a removable medium) as NTFS. + // It often helps to retry several times. + for (i = 0; i < 50 && FormatExError; i++) + { + FormatExError = FALSE; + FormatEx (dir, FMIFS_HARDDISK, szFsFormat, szLabel, TRUE, clusterSize * FormatSectorSize, FormatExCallback); + } + + // The device may be referenced for some time after FormatEx() returns + Sleep (4000); + + FreeLibrary (hModule); + return FormatExError? FALSE : TRUE; +} + +BOOL FormatNtfs (int driveNo, int clusterSize) +{ + return FormatFs (driveNo, clusterSize, FILESYS_NTFS); +} + +BOOL WriteSector (void *dev, char *sector, + char *write_buf, int *write_buf_cnt, + __int64 *nSecNo, PCRYPTO_INFO cryptoInfo) +{ + static __int32 updateTime = 0; + + (*nSecNo)++; + + memcpy (write_buf + *write_buf_cnt, sector, FormatSectorSize); + (*write_buf_cnt) += FormatSectorSize; + + if (*write_buf_cnt == FormatWriteBufferSize && !FlushFormatWriteBuffer (dev, write_buf, write_buf_cnt, nSecNo, cryptoInfo)) + return FALSE; + + if (GetTickCount () - updateTime > 25) + { + if (UpdateProgressBar (*nSecNo * FormatSectorSize)) + return FALSE; + + updateTime = GetTickCount (); + } + + return TRUE; + +} + + +static volatile BOOL WriteThreadRunning; +static volatile BOOL WriteThreadExitRequested; +static HANDLE WriteThreadHandle; + +static byte *WriteThreadBuffer; +static HANDLE WriteBufferEmptyEvent; +static HANDLE WriteBufferFullEvent; + +static volatile HANDLE WriteRequestHandle; +static volatile int WriteRequestSize; +static volatile DWORD WriteRequestResult; + + +static void __cdecl FormatWriteThreadProc (void *arg) +{ + DWORD bytesWritten; + + SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + + while (!WriteThreadExitRequested) + { + if (WaitForSingleObject (WriteBufferFullEvent, INFINITE) == WAIT_FAILED) + { + handleWin32Error (NULL, SRC_POS); + break; + } + + if (WriteThreadExitRequested) + break; + + if (!WriteFile (WriteRequestHandle, WriteThreadBuffer, WriteRequestSize, &bytesWritten, NULL)) + WriteRequestResult = GetLastError(); + else + WriteRequestResult = ERROR_SUCCESS; + + if (!SetEvent (WriteBufferEmptyEvent)) + { + handleWin32Error (NULL, SRC_POS); + break; + } + } + + WriteThreadRunning = FALSE; + _endthread(); +} + + +static BOOL StartFormatWriteThread () +{ + DWORD sysErr; + + WriteBufferEmptyEvent = NULL; + WriteBufferFullEvent = NULL; + WriteThreadBuffer = NULL; + + WriteBufferEmptyEvent = CreateEvent (NULL, FALSE, TRUE, NULL); + if (!WriteBufferEmptyEvent) + goto err; + + WriteBufferFullEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + if (!WriteBufferFullEvent) + goto err; + + WriteThreadBuffer = TCalloc (FormatWriteBufferSize); + if (!WriteThreadBuffer) + { + SetLastError (ERROR_OUTOFMEMORY); + goto err; + } + + WriteThreadExitRequested = FALSE; + WriteRequestResult = ERROR_SUCCESS; + + WriteThreadHandle = (HANDLE) _beginthread (FormatWriteThreadProc, 0, NULL); + if ((uintptr_t) WriteThreadHandle == -1L) + goto err; + + WriteThreadRunning = TRUE; + return TRUE; + +err: + sysErr = GetLastError(); + + if (WriteBufferEmptyEvent) + CloseHandle (WriteBufferEmptyEvent); + if (WriteBufferFullEvent) + CloseHandle (WriteBufferFullEvent); + if (WriteThreadBuffer) + TCfree (WriteThreadBuffer); + + SetLastError (sysErr); + return FALSE; +} + + +static void StopFormatWriteThread () +{ + if (WriteThreadRunning) + { + WaitForSingleObject (WriteBufferEmptyEvent, INFINITE); + + WriteThreadExitRequested = TRUE; + SetEvent (WriteBufferFullEvent); + + WaitForSingleObject (WriteThreadHandle, INFINITE); + } + + CloseHandle (WriteBufferEmptyEvent); + CloseHandle (WriteBufferFullEvent); + TCfree (WriteThreadBuffer); +} + + +BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __int64 *nSecNo, PCRYPTO_INFO cryptoInfo) +{ + UINT64_STRUCT unitNo; + DWORD bytesWritten; + + if (*write_buf_cnt == 0) + return TRUE; + + unitNo.Value = (*nSecNo * FormatSectorSize - *write_buf_cnt) / ENCRYPTION_DATA_UNIT_SIZE; + + EncryptDataUnits (write_buf, &unitNo, *write_buf_cnt / ENCRYPTION_DATA_UNIT_SIZE, cryptoInfo); + + if (WriteThreadRunning) + { + if (WaitForSingleObject (WriteBufferEmptyEvent, INFINITE) == WAIT_FAILED) + return FALSE; + + if (WriteRequestResult != ERROR_SUCCESS) + { + SetEvent (WriteBufferEmptyEvent); + SetLastError (WriteRequestResult); + return FALSE; + } + + memcpy (WriteThreadBuffer, write_buf, *write_buf_cnt); + WriteRequestHandle = dev; + WriteRequestSize = *write_buf_cnt; + + if (!SetEvent (WriteBufferFullEvent)) + return FALSE; + } + else + { + if (!WriteFile ((HANDLE) dev, write_buf, *write_buf_cnt, &bytesWritten, NULL)) + return FALSE; + } + + *write_buf_cnt = 0; + return TRUE; +} -- cgit v1.2.3 From 11716ed2dacbb104f8f59867fe66f2c0a6984291 Mon Sep 17 00:00:00 2001 From: David Foerster Date: Tue, 10 May 2016 22:16:32 +0200 Subject: Remove trailing whitespace --- src/Common/Format.c | 82 ++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'src/Common/Format.c') diff --git a/src/Common/Format.c b/src/Common/Format.c index 43a96d04..f3114e5e 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -1,11 +1,11 @@ /* Legal Notice: Some portions of the source code contained in this file were - derived from the source code of TrueCrypt 7.1a, which is - Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux - and which is governed by the 'License Agreement for Encryption for the Masses' - Modifications and additions to the original source code (contained in this file) + and which is governed by the 'License Agreement for Encryption for the Masses' + Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2016 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source @@ -60,7 +60,7 @@ uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize) #if TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH < TC_MAX_VOLUME_SECTOR_SIZE # error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH too small. #endif - + if (volumeSize < TC_VOLUME_SMALL_SIZE_THRESHOLD) reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE; else @@ -108,16 +108,16 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) || FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) { Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); - return ERR_DONT_REPORT; + return ERR_DONT_REPORT; } /* WARNING: Note that if Windows fails to format the volume as NTFS and the volume size is less than the maximum FAT size, the user is asked within this function whether he wants to instantly retry FAT format instead (to avoid having to re-create the whole container again). If the user - answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed - and some destructive operations that were performed during the first attempt must be (and are) skipped. + answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed + and some destructive operations that were performed during the first attempt must be (and are) skipped. Therefore, whenever adding or modifying any potentially destructive operations below 'begin_format', - determine whether they (or their portions) need to be skipped during such a second attempt; if so, + determine whether they (or their portions) need to be skipped during such a second attempt; if so, use the 'bInstantRetryOtherFilesys' flag to skip them. */ if (volParams->hiddenVol) @@ -187,17 +187,17 @@ begin_format: if ((dev = DismountDrive (devName, volParams->volumePath)) == INVALID_HANDLE_VALUE) { Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); - nStatus = ERR_DONT_REPORT; + nStatus = ERR_DONT_REPORT; goto error; } - /* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver + /* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver would otherwise prevent us from writing to hidden sectors). */ if (!DeviceIoControl (dev, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, - 0, + 0, NULL, 0, &dwResult, @@ -208,7 +208,7 @@ begin_format: } else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1) { - // Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition + // Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition // to which no drive letter has been assigned under the system. This problem can be worked // around by assigning a drive letter to the partition temporarily. @@ -219,7 +219,7 @@ begin_format: BOOL bResult = FALSE; tmpDriveLetter = GetFirstAvailableDrive (); - + if (tmpDriveLetter != -1) { rootPath[0] += (wchar_t) tmpDriveLetter; @@ -233,7 +233,7 @@ begin_format: szDriveLetter, volParams->volumePath); - if (bResult + if (bResult && SetVolumeMountPoint (rootPath, uniqVolName)) { // The drive letter can be removed now @@ -245,21 +245,21 @@ begin_format: // For extra safety, we will try to gain "raw" access to the partition. Note that this should actually be // redundant because if the filesystem was mounted, we already tried to obtain DASD above. If we failed, - // bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, + // bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, // for extra safety, in case IsDeviceMounted() failed to detect a live filesystem, we will blindly // send FSCTL_ALLOW_EXTENDED_DASD_IO (possibly for a second time) without checking the result. DeviceIoControl (dev, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, - 0, + 0, NULL, 0, &dwResult, NULL); - // If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open + // If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open // so that the filesystem driver does not prevent us from formatting hidden sectors. for (nPass = (bFailedRequiredDASD ? 0 : 1); nPass < 2; nPass++) { @@ -285,7 +285,7 @@ begin_format: { if (!volParams->bForceOperation && (Silent || (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2)))) { - nStatus = ERR_DONT_REPORT; + nStatus = ERR_DONT_REPORT; goto error; } } @@ -293,7 +293,7 @@ begin_format: { handleWin32Error (volParams->hwndDlg, SRC_POS); Error ("CANT_ACCESS_VOL", hwndDlg); - nStatus = ERR_DONT_REPORT; + nStatus = ERR_DONT_REPORT; goto error; } } @@ -306,13 +306,13 @@ begin_format: char buf [2 * TC_MAX_VOLUME_SECTOR_SIZE]; DWORD bw; - // Perform pseudo "quick format" so that the filesystem driver does not prevent us from + // Perform pseudo "quick format" so that the filesystem driver does not prevent us from // formatting hidden sectors memset (buf, 0, sizeof (buf)); if (!WriteFile (dev, buf, sizeof (buf), &bw, NULL)) { - nStatus = ERR_OS_ERROR; + nStatus = ERR_OS_ERROR; goto error; } @@ -325,7 +325,7 @@ begin_format: if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL)) { Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg); - nStatus = ERR_DONT_REPORT; + nStatus = ERR_DONT_REPORT; goto error; } } @@ -339,7 +339,7 @@ begin_format: if (dev == INVALID_HANDLE_VALUE) { - nStatus = ERR_OS_ERROR; + nStatus = ERR_OS_ERROR; goto error; } @@ -356,7 +356,7 @@ begin_format: DWORD tmp; if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL)) { - nStatus = ERR_OS_ERROR; + nStatus = ERR_OS_ERROR; goto error; } } @@ -391,13 +391,13 @@ begin_format: // Check hidden volume size if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE) - { + { nStatus = ERR_VOL_SIZE_WRONG; goto error; } // Seek to hidden volume header location - + headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET; if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN)) @@ -458,7 +458,7 @@ begin_format: // Validate the offset if (dataOffset % FormatSectorSize != 0) { - nStatus = ERR_VOL_SIZE_WRONG; + nStatus = ERR_VOL_SIZE_WRONG; goto error; } @@ -478,7 +478,7 @@ begin_format: if (volParams->bDevice && !StartFormatWriteThread()) { - nStatus = ERR_OS_ERROR; + nStatus = ERR_OS_ERROR; goto error; } @@ -488,11 +488,11 @@ begin_format: StopFormatWriteThread(); break; - + case FILESYS_FAT: if (num_sectors > 0xFFFFffff) { - nStatus = ERR_VOL_SIZE_WRONG; + nStatus = ERR_VOL_SIZE_WRONG; goto error; } @@ -506,12 +506,12 @@ begin_format: ft.sector_size = (uint16) FormatSectorSize; ft.cluster_size = volParams->clusterSize; memcpy (ft.volume_name, "NO NAME ", 11); - GetFatParams (&ft); + GetFatParams (&ft); *(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize; if (volParams->bDevice && !StartFormatWriteThread()) { - nStatus = ERR_OS_ERROR; + nStatus = ERR_OS_ERROR; goto error; } @@ -523,7 +523,7 @@ begin_format: break; default: - nStatus = ERR_PARAMETER_INCORRECT; + nStatus = ERR_PARAMETER_INCORRECT; goto error; } @@ -883,14 +883,14 @@ BOOL FormatFs (int driveNo, int clusterSize, int fsType) return FALSE; } - + if (GetSystemDirectory (dllPath, MAX_PATH)) { StringCchCatW(dllPath, ARRAYSIZE(dllPath), L"\\fmifs.dll"); } else StringCchCopyW(dllPath, ARRAYSIZE(dllPath), L"C:\\Windows\\System32\\fmifs.dll"); - + hModule = LoadLibrary (dllPath); if (hModule == NULL) @@ -905,7 +905,7 @@ BOOL FormatFs (int driveNo, int clusterSize, int fsType) StringCchCatW (dir, ARRAYSIZE(dir), L":\\"); FormatExError = TRUE; - + // Windows sometimes fails to format a volume (hosted on a removable medium) as NTFS. // It often helps to retry several times. for (i = 0; i < 50 && FormatExError; i++) @@ -939,7 +939,7 @@ BOOL WriteSector (void *dev, char *sector, if (*write_buf_cnt == FormatWriteBufferSize && !FlushFormatWriteBuffer (dev, write_buf, write_buf_cnt, nSecNo, cryptoInfo)) return FALSE; - + if (GetTickCount () - updateTime > 25) { if (UpdateProgressBar (*nSecNo * FormatSectorSize)) @@ -962,7 +962,7 @@ static HANDLE WriteBufferEmptyEvent; static HANDLE WriteBufferFullEvent; static volatile HANDLE WriteRequestHandle; -static volatile int WriteRequestSize; +static volatile int WriteRequestSize; static volatile DWORD WriteRequestResult; @@ -985,7 +985,7 @@ static void __cdecl FormatWriteThreadProc (void *arg) if (!WriteFile (WriteRequestHandle, WriteThreadBuffer, WriteRequestSize, &bytesWritten, NULL)) WriteRequestResult = GetLastError(); - else + else WriteRequestResult = ERROR_SUCCESS; if (!SetEvent (WriteBufferEmptyEvent)) @@ -1082,7 +1082,7 @@ BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __i { if (WaitForSingleObject (WriteBufferEmptyEvent, INFINITE) == WAIT_FAILED) return FALSE; - + if (WriteRequestResult != ERROR_SUCCESS) { SetEvent (WriteBufferEmptyEvent); -- cgit v1.2.3