📄 tcformat.c
字号:
/* The source code contained in this file has been derived from the source code
of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
additions to that source code contained in this file are Copyright (c) 2004-2005
TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
release. Please see the file license.txt for full license details. */
#include "TCdefs.h"
#include <stdlib.h>
#include <limits.h>
#include <time.h>
#include <errno.h>
#include <io.h>
#include <sys/stat.h>
#include "crypto.h"
#include "apidrvr.h"
#include "dlgcode.h"
#include "combo.h"
#include "registry.h"
#include "../common/common.h"
#include "../common/resource.h"
#include "random.h"
#include "fat.h"
#include "resource.h"
#include "TCFormat.h"
#include "uncroot.h"
#include "format.h"
#include "password.h"
#include "testcrypt.h"
#include "redtick.h"
#include "endian.h"
#include "cmdline.h"
#define WM_THREAD_ENDED 0x7ffe /* WM_USER range message */
#define WM_FORMAT_FINISHED 0x7ffe+1
#define RANDOM_SHOW_TIMER 30 // Refresh interval for Random pool display
enum wizard_pages
{
INTRO_PAGE,
HIDDEN_VOL_WIZARD_MODE_PAGE,
FILE_PAGE,
HIDDEN_VOL_HOST_PRE_CIPHER_PAGE,
HIDDEN_VOL_PRE_CIPHER_PAGE,
CIPHER_PAGE,
SIZE_PAGE,
HIDVOL_HOST_PASSWORD_PAGE,
PASSWORD_PAGE,
FORMAT_PAGE,
FORMAT_FINISHED_PAGE
};
HWND hCurPage = NULL; /* Handle to current wizard page */
int nCurPageNo = -1; /* The current wizard page */
int nVolumeEA = 1; /* Default encryption algorithm */
BOOL bHiddenVol = FALSE; /* If true, we are (or will be) creating a hidden volume. */
BOOL bHiddenVolHost = FALSE; /* If true, we are (or will be) creating the host volume (called "outer") for a hidden volume. */
BOOL bHiddenVolDirect = FALSE; /* If true, the wizard omits creating a host volume in the course of the process of hidden volume creation. */
BOOL bHiddenVolFinished = FALSE;
int hiddenVolHostDriveNo = -1; /* Drive letter for the volume intended to host a hidden volume. */
int realClusterSize; /* Parameter used when determining the maximum possible size of a hidden volume. */
int pkcs5 = SHA1; /* Which PRF to use in header key derivation, default = HMAC-SHA-1 */
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 */
int nMultiplier = 1024*1024; /* Size selection multiplier. */
char szFileName[TC_MAX_PATH]; /* The file selected by the user */
char szDiskFile[TC_MAX_PATH]; /* Fully qualified name derived from szFileName */
BOOL bThreadCancel = FALSE; /* TRUE if the user cancels the volume formatting */
BOOL bThreadRunning = FALSE; /* Is the thread running */
BOOL bDevice = FALSE; /* Is this a partition volume ? */
BOOL showKeys = TRUE;
HWND hDiskKey = NULL; /* Text box showing hex dump of disk key */
HWND hHeaderKey = NULL; /* Text box showing hex dump of header key */
char szPassword[MAX_PASSWORD + 1]; /* Users password */
char szVerify[MAX_PASSWORD + 1];/* Tmp password buffer */
BOOL bHistory = FALSE; /* Remember all the settings */
BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */
int nPbar = 0; /* Control ID of progress bar:- for format
code */
volatile BOOL quickFormat = FALSE;
volatile int fileSystem = 0;
volatile int clusterSize = 0;
void
localcleanup (void)
{
Randfree ();
/* Zero the password */
burn (&szVerify[0], sizeof (szVerify));
burn (&szPassword[0], sizeof (szPassword));
/* Free the application title */
if (lpszTitle != NULL)
free (lpszTitle);
UnregisterRedTick (hInst);
/* Cleanup common code resources */
cleanup ();
}
void
LoadSettings (HWND hwndDlg)
{
bHistory = ReadRegistryInt ("SaveMountedVolumesHistory", FALSE);
if (hwndDlg != NULL)
{
LoadCombo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), "LastMountedVolume");
return;
}
if (bHistoryCmdLine == TRUE)
return;
}
void
SaveSettings (HWND hwndDlg)
{
if (IsNonInstallMode ()) return;
if (hwndDlg != NULL)
DumpCombo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), "LastMountedVolume", !bHistory);
WriteRegistryInt ("SaveMountedVolumesHistory", bHistory);
}
void
EndMainDlg (HWND hwndDlg)
{
if (nCurPageNo == FILE_PAGE)
{
if (IsWindow(GetDlgItem(hCurPage, IDC_NO_HISTORY)))
bHistory = !IsButtonChecked (GetDlgItem (hCurPage, IDC_NO_HISTORY));
MoveEditToCombo (GetDlgItem (hCurPage, IDC_COMBO_BOX));
SaveSettings (hCurPage);
}
else
{
SaveSettings (NULL);
}
EndDialog (hwndDlg, 0);
}
void
ComboSelChangeEA (HWND hwndDlg)
{
LPARAM nIndex = SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_GETCURSEL, 0, 0);
if (nIndex == CB_ERR)
{
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), "");
}
else
{
char name[100];
char auxLine[1024];
char tmpStr[256];
char cipherIDs[5];
int i, cnt = 0;
UINT nID[4];
nIndex = SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_GETITEMDATA, nIndex, 0);
EAGetName (name, nIndex);
memset (nID, 0, sizeof (nID));
if (strcmp (name, "Blowfish") == 0)
{
nID[0] = IDS_BLOWFISH_HELP0;
nID[1] = IDS_BLOWFISH_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
else if (strcmp (name, "AES") == 0)
{
nID[0] = IDS_AES_HELP0;
nID[1] = IDS_AES_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
else if (strcmp (name, "CAST5") == 0)
{
nID[0] = IDS_CAST_HELP0;
nID[1] = IDS_CAST_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
else if (strcmp (name, "Serpent") == 0)
{
nID[0] = IDS_SERPENT_HELP0;
nID[1] = IDS_SERPENT_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
else if (strcmp (name, "Triple DES") == 0)
{
nID[0] = IDS_TRIPLEDES_HELP0;
nID[1] = IDS_TRIPLEDES_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
else if (strcmp (name, "Twofish") == 0)
{
nID[0] = IDS_TWOFISH_HELP0;
nID[1] = IDS_TWOFISH_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
else if (EAGetCipherCount (nIndex) > 1)
{
// Cascade
switch (EAGetMode(nIndex))
{
case INNER_CBC:
sprintf(tmpStr, "sector");
break;
case OUTER_CBC:
sprintf(tmpStr, "block");
break;
default:
sprintf(tmpStr, "[?]");
break;
}
cipherIDs[cnt++] = i = EAGetLastCipher(nIndex);
while (i = EAGetPreviousCipher(nIndex, i))
{
cipherIDs[cnt] = i;
cnt++;
}
switch (cnt) // Number of ciphers in the cascade
{
case 2:
nID[0] = IDS_TWO_LAYER_CASCADE_HELP0;
nID[1] = IDS_TWO_LAYER_CASCADE_HELP1;
sprintf (auxLine, getmultilinestr (nID),
EAGetModeName(name, nIndex, FALSE),
tmpStr,
CipherGetName (cipherIDs[1]),
CipherGetKeySize (cipherIDs[1])*8,
CipherGetName (cipherIDs[0]),
CipherGetKeySize (cipherIDs[0])*8);
break;
case 3:
nID[0] = IDS_THREE_LAYER_CASCADE_HELP0;
nID[1] = IDS_THREE_LAYER_CASCADE_HELP1;
sprintf (auxLine, getmultilinestr (nID),
EAGetModeName(name, nIndex, FALSE),
tmpStr,
CipherGetName (cipherIDs[2]),
CipherGetKeySize (cipherIDs[2])*8,
CipherGetName (cipherIDs[1]),
CipherGetKeySize (cipherIDs[1])*8,
CipherGetName (cipherIDs[0]),
CipherGetKeySize (cipherIDs[0])*8);
break;
default:
nID[0] = IDS_CIPHER_NONE_HELP0;
break;
}
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), auxLine);
}
else
{
// No info available for this encryption algorithm
nID[0] = IDS_CIPHER_NONE_HELP0;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
}
}
}
void
VerifySizeAndUpdate (HWND hwndDlg, BOOL bUpdate)
{
BOOL bEnable = TRUE;
char szTmp[16];
__int64 lTmp;
size_t i;
GetWindowText (GetDlgItem (hwndDlg, IDC_SIZEBOX), szTmp, sizeof (szTmp));
for (i = 0; i < strlen (szTmp); i++)
{
if (szTmp[i] >= '0' && szTmp[i] <= '9')
continue;
else
{
bEnable = FALSE;
break;
}
}
if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_KB)) == TRUE)
nMultiplier = BYTES_PER_KB;
else
nMultiplier = BYTES_PER_MB;
if (bDevice && !(bHiddenVol && !bHiddenVolHost)) // If raw device but not a hidden volume
{
lTmp = nVolumeSize;
i = 1;
}
else
{
i = nMultiplier;
lTmp = atoi64 (szTmp);
}
if (bEnable == TRUE)
{
if (lTmp * i < (bHiddenVolHost ? MIN_HIDDEN_VOLUME_HOST_SIZE : MIN_VOLUME_SIZE))
bEnable = FALSE;
if (!bHiddenVolHost && bHiddenVol)
{
if (lTmp * i > nMaximumHiddenVolSize)
bEnable = FALSE;
}
else
{
if (lTmp * i > (bHiddenVolHost ? MAX_HIDDEN_VOLUME_HOST_SIZE : MAX_VOLUME_SIZE))
bEnable = FALSE;
}
if (lTmp * i % SECTOR_SIZE != 0)
bEnable = FALSE;
}
if (bUpdate == TRUE)
{
nUIVolumeSize = lTmp;
if (!bDevice || (bHiddenVol && !bHiddenVolHost)) // Update only if it's not a raw device or if it's a hidden volume
nVolumeSize = i * lTmp;
}
EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), bEnable);
}
/* Even though certain functions like getstr are not thread safe, they don't
need to be, this is because the idea of have this app being multi-threaded
is to allow a user to cancel the format process once it begins, not to do
two things at once, so getstr will only ever have one thread running
through it. */
void
formatThreadFunction (void *hwndDlg)
{
int nStatus;
char szDosDevice[TC_MAX_PATH];
char szCFDevice[TC_MAX_PATH];
char summaryMsg[512];
DWORD dwWin32FormatError;
int nDosLinkCreated = -1;
// Check administrator privileges
if (!IsAdmin())
{
if (fileSystem == FILESYS_NTFS)
{
if (MessageBox (hwndDlg, getstr (IDS_ADMIN_PRIVILEGES_WARN_NTFS), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL)
goto cancel;
}
if (bDevice)
{
if (MessageBox (hwndDlg, getstr (IDS_ADMIN_PRIVILEGES_WARN_DEVICES), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL)
goto cancel;
}
}
ArrowWaitCursor ();
if (bDevice == FALSE)
{
int x = _access (szDiskFile, 06);
if (x == 0 || errno != ENOENT)
{
char szTmp[512];
UINT nID;
if (errno == EACCES)
nID = IDS_READONLYPROMPT;
else
nID = IDS_OVERWRITEPROMPT;
if (! ((bHiddenVol && !bHiddenVolHost) && nID == IDS_OVERWRITEPROMPT)) // Only ask ask for permission to overwrite an existing volume if we're not creating a hidden volume
{
sprintf (szTmp, getstr (nID), szDiskFile);
x = MessageBox (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2);
if (x != IDYES)
goto cancel;
}
}
if (_access (szDiskFile, 06) != 0)
{
if (errno == EACCES)
{
if (_chmod (szDiskFile, _S_IREAD | _S_IWRITE) != 0)
{
MessageBox (hwndDlg, getstr (IDS_ACCESSMODEFAIL), lpszTitle, ICON_HAND);
goto cancel;
}
}
}
strcpy (szCFDevice, szDiskFile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -