📄 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.6 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 <windowsx.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 "Platform/Finally.h"
#include "Platform/ForEach.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 "SecurityToken.h"
#include "Tests.h"
#include "Volumes.h"
#include "Wipe.h"
#include "Xml.h"
#include "Xts.h"
#include "Boot/Windows/BootCommon.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];
char SecurityTokenLibraryPath[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
BOOL bInPlaceEncNonSysPending = FALSE; // TRUE if the non-system in-place encryption config file indicates that one or more partitions are scheduled to be encrypted. This flag is set only when config files are loaded during app startup.
/* 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 for non-system in-place encryption but only for informative (non-blocking) purposes,
such as whether an app should prompt the user whether to resume scheduled process. */
volatile HANDLE hNonSysInplaceEncMutex = 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 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
typedef struct
{
void *strings;
BOOL bold;
} MULTI_CHOICE_DLGPROC_PARAMS;
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
try
{
if (SecurityToken::IsInitialized())
SecurityToken::CloseLibrary();
}
catch (...) { }
EncryptionThreadPoolStop();
#endif
}
void LowerCaseCopy (char *lpszDest, const char *lpszSource)
{
int i = strlen (lpszSource);
lpszDest[i] = 0;
while (--i >= 0)
{
lpszDest[i] = (char) tolower (lpszSource[i]);
}
}
void UpperCaseCopy (char *lpszDest, const char *lpszSource)
{
int i = strlen (lpszSource);
lpszDest[i] = 0;
while (--i >= 0)
{
lpszDest[i] = (char) toupper (lpszSource[i]);
}
}
std::string ToUpperCase (const std::string &str)
{
string u;
foreach (char c, str)
{
u += (char) toupper (c);
}
return u;
}
BOOL IsVolumeDeviceHosted (char *lpszDiskFile)
{
return strstr (lpszDiskFile, "\\Device\\") == lpszDiskFile
|| strstr (lpszDiskFile, "\\DEVICE\\") == lpszDiskFile;
}
void CreateFullVolumePath (char *lpszDiskFile, const char *lpszFileName, BOOL * bDevice)
{
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 (const 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -