📄 format.c
字号:
nStatus = FormatNoFs (startSector, num_sectors, dev, cryptoInfo, quickFormat);
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);
ft.cluster_size = clusterSize;
memcpy (ft.volume_name, "NO NAME ", 11);
GetFatParams (&ft);
*realClusterSize = ft.cluster_size * SECTOR_SIZE;
nStatus = FormatFat (startSector, &ft, (void *) dev, cryptoInfo, quickFormat);
break;
default:
nStatus = ERR_PARAMETER_INCORRECT;
goto error;
}
error:
dwError = GetLastError();
burn (header, sizeof (header));
VirtualUnlock (header, sizeof (header));
if (dev != INVALID_HANDLE_VALUE)
{
if (!bDevice && !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)
{
// Restore the container timestamp (to preserve plausible deniability of the hidden volume)
if (SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
MessageBoxW (hwndDlg, GetString ("SETFILETIME_FAILED_IMPLANT"), lpszTitle, MB_OK | MB_ICONEXCLAMATION);
}
CloseHandle (dev);
dev = INVALID_HANDLE_VALUE;
}
if (nStatus != 0)
{
SetLastError(dwError);
goto fv_end;
}
if (fileSystem == FILESYS_NTFS)
{
// Quick-format volume as NTFS
int driveNo = GetLastAvailableDrive ();
MountOptions mountOptions;
int retCode;
ZeroMemory (&mountOptions, sizeof (mountOptions));
if (driveNo == -1)
{
MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
MessageBoxW (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;
if (MountVolume (hwndDlg, driveNo, volumePath, password, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
{
MessageBoxW (hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND);
MessageBoxW (hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
nStatus = ERR_VOL_MOUNT_FAILED;
goto fv_end;
}
if (!IsAdmin () && IsUacSupported ())
retCode = UacFormatNtfs (hwndDlg, driveNo, clusterSize);
else
retCode = FormatNtfs (driveNo, clusterSize);
if (retCode != TRUE)
{
if (!UnmountVolume (hwndDlg, driveNo, FALSE))
MessageBoxW (hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
if (size <= MAX_FAT_VOLUME_SIZE)
{
if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT") == IDYES)
{
// NTFS format failed and the user wants to try FAT format immediately
fileSystem = FILESYS_FAT;
bInstantRetryOtherFilesys = TRUE;
quickFormat = TRUE; // Volume has already been successfully TC-formatted
clusterSize = 0; // Default cluster size
goto begin_format;
}
}
else
Error ("FORMAT_NTFS_FAILED");
nStatus = ERR_DONT_REPORT;
goto fv_end;
}
if (!UnmountVolume (hwndDlg, driveNo, FALSE))
MessageBoxW (hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
}
fv_end:
if (dosDev[0])
RemoveFakeDosName (volumePath, dosDev);
crypto_close (cryptoInfo);
return nStatus;
}
#endif // _WIN32
int FormatNoFs (unsigned __int64 startSector, __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat)
{
int write_buf_cnt = 0;
char sector[SECTOR_SIZE], *write_buf;
unsigned __int64 nSecNo = startSector;
int retVal = 0;
char temporaryKey[MASTER_KEYDATA_SIZE];
char originalK2[MASTER_KEYDATA_SIZE];
#ifdef _WIN32
LARGE_INTEGER startOffset;
LARGE_INTEGER newOffset;
// Seek to start sector
startOffset.QuadPart = startSector * SECTOR_SIZE;
if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
|| newOffset.QuadPart != startOffset.QuadPart)
{
return ERR_VOL_SEEKING;
}
VirtualLock (temporaryKey, sizeof (temporaryKey));
VirtualLock (originalK2, sizeof (originalK2));
#endif
write_buf = (char *) TCalloc (WRITE_BUF_SIZE);
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 (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
goto fail;
// Temporary secondary key (XTS mode)
if (!RandgetBytes (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--)
{
/* Generate random plaintext. Note that reused plaintext blocks are not a concern here
since XTS mode is designed to hide patterns. Furthermore, patterns in plaintext do
occur commonly on media in the "real world", so it might actually be a fatal mistake
to try to avoid them completely. */
#if RNG_POOL_SIZE < SECTOR_SIZE
#error RNG_POOL_SIZE < SECTOR_SIZE
#endif
#ifdef _WIN32
if (!RandpeekBytes (sector, SECTOR_SIZE))
goto fail;
#else
if ((nSecNo & 0x3fff) == 0)
{
if (!RandgetBytes (sector, SECTOR_SIZE, FALSE))
goto fail;
}
#endif
// Encrypt the random plaintext and write it to the disk
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
cryptoInfo) == FALSE)
goto fail;
}
if (write_buf_cnt != 0 &&
#ifdef _WIN32
_lwrite ((HFILE)dev, write_buf, write_buf_cnt) == HFILE_ERROR)
#else
fwrite (write_buf, 1, write_buf_cnt, (FILE *)dev) != (size_t)write_buf_cnt)
#endif
goto fail;
}
else
nSecNo = num_sectors;
UpdateProgressBar (nSecNo);
// 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;
}
if (write_buf != NULL)
TCfree (write_buf);
burn (temporaryKey, sizeof(temporaryKey));
burn (originalK2, sizeof(originalK2));
#ifdef _WIN32
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
#endif
return 0;
fail:
if (write_buf != NULL)
TCfree (write_buf);
burn (temporaryKey, sizeof(temporaryKey));
burn (originalK2, sizeof(originalK2));
#ifdef _WIN32
VirtualUnlock (temporaryKey, sizeof (temporaryKey));
VirtualUnlock (originalK2, sizeof (originalK2));
#endif
return (retVal ? retVal : ERR_OS_ERROR);
}
#ifdef _WIN32
volatile BOOLEAN FormatExResult;
BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter)
{
if (command == FMIFS_DONE)
FormatExResult = *(BOOLEAN *) parameter;
return TRUE;
}
BOOL FormatNtfs (int driveNo, int clusterSize)
{
WCHAR dir[8] = { driveNo + 'A', 0 };
PFORMATEX FormatEx;
HMODULE hModule = LoadLibrary ("fmifs.dll");
int i;
if (hModule == NULL)
return FALSE;
if (!(FormatEx = (void *) GetProcAddress (GetModuleHandle("fmifs.dll"), "FormatEx")))
{
FreeLibrary (hModule);
return FALSE;
}
wcscat (dir, L":\\");
FormatExResult = FALSE;
// 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 < 10 && FormatExResult != TRUE; i++)
{
FormatEx (dir, FMIFS_HARDDISK, L"NTFS", L"", TRUE, clusterSize * SECTOR_SIZE, FormatExCallback);
}
FreeLibrary (hModule);
return FormatExResult;
}
#endif
BOOL WriteSector (void *dev, char *sector,
char *write_buf, int *write_buf_cnt,
__int64 *nSecNo, PCRYPTO_INFO cryptoInfo)
{
static __int32 updateTime = 0;
UINT64_STRUCT unitNo;
unitNo.Value = *nSecNo * SECTOR_SIZE / ENCRYPTION_DATA_UNIT_SIZE;
EncryptDataUnits (sector, &unitNo, SECTOR_SIZE / ENCRYPTION_DATA_UNIT_SIZE, cryptoInfo);
(*nSecNo)++;
memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE);
(*write_buf_cnt) += SECTOR_SIZE;
if (*write_buf_cnt == WRITE_BUF_SIZE)
{
if (
#ifdef _WIN32
_lwrite ((HFILE)dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR)
#else
fwrite (write_buf, 1, WRITE_BUF_SIZE, (FILE *)dev) != WRITE_BUF_SIZE)
#endif
return FALSE;
else
*write_buf_cnt = 0;
}
#ifdef _WIN32
if (GetTickCount () - updateTime > 25)
{
if (UpdateProgressBar (*nSecNo))
return FALSE;
updateTime = GetTickCount ();
}
#else
UpdateProgressBar (*nSecNo);
#endif
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -