diff options
-rw-r--r-- | src/Common/Fat.c | 63 | ||||
-rw-r--r-- | src/Common/Fat.h | 2 | ||||
-rw-r--r-- | src/Common/Format.c | 56 | ||||
-rw-r--r-- | src/Common/Format.h | 5 | ||||
-rw-r--r-- | src/Format/InPlace.h | 1 |
5 files changed, 104 insertions, 23 deletions
diff --git a/src/Common/Fat.c b/src/Common/Fat.c index cd2c124f..19720b17 100644 --- a/src/Common/Fat.c +++ b/src/Common/Fat.c @@ -255,11 +255,14 @@ static void PutFSInfo (unsigned char *sector, fatparams *ft) int -FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat) +FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat, BOOL bDevice) { int write_buf_cnt = 0; char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf; unsigned __int64 nSecNo = startSector; + unsigned __int64 nSkipSectors = 128 * (unsigned __int64) BYTES_PER_MB / ft->sector_size; + unsigned __int64 num_sectors; + DWORD bytesWritten; int x, n; int retVal; CRYPTOPP_ALIGN_DATA(16) char temporaryKey[MASTER_KEYDATA_SIZE]; @@ -288,7 +291,7 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void goto fail; PutBoot (ft, (unsigned char *) sector); - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; @@ -297,7 +300,7 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void { /* fsinfo */ PutFSInfo((unsigned char *) sector, ft); - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; @@ -307,7 +310,7 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void memset (sector, 0, ft->sector_size); sector[508+3]=0xaa; /* TrailSig */ sector[508+2]=0x55; - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; } @@ -315,12 +318,12 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void /* bootsector backup */ memset (sector, 0, ft->sector_size); PutBoot (ft, (unsigned char *) sector); - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; PutFSInfo((unsigned char *) sector, ft); - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; } @@ -329,7 +332,7 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void while (nSecNo - startSector < (unsigned int)ft->reserved) { memset (sector, 0, ft->sector_size); - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; } @@ -373,7 +376,7 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void } } - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; } @@ -384,7 +387,7 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void for (x = 0; x < ft->size_root_dir / ft->sector_size; x++) { memset (sector, 0, ft->sector_size); - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; @@ -450,11 +453,11 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void x = ft->num_sectors - ft->reserved - ft->size_root_dir / ft->sector_size - ft->fat_length * 2; while (x--) { - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; } - UpdateProgressBar (nSecNo * ft->sector_size); + UpdateProgressBar ((nSecNo - startSector) * ft->sector_size); if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) { @@ -466,6 +469,44 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void burn (&tmpCI, sizeof (tmpCI)); VirtualUnlock (&tmpCI, sizeof (tmpCI)); } + else if (!bDevice) + { + if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) + goto fail; + + // Quick format: write a zeroed sector every 128 MiB, leaving other sectors untouched + // This helps users visualize the progress of actual file creation while forcing Windows + // to allocate the disk space of each 128 MiB chunk immediately, otherwise, Windows + // would delay the allocation until we write the backup header at the end of the volume which + // would make the user think that the format process has stalled after progress bar reaches 100%. + num_sectors = ft->num_sectors - ft->reserved - ft->size_root_dir / ft->sector_size - ft->fat_length * 2; + while (num_sectors >= nSkipSectors) + { + // seek to next sector to be written + nSecNo += (nSkipSectors - 1); + startOffset.QuadPart = nSecNo * ft->sector_size; + if (!MoveFilePointer ((HANDLE) dev, startOffset)) + { + goto fail; + } + + // sector array has been zeroed above + if (!WriteFile ((HANDLE) dev, sector, ft->sector_size, &bytesWritten, NULL) + || bytesWritten != ft->sector_size) + { + goto fail; + } + + nSecNo++; + num_sectors -= nSkipSectors; + + if (UpdateProgressBar ((nSecNo - startSector)* ft->sector_size)) + goto fail; + } + + nSecNo += num_sectors; + UpdateProgressBar ((nSecNo - startSector)* ft->sector_size); + } else { UpdateProgressBar ((uint64) ft->num_sectors * ft->sector_size); diff --git a/src/Common/Fat.h b/src/Common/Fat.h index 375b9dc2..b2457be2 100644 --- a/src/Common/Fat.h +++ b/src/Common/Fat.h @@ -66,4 +66,4 @@ struct msdos_boot_sector void GetFatParams ( fatparams *ft ); void PutBoot ( fatparams *ft , unsigned char *boot ); -int FormatFat (void* hwndDlg, unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat); +int FormatFat (void* hwndDlg, unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat, BOOL bDevice); diff --git a/src/Common/Format.c b/src/Common/Format.c index f34ee39b..15ca9518 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -538,7 +538,7 @@ begin_format: goto error; } - nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat); + nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat, volParams->bDevice); if (volParams->bDevice) StopFormatWriteThread(); @@ -571,7 +571,7 @@ begin_format: goto error; } - nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat); + nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat, volParams->bDevice); if (volParams->bDevice) StopFormatWriteThread(); @@ -847,11 +847,13 @@ fv_end: } -int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat) +int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, unsigned __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat, BOOL bDevice) { int write_buf_cnt = 0; char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf; unsigned __int64 nSecNo = startSector; + unsigned __int64 nSkipSectors = 128 * (unsigned __int64) BYTES_PER_MB / FormatSectorSize; + DWORD bytesWritten; int retVal = 0; DWORD err; CRYPTOPP_ALIGN_DATA(16) char temporaryKey[MASTER_KEYDATA_SIZE]; @@ -927,18 +929,56 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, while (num_sectors--) { - if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, + if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, startSector, cryptoInfo) == FALSE) goto fail; } + if (UpdateProgressBar ((nSecNo - startSector) * FormatSectorSize)) + return FALSE; + if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) goto fail; } + else if (!bDevice) + { + // Quick format: write a zeroed sector every 128 MiB, leaving other sectors untouched + // This helps users visualize the progress of actual file creation while forcing Windows + // to allocate the disk space of each 128 MiB chunk immediately, otherwise, Windows + // would delay the allocation until we write the backup header at the end of the volume which + // would make the user think that the format process has stalled after progress bar reaches 100%. + while (num_sectors >= nSkipSectors) + { + // seek to next sector to be written + nSecNo += (nSkipSectors - 1); + startOffset.QuadPart = nSecNo * FormatSectorSize; + if (!MoveFilePointer ((HANDLE) dev, startOffset)) + { + goto fail; + } + + // sector array has been zeroed above + if (!WriteFile ((HANDLE) dev, sector, FormatSectorSize, &bytesWritten, NULL) + || bytesWritten != FormatSectorSize) + { + goto fail; + } + + nSecNo++; + num_sectors -= nSkipSectors; + + if (UpdateProgressBar ((nSecNo - startSector)* FormatSectorSize)) + goto fail; + } + + nSecNo += num_sectors; + } else - nSecNo = num_sectors; + { + nSecNo += num_sectors; + } - UpdateProgressBar (nSecNo * FormatSectorSize); + UpdateProgressBar ((nSecNo - startSector) * 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)); @@ -1269,7 +1309,7 @@ BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType) BOOL WriteSector (void *dev, char *sector, char *write_buf, int *write_buf_cnt, - __int64 *nSecNo, PCRYPTO_INFO cryptoInfo) + unsigned __int64 *nSecNo, unsigned __int64 startSector, PCRYPTO_INFO cryptoInfo) { static __int32 updateTime = 0; @@ -1283,7 +1323,7 @@ BOOL WriteSector (void *dev, char *sector, if (GetTickCount () - updateTime > 25) { - if (UpdateProgressBar (*nSecNo * FormatSectorSize)) + if (UpdateProgressBar ((*nSecNo - startSector) * FormatSectorSize)) return FALSE; updateTime = GetTickCount (); diff --git a/src/Common/Format.h b/src/Common/Format.h index 139607e5..f5d65f14 100644 --- a/src/Common/Format.h +++ b/src/Common/Format.h @@ -78,11 +78,12 @@ BOOL FormatNtfs (int driveNo, int clusterSize); BOOL FormatFs (int driveNo, int clusterSize, int fsType); BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType); uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize); -int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, void *dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat); -BOOL WriteSector ( void *dev , char *sector , char *write_buf , int *write_buf_cnt , __int64 *nSecNo , PCRYPTO_INFO cryptoInfo ); +int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, unsigned __int64 num_sectors, void *dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat, BOOL bDevice); +BOOL WriteSector ( void *dev , char *sector , char *write_buf , int *write_buf_cnt , unsigned __int64 *nSecNo , unsigned __int64 startSector, PCRYPTO_INFO cryptoInfo ); BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __int64 *nSecNo, PCRYPTO_INFO cryptoInfo); static BOOL StartFormatWriteThread (); static void StopFormatWriteThread (); +BOOL MoveFilePointer (HANDLE dev, LARGE_INTEGER offset); #define FILESYS_NONE 0 #define FILESYS_FAT 1 diff --git a/src/Format/InPlace.h b/src/Format/InPlace.h index f2d97bed..717a8ed3 100644 --- a/src/Format/InPlace.h +++ b/src/Format/InPlace.h @@ -43,7 +43,6 @@ static int DismountFileSystem (HWND hwndDlg, HANDLE dev, int driveLetter, BOOL b static int ConcealNTFS (HANDLE dev); BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId wipeAlgorithm, BOOL bDecrypting); static void ExportProgressStats (__int64 bytesDone, __int64 totalSize); -BOOL MoveFilePointer (HANDLE dev, LARGE_INTEGER offset); int ZeroUnreadableSectors (HANDLE dev, LARGE_INTEGER startOffset, int64 size, int sectorSize, uint64 *zeroedSectorCount); static int OpenBackupHeader (HANDLE dev, const wchar_t *devicePath, Password *password, int pkcs5, int pim, PCRYPTO_INFO *retCryptoInfo, CRYPTO_INFO *headerCryptoInfo, __int64 deviceSize); BOOL MoveClustersBeforeThreshold (HANDLE volumeHandle, PWSTR volumeDevicePath, int64 clusterThreshold); |