📄 tcformat.c
字号:
/*
Legal Notice: Some portions of the source code contained in this file were
derived 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) 2003-2008 TrueCrypt Foundation and are governed
by the TrueCrypt License 2.5 the full text of which is contained in the
file License.txt included in TrueCrypt binary and source code distribution
packages. */
#include "Tcdefs.h"
#include <stdlib.h>
#include <limits.h>
#include <time.h>
#include <errno.h>
#include <io.h>
#include <sys/stat.h>
#include <shlobj.h>
#include "Crypto.h"
#include "Apidrvr.h"
#include "Dlgcode.h"
#include "Language.h"
#include "Combo.h"
#include "Registry.h"
#include "Boot/Windows/BootDefs.h"
#include "Common/Common.h"
#include "Common/BootEncryption.h"
#include "Common/Dictionary.h"
#include "Common/Endian.h"
#include "Common/resource.h"
#include "Random.h"
#include "Fat.h"
#include "Resource.h"
#include "TcFormat.h"
#include "Format.h"
#include "FormatCom.h"
#include "Password.h"
#include "Progress.h"
#include "Tests.h"
#include "Cmdline.h"
#include "Volumes.h"
#include "Wipe.h"
#include "Xml.h"
using namespace TrueCrypt;
enum wizard_pages
{
INTRO_PAGE,
SYSENC_TYPE_PAGE,
SYSENC_HIDDEN_OS_REQ_CHECK_PAGE,
SYSENC_SPAN_PAGE,
SYSENC_PRE_DRIVE_ANALYSIS_PAGE,
SYSENC_DRIVE_ANALYSIS_PAGE,
SYSENC_MULTI_BOOT_MODE_PAGE,
SYSENC_MULTI_BOOT_SYS_EQ_BOOT_PAGE,
SYSENC_MULTI_BOOT_NBR_SYS_DRIVES_PAGE,
SYSENC_MULTI_BOOT_ADJACENT_SYS_PAGE,
SYSENC_MULTI_BOOT_NONWIN_BOOT_LOADER_PAGE,
SYSENC_MULTI_BOOT_OUTCOME_PAGE,
VOLUME_TYPE_PAGE,
HIDDEN_VOL_WIZARD_MODE_PAGE,
FILE_PAGE,
HIDDEN_VOL_HOST_PRE_CIPHER_PAGE,
HIDDEN_VOL_PRE_CIPHER_PAGE,
CIPHER_PAGE,
SIZE_PAGE,
HIDDEN_VOL_HOST_PASSWORD_PAGE,
PASSWORD_PAGE,
FILESYS_PAGE,
SYSENC_COLLECTING_RANDOM_DATA_PAGE,
SYSENC_KEYS_GEN_PAGE,
SYSENC_RESCUE_DISK_CREATION_PAGE,
SYSENC_RESCUE_DISK_BURN_PAGE,
SYSENC_RESCUE_DISK_VERIFIED_PAGE,
SYSENC_WIPE_MODE_PAGE,
SYSENC_PRETEST_INFO_PAGE,
SYSENC_PRETEST_RESULT_PAGE,
SYSENC_ENCRYPTION_PAGE,
FORMAT_PAGE,
FORMAT_FINISHED_PAGE
};
enum timer_ids
{
TIMER_ID_RANDVIEW = 0xff,
TIMER_ID_SYSENC_PROGRESS,
TIMER_ID_SYSENC_DRIVE_ANALYSIS_PROGRESS,
TIMER_ID_KEYB_LAYOUT_GUARD
};
#define TIMER_INTERVAL_RANDVIEW 30 // Refresh interval for Random pool display
#define TIMER_INTERVAL_SYSENC_PROGRESS 30
#define TIMER_INTERVAL_SYSENC_DRIVE_ANALYSIS_PROGRESS 100
#define TIMER_INTERVAL_KEYB_LAYOUT_GUARD 10
enum sys_encryption_cmd_line_switches
{
SYSENC_COMMAND_NONE = 0,
SYSENC_COMMAND_RESUME,
SYSENC_COMMAND_STARTUP_SEQ_RESUME,
SYSENC_COMMAND_ENCRYPT,
SYSENC_COMMAND_DECRYPT,
SYSENC_COMMAND_CREATE_HIDDEN_OS,
SYSENC_COMMAND_CREATE_HIDDEN_OS_ELEV
};
typedef struct
{
int NumberOfSysDrives; // Number of drives that contain an operating system. -1: unknown, 1: one, 2: two or more
int MultipleSystemsOnDrive; // Multiple systems are installed on the drive where the currently running system resides. -1: unknown, 0: no, 1: yes
int BootLoaderLocation; // Boot loader (boot manager) installed in: 1: MBR/1st cylinder, 0: partition/bootsector: -1: unknown
int BootLoaderBrand; // -1: unknown, 0: Microsoft Windows, 1: any non-Windows boot manager/loader
int SystemOnBootDrive; // If the currently running operating system is installed on the boot drive. -1: unknown, 0: no, 1: yes
} SYSENC_MULTIBOOT_CFG;
#define SYSENC_PAUSE_RETRY_INTERVAL 100
#define SYSENC_PAUSE_RETRIES 200
// Expected duration of system drive analysis, in ms
#define SYSENC_DRIVE_ANALYSIS_ETA (4*60000)
BootEncryption *BootEncObj = NULL;
BootEncryptionStatus BootEncStatus;
HWND hCurPage = NULL; /* Handle to current wizard page */
int nCurPageNo = -1; /* The current wizard page */
int nLastPageNo = -1;
volatile int WizardMode = DEFAULT_VOL_CREATION_WIZARD_MODE; /* IMPORTANT: Never change this value directly -- always use ChangeWizardMode() instead. */
volatile BOOL bHiddenOS = FALSE; /* If TRUE, we are performing or (or supposed to perform) actions relating to an operating system installed in a hidden volume (i.e., encrypting a decoy OS partition or creating the outer/hidden volume for the hidden OS). To determine or set the phase of the process, call ChangeHiddenOSCreationPhase() and DetermineHiddenOSCreationPhase()) */
BOOL bDirectSysEncMode = FALSE;
BOOL bDirectSysEncModeCommand = SYSENC_COMMAND_NONE;
BOOL DirectDeviceEncMode = FALSE;
int nNeedToStoreFilesOver4GB = 0; /* Whether the user wants to be able to store files larger than 4GB on the volume: -1 = Undecided or error, 0 = No, 1 = Yes */
int nVolumeEA = 1; /* Default encryption algorithm */
BOOL bSystemEncryptionInProgress = FALSE; /* TRUE when encrypting/decrypting the system partition/drive (FALSE when paused). */
BOOL bWholeSysDrive = FALSE; /* Whether to encrypt the entire system drive or just the system partition. */
static BOOL bSystemEncryptionStatusChanged = FALSE; /* TRUE if this instance changed the value of SystemEncryptionStatus (it's set to FALSE each time the system encryption settings are saved to the config file). This value is to be treated as protected -- only the wizard can change this value (others may only read it). */
volatile BOOL bSysEncDriveAnalysisInProgress = FALSE;
volatile BOOL bSysEncDriveAnalysisTimeOutOccurred = FALSE;
int SysEncDetectHiddenSectors = -1; /* Whether the user wants us to detect and encrypt the Host Protect Area (if any): -1 = Undecided or error, 0 = No, 1 = Yes */
int SysEncDriveAnalysisStart;
BOOL bDontVerifyRescueDisk = FALSE;
BOOL bFirstSysEncResumeDone = FALSE;
int nMultiBoot = 0; /* The number of operating systems installed on the computer, according to the user. 0: undetermined, 1: one, 2: two or more */
volatile BOOL bHiddenVol = FALSE; /* If true, we are (or will be) creating a hidden volume. */
volatile BOOL bHiddenVolHost = FALSE; /* If true, we are (or will be) creating the host volume (called "outer") for a hidden volume. */
volatile BOOL bHiddenVolDirect = FALSE; /* If true, the wizard omits creating a host volume in the course of the process of hidden volume creation. */
volatile BOOL bHiddenVolFinished = FALSE;
int hiddenVolHostDriveNo = -1; /* Drive letter for the volume intended to host a hidden volume. */
BOOL bRemovableHostDevice = FALSE; /* TRUE when creating a device/partition-hosted volume on a removable device. State undefined when creating file-hosted volumes. */
int realClusterSize; /* Parameter used when determining the maximum possible size of a hidden volume. */
int hash_algo = DEFAULT_HASH_ALGORITHM; /* Which PRF to use in header key derivation (PKCS #5) and in the RNG. */
unsigned __int64 nUIVolumeSize = 0; /* The volume size. Important: This value is not in bytes. It has to be multiplied by nMultiplier. Do not use this value when actually creating the volume (it may chop off 512 bytes, if it is not a multiple of 1024 bytes). */
unsigned __int64 nVolumeSize = 0; /* The volume size, in bytes. */
unsigned __int64 nHiddenVolHostSize = 0; /* Size of the hidden volume host, in bytes */
__int64 nMaximumHiddenVolSize = 0; /* Maximum possible size of the hidden volume, in bytes */
__int64 nbrFreeClusters = 0;
int nMultiplier = 1024*1024; /* Size selection multiplier. */
char szFileName[TC_MAX_PATH+1]; /* The file selected by the user */
char szDiskFile[TC_MAX_PATH+1]; /* Fully qualified name derived from szFileName */
char szRescueDiskISO[TC_MAX_PATH+1]; /* The filename and path to the Rescue Disk ISO file to be burned (for boot encryption) */
volatile BOOL bThreadCancel = FALSE; /* TRUE if the user cancels the volume formatting */
volatile BOOL bThreadRunning = FALSE; /* Is the thread running */
volatile BOOL bConfirmQuit = FALSE; /* If TRUE, the user is asked to confirm exit when he clicks the X icon, Exit, etc. */
volatile BOOL bConfirmQuitSysEncPretest = FALSE;
BOOL bDevice = FALSE; /* Is this a partition volume ? */
BOOL showKeys = TRUE;
volatile HWND hMasterKey = NULL; /* Text box showing hex dump of the master key */
volatile HWND hHeaderKey = NULL; /* Text box showing hex dump of the header key */
volatile HWND hRandPool = NULL; /* Text box showing hex dump of the random pool */
volatile HWND hRandPoolSys = NULL; /* Text box showing hex dump of the random pool for system encryption */
volatile HWND hPasswordInputField = NULL; /* Password input field */
volatile HWND hVerifyPasswordInputField = NULL; /* Verify-password input field */
HBITMAP hbmWizardBitmapRescaled = NULL;
char OrigKeyboardLayout [8+1] = "00000409";
BOOL bKeyboardLayoutChanged = FALSE; /* TRUE if the keyboard layout was changed to the standard US keyboard layout (from any other layout). */
BOOL bKeybLayoutAltKeyWarningShown = FALSE; /* TRUE if the user has been informed that it is not possible to type characters by pressing keys while the right Alt key is held down. */
BOOL bWarnDeviceFormatAdvanced = TRUE;
BOOL bWarnOuterVolSuitableFileSys = TRUE;
Password volumePassword; /* User password */
char szVerify[MAX_PASSWORD + 1]; /* Tmp password buffer */
char szRawPassword[MAX_PASSWORD + 1]; /* Password before keyfile was applied to it */
BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */
BOOL ComServerMode = FALSE;
int nPbar = 0; /* Control ID of progress bar:- for format code */
char HeaderKeyGUIView [KEY_GUI_VIEW_SIZE];
char MasterKeyGUIView [KEY_GUI_VIEW_SIZE];
#define RANDPOOL_DISPLAY_COLUMNS 15
#define RANDPOOL_DISPLAY_ROWS 8
#define RANDPOOL_DISPLAY_BYTE_PORTION (RANDPOOL_DISPLAY_COLUMNS * RANDPOOL_DISPLAY_ROWS)
#define RANDPOOL_DISPLAY_SIZE (RANDPOOL_DISPLAY_BYTE_PORTION * 3 + RANDPOOL_DISPLAY_ROWS + 2)
unsigned char randPool [RANDPOOL_DISPLAY_BYTE_PORTION];
unsigned char lastRandPool [RANDPOOL_DISPLAY_BYTE_PORTION];
unsigned char outRandPoolDispBuffer [RANDPOOL_DISPLAY_SIZE];
BOOL bDisplayPoolContents = TRUE;
volatile BOOL bSparseFileSwitch = FALSE;
volatile BOOL quickFormat = FALSE; /* WARNING: Meaning of this variable depends on bSparseFileSwitch. If bSparseFileSwitch is TRUE, this variable represents the sparse file flag. */
volatile int fileSystem = FILESYS_NONE;
volatile int clusterSize = 0;
SYSENC_MULTIBOOT_CFG SysEncMultiBootCfg;
wchar_t SysEncMultiBootCfgOutcome [4096] = {'N','/','A',0};
static BOOL ElevateWholeWizardProcess (string arguments)
{
char modPath[MAX_PATH];
if (IsAdmin())
return TRUE;
if (!IsUacSupported())
return IsAdmin();
GetModuleFileName (NULL, modPath, sizeof (modPath));
if ((int)ShellExecute (MainDlg, "runas", modPath, (string("/q UAC ") + arguments).c_str(), NULL, SW_SHOWNORMAL) > 32)
{
exit (0);
}
else
{
Error ("UAC_INIT_ERROR");
return FALSE;
}
}
static void WipePasswordsAndKeyfiles (void)
{
char tmp[MAX_PASSWORD+1];
// Attempt to wipe passwords stored in the input field buffers
memset (tmp, 'X', MAX_PASSWORD);
tmp [MAX_PASSWORD] = 0;
SetWindowText (hPasswordInputField, tmp);
SetWindowText (hVerifyPasswordInputField, tmp);
burn (&szVerify[0], sizeof (szVerify));
burn (&volumePassword, sizeof (volumePassword));
burn (&szRawPassword[0], sizeof (szRawPassword));
SetWindowText (hPasswordInputField, "");
SetWindowText (hVerifyPasswordInputField, "");
KeyFileRemoveAll (&FirstKeyFile);
KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile);
}
static void localcleanup (void)
{
char tmp[RANDPOOL_DISPLAY_SIZE+1];
if (WizardMode == WIZARD_MODE_SYS_DEVICE
&& InstanceHasSysEncMutex ())
{
try
{
BootEncStatus = BootEncObj->GetStatus();
if (BootEncStatus.SetupInProgress)
{
BootEncObj->AbortSetup ();
}
}
catch (...)
{
// NOP
}
}
WipePasswordsAndKeyfiles ();
Randfree ();
burn (HeaderKeyGUIView, sizeof(HeaderKeyGUIView));
burn (MasterKeyGUIView, sizeof(MasterKeyGUIView));
burn (randPool, sizeof(randPool));
burn (lastRandPool, sizeof(lastRandPool));
burn (outRandPoolDispBuffer, sizeof(outRandPoolDispBuffer));
// Attempt to wipe the GUI fields showing portions of randpool, of the master and header keys
memset (tmp, 'X', sizeof(tmp));
tmp [sizeof(tmp)-1] = 0;
SetWindowText (hRandPool, tmp);
SetWindowText (hRandPoolSys, tmp);
SetWindowText (hMasterKey, tmp);
SetWindowText (hHeaderKey, tmp);
UnregisterRedTick (hInst);
/* Delete buffered bitmaps (if any) */
if (hbmWizardBitmapRescaled != NULL)
{
DeleteObject ((HGDIOBJ) hbmWizardBitmapRescaled);
hbmWizardBitmapRescaled = NULL;
}
/* Cleanup common code resources */
cleanup ();
if (BootEncObj != NULL)
{
delete BootEncObj;
BootEncObj = NULL;
}
}
static BOOL CALLBACK BroadcastSysEncCfgUpdateCallb (HWND hwnd, LPARAM lParam)
{
if (GetWindowLongPtr (hwnd, GWLP_USERDATA) == (LONG_PTR) 'TRUE')
{
char name[1024] = { 0 };
GetWindowText (hwnd, name, sizeof (name) - 1);
if (hwnd != MainDlg && strstr (name, "TrueCrypt"))
{
PostMessage (hwnd, TC_APPMSG_SYSENC_CONFIG_UPDATE, 0, 0);
}
}
return TRUE;
}
static BOOL BroadcastSysEncCfgUpdate (void)
{
BOOL bSuccess = FALSE;
EnumWindows (BroadcastSysEncCfgUpdateCallb, (LPARAM) &bSuccess);
return bSuccess;
}
// IMPORTANT: This function may be called only by Format (other modules can only _read_ the system encryption config).
// Returns TRUE if successful (otherwise FALSE)
static BOOL SaveSysEncSettings (HWND hwndDlg)
{
FILE *f;
if (!bSystemEncryptionStatusChanged)
return TRUE;
if (hwndDlg == NULL && MainDlg != NULL)
hwndDlg = MainDlg;
if (!CreateSysEncMutex ())
return FALSE; // Only one instance that has the mutex can modify the system encryption settings
if (SystemEncryptionStatus == SYSENC_STATUS_NONE)
{
if (remove (GetConfigPath (FILE_SYSTEM_ENCRYPTION_CFG)) != 0)
{
Error ("CANNOT_SAVE_SYS_ENCRYPTION_SETTINGS");
return FALSE;
}
bSystemEncryptionStatusChanged = FALSE;
BroadcastSysEncCfgUpdate ();
return TRUE;
}
f = fopen (GetConfigPath (FILE_SYSTEM_ENCRYPTION_CFG), "w");
if (f == NULL)
{
Error ("CANNOT_SAVE_SYS_ENCRYPTION_SETTINGS");
handleWin32Error (hwndDlg);
return FALSE;
}
if (XmlWriteHeader (f) < 0
|| fputs ("\n\t<sysencryption>", f) < 0
|| fprintf (f, "\n\t\t<config key=\"SystemEncryptionStatus\">%d</config>", SystemEncryptionStatus) < 0
|| fprintf (f, "\n\t\t<config key=\"WipeMode\">%d</config>", (int) nWipeMode) < 0
|| fputs ("\n\t</sysencryption>", f) < 0
|| XmlWriteFooter (f) < 0)
{
handleWin32Error (hwndDlg);
fclose (f);
Error ("CANNOT_SAVE_SYS_ENCRYPTION_SETTINGS");
return FALSE;
}
TCFlushFile (f);
fclose (f);
bSystemEncryptionStatusChanged = FALSE;
BroadcastSysEncCfgUpdate ();
return TRUE;
}
// WARNING: This function may take a long time to finish
static unsigned int DetermineHiddenOSCreationPhase (void)
{
unsigned int phase = TC_HIDDEN_OS_CREATION_PHASE_NONE;
try
{
phase = BootEncObj->GetHiddenOSCreationPhase();
}
catch (Exception &e)
{
e.Show (MainDlg);
AbortProcess("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS");
}
return phase;
}
// IMPORTANT: This function may be called only by Format (other modules can only _read_ the status).
// Returns TRUE if successful (otherwise FALSE)
static BOOL ChangeHiddenOSCreationPhase (int newPhase)
{
if (!CreateSysEncMutex ())
{
Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE");
return FALSE;
}
try
{
BootEncObj->SetHiddenOSCreationPhase (newPhase);
}
catch (Exception &e)
{
e.Show (MainDlg);
return FALSE;
}
//// The contents of the following items might be inappropriate after a change of the phase
//szFileName[0] = 0;
//szDiskFile[0] = 0;
//nUIVolumeSize = 0;
//nVolumeSize = 0;
return TRUE;
}
// IMPORTANT: This function may be called only by Format (other modules can only _read_ the system encryption status).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -