📄 tcformat.c
字号:
/* Copyright (C) 2004 TrueCrypt Team, truecrypt.org
This product uses components written by Paul Le Roux <pleroux@swprofessionals.com> */
#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/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
{
FILE_PAGE,
CIPHER_PAGE,
SIZE_PAGE,
PASSWORD_PAGE,
FORMAT_PAGE
};
HWND hCurPage = NULL; /* Handle to current wizard page */
int nCurPageNo = -1; /* The current wizard page */
int nVolCipher = BLOWFISH; /* Default cipher = Blowfish */
int pkcs5 = SHA1; /* Which key derivation to use,
default=HMAC-SHA1 */
unsigned __int64 nFileSize = 0; /* The volume size */
int nMultiplier = 1024*1024; /* Was the size selection in KB or MB */
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; /* If the user cancels the volume formatting;
this is set */
BOOL bThreadRunning = FALSE; /* Is the thread running */
BOOL bDevice = FALSE; /* Is this a partition volume ? */
HWND hDiskKey = NULL; /* Text box showing hex dump of disk key */
HWND hKeySalt = NULL; /* Text box showing hex dump of key salt */
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;
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 (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
ComboSelChangeCipher (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
{
UINT nID[4];
nIndex = SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_GETITEMDATA, nIndex, 0);
memset (nID, 0, sizeof (nID));
switch (nIndex)
{
case DES56:
nID[0] = IDS_DES_HELP0;
nID[1] = IDS_DES_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
break;
case BLOWFISH:
nID[0] = IDS_BLOWFISH_HELP0;
nID[1] = IDS_BLOWFISH_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
break;
case IDEA:
nID[0] = IDS_IDEA_HELP0;
nID[1] = IDS_IDEA_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
break;
case CAST:
nID[0] = IDS_CAST_HELP0;
nID[1] = IDS_CAST_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
break;
case TRIPLEDES:
nID[0] = IDS_TRIPLEDES_HELP0;
nID[1] = IDS_TRIPLEDES_HELP1;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
break;
case NONE:
nID[0] = IDS_CIPHER_NONE_HELP0;
nID[1] = 0;
nID[2] = 0;
nID[3] = 0;
SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), getmultilinestr (nID));
break;
}
}
}
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;
}
}
GetWindowText (GetDlgItem (hwndDlg, IDC_SIZEBOX), szTmp, sizeof (szTmp));
lTmp = atoi64 (szTmp);
if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_KB)) == TRUE)
i = BYTES_PER_KB;
else
i = BYTES_PER_MB;
if (bEnable == TRUE)
{
if (lTmp * i < MIN_VOLUME_SIZE)
bEnable = FALSE;
if (lTmp * i > MAX_VOLUME_SIZE)
bEnable = FALSE;
}
if (bUpdate == TRUE)
{
nFileSize = lTmp;
}
nMultiplier = i;
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)
{
fatparams ft;
int nStatus;
char szDosDevice[TC_MAX_PATH];
char szCFDevice[TC_MAX_PATH];
DWORD dwWin32FormatError, dwThen, dwNow;
int nDosLinkCreated = -1;
ArrowWaitCursor ();
ft.cluster_size = SendMessage (GetDlgItem (hCurPage, IDC_CLUSTERSIZE), CB_GETITEMDATA
,SendMessage (GetDlgItem (hCurPage, IDC_CLUSTERSIZE), CB_GETCURSEL, 0, 0) , 0);
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;
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);
}
else
{
char szTmp[512];
int x;
sprintf (szTmp, getstr (IDS_OVERWRITEPROMPT_DEVICE), szFileName);
x = MessageBox (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2);
if (x != IDYES)
goto cancel;
if (nCurrentOS == WIN_NT)
{
nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, szCFDevice, FALSE);
if (nDosLinkCreated != 0)
{
handleWin32Error (hwndDlg);
goto cancel;
}
}
else
{
strcpy (szCFDevice, szDiskFile);
}
}
dwThen = GetTickCount ();
nStatus = FormatVolume (szCFDevice,
bDevice,
nFileSize * nMultiplier,
szPassword,
nVolCipher,
pkcs5,
&ft,
quickFormat,
hwndDlg
);
dwNow = GetTickCount ();
if (nStatus == ERR_OUTOFMEMORY)
{
AbortProcess (IDS_OUTOFMEMORY);
}
dwWin32FormatError = GetLastError ();
if (nDosLinkCreated == 0)
{
/* Only comes here when it's WIN_NT & disk partitions */
int nStatus = RemoveFakeDosName (szDiskFile, szDosDevice);
if (nStatus != 0)
handleWin32Error (hwndDlg);
}
SetLastError (dwWin32FormatError);
if (bThreadCancel == TRUE)
{
if (bDevice == FALSE)
remove (szCFDevice);
goto cancel;
}
if (nStatus != 0)
{
char szMsg[512];
handleWin32Error (hwndDlg);
sprintf (szMsg, getstr (IDS_CREATE_FAILED), szDiskFile);
MessageBox (hwndDlg, szMsg, lpszTitle, ICON_HAND);
if (bDevice == FALSE)
remove (szCFDevice);
goto cancel;
}
else
{
char szMsg[512];
char szLabel[64];
UINT nID[4] =
{IDS_VOL_STATUS0,
IDS_VOL_STATUS1, IDS_VOL_STATUS2, 0};
if (!strcmp ((char *) ft.volume_name, " "))
{
strcat (szLabel, getstr (IDS_VOL_NO_LABEL));
}
else
{
sprintf (szLabel, getstr (IDS_VOL_LABEL), ft.volume_name);
}
sprintf (szMsg, getmultilinestr (nID), ft.num_sectors, ((__int64) ft.num_sectors*512)/1024/1024, ft.size_fat
, (int) (512*ft.fats*ft.fat_length),
(int) (512*ft.cluster_size), ft.cluster_count,
(dwNow - dwThen)/1000);
NormalCursor ();
/* Create the volstats dialog box */
DialogBoxParam (hInst, MAKEINTRESOURCE (IDD_VOLSTATS_DLG), hwndDlg,
(DLGPROC) VolstatsDlgProc, (LPARAM) & szMsg[0]);
SetTimer (hwndDlg, 0xff, RANDOM_SHOW_TIMER, NULL);
PostMessage (hwndDlg, WM_FORMAT_FINISHED, 0, 0);
bThreadRunning = FALSE;
NormalCursor ();
_endthread ();
}
cancel:
SetTimer (hwndDlg, 0xff, RANDOM_SHOW_TIMER, NULL);
PostMessage (hwndDlg, WM_THREAD_ENDED, 0, 0);
bThreadRunning = FALSE;
NormalCursor ();
_endthread ();
}
void
OpenPageHelp (HWND hwndDlg, int nPage)
{
int r = (int)ShellExecute (NULL, "open", szHelpFile, NULL, NULL, SW_SHOWNORMAL);
if (nPage); /* Remove warning */
if (r == ERROR_FILE_NOT_FOUND)
MessageBox (hwndDlg, getstr (IDS_HELP_ERROR), lpszTitle, MB_ICONERROR);
if (r == SE_ERR_NOASSOC)
MessageBox (hwndDlg, getstr (IDS_HELP_READER_ERROR), lpszTitle, MB_ICONERROR);
}
void
LoadPage (HWND hwndDlg, int nPageNo)
{
RECT rW, rD;
if (hCurPage != NULL)
{
DestroyWindow (hCurPage);
}
nCurPageNo = nPageNo;
ShowWindow (GetDlgItem (hwndDlg, IDC_POS_BOX), SW_HIDE);
EnableWindow (GetDlgItem (hwndDlg, IDC_POS_BOX), TRUE);
GetWindowRect (GetDlgItem (hwndDlg, IDC_POS_BOX), &rW);
switch (nPageNo)
{
case FILE_PAGE:
hCurPage = CreateDialog (hInst, MAKEINTRESOURCE (IDD_FILE_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
if (bHistoryCmdLine == TRUE)
EnableWindow (GetDlgItem(hCurPage, IDC_NO_HISTORY), FALSE);
else
EnableWindow (GetDlgItem(hCurPage, IDC_NO_HISTORY), TRUE);
break;
case CIPHER_PAGE:
hCurPage = CreateDialog (hInst, MAKEINTRESOURCE (IDD_CIPHER_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
break;
case SIZE_PAGE:
hCurPage = CreateDialog (hInst, MAKEINTRESOURCE (IDD_SIZE_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
break;
case PASSWORD_PAGE:
hCurPage = CreateDialog (hInst, MAKEINTRESOURCE (IDD_PASSWORD_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
break;
case FORMAT_PAGE:
hCurPage = CreateDialog (hInst, MAKEINTRESOURCE (IDD_FORMAT_PAGE_DLG), hwndDlg,
(DLGPROC) PageDialogProc);
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -