📄 mount.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 <time.h>
#include <math.h>
#include <dbt.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
#include <windowsx.h>
#include "Apidrvr.h"
#include "BootEncryption.h"
#include "Cmdline.h"
#include "Crypto.h"
#include "Dlgcode.h"
#include "Combo.h"
#include "Hotkeys.h"
#include "Keyfiles.h"
#include "Language.h"
#include "MainCom.h"
#include "Mount.h"
#include "Pkcs5.h"
#include "Random.h"
#include "Registry.h"
#include "Resource.h"
#include "Password.h"
#include "Xml.h"
#include "../Boot/Windows/BootCommon.h"
#include "../Common/Dictionary.h"
#include "../Common/Common.h"
#include "../Common/Resource.h"
#include "../Common/SecurityToken.h"
#include "../Platform/Finally.h"
#include "../Platform/ForEach.h"
using namespace TrueCrypt;
enum timer_ids
{
TIMER_ID_MAIN = 0xff,
TIMER_ID_KEYB_LAYOUT_GUARD
};
enum hidden_os_read_only_notif_mode
{
TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE = 0,
TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT,
TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED
};
#define TIMER_INTERVAL_MAIN 500
#define TIMER_INTERVAL_KEYB_LAYOUT_GUARD 10
BootEncryption *BootEncObj = NULL;
BootEncryptionStatus BootEncStatus;
BootEncryptionStatus RecentBootEncStatus;
BOOL bExplore = FALSE; /* Display explorer window after mount */
BOOL bBeep = FALSE; /* Donot beep after mount */
char szFileName[TC_MAX_PATH+1]; /* Volume to mount */
char szDriveLetter[3]; /* Drive Letter to mount */
char commandLineDrive = 0;
BOOL bCacheInDriver = FALSE; /* Cache any passwords we see */
BOOL bCacheInDriverDefault = FALSE;
BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */
BOOL bCloseDismountedWindows=TRUE; /* Close all open explorer windows of dismounted volume */
BOOL bWipeCacheOnExit = FALSE; /* Wipe password from chace on exit */
BOOL bWipeCacheOnAutoDismount = TRUE;
BOOL bEnableBkgTask = FALSE;
BOOL bCloseBkgTaskWhenNoVolumes = FALSE;
BOOL bDismountOnLogOff = TRUE;
BOOL bDismountOnScreenSaver = TRUE;
BOOL bDismountOnPowerSaving = FALSE;
BOOL bForceAutoDismount = TRUE;
BOOL bForceMount = FALSE; /* Mount volume even if host file/device already in use */
BOOL bForceUnmount = FALSE; /* Unmount volume even if it cannot be locked */
BOOL bWipe = FALSE; /* Wipe driver passwords */
BOOL bAuto = FALSE; /* Do everything without user input */
BOOL bAutoMountDevices = FALSE; /* Auto-mount devices */
BOOL bAutoMountFavorites = FALSE;
BOOL bPlaySoundOnHotkeyMountDismount = TRUE;
BOOL bDisplayMsgBoxOnHotkeyDismount = FALSE;
BOOL bHibernationPreventionNotified = FALSE; /* TRUE if the user has been notified that hibernation was prevented (system encryption) during the session. */
BOOL bHiddenSysLeakProtNotifiedDuringSession = FALSE; /* TRUE if the user has been notified during the session that unencrypted filesystems and non-hidden TrueCrypt volumes are mounted as read-only under hidden OS. */
BOOL CloseSecurityTokenSessionsAfterMount = FALSE;
BOOL MultipleMountOperationInProgress = FALSE;
BOOL Quit = FALSE; /* Exit after processing command line */
BOOL ComServerMode = FALSE;
BOOL UsePreferences = TRUE;
int HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE;
int MaxVolumeIdleTime = -120;
int nCurrentShowType = 0; /* current display mode, mount, unmount etc */
int nSelectedDriveIndex = -1; /* Item number of selected drive */
int cmdUnmountDrive = 0; /* Volume drive letter to unmount (-1 = all) */
Password VolumePassword; /* Password used for mounting volumes */
Password CmdVolumePassword; /* Password passed from command line */
BOOL CmdVolumePasswordValid = FALSE;
MountOptions mountOptions;
MountOptions defaultMountOptions;
KeyFile *FirstCmdKeyFile;
HBITMAP hbmLogoBitmapRescaled = 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. */
static KeyFilesDlgParam hidVolProtKeyFilesParam;
static MOUNT_LIST_STRUCT LastKnownMountList;
VOLUME_NOTIFICATIONS_LIST VolumeNotificationsList;
static DWORD LastKnownLogicalDrives;
static HANDLE TaskBarIconMutex = NULL;
static BOOL MainWindowHidden = FALSE;
static int pwdChangeDlgMode = PCDM_CHANGE_PASSWORD;
static int bSysEncPwdChangeDlgMode = FALSE;
static int bPrebootPasswordDlgMode = FALSE;
static int NoCmdLineArgs;
static BOOL CmdLineVolumeSpecified;
static void localcleanup (void)
{
// Wipe command line
char *c = GetCommandLineA ();
wchar_t *wc = GetCommandLineW ();
burn(c, strlen (c));
burn(wc, wcslen (wc) * sizeof (wchar_t));
/* Delete buffered bitmaps (if any) */
if (hbmLogoBitmapRescaled != NULL)
{
DeleteObject ((HGDIOBJ) hbmLogoBitmapRescaled);
hbmLogoBitmapRescaled = NULL;
}
/* These items should have already been cleared by the functions that used them, but we're going to
clear them for extra security. */
burn (&VolumePassword, sizeof (VolumePassword));
burn (&CmdVolumePassword, sizeof (CmdVolumePassword));
burn (&mountOptions, sizeof (mountOptions));
burn (&defaultMountOptions, sizeof (defaultMountOptions));
burn (&szFileName, sizeof(szFileName));
/* Cleanup common code resources */
cleanup ();
if (BootEncObj != NULL)
{
delete BootEncObj;
BootEncObj = NULL;
}
}
void RefreshMainDlg (HWND hwndDlg)
{
int drive = (char) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))));
MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory);
LoadDriveLetters (GetDlgItem (hwndDlg, IDC_DRIVELIST), drive);
EnableDisableButtons (hwndDlg);
}
void EndMainDlg (HWND hwndDlg)
{
MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory);
if (UsePreferences)
SaveSettings (hwndDlg);
if (bWipeCacheOnExit)
{
DWORD dwResult;
DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
}
if (!bHistory)
{
SetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), "");
ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME));
}
if (TaskBarIconMutex != NULL)
{
MainWindowHidden = TRUE;
ShowWindow (hwndDlg, SW_HIDE);
}
else
{
TaskBarIconRemove (hwndDlg);
EndDialog (hwndDlg, 0);
}
}
static void InitMainDialog (HWND hwndDlg)
{
MENUITEMINFOW info;
char *popupTexts[] = {"MENU_VOLUMES", "MENU_SYSTEM_ENCRYPTION", "MENU_KEYFILES", "MENU_TOOLS", "MENU_SETTINGS", "MENU_HELP", "MENU_WEBSITE", 0};
wchar_t *str;
int i;
/* Call the common dialog init code */
InitDialog (hwndDlg);
LocalizeDialog (hwndDlg, NULL);
DragAcceptFiles (hwndDlg, TRUE);
SendMessage (GetDlgItem (hwndDlg, IDC_VOLUME), CB_LIMITTEXT, TC_MAX_PATH, 0);
SetWindowTextW (hwndDlg, lpszTitle);
// Help file name
InitHelpFileName();
// Localize menu strings
for (i = 40001; str = (wchar_t *)GetDictionaryValueByInt (i); i++)
{
info.cbSize = sizeof (info);
info.fMask = MIIM_TYPE;
info.fType = MFT_STRING;
info.dwTypeData = str;
info.cch = wcslen (str);
SetMenuItemInfoW (GetMenu (hwndDlg), i, FALSE, &info);
}
for (i = 0; popupTexts[i] != 0; i++)
{
str = GetString (popupTexts[i]);
info.cbSize = sizeof (info);
info.fMask = MIIM_TYPE;
if (memcmp (popupTexts[i], "MENU_WEBSITE", 6) == 0)
info.fType = MFT_STRING | MFT_RIGHTJUSTIFY;
else
info.fType = MFT_STRING;
info.dwTypeData = str;
info.cch = wcslen (str);
SetMenuItemInfoW (GetMenu (hwndDlg), i, TRUE, &info);
}
// Resize the logo bitmap if the user has a non-default DPI
if (ScreenDPI != USER_DEFAULT_SCREEN_DPI
&& hbmLogoBitmapRescaled == NULL) // If not re-called (e.g. after language pack change)
{
hbmLogoBitmapRescaled = RenderBitmap (MAKEINTRESOURCE (IDB_LOGO_288DPI),
GetDlgItem (hwndDlg, IDC_LOGO),
0, 0, 0, 0, FALSE, TRUE);
}
BuildTree (GetDlgItem (hwndDlg, IDC_DRIVELIST));
if (*szDriveLetter != 0)
{
SelectItem (GetDlgItem (hwndDlg, IDC_DRIVELIST), *szDriveLetter);
if(nSelectedDriveIndex > SendMessage (GetDlgItem (hwndDlg, IDC_DRIVELIST), LVM_GETITEMCOUNT, 0, 0)/2)
SendMessage(GetDlgItem (hwndDlg, IDC_DRIVELIST), LVM_SCROLL, 0, 1000);
}
SendMessage (GetDlgItem (hwndDlg, IDC_NO_HISTORY), BM_SETCHECK, bHistory ? BST_UNCHECKED : BST_CHECKED, 0);
EnableDisableButtons (hwndDlg);
}
void EnableDisableButtons (HWND hwndDlg)
{
HWND hOKButton = GetDlgItem (hwndDlg, IDOK);
WORD x;
x = LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)));
EnableMenuItem (GetMenu (hwndDlg), IDM_MOUNT_VOLUME, MF_ENABLED);
EnableMenuItem (GetMenu (hwndDlg), IDM_MOUNT_VOLUME_OPTIONS, MF_ENABLED);
EnableMenuItem (GetMenu (hwndDlg), IDM_BACKUP_VOL_HEADER, MF_ENABLED);
EnableMenuItem (GetMenu (hwndDlg), IDM_RESTORE_VOL_HEADER, MF_ENABLED);
EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_PASSWORD, MF_ENABLED);
EnableWindow (hOKButton, TRUE);
switch (x)
{
case TC_MLIST_ITEM_NONSYS_VOL:
{
SetWindowTextW (hOKButton, GetString ("UNMOUNT_BUTTON"));
EnableWindow (hOKButton, TRUE);
EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_ENABLED);
EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), TRUE);
EnableMenuItem (GetMenu (hwndDlg), IDM_VOLUME_PROPERTIES, MF_ENABLED);
}
break;
case TC_MLIST_ITEM_SYS_PARTITION:
case TC_MLIST_ITEM_SYS_DRIVE:
EnableWindow (hOKButton, FALSE);
SetWindowTextW (hOKButton, GetString ("MOUNT_BUTTON"));
EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), TRUE);
EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_GRAYED);
break;
case TC_MLIST_ITEM_FREE:
default:
SetWindowTextW (hOKButton, GetString ("MOUNT_BUTTON"));
EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), FALSE);
EnableMenuItem (GetMenu (hwndDlg), IDM_VOLUME_PROPERTIES, MF_GRAYED);
EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_GRAYED);
}
EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty());
EnableMenuItem (GetMenu (hwndDlg), IDM_WIPE_CACHE, IsPasswordCacheEmpty() ? MF_GRAYED:MF_ENABLED);
EnableMenuItem (GetMenu (hwndDlg), IDM_CLEAR_HISTORY, IsComboEmpty (GetDlgItem (hwndDlg, IDC_VOLUME)) ? MF_GRAYED:MF_ENABLED);
}
BOOL VolumeSelected (HWND hwndDlg)
{
return (GetWindowTextLength (GetDlgItem (hwndDlg, IDC_VOLUME)) > 0);
}
/* Returns TRUE if the last partition/drive selected via the Select Device dialog box was the system
partition/drive and if it is encrypted.
WARNING: This function is very fast but not always reliable (for example, if the user manually types
a device path before Select Device is invoked during the session; after the Select Device dialog
has been invoked at least once, the correct system device paths are cached). Therefore, it must NOT
be used before performing any dangerous operations (such as header backup restore or formatting a
supposedly non-system device) -- instead use IsSystemDevicePath(path, hwndDlg, TRUE) for such
purposes. This function can be used only for preliminary GUI checks requiring very fast responses. */
BOOL ActiveSysEncDeviceSelected (void)
{
try
{
BootEncStatus = BootEncObj->GetStatus();
if (BootEncStatus.DriveEncrypted)
{
int retCode = 0;
GetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szFileName, sizeof (szFileName));
retCode = IsSystemDevicePath (szFileName, MainDlg, FALSE);
return (WholeSysDriveEncryption(FALSE) ? (retCode == 2 || retCode == 1) : (retCode == 1));
}
}
catch (Exception &e)
{
e.Show (MainDlg);
}
return FALSE;
}
void LoadSettings (HWND hwndDlg)
{
WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE;
LoadSysEncSettings (hwndDlg);
if (LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0)
bInPlaceEncNonSysPending = TRUE;
// If the config file has already been loaded during this session
if (ConfigBuffer != NULL)
{
free (ConfigBuffer);
ConfigBuffer = NULL;
}
// Options
bExplore = ConfigReadInt ("OpenExplorerWindowAfterMount", FALSE);
bCloseDismountedWindows = ConfigReadInt ("CloseExplorerWindowsOnDismount", TRUE);
bHistory = ConfigReadInt ("SaveVolumeHistory", FALSE);
bCacheInDriverDefault = bCacheInDriver = ConfigReadInt ("CachePasswords", FALSE);
bWipeCacheOnExit = ConfigReadInt ("WipePasswordCacheOnExit", FALSE);
bWipeCacheOnAutoDismount = ConfigReadInt ("WipeCacheOnAutoDismount", TRUE);
bStartOnLogon = ConfigReadInt ("StartOnLogon", FALSE);
bMountDevicesOnLogon = ConfigReadInt ("MountDevicesOnLogon", FALSE);
bMountFavoritesOnLogon = ConfigReadInt ("MountFavoritesOnLogon", FALSE);
bEnableBkgTask = ConfigReadInt ("EnableBackgroundTask", TRUE);
bCloseBkgTaskWhenNoVolumes = ConfigReadInt ("CloseBackgroundTaskOnNoVolumes", FALSE);
bDismountOnLogOff = ConfigReadInt ("DismountOnLogOff", TRUE);
bDismountOnPowerSaving = ConfigReadInt ("DismountOnPowerSaving", TRUE);
bDismountOnScreenSaver = ConfigReadInt ("DismountOnScreenSaver", FALSE);
bForceAutoDismount = ConfigReadInt ("ForceAutoDismount", TRUE);
MaxVolumeIdleTime = ConfigReadInt ("MaxVolumeIdleTime", -60);
HiddenSectorDetectionStatus = ConfigReadInt ("HiddenSectorDetectionStatus", 0);
defaultKeyFilesParam.EnableKeyFiles = ConfigReadInt ("UseKeyfiles", FALSE);
bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = ConfigReadInt ("PreserveTimestamps", TRUE);
defaultMountOptions.Removable = ConfigReadInt ("MountVolumesRemovable", FALSE);
defaultMountOptions.ReadOnly = ConfigReadInt ("MountVolumesReadOnly", FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -