VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Format.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Format.c')
-rw-r--r--src/Common/Format.c436
1 files changed, 403 insertions, 33 deletions
diff --git a/src/Common/Format.c b/src/Common/Format.c
index bd33f754..4d8dfed9 100644
--- a/src/Common/Format.c
+++ b/src/Common/Format.c
@@ -100,6 +100,10 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams)
LARGE_INTEGER offset;
BOOL bFailedRequiredDASD = FALSE;
HWND hwndDlg = volParams->hwndDlg;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+ PCRYPTO_INFO cryptoInfoBackup = NULL;
+#endif
FormatSectorSize = volParams->sectorSize;
@@ -214,7 +218,7 @@ begin_format:
bFailedRequiredDASD = TRUE;
}
}
- else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1)
+ else if (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
@@ -340,6 +344,32 @@ begin_format:
else
{
/* File-hosted volume */
+ BOOL speedupFileCreation = FALSE;
+ BOOL delayedSpeedupFileCreation = FALSE;
+ // speedup for file creation only makes sens when using quick format for non hidden volumes
+ if (!volParams->hiddenVol && !bInstantRetryOtherFilesys && volParams->quickFormat && volParams->fastCreateFile)
+ {
+ // we set required privileges to speedup file creation before we create the file so that the file handle inherits the privileges
+ if (!SetPrivilege(SE_MANAGE_VOLUME_NAME, TRUE))
+ {
+ DWORD dwLastError = GetLastError();
+ if (!IsAdmin () && IsUacSupported ())
+ {
+ speedupFileCreation = TRUE;
+ delayedSpeedupFileCreation = TRUE;
+ }
+ else if (Silent || (MessageBoxW(hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_MANAGE_VOLUME"), lpszTitle, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDNO))
+ {
+ SetLastError(dwLastError);
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+ }
+ else
+ {
+ speedupFileCreation = TRUE;
+ }
+ }
dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE,
(volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
@@ -350,6 +380,19 @@ begin_format:
nStatus = ERR_OS_ERROR;
goto error;
}
+ else if (volParams->hiddenVol && bPreserveTimestamp)
+ {
+ // ensure that Last Access and Last Write timestamps are not modified
+ ftLastAccessTime.dwHighDateTime = 0xFFFFFFFF;
+ ftLastAccessTime.dwLowDateTime = 0xFFFFFFFF;
+
+ SetFileTime (dev, NULL, &ftLastAccessTime, NULL);
+
+ if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
+ bTimeStampValid = FALSE;
+ else
+ bTimeStampValid = TRUE;
+ }
DisableFileCompression (dev);
@@ -369,23 +412,72 @@ begin_format:
}
}
- // Preallocate the file
- if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
- || !SetEndOfFile (dev)
- || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
+ if (!delayedSpeedupFileCreation)
+ {
+ // Preallocate the file
+ if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
+ || !SetEndOfFile (dev))
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+ }
+
+ if (speedupFileCreation)
+ {
+ // accelerate file creation by telling Windows not to fill all file content with zeros
+ // this has security issues since it will put existing disk content into file container
+ // We use this mechanism only when switch /fastCreateFile specific and when quick format
+ // also specified and which is documented to have security issues.
+ if (delayedSpeedupFileCreation)
+ {
+ // in case of delayed speedup we need to set the file size to a minimal value before performing the real preallocation through UAC
+ LARGE_INTEGER minimalSize;
+ DWORD dwOpStatus;
+ // 16K
+ minimalSize.QuadPart = 16 * 1024;
+ if (!SetFilePointerEx (dev, minimalSize, NULL, FILE_BEGIN)
+ || !SetEndOfFile (dev))
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+
+ FlushFileBuffers (dev);
+ CloseHandle (dev);
+ dev = INVALID_HANDLE_VALUE;
+
+ dwOpStatus = UacFastFileCreation (volParams->hwndDlg, volParams->volumePath, volumeSize.QuadPart);
+ if (dwOpStatus != 0)
+ {
+ SetLastError(dwOpStatus);
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+
+ // open again the file now that it was created
+ dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (dev == INVALID_HANDLE_VALUE)
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+ }
+ else if (!SetFileValidData (dev, volumeSize.QuadPart))
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+ }
+
+ if (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);
@@ -491,7 +583,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();
@@ -524,7 +616,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();
@@ -548,6 +640,17 @@ begin_format:
goto error;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfoBackup = cryptoInfo;
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
header,
volParams->ea,
@@ -566,6 +669,15 @@ begin_format:
FormatSectorSize,
FALSE);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ cryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
+
if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
{
nStatus = ERR_OS_ERROR;
@@ -577,8 +689,28 @@ begin_format:
{
BOOL bUpdateBackup = FALSE;
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfoBackup = cryptoInfo;
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ cryptoInfo = cryptoInfoBackup;
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
+
if (nStatus != ERR_SUCCESS)
goto error;
@@ -692,13 +824,13 @@ error:
}
mountOptions.ReadOnly = FALSE;
- mountOptions.Removable = FALSE;
+ mountOptions.Removable = TRUE; /* mount as removal media to allow formatting without admin rights */
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 (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, TRUE, &mountOptions, Silent, TRUE) < 1)
{
if (!Silent)
{
@@ -709,12 +841,25 @@ error:
goto fv_end;
}
- if (!Silent && !IsAdmin () && IsUacSupported ())
- retCode = UacFormatFs (volParams->hwndDlg, driveNo, volParams->clusterSize, fsType);
- else
- retCode = FormatFs (driveNo, volParams->clusterSize, fsType);
+ retCode = ExternalFormatFs (driveNo, volParams->clusterSize, fsType);
+ if (retCode != 0)
+ {
+
+ /* fallback to using FormatEx function from fmifs.dll */
+ if (!Silent && !IsAdmin () && IsUacSupported ())
+ retCode = UacFormatFs (volParams->hwndDlg, driveNo, volParams->clusterSize, fsType);
+ else
+ retCode = FormatFs (driveNo, volParams->clusterSize, fsType, FALSE); /* no need to fallback to format.com since we have already tried it without elevation */
+
+ if (retCode != 0)
+ {
+ wchar_t auxLine[2048];
+ StringCbPrintfW (auxLine, sizeof(auxLine), GetString ("FORMATEX_API_FAILED"), FormatExGetMessage(retCode));
+ ErrorDirect(auxLine, volParams->hwndDlg);
+ }
+ }
- if (retCode != TRUE)
+ if (retCode != 0)
{
if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent)
MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
@@ -755,11 +900,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];
@@ -768,6 +915,10 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
LARGE_INTEGER startOffset;
LARGE_INTEGER newOffset;
+#ifdef _WIN64
+ CRYPTO_INFO tmpCI;
+#endif
+
// Seek to start sector
startOffset.QuadPart = startSector * FormatSectorSize;
if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
@@ -785,6 +936,16 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
memset (sector, 0, sizeof (sector));
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ VirtualLock (&tmpCI, sizeof (tmpCI));
+ memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO));
+ VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo));
+ cryptoInfo = &tmpCI;
+ }
+#endif
+
// Remember the original secondary key (XTS mode) before generating a temporary one
memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
@@ -814,20 +975,63 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
goto fail;
}
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ VcProtectKeys (cryptoInfo, VcGetEncryptionID (cryptoInfo));
+#endif
+
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));
@@ -847,6 +1051,13 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors,
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
TCfree (write_buf);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
return 0;
@@ -858,6 +1069,13 @@ fail:
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
TCfree (write_buf);
+#ifdef _WIN64
+ if (IsRamEncryptionEnabled ())
+ {
+ burn (&tmpCI, sizeof (CRYPTO_INFO));
+ VirtualUnlock (&tmpCI, sizeof (tmpCI));
+ }
+#endif
SetLastError (err);
return (retVal ? retVal : ERR_OS_ERROR);
@@ -865,6 +1083,46 @@ fail:
volatile BOOLEAN FormatExError;
+volatile int FormatExErrorCommand;
+
+LPCWSTR FormatExGetMessage (int command)
+{
+ static WCHAR h_szMsg[32];
+ switch (command)
+ {
+ case FMIFS_DONE:
+ return L"FORMAT_FINISHED";
+ case FMIFS_STRUCTURE_PROGRESS:
+ return L"FORMAT_STRUCTURE_PROGRESS";
+ case FMIFS_MEDIA_WRITE_PROTECTED:
+ return L"FORMAT_MEDIA_WRITE_PROTECTED";
+ case FMIFS_INCOMPATIBLE_FILE_SYSTEM:
+ return L"FORMAT_INCOMPATIBLE_FILE_SYSTEM";
+ case FMIFS_ACCESS_DENIED:
+ return L"FORMAT_ACCESS_DENIED";
+ case FMIFS_VOLUME_IN_USE:
+ return L"FORMAT_VOLUME_IN_USE";
+ case FMIFS_CLUSTER_SIZE_TOO_SMALL:
+ return L"FORMAT_CLUSTER_SIZE_TOO_SMALL";
+ case FMIFS_CLUSTER_SIZE_TOO_BIG:
+ return L"FORMAT_CLUSTER_SIZE_TOO_BIG";
+ case FMIFS_VOLUME_TOO_SMALL:
+ return L"FORMAT_VOLUME_TOO_SMALL";
+ case FMIFS_VOLUME_TOO_BIG:
+ return L"FORMAT_VOLUME_TOO_BIG";
+ case FMIFS_NO_MEDIA_IN_DRIVE:
+ return L"FORMAT_NO_MEDIA_IN_DRIVE";
+ case FMIFS_DEVICE_NOT_READY:
+ return L"FORMAT_DEVICE_NOT_READY";
+ case FMIFS_BAD_LABEL:
+ return L"FORMAT_BAD_LABEL";
+ case FMIFS_CANT_QUICK_FORMAT:
+ return L"FORMAT_CANT_QUICK_FORMAT";
+ default:
+ StringCbPrintfW (h_szMsg, sizeof(h_szMsg), L"0x%.8X", command);
+ return h_szMsg;
+ }
+}
BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter)
{
@@ -921,10 +1179,14 @@ BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID paramet
FormatExError = TRUE;
break;
}
+ if (FormatExError)
+ {
+ FormatExErrorCommand = command;
+ }
return (FormatExError? FALSE : TRUE);
}
-BOOL FormatFs (int driveNo, int clusterSize, int fsType)
+int FormatFs (int driveNo, int clusterSize, int fsType, BOOL bFallBackExternal)
{
wchar_t dllPath[MAX_PATH] = {0};
WCHAR dir[8] = { (WCHAR) driveNo + L'A', 0 };
@@ -970,30 +1232,138 @@ BOOL FormatFs (int driveNo, int clusterSize, int fsType)
StringCchCatW (dir, ARRAYSIZE(dir), L":\\");
FormatExError = TRUE;
+ FormatExErrorCommand = 0;
// 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);
+ FormatExErrorCommand = 0;
+ FormatEx (dir, FMIFS_REMOVAL, 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;
+
+ if (FormatExError && bFallBackExternal)
+ {
+ return ExternalFormatFs (driveNo, clusterSize, fsType);
+ }
+
+ return FormatExError? FormatExErrorCommand : 0;
}
-BOOL FormatNtfs (int driveNo, int clusterSize)
+int FormatNtfs (int driveNo, int clusterSize, BOOL bFallBackExternal)
{
- return FormatFs (driveNo, clusterSize, FILESYS_NTFS);
+ return FormatFs (driveNo, clusterSize, FILESYS_NTFS, bFallBackExternal);
+}
+
+/* call Windows format.com program to perform formatting */
+int ExternalFormatFs (int driveNo, int clusterSize, int fsType)
+{
+ wchar_t exePath[MAX_PATH] = {0};
+ WCHAR szFsFormat[16];
+ TCHAR szCmdline[2 * MAX_PATH];
+ STARTUPINFO siStartInfo;
+ PROCESS_INFORMATION piProcInfo;
+ BOOL bSuccess = FALSE;
+ int iRet = 0;
+
+ switch (fsType)
+ {
+ case FILESYS_NTFS:
+ StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"NTFS");
+ break;
+ case FILESYS_EXFAT:
+ StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"exFAT");
+ break;
+ case FILESYS_REFS:
+ StringCchCopyW (szFsFormat, ARRAYSIZE (szFsFormat),L"ReFS");
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (GetSystemDirectory (exePath, MAX_PATH))
+ {
+ StringCchCatW(exePath, ARRAYSIZE(exePath), L"\\format.com");
+ }
+ else
+ StringCchCopyW(exePath, ARRAYSIZE(exePath), L"C:\\Windows\\System32\\format.com");
+
+ StringCbPrintf (szCmdline, sizeof(szCmdline), L"%s %c: /FS:%s /Q /X /V:\"\" /Y", exePath, (WCHAR) driveNo + L'A', szFsFormat);
+
+ if (clusterSize)
+ {
+ WCHAR szSize[8];
+ uint32 unitSize = (uint32) clusterSize * FormatSectorSize;
+ if (unitSize <= 8192)
+ StringCbPrintf (szSize, sizeof (szSize), L"%d", unitSize);
+ else if (unitSize < BYTES_PER_MB)
+ {
+ StringCbPrintf (szSize, sizeof (szSize), L"%dK", unitSize / BYTES_PER_KB);
+ }
+ else
+ StringCbPrintf (szSize, sizeof (szSize), L"%dM", unitSize / BYTES_PER_MB);
+
+ StringCbCat (szCmdline, sizeof (szCmdline), L" /A:");
+ StringCbCat (szCmdline, sizeof (szCmdline), szSize);
+ }
+
+
+ ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
+
+ /* Set up members of the STARTUPINFO structure.
+ */
+ ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
+ siStartInfo.cb = sizeof(STARTUPINFO);
+ siStartInfo.wShowWindow = SW_HIDE;
+ siStartInfo.dwFlags |= STARTF_USESHOWWINDOW;
+
+ /* Create the child process. */
+ bSuccess = CreateProcess(NULL,
+ szCmdline, // command line
+ NULL, // process security attributes
+ NULL, // primary thread security attributes
+ TRUE, // handles are inherited
+ 0, // creation flags
+ NULL, // use parent's environment
+ NULL, // use parent's current directory
+ &siStartInfo, // STARTUPINFO pointer
+ &piProcInfo); // receives PROCESS_INFORMATION
+
+ if (bSuccess)
+ {
+ DWORD dwExitCode;
+
+ /* wait for the format process to finish */
+ WaitForSingleObject (piProcInfo.hProcess, INFINITE);
+
+ /* check if it was successfull */
+ if (GetExitCodeProcess (piProcInfo.hProcess, &dwExitCode))
+ {
+ iRet = (int) dwExitCode; /* dwExitCode will be 0 in case of success */
+ }
+ else
+ iRet = (int) GetLastError();
+
+ CloseHandle (piProcInfo.hThread);
+ CloseHandle (piProcInfo.hProcess);
+ }
+ else
+ {
+ iRet = (int) GetLastError();
+ }
+
+ return iRet;
}
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;
@@ -1007,7 +1377,7 @@ BOOL WriteSector (void *dev, char *sector,
if (GetTickCount () - updateTime > 25)
{
- if (UpdateProgressBar (*nSecNo * FormatSectorSize))
+ if (UpdateProgressBar ((*nSecNo - startSector) * FormatSectorSize))
return FALSE;
updateTime = GetTickCount ();