?? dlgcode.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 <dbt.h>
#include <fcntl.h>
#include <io.h>
#include <math.h>
#include <shlobj.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#include "Resource.h"
#include "Apidrvr.h"
#include "BootEncryption.h"
#include "Combo.h"
#include "Crc.h"
#include "Crypto.h"
#include "Dictionary.h"
#include "Dlgcode.h"
#include "EncryptionThreadPool.h"
#include "Endian.h"
#include "Language.h"
#include "Keyfiles.h"
#include "Mount/Mount.h"
#include "Pkcs5.h"
#include "Random.h"
#include "Registry.h"
#include "Tests.h"
#include "Volumes.h"
#include "Wipe.h"
#include "Xml.h"
#include "Xts.h"
using namespace TrueCrypt;
#ifdef VOLFORMAT
#include "Format/Tcformat.h"
#endif
#ifdef SETUP
#include "Setup/Setup.h"
#endif
LONG DriverVersion;
char *LastDialogId;
char szHelpFile[TC_MAX_PATH];
char szHelpFile2[TC_MAX_PATH];
HFONT hFixedDigitFont = NULL;
HFONT hBoldFont = NULL;
HFONT hTitleFont = NULL;
HFONT hFixedFont = NULL;
HFONT hUserFont = NULL;
HFONT hUserUnderlineFont = NULL;
HFONT hUserBoldFont = NULL;
HFONT hUserUnderlineBoldFont = NULL;
int ScreenDPI = USER_DEFAULT_SCREEN_DPI;
double DPIScaleFactorX = 1;
double DPIScaleFactorY = 1;
double DlgAspectRatio = 1;
HWND MainDlg = NULL;
wchar_t *lpszTitle = NULL;
BOOL Silent = FALSE;
BOOL bPreserveTimestamp = TRUE;
BOOL bStartOnLogon = FALSE;
BOOL bMountDevicesOnLogon = FALSE;
BOOL bMountFavoritesOnLogon = FALSE;
BOOL bHistory = FALSE;
// Status of detection of hidden sectors (whole-system-drive encryption).
// 0 - Unknown/undetermined/success, 1: Detection is or was in progress (but did not complete e.g. due to system crash).
int HiddenSectorDetectionStatus = 0;
int nCurrentOS = 0;
int CurrentOSMajor = 0;
int CurrentOSMinor = 0;
int CurrentOSServicePack = 0;
BOOL RemoteSession = FALSE;
BOOL UacElevated = FALSE;
BOOL bTravelerModeConfirmed = FALSE; // TRUE if it is certain that the instance is running in traveler mode
/* Globals used by Mount and Format (separately per instance) */
BOOL KeyFilesEnable = FALSE;
KeyFile *FirstKeyFile = NULL;
KeyFilesDlgParam defaultKeyFilesParam;
BOOL IgnoreWmDeviceChange = FALSE;
/* Handle to the device driver */
HANDLE hDriver = INVALID_HANDLE_VALUE;
/* This mutex is used to prevent multiple instances of the wizard or main app from dealing with system encryption */
volatile HANDLE hSysEncMutex = NULL;
/* This mutex is used to prevent multiple instances of the wizard or main app from trying to install or
register the driver or from trying to launch it in traveler mode at the same time. */
volatile HANDLE hDriverSetupMutex = NULL;
/* This mutex is used to prevent users from running the main TrueCrypt app or the wizard while an instance
of the TrueCrypt installer is running (which is also useful for enforcing restart before the apps can be used). */
volatile HANDLE hAppSetupMutex = NULL;
HINSTANCE hInst = NULL;
HCURSOR hCursor = NULL;
ATOM hDlgClass, hSplashClass;
/* This value may changed only by calling ChangeSystemEncryptionStatus(). Only the wizard can change it
(others may still read it though). */
int SystemEncryptionStatus = SYSENC_STATUS_NONE;
/* Only the wizard can change this value (others may only read it). */
WipeAlgorithmId nWipeMode = TC_WIPE_NONE;
BOOL bSysPartitionSelected = FALSE; /* TRUE if the user selected the system partition via the Select Device dialog */
BOOL bSysDriveSelected = FALSE; /* TRUE if the user selected the system drive via the Select Device dialog */
/* To populate these arrays, call GetSysDevicePaths(). If they contain valid paths, bCachedSysDevicePathsValid is TRUE. */
char SysPartitionDevicePath [TC_MAX_PATH];
char SysDriveDevicePath [TC_MAX_PATH];
char bCachedSysDevicePathsValid = FALSE;
BOOL bRawDevicesDlgProcInstantExit = FALSE;
BOOL bHyperLinkBeingTracked = FALSE;
int WrongPwdRetryCounter = 0;
static FILE *ConfigFileHandle;
char *ConfigBuffer;
#define RANDPOOL_DISPLAY_REFRESH_INTERVAL 30
#define RANDPOOL_DISPLAY_ROWS 20
#define RANDPOOL_DISPLAY_COLUMNS 32
/* Windows dialog class */
#define WINDOWS_DIALOG_CLASS "#32770"
/* Custom class names */
#define TC_DLG_CLASS "CustomDlg"
#define TC_SPLASH_CLASS "SplashDlg"
/* Benchmarks */
#ifndef SETUP
#define BENCHMARK_MAX_ITEMS 100
#define BENCHMARK_DEFAULT_BUF_SIZE BYTES_PER_MB
#define HASH_FNC_BENCHMARKS FALSE // For development purposes only. Must be FALSE when building a public release.
#define PKCS5_BENCHMARKS FALSE // For development purposes only. Must be FALSE when building a public release.
#if PKCS5_BENCHMARKS && HASH_FNC_BENCHMARKS
#error PKCS5_BENCHMARKS and HASH_FNC_BENCHMARKS are both TRUE (at least one of them should be FALSE).
#endif
enum
{
BENCHMARK_SORT_BY_NAME = 0,
BENCHMARK_SORT_BY_SPEED
};
typedef struct
{
int id;
char name[100];
unsigned __int64 encSpeed;
unsigned __int64 decSpeed;
unsigned __int64 meanBytesPerSec;
} BENCHMARK_REC;
BENCHMARK_REC benchmarkTable [BENCHMARK_MAX_ITEMS];
int benchmarkTotalItems = 0;
int benchmarkBufferSize = BENCHMARK_DEFAULT_BUF_SIZE;
int benchmarkLastBufferSize = BENCHMARK_DEFAULT_BUF_SIZE;
int benchmarkSortMethod = BENCHMARK_SORT_BY_SPEED;
LARGE_INTEGER benchmarkPerformanceFrequency;
#endif // #ifndef SETUP
void cleanup ()
{
/* Cleanup the GDI fonts */
if (hFixedFont != NULL)
DeleteObject (hFixedFont);
if (hFixedDigitFont != NULL)
DeleteObject (hFixedDigitFont);
if (hBoldFont != NULL)
DeleteObject (hBoldFont);
if (hTitleFont != NULL)
DeleteObject (hTitleFont);
if (hUserFont != NULL)
DeleteObject (hUserFont);
if (hUserUnderlineFont != NULL)
DeleteObject (hUserUnderlineFont);
if (hUserBoldFont != NULL)
DeleteObject (hUserBoldFont);
if (hUserUnderlineBoldFont != NULL)
DeleteObject (hUserUnderlineBoldFont);
/* Cleanup our dialog class */
if (hDlgClass)
UnregisterClass (TC_DLG_CLASS, hInst);
if (hSplashClass)
UnregisterClass (TC_SPLASH_CLASS, hInst);
/* Close the device driver handle */
if (hDriver != INVALID_HANDLE_VALUE)
{
// Unload driver mode if possible (non-install mode)
if (IsNonInstallMode ())
{
// If a dismount was forced in the lifetime of the driver, Windows may later prevent it to be loaded again from
// the same path. Therefore, the driver will not be unloaded even though it was loaded in non-install mode.
int refDevDeleted;
DWORD dwResult;
if (!DeviceIoControl (hDriver, TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED, NULL, 0, &refDevDeleted, sizeof (refDevDeleted), &dwResult, NULL))
refDevDeleted = 0;
if (!refDevDeleted)
DriverUnload ();
else
{
CloseHandle (hDriver);
hDriver = INVALID_HANDLE_VALUE;
}
}
else
{
CloseHandle (hDriver);
hDriver = INVALID_HANDLE_VALUE;
}
}
if (ConfigBuffer != NULL)
{
free (ConfigBuffer);
ConfigBuffer = NULL;
}
CoUninitialize ();
CloseSysEncMutex ();
#ifndef SETUP
EncryptionThreadPoolStop();
#endif
}
void
LowerCaseCopy (char *lpszDest, char *lpszSource)
{
int i = strlen (lpszSource);
lpszDest[i] = 0;
while (--i >= 0)
{
lpszDest[i] = (char) tolower (lpszSource[i]);
}
}
void
UpperCaseCopy (char *lpszDest, char *lpszSource)
{
int i = strlen (lpszSource);
lpszDest[i] = 0;
while (--i >= 0)
{
lpszDest[i] = (char) toupper (lpszSource[i]);
}
}
BOOL IsVolumeDeviceHosted (char *lpszDiskFile)
{
return strstr (lpszDiskFile, "\\Device\\") == lpszDiskFile
|| strstr (lpszDiskFile, "\\DEVICE\\") == lpszDiskFile;
}
void
CreateFullVolumePath (char *lpszDiskFile, char *lpszFileName, BOOL * bDevice)
{
if (strcmp (lpszFileName, "Floppy (A:)") == 0)
strcpy (lpszFileName, "\\Device\\Floppy0");
else if (strcmp (lpszFileName, "Floppy (B:)") == 0)
strcpy (lpszFileName, "\\Device\\Floppy1");
UpperCaseCopy (lpszDiskFile, lpszFileName);
*bDevice = FALSE;
if (memcmp (lpszDiskFile, "\\DEVICE", sizeof (char) * 7) == 0)
{
*bDevice = TRUE;
}
strcpy (lpszDiskFile, lpszFileName);
#if _DEBUG
OutputDebugString ("CreateFullVolumePath: ");
OutputDebugString (lpszDiskFile);
OutputDebugString ("\n");
#endif
}
int
FakeDosNameForDevice (char *lpszDiskFile, char *lpszDosDevice, char *lpszCFDevice, BOOL bNameOnly)
{
BOOL bDosLinkCreated = TRUE;
sprintf (lpszDosDevice, "truecrypt%lu", GetCurrentProcessId ());
if (bNameOnly == FALSE)
bDosLinkCreated = DefineDosDevice (DDD_RAW_TARGET_PATH, lpszDosDevice, lpszDiskFile);
if (bDosLinkCreated == FALSE)
return ERR_OS_ERROR;
else
sprintf (lpszCFDevice, "\\\\.\\%s", lpszDosDevice);
return 0;
}
int
RemoveFakeDosName (char *lpszDiskFile, char *lpszDosDevice)
{
BOOL bDosLinkRemoved = DefineDosDevice (DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE |
DDD_REMOVE_DEFINITION, lpszDosDevice, lpszDiskFile);
if (bDosLinkRemoved == FALSE)
{
return ERR_OS_ERROR;
}
return 0;
}
void
AbortProcess (char *stringId)
{
// Note that this function also causes localcleanup() to be called (see atexit())
MessageBeep (MB_ICONEXCLAMATION);
MessageBoxW (NULL, GetString (stringId), lpszTitle, ICON_HAND);
exit (1);
}
void
AbortProcessSilent (void)
{
// Note that this function also causes localcleanup() to be called (see atexit())
exit (1);
}
void *
err_malloc (size_t size)
{
void *z = (void *) TCalloc (size);
if (z)
return z;
AbortProcess ("OUTOFMEMORY");
return 0;
}
char *
err_strdup (char *lpszText)
{
int j = (strlen (lpszText) + 1) * sizeof (char);
char *z = (char *) err_malloc (j);
memmove (z, lpszText, j);
return z;
}
DWORD
handleWin32Error (HWND hwndDlg)
{
PWSTR lpMsgBuf;
DWORD dwError = GetLastError ();
if (Silent || dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE)
return dwError;
// Access denied
if (dwError == ERROR_ACCESS_DENIED && !IsAdmin ())
{
Error ("ERR_ACCESS_DENIED");
SetLastError (dwError); // Preserve the original error code
return dwError;
}
FormatMessageW (
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(PWSTR) &lpMsgBuf,
0,
NULL
);
MessageBoxW (hwndDlg, lpMsgBuf, lpszTitle, ICON_HAND);
LocalFree (lpMsgBuf);
// User-friendly hardware error explanation
if (dwError == ERROR_CRC || dwError == ERROR_IO_DEVICE || dwError == ERROR_BAD_CLUSTERS
|| dwError == ERROR_SEM_TIMEOUT) // Semaphore timeout is sometimes reported instead of an I/O error
{
Error ("ERR_HARDWARE_ERROR");
}
// Device not ready
if (dwError == ERROR_NOT_READY)
CheckSystemAutoMount();
SetLastError (dwError); // Preserve the original error code
return dwError;
}
BOOL
translateWin32Error (wchar_t *lpszMsgBuf, int nWSizeOfBuf)
{
DWORD dwError = GetLastError ();
if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
lpszMsgBuf, nWSizeOfBuf, NULL))
{
SetLastError (dwError); // Preserve the original error code
return TRUE;
}
SetLastError (dwError); // Preserve the original error code
return FALSE;
}
// If the user has a non-default screen DPI, all absolute font sizes must be
// converted using this function.
int CompensateDPIFont (int val)
{
if (ScreenDPI == USER_DEFAULT_SCREEN_DPI)
return val;
else
{
double tmpVal = (double) val * DPIScaleFactorY * DlgAspectRatio * 0.999;
if (tmpVal > 0)
return (int) floor(tmpVal);
else
return (int) ceil(tmpVal);
}
}
// If the user has a non-default screen DPI, some screen coordinates and sizes must
// be converted using this function
int CompensateXDPI (int val)
{
if (ScreenDPI == USER_DEFAULT_SCREEN_DPI)
return val;
else
{
double tmpVal = (double) val * DPIScaleFactorX;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -