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.c104
1 files changed, 76 insertions, 28 deletions
diff --git a/src/Common/Format.c b/src/Common/Format.c
index 15ca9518..d5514bf9 100644
--- a/src/Common/Format.c
+++ b/src/Common/Format.c
@@ -797,16 +797,26 @@ error:
}
retCode = ExternalFormatFs (driveNo, volParams->clusterSize, fsType);
- if (retCode != TRUE)
+ if (retCode != 0)
{
+ wchar_t auxLine[2048];
+ StringCbPrintfW (auxLine, sizeof(auxLine), GetString ("FORMAT_EXTERNAL_FAILED"), retCode);
+ WarningDirect(auxLine, volParams->hwndDlg);
+
/* 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);
+
+ if (retCode != 0)
+ {
+ 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);
@@ -1030,6 +1040,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)
{
@@ -1086,10 +1136,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)
{
wchar_t dllPath[MAX_PATH] = {0};
WCHAR dir[8] = { (WCHAR) driveNo + L'A', 0 };
@@ -1135,29 +1189,31 @@ 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;
+ return FormatExError? FormatExErrorCommand : 0;
}
-BOOL FormatNtfs (int driveNo, int clusterSize)
+int FormatNtfs (int driveNo, int clusterSize)
{
return FormatFs (driveNo, clusterSize, FILESYS_NTFS);
}
/* call Windows format.com program to perform formatting */
-BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType)
+int ExternalFormatFs (int driveNo, int clusterSize, int fsType)
{
wchar_t exePath[MAX_PATH] = {0};
HANDLE hChildStd_IN_Rd = NULL;
@@ -1170,6 +1226,7 @@ BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType)
PROCESS_INFORMATION piProcInfo;
BOOL bSuccess = FALSE;
SECURITY_ATTRIBUTES saAttr;
+ int iRet = 0;
switch (fsType)
{
@@ -1222,7 +1279,7 @@ BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType)
else
StringCchCopyW(exePath, ARRAYSIZE(exePath), L"C:\\Windows\\System32\\format.com");
- StringCbPrintf (szCmdline, sizeof(szCmdline), L"%s %c: /FS:%s /Q /X /V:\"\"", exePath, (WCHAR) driveNo + L'A', szFsFormat);
+ StringCbPrintf (szCmdline, sizeof(szCmdline), L"%s %c: /FS:%s /Q /X /V:\"\" /Y", exePath, (WCHAR) driveNo + L'A', szFsFormat);
if (clusterSize)
{
@@ -1269,42 +1326,33 @@ BOOL ExternalFormatFs (int driveNo, int clusterSize, int fsType)
if (bSuccess)
{
- /* Unblock the format process by simulating hit on ENTER key */
- DWORD dwExitCode, dwWritten;
- LPCSTR newLine = "\n";
-
- if (WriteFile(hChildStd_IN_Wr, (LPCVOID) newLine, 1, &dwWritten, NULL))
- {
- /* wait for the format process to finish */
- WaitForSingleObject (piProcInfo.hProcess, INFINITE);
- }
- else
- {
- /* we failed to write "\n". Maybe process exited too quickly. We wait 1 second */
- WaitForSingleObject (piProcInfo.hProcess, 1000);
- }
+ DWORD dwExitCode;
+
+ /* wait for the format process to finish */
+ WaitForSingleObject (piProcInfo.hProcess, INFINITE);
/* check if it was successfull */
if (GetExitCodeProcess (piProcInfo.hProcess, &dwExitCode))
{
- if (dwExitCode == 0)
- bSuccess = TRUE;
- else
- bSuccess = FALSE;
+ iRet = (int) dwExitCode; /* dwExitCode will be 0 in case of success */
}
else
- bSuccess = FALSE;
+ iRet = (int) GetLastError();
CloseHandle (piProcInfo.hThread);
CloseHandle (piProcInfo.hProcess);
}
+ else
+ {
+ iRet = (int) GetLastError();
+ }
CloseHandle(hChildStd_OUT_Wr);
CloseHandle(hChildStd_OUT_Rd);
CloseHandle(hChildStd_IN_Rd);
CloseHandle(hChildStd_IN_Wr);
- return bSuccess;
+ return iRet;
}
BOOL WriteSector (void *dev, char *sector,