From fc37cc4a02ed13d1a73b941a9f80975600fd1b99 Mon Sep 17 00:00:00 2001 From: David Foerster Date: Tue, 10 May 2016 20:20:14 +0200 Subject: Normalize all line terminators --- src/Mount/Mount.c | 22048 ++++++++++++++++++++++++++-------------------------- 1 file changed, 11024 insertions(+), 11024 deletions(-) (limited to 'src/Mount/Mount.c') diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 5bcaddad..ef665a5a 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -1,11024 +1,11024 @@ -/* - Legal Notice: Some portions of the source code contained in this file were - derived from the source code of TrueCrypt 7.1a, which is - Copyright (c) 2003-2012 TrueCrypt Developers Association and which is - governed by the TrueCrypt License 3.0, also 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) 2013-2016 IDRIX - and are governed by the Apache License 2.0 the full text of which is - contained in the file License.txt included in VeraCrypt binary and source - code distribution packages. */ - -#include "Tcdefs.h" -#include "cpu.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Apidrvr.h" -#include "BootEncryption.h" -#include "Cmdline.h" -#include "Crypto.h" -#include "Dlgcode.h" -#include "Combo.h" -#include "Favorites.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" - -#include - -#include - -typedef BOOL (WINAPI *WTSREGISTERSESSIONNOTIFICATION)(HWND, DWORD); -typedef BOOL (WINAPI *WTSUNREGISTERSESSIONNOTIFICATION)(HWND); - -using namespace VeraCrypt; - -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 */ -wchar_t szFileName[TC_MAX_PATH+1]; /* Volume to mount */ -wchar_t szDriveLetter[3]; /* Drive Letter to mount */ -wchar_t commandLineDrive = 0; -BOOL bCacheInDriver = FALSE; /* Cache any passwords we see */ -BOOL bCacheInDriverDefault = FALSE; -BOOL bCacheDuringMultipleMount = FALSE; -BOOL bCmdCacheDuringMultipleMount = FALSE; -BOOL bIncludePimInCache = FALSE; -BOOL bTryEmptyPasswordWhenKeyfileUsed = FALSE; -BOOL bCmdTryEmptyPasswordWhenKeyfileUsed = FALSE; -BOOL bCmdTryEmptyPasswordWhenKeyfileUsedValid = FALSE; -BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */ -BOOL bUseDifferentTrayIconIfVolMounted = TRUE; -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 bDismountOnSessionLocked = 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 LogOn = FALSE; -BOOL bAutoMountDevices = FALSE; /* Auto-mount devices */ -BOOL bAutoMountFavorites = FALSE; -BOOL bPlaySoundOnSuccessfulHkDismount = TRUE; -BOOL bDisplayBalloonOnSuccessfulHkDismount = TRUE; -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 Quit = FALSE; /* Exit after processing command line */ -BOOL ComServerMode = FALSE; -BOOL ServiceMode = 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 = -2; /* Volume drive letter to unmount (-1 = all) */ -Password VolumePassword; /* Password used for mounting volumes */ -Password CmdVolumePassword; /* Password passed from command line */ -char CmdTokenPin [SecurityToken::MaxPasswordLength + 1] = {0}; -int VolumePkcs5 = 0; -int CmdVolumePkcs5 = 0; -int VolumePim = -1; -int CmdVolumePim = -1; -int DefaultVolumePkcs5 = 0; -BOOL VolumeTrueCryptMode = FALSE; -BOOL CmdVolumeTrueCryptMode = FALSE; -BOOL DefaultVolumeTrueCryptMode = FALSE; -BOOL CmdVolumePasswordValid = FALSE; -MountOptions CmdMountOptions; -BOOL CmdMountOptionsValid = FALSE; -MountOptions mountOptions; -MountOptions defaultMountOptions; -KeyFile *FirstCmdKeyFile; - -HBITMAP hbmLogoBitmapRescaled = NULL; -wchar_t OrigKeyboardLayout [8+1] = L"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 int LastDriveListVolumeColumnWidth; -// WTS handling -static HMODULE hWtsLib = NULL; -static WTSREGISTERSESSIONNOTIFICATION fnWtsRegisterSessionNotification = NULL; -static WTSUNREGISTERSESSIONNOTIFICATION fnWtsUnRegisterSessionNotification = NULL; - -static void RegisterWtsNotification(HWND hWnd) -{ - if (!hWtsLib) - { - wchar_t dllPath[MAX_PATH]; - if (GetSystemDirectory(dllPath, MAX_PATH)) - StringCbCatW(dllPath, sizeof(dllPath), L"\\wtsapi32.dll"); - else - StringCbCopyW(dllPath, sizeof(dllPath), L"c:\\Windows\\System32\\wtsapi32.dll"); - - hWtsLib = LoadLibrary(dllPath); - if (hWtsLib) - { - fnWtsRegisterSessionNotification = (WTSREGISTERSESSIONNOTIFICATION) GetProcAddress(hWtsLib, "WTSRegisterSessionNotification" ); - fnWtsUnRegisterSessionNotification = (WTSUNREGISTERSESSIONNOTIFICATION) GetProcAddress(hWtsLib, "WTSUnRegisterSessionNotification" ); - if ( !fnWtsRegisterSessionNotification - || !fnWtsUnRegisterSessionNotification - || !fnWtsRegisterSessionNotification( hWnd, NOTIFY_FOR_THIS_SESSION ) - ) - { - fnWtsRegisterSessionNotification = NULL; - fnWtsUnRegisterSessionNotification = NULL; - FreeLibrary(hWtsLib); - hWtsLib = NULL; - } - } - } -} - -static void UnregisterWtsNotification(HWND hWnd) -{ - if (hWtsLib && fnWtsUnRegisterSessionNotification) - { - fnWtsUnRegisterSessionNotification(hWnd); - FreeLibrary(hWtsLib); - hWtsLib = NULL; - fnWtsRegisterSessionNotification = NULL; - fnWtsUnRegisterSessionNotification = NULL; - } -} - -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 (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&CmdVolumePkcs5, sizeof (CmdVolumePkcs5)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&CmdVolumePim, sizeof (CmdVolumePim)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&CmdVolumeTrueCryptMode, sizeof (CmdVolumeTrueCryptMode)); - burn (&mountOptions, sizeof (mountOptions)); - burn (&defaultMountOptions, sizeof (defaultMountOptions)); - burn (szFileName, sizeof(szFileName)); - burn (&CmdTokenPin, sizeof (CmdTokenPin)); - - /* Cleanup common code resources */ - cleanup (); - - if (BootEncObj != NULL) - { - delete BootEncObj; - BootEncObj = NULL; - } - - RandStop (TRUE); -} - -void RefreshMainDlg (HWND hwndDlg) -{ - int drive = (wchar_t) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)))); - - MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory); - LoadDriveLetters (hwndDlg, 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), L""); - ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); - } - - if (TaskBarIconMutex != NULL) - { - MainWindowHidden = TRUE; - ShowWindow (hwndDlg, SW_HIDE); - } - else - { - KillTimer (hwndDlg, TIMER_ID_MAIN); - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - EndDialog (hwndDlg, 0); - } -} - -static void InitMainDialog (HWND hwndDlg) -{ - MENUITEMINFOW info; - char *popupTexts[] = {"MENU_VOLUMES", "MENU_SYSTEM_ENCRYPTION", "MENU_FAVORITES", "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); - - SetWindowLongPtrW (hwndDlg, DWLP_USER, (LONG_PTR) (IsAdmin() ? TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES : 0)); - - DragAcceptFiles (hwndDlg, TRUE); - - SendMessageW (GetDlgItem (hwndDlg, IDC_VOLUME), CB_LIMITTEXT, TC_MAX_PATH, 0); - SetWindowTextW (hwndDlg, (IsAdmin() && !IsBuiltInAdmin() && IsUacSupported() && !IsNonInstallMode()) ? (wstring (lpszTitle) + L" [" + GetString ("ADMINISTRATOR") + L"]").c_str() : 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 = (UINT) 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 (strcmp (popupTexts[i], "MENU_WEBSITE") == 0) - info.fType = MFT_STRING | MFT_RIGHTJUSTIFY; - else - info.fType = MFT_STRING; - - if (strcmp (popupTexts[i], "MENU_FAVORITES") == 0) - FavoriteVolumesMenu = GetSubMenu (GetMenu (hwndDlg), i); - - info.dwTypeData = str; - info.cch = (UINT) wcslen (str); - - SetMenuItemInfoW (GetMenu (hwndDlg), i, TRUE, &info); - } - - // Disable menu item for changing system header key derivation algorithm until it's implemented - EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO, MF_GRAYED); - - try - { - LoadFavoriteVolumes(); - } - catch (Exception &e) - { - e.Show (NULL); - } - - // 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 (hwndDlg, 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, 10000); - } - else - { - SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_DRIVELIST), 1L); - } - - 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); -} - -void GetVolumePath (HWND hwndDlg, LPWSTR szPath, int nMaxCount) -{ - GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), szPath, nMaxCount); - CorrectFileName (szPath); -} - -/* 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; - - GetVolumePath (MainDlg, szFileName, ARRAYSIZE (szFileName)); - - retCode = IsSystemDevicePath (szFileName, MainDlg, FALSE); - - return (WholeSysDriveEncryption(FALSE) ? (retCode == 2 || retCode == 1) : (retCode == 1)); - } - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - return FALSE; -} - -// When a function does not require the affected volume to be dismounted, there may be cases where we have two valid -// paths selected in the main window and we cannot be sure which of them the user really intends to apply the function to. -// This function asks the user to explicitly select either the volume path specified in the input field below the main -// drive list (whether mounted or not), or the path to the volume selected in the main drive list. If, however, both -// of the GUI elements contain the same volume (or one of them does not contain any path), this function does not -// ask the user and returns the volume path directly (no selection ambiguity). -// If driveNoPtr is not NULL, and the volume is mounted, its drive letter is returned in *driveNoPtr (if no valid drive -// letter is resolved, -1 is stored instead). -static wstring ResolveAmbiguousSelection (HWND hwndDlg, int *driveNoPtr) -{ - LPARAM selectedDrive = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); - - wchar_t volPathInputField [TC_MAX_PATH]; - - wchar_t volPathDriveListW [TC_MAX_PATH]; - wstring volPathDriveListStr; - - wstring retPath; - - VOLUME_PROPERTIES_STRUCT prop; - DWORD dwResult; - - BOOL useInputField = TRUE; - - memset (&prop, 0, sizeof(prop)); - - BOOL ambig = (LOWORD (selectedDrive) != TC_MLIST_ITEM_FREE && LOWORD (selectedDrive) != 0xffff && HIWORD (selectedDrive) != 0xffff - && VolumeSelected (MainDlg)); - - if (VolumeSelected (MainDlg)) - { - // volPathInputField will contain the volume path (if any) from the input field below the drive list - GetVolumePath (MainDlg, volPathInputField, ARRAYSIZE (volPathInputField)); - - if (!ambig) - retPath = (wstring) volPathInputField; - } - - if (LOWORD (selectedDrive) != TC_MLIST_ITEM_FREE && LOWORD (selectedDrive) != 0xffff && HIWORD (selectedDrive) != 0xffff) - { - // A volume is selected in the main drive list. - - switch (LOWORD (selectedDrive)) - { - case TC_MLIST_ITEM_NONSYS_VOL: - prop.driveNo = HIWORD (selectedDrive) - L'A'; - - if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) - { - // The driver did not return any path for this drive letter (the volume may have been dismounted). - - // Return whatever is in the input field below the drive list (even if empty) - return ((wstring) volPathInputField); - } - - // volPathDriveListWStr will contain the volume path selected in the main drive list - volPathDriveListStr = (wstring) prop.wszVolume; - break; - - case TC_MLIST_ITEM_SYS_PARTITION: - - GetSysDevicePaths (MainDlg); - - if (bCachedSysDevicePathsValid) - { - volPathDriveListStr = (wstring) SysPartitionDevicePath; - } - - break; - - case TC_MLIST_ITEM_SYS_DRIVE: - - GetSysDevicePaths (MainDlg); - - if (bCachedSysDevicePathsValid) - { - volPathDriveListStr = (wstring) SysDriveDevicePath; - } - - break; - } - - if (!ambig) - { - useInputField = FALSE; - retPath = volPathDriveListStr; - } - } - - if (ambig) - { - /* We have two paths. Compare them and if they don't match, ask the user to select one of them. Otherwise, return the path without asking. */ - - if (wmemcmp (volPathDriveListStr.c_str (), L"\\??\\", 4) == 0) - { - // The volume path starts with "\\??\\" which is used for file-hosted containers. We're going to strip this prefix. - - volPathDriveListStr = (wstring) (volPathDriveListStr.c_str () + 4); - } - - StringCbCopyW (volPathDriveListW, sizeof(volPathDriveListW), volPathDriveListStr.c_str ()); - - if (wcscmp (((wmemcmp (volPathDriveListW, L"\\??\\", 4) == 0) ? volPathDriveListW + 4 : volPathDriveListW), volPathInputField) != 0) - { - // The path selected in the input field is different from the path to the volume selected - // in the drive lettter list. We have to resolve possible ambiguity. - - wchar_t *tmp[] = {L"", L"", L"", L"", L"", 0}; - const int maxVolPathLen = 80; - - if (volPathDriveListStr.length () > maxVolPathLen) - { - // Ellipsis (path too long) - volPathDriveListStr = wstring (L"...") + volPathDriveListStr.substr (volPathDriveListStr.length () - maxVolPathLen, maxVolPathLen); - } - - wstring volPathInputFieldWStr (volPathInputField); - - if (volPathInputFieldWStr.length () > maxVolPathLen) - { - // Ellipsis (path too long) - volPathInputFieldWStr = wstring (L"...") + volPathInputFieldWStr.substr (volPathInputFieldWStr.length () - maxVolPathLen, maxVolPathLen); - } - - tmp[1] = GetString ("AMBIGUOUS_VOL_SELECTION"); - tmp[2] = (wchar_t *) volPathDriveListStr.c_str(); - tmp[3] = (wchar_t *) volPathInputFieldWStr.c_str(); - tmp[4] = GetString ("IDCANCEL"); - - switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg)) - { - case 1: - retPath = volPathDriveListStr; - break; - - case 2: - retPath = (wstring) volPathInputField; - break; - - default: - if (driveNoPtr != NULL) - *driveNoPtr = -1; - - return wstring (L""); - } - } - else - { - // Both selected paths are the same - retPath = (wstring) volPathInputField; - } - } - - if (driveNoPtr != NULL) - *driveNoPtr = GetMountedVolumeDriveNo ((wchar_t *) retPath.c_str ()); - - - if (wmemcmp (retPath.c_str (), L"\\??\\", 4) == 0) - { - // The selected volume path starts with "\\??\\" which is used for file-hosted containers. We're going to strip this prefix. - - retPath = (wstring) (retPath.c_str () + 4); - } - - return retPath; -} - -void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL* pbSettingsModified, BOOL* pbHistoryModified) -{ - char langid[6] = {0}; - if (!bOnlyCheckModified) - EnableHwEncryption ((ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE); - - WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE; - - if (!bOnlyCheckModified) - LoadSysEncSettings (); - - if (!bOnlyCheckModified && LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0) - bInPlaceEncNonSysPending = TRUE; - - // If the config file has already been loaded during this session - if (ConfigBuffer != NULL) - { - free (ConfigBuffer); - ConfigBuffer = NULL; - } - - // Options - ConfigReadCompareInt ("OpenExplorerWindowAfterMount", FALSE, &bExplore, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("UseDifferentTrayIconIfVolumesMounted", TRUE, &bUseDifferentTrayIconIfVolMounted, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("SaveVolumeHistory", FALSE, &bHistory, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("CachePasswords", FALSE, &bCacheInDriverDefault, bOnlyCheckModified, pbSettingsModified); - if (!bOnlyCheckModified) - bCacheInDriver = bCacheInDriverDefault; - - ConfigReadCompareInt ("CachePasswordDuringMultipleMount", FALSE, &bCacheDuringMultipleMount, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("WipePasswordCacheOnExit", FALSE, &bWipeCacheOnExit, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("WipeCacheOnAutoDismount", TRUE, &bWipeCacheOnAutoDismount, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("IncludePimInCache", FALSE, &bIncludePimInCache, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("TryEmptyPasswordWhenKeyfileUsed",FALSE, &bTryEmptyPasswordWhenKeyfileUsed, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("StartOnLogon", FALSE, &bStartOnLogon, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("MountDevicesOnLogon", FALSE, &bMountDevicesOnLogon, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("MountFavoritesOnLogon", FALSE, &bMountFavoritesOnLogon, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("EnableBackgroundTask", TRUE, &bEnableBkgTask, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("CloseBackgroundTaskOnNoVolumes", FALSE, &bCloseBkgTaskWhenNoVolumes, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("DismountOnLogOff", !(IsServerOS() && IsAdmin()), &bDismountOnLogOff, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("DismountOnSessionLocked", FALSE, &bDismountOnSessionLocked, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("DismountOnPowerSaving", FALSE, &bDismountOnPowerSaving, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("DismountOnScreenSaver", FALSE, &bDismountOnScreenSaver, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("ForceAutoDismount", TRUE, &bForceAutoDismount, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("MaxVolumeIdleTime", -60, &MaxVolumeIdleTime, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("HiddenSectorDetectionStatus", 0, &HiddenSectorDetectionStatus, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("UseKeyfiles", FALSE, &defaultKeyFilesParam.EnableKeyFiles, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("PreserveTimestamps", TRUE, &defaultMountOptions.PreserveTimestamp, bOnlyCheckModified, pbSettingsModified); - if (!bOnlyCheckModified) - bPreserveTimestamp = defaultMountOptions.PreserveTimestamp; - - ConfigReadCompareInt ("ShowDisconnectedNetworkDrives", FALSE, &bShowDisconnectedNetworkDrives, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("HideWaitingDialog", FALSE, &bHideWaitingDialog, bOnlyCheckModified, pbSettingsModified); - - ConfigReadCompareInt ("MountVolumesRemovable", FALSE, &defaultMountOptions.Removable, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("MountVolumesReadOnly", FALSE, &defaultMountOptions.ReadOnly, bOnlyCheckModified, pbSettingsModified); - - if (!bOnlyCheckModified) - { - defaultMountOptions.ProtectHiddenVolume = FALSE; - defaultMountOptions.ProtectedHidVolPkcs5Prf = 0; - defaultMountOptions.ProtectedHidVolPim = 0; - defaultMountOptions.PartitionInInactiveSysEncScope = FALSE; - defaultMountOptions.RecoveryMode = FALSE; - defaultMountOptions.UseBackupHeader = FALSE; - - mountOptions = defaultMountOptions; - } - - ConfigReadCompareInt ("CloseSecurityTokenSessionsAfterMount", 0, &CloseSecurityTokenSessionsAfterMount, bOnlyCheckModified, pbSettingsModified); - - if (IsHiddenOSRunning()) - ConfigReadCompareInt ("HiddenSystemLeakProtNotifStatus", TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE, &HiddenSysLeakProtectionNotificationStatus, bOnlyCheckModified, pbSettingsModified); - - // Drive letter - command line arg overrides registry - if (!bOnlyCheckModified && bHistory && szDriveLetter[0] == 0) - { - char szTmp[3] = {0}; - ConfigReadString ("LastSelectedDrive", "", szTmp, sizeof (szTmp)); - MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, szDriveLetter, ARRAYSIZE (szDriveLetter)); - } - if (bHistory && pbSettingsModified) - { - // only check for last drive modification if history enabled - char szTmp[32] = {0}; - LPARAM lLetter; - lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); - if (LOWORD (lLetter) != 0xffff) - StringCbPrintfA (szTmp, sizeof(szTmp), "%lc:", (wchar_t) HIWORD (lLetter)); - - ConfigReadCompareString ("LastSelectedDrive", "", szTmp, sizeof (szTmp), bOnlyCheckModified, pbSettingsModified); - } - - { - char szTmp[MAX_PATH]; - WideCharToMultiByte (CP_UTF8, 0, SecurityTokenLibraryPath, -1, szTmp, MAX_PATH, NULL, NULL); - ConfigReadCompareString ("SecurityTokenLibrary", "", szTmp, sizeof (szTmp) - 1, bOnlyCheckModified, pbSettingsModified); - MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, SecurityTokenLibraryPath, ARRAYSIZE (SecurityTokenLibraryPath)); - if (!bOnlyCheckModified && SecurityTokenLibraryPath[0]) - { - InitSecurityTokenLibrary(hwndDlg); - } - } - - // Hotkeys - ConfigReadCompareInt ("PlaySoundOnHotkeyMountDismount", TRUE, &bPlaySoundOnSuccessfulHkDismount, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("DisplayMsgBoxOnHotkeyDismount", TRUE, &bDisplayBalloonOnSuccessfulHkDismount, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModAutoMountDevices", 0, (int*) &Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeAutoMountDevices", 0, (int*) &Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModDismountAll", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeDismountAll", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModWipeCache", 0, (int*) &Hotkeys [HK_WIPE_CACHE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeWipeCache", 0, (int*) &Hotkeys [HK_WIPE_CACHE].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModDismountAllWipe", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeDismountAllWipe", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModForceDismountAllWipe", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeForceDismountAllWipe", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModForceDismountAllWipeExit", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeForceDismountAllWipeExit", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModMountFavoriteVolumes", 0, (int*) &Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeMountFavoriteVolumes", 0, (int*) &Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModShowHideMainWindow", 0, (int*) &Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeShowHideMainWindow", 0, (int*) &Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyModCloseSecurityTokenSessions", 0, (int*) &Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("HotkeyCodeCloseSecurityTokenSessions", 0, (int*) &Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode, bOnlyCheckModified, pbSettingsModified); - - // History - if (bHistoryCmdLine != TRUE) - { - LoadCombo (GetDlgItem (MainDlg, IDC_VOLUME), bHistory, bOnlyCheckModified, pbHistoryModified); - if (!bOnlyCheckModified && CmdLineVolumeSpecified) - SetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szFileName); - } - - // Mount Options - ConfigReadCompareInt ("DefaultPRF", 0, &DefaultVolumePkcs5, bOnlyCheckModified, pbSettingsModified); - ConfigReadCompareInt ("DefaultTrueCryptMode", FALSE, &DefaultVolumeTrueCryptMode, bOnlyCheckModified, pbSettingsModified); - - if (bOnlyCheckModified) - { - if (!IsNonInstallMode ()) - { - ConfigReadString ("Language", "", langid, sizeof (langid)); - // when installed, if no preferred language set by user, English is set default - // - if (langid [0] == 0) - StringCbCopyA (langid, sizeof(langid), "en"); - - if (pbSettingsModified && strcmp (langid, GetPreferredLangId ())) - *pbSettingsModified = TRUE; - } - else - { - StringCbCopyA (langid, sizeof(langid), GetPreferredLangId ()); - ConfigReadCompareString ("Language", "", langid, sizeof (langid), TRUE, pbSettingsModified); - } - } - - if (DefaultVolumePkcs5 < 0 || DefaultVolumePkcs5 > LAST_PRF_ID) - DefaultVolumePkcs5 = 0; - if (DefaultVolumeTrueCryptMode != TRUE && DefaultVolumeTrueCryptMode != FALSE) - DefaultVolumeTrueCryptMode = FALSE; - -} - -void LoadSettings ( HWND hwndDlg ) -{ - LoadSettingsAndCheckModified (hwndDlg, FALSE, NULL, NULL); -} - -void SaveSettings (HWND hwndDlg) -{ - WaitCursor (); - - // Check first if modifications ocurred before writing to the settings and history files - // This avoids leaking information about VeraCrypt usage when user only mount volumes without changing setttings or history - BOOL bSettingsChanged = FALSE; - BOOL bHistoryChanged = FALSE; - - LoadSettingsAndCheckModified (hwndDlg, TRUE, &bSettingsChanged, &bHistoryChanged); - - if (bSettingsChanged) - { - char szTmp[32] = {0}; - LPARAM lLetter; - - // Options - ConfigWriteBegin (); - - ConfigWriteInt ("OpenExplorerWindowAfterMount", bExplore); - ConfigWriteInt ("UseDifferentTrayIconIfVolumesMounted", bUseDifferentTrayIconIfVolMounted); - ConfigWriteInt ("SaveVolumeHistory", bHistory); - - ConfigWriteInt ("CachePasswords", bCacheInDriverDefault); - ConfigWriteInt ("CachePasswordDuringMultipleMount", bCacheDuringMultipleMount); - ConfigWriteInt ("WipePasswordCacheOnExit", bWipeCacheOnExit); - ConfigWriteInt ("WipeCacheOnAutoDismount", bWipeCacheOnAutoDismount); - - ConfigWriteInt ("IncludePimInCache", bIncludePimInCache); - - ConfigWriteInt ("TryEmptyPasswordWhenKeyfileUsed", bTryEmptyPasswordWhenKeyfileUsed); - - ConfigWriteInt ("StartOnLogon", bStartOnLogon); - ConfigWriteInt ("MountDevicesOnLogon", bMountDevicesOnLogon); - ConfigWriteInt ("MountFavoritesOnLogon", bMountFavoritesOnLogon); - - ConfigWriteInt ("MountVolumesReadOnly", defaultMountOptions.ReadOnly); - ConfigWriteInt ("MountVolumesRemovable", defaultMountOptions.Removable); - ConfigWriteInt ("PreserveTimestamps", defaultMountOptions.PreserveTimestamp); - ConfigWriteInt ("ShowDisconnectedNetworkDrives",bShowDisconnectedNetworkDrives); - ConfigWriteInt ("HideWaitingDialog", bHideWaitingDialog); - - ConfigWriteInt ("EnableBackgroundTask", bEnableBkgTask); - ConfigWriteInt ("CloseBackgroundTaskOnNoVolumes", bCloseBkgTaskWhenNoVolumes); - - ConfigWriteInt ("DismountOnLogOff", bDismountOnLogOff); - ConfigWriteInt ("DismountOnSessionLocked", bDismountOnSessionLocked); - ConfigWriteInt ("DismountOnPowerSaving", bDismountOnPowerSaving); - ConfigWriteInt ("DismountOnScreenSaver", bDismountOnScreenSaver); - ConfigWriteInt ("ForceAutoDismount", bForceAutoDismount); - ConfigWriteInt ("MaxVolumeIdleTime", MaxVolumeIdleTime); - - ConfigWriteInt ("HiddenSectorDetectionStatus", HiddenSectorDetectionStatus); - - ConfigWriteInt ("UseKeyfiles", defaultKeyFilesParam.EnableKeyFiles); - - if (IsHiddenOSRunning()) - ConfigWriteInt ("HiddenSystemLeakProtNotifStatus", HiddenSysLeakProtectionNotificationStatus); - - // save last selected drive only when history enabled - if (bHistory) - { - // Drive Letter - lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); - if (LOWORD (lLetter) != 0xffff) - StringCbPrintfA (szTmp, sizeof(szTmp), "%lc:", (wchar_t) HIWORD (lLetter)); - ConfigWriteString ("LastSelectedDrive", szTmp); - } - - ConfigWriteInt ("CloseSecurityTokenSessionsAfterMount", CloseSecurityTokenSessionsAfterMount); - - // Hotkeys - ConfigWriteInt ("HotkeyModAutoMountDevices", Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeAutoMountDevices", Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyCode); - ConfigWriteInt ("HotkeyModDismountAll", Hotkeys[HK_DISMOUNT_ALL].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeDismountAll", Hotkeys[HK_DISMOUNT_ALL].vKeyCode); - ConfigWriteInt ("HotkeyModWipeCache", Hotkeys[HK_WIPE_CACHE].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeWipeCache", Hotkeys[HK_WIPE_CACHE].vKeyCode); - ConfigWriteInt ("HotkeyModDismountAllWipe", Hotkeys[HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeDismountAllWipe", Hotkeys[HK_DISMOUNT_ALL_AND_WIPE].vKeyCode); - ConfigWriteInt ("HotkeyModForceDismountAllWipe", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeForceDismountAllWipe", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode); - ConfigWriteInt ("HotkeyModForceDismountAllWipeExit", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeForceDismountAllWipeExit", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode); - ConfigWriteInt ("HotkeyModMountFavoriteVolumes", Hotkeys[HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeMountFavoriteVolumes", Hotkeys[HK_MOUNT_FAVORITE_VOLUMES].vKeyCode); - ConfigWriteInt ("HotkeyModShowHideMainWindow", Hotkeys[HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeShowHideMainWindow", Hotkeys[HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode); - ConfigWriteInt ("HotkeyModCloseSecurityTokenSessions", Hotkeys[HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers); - ConfigWriteInt ("HotkeyCodeCloseSecurityTokenSessions", Hotkeys[HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode); - ConfigWriteInt ("PlaySoundOnHotkeyMountDismount", bPlaySoundOnSuccessfulHkDismount); - ConfigWriteInt ("DisplayMsgBoxOnHotkeyDismount", bDisplayBalloonOnSuccessfulHkDismount); - - // Language - ConfigWriteString ("Language", GetPreferredLangId ()); - - // PKCS#11 Library Path - ConfigWriteStringW ("SecurityTokenLibrary", SecurityTokenLibraryPath[0] ? SecurityTokenLibraryPath : L""); - - // Mount Options - ConfigWriteInt ("DefaultPRF", DefaultVolumePkcs5); - ConfigWriteInt ("DefaultTrueCryptMode", DefaultVolumeTrueCryptMode); - - ConfigWriteEnd (hwndDlg); - } - - if (bHistoryChanged) - { - // History - DumpCombo (GetDlgItem (MainDlg, IDC_VOLUME), IsButtonChecked (GetDlgItem (MainDlg, IDC_NO_HISTORY))); - } - - NormalCursor (); -} - -// Returns TRUE if system encryption or decryption had been or is in progress and has not been completed -static BOOL SysEncryptionOrDecryptionRequired (void) -{ - /* If you update this function, revise SysEncryptionOrDecryptionRequired() in Tcformat.c as well. */ - - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - return (SystemEncryptionStatus == SYSENC_STATUS_ENCRYPTING - || SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING - || - ( - BootEncStatus.DriveMounted - && - ( - BootEncStatus.ConfiguredEncryptedAreaStart != BootEncStatus.EncryptedAreaStart - || BootEncStatus.ConfiguredEncryptedAreaEnd != BootEncStatus.EncryptedAreaEnd - ) - ) - ); -} - -// Returns TRUE if the system partition/drive is completely encrypted -static BOOL SysDriveOrPartitionFullyEncrypted (BOOL bSilent) -{ - /* If you update this function, revise SysDriveOrPartitionFullyEncrypted() in Tcformat.c as well. */ - - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - if (!bSilent) - e.Show (MainDlg); - } - - return (!BootEncStatus.SetupInProgress - && BootEncStatus.ConfiguredEncryptedAreaEnd != 0 - && BootEncStatus.ConfiguredEncryptedAreaEnd != -1 - && BootEncStatus.ConfiguredEncryptedAreaStart == BootEncStatus.EncryptedAreaStart - && BootEncStatus.ConfiguredEncryptedAreaEnd == BootEncStatus.EncryptedAreaEnd); -} - -// Returns TRUE if the system partition/drive is being filtered by the TrueCrypt driver and the key data -// was successfully decrypted (the device is fully ready to be encrypted or decrypted). Note that this -// function does not examine whether the system device is encrypted or not (or to what extent). -static BOOL SysEncDeviceActive (BOOL bSilent) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - if (!bSilent) - e.Show (MainDlg); - - return FALSE; - } - - return (BootEncStatus.DriveMounted); -} - -// Returns TRUE if the entire system drive (as opposed to the system partition only) of the currently running OS is (or is to be) encrypted -BOOL WholeSysDriveEncryption (BOOL bSilent) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - - if (BootEncStatus.BootDriveLength.QuadPart < 1) // paranoid check - return FALSE; - else - return (BootEncStatus.ConfiguredEncryptedAreaStart == TC_BOOT_LOADER_AREA_SIZE - && BootEncStatus.ConfiguredEncryptedAreaEnd >= BootEncStatus.BootDriveLength.QuadPart - 1); - } - catch (Exception &e) - { - if (!bSilent) - e.Show (MainDlg); - - return FALSE; - } -} - -// Returns the size of the system drive/partition (if encrypted) in bytes -unsigned __int64 GetSysEncDeviceSize (BOOL bSilent) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - if (!bSilent) - e.Show (MainDlg); - return 1; - } - - if ( BootEncStatus.ConfiguredEncryptedAreaEnd < 0 - || BootEncStatus.ConfiguredEncryptedAreaStart < 0 - || BootEncStatus.ConfiguredEncryptedAreaEnd < BootEncStatus.ConfiguredEncryptedAreaStart - ) - return 1; // we return 1 to avoid devision by zero - else - return ((unsigned __int64)(BootEncStatus.ConfiguredEncryptedAreaEnd - BootEncStatus.ConfiguredEncryptedAreaStart)) + 1; -} - -// Returns the current size of the encrypted area of the system drive/partition in bytes -unsigned __int64 GetSysEncDeviceEncryptedPartSize (BOOL bSilent) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - if (!bSilent) - e.Show (MainDlg); - return 0; - } - - if ( BootEncStatus.EncryptedAreaEnd < 0 - || BootEncStatus.EncryptedAreaStart < 0 - || BootEncStatus.EncryptedAreaEnd < BootEncStatus.EncryptedAreaStart - ) - return 0; - else - return ((unsigned __int64)(BootEncStatus.EncryptedAreaEnd - BootEncStatus.EncryptedAreaStart)) + 1; -} - - -static void PopulateSysEncContextMenu (HMENU popup, BOOL bToolsOnly) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (!bToolsOnly && !IsHiddenOSRunning()) - { - if (SysEncryptionOrDecryptionRequired ()) - { - if (!BootEncStatus.SetupInProgress) - AppendMenuW (popup, MF_STRING, IDM_SYSENC_RESUME, GetString ("IDM_SYSENC_RESUME")); - - if (SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING) - AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT")); - - AppendMenuW (popup, MF_STRING, IDM_ENCRYPT_SYSTEM_DEVICE, GetString ("ENCRYPT")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - } - } - - AppendMenuW (popup, MF_STRING, IDM_CHANGE_SYS_PASSWORD, GetString ("IDM_CHANGE_SYS_PASSWORD")); - // AppendMenuW (popup, MF_STRING, IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO, GetString ("IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO")); - - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_SYS_ENC_SETTINGS, GetString ("IDM_SYS_ENC_SETTINGS")); - - if (!IsHiddenOSRunning()) - { - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_CREATE_RESCUE_DISK, GetString ("IDM_CREATE_RESCUE_DISK")); - AppendMenuW (popup, MF_STRING, IDM_VERIFY_RESCUE_DISK, GetString ("IDM_VERIFY_RESCUE_DISK")); - AppendMenuW (popup, MF_STRING, IDM_VERIFY_RESCUE_DISK_ISO, GetString ("IDM_VERIFY_RESCUE_DISK_ISO")); - } - - if (!bToolsOnly) - { - if (SysDriveOrPartitionFullyEncrypted (FALSE) && !IsHiddenOSRunning()) - { - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT")); - } - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_VOLUME_PROPERTIES, GetString ("IDPM_PROPERTIES")); - } -} - - -// WARNING: This function may take a long time to complete. To prevent data corruption, it MUST be called before -// mounting a partition (as a regular volume) that is within key scope of system encryption. -// Returns TRUE if the partition can be mounted as a partition within key scope of inactive system encryption. -// If devicePath is empty, the currently selected partition in the GUI is checked. -BOOL CheckSysEncMountWithoutPBA (HWND hwndDlg, const wchar_t *devicePath, BOOL quiet) -{ - BOOL tmpbDevice; - wchar_t szDevicePath [TC_MAX_PATH+1]; - wchar_t szDiskFile [TC_MAX_PATH+1]; - - if (wcslen (devicePath) < 2) - { - GetVolumePath (MainDlg, szDevicePath, ARRAYSIZE (szDevicePath)); - CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), szDevicePath, &tmpbDevice); - - if (!tmpbDevice) - { - if (!quiet) - Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg); - - return FALSE; - } - - if (LOWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))) != TC_MLIST_ITEM_FREE) - { - if (!quiet) - Warning ("SELECT_FREE_DRIVE", hwndDlg); - - return FALSE; - } - } - else - StringCbCopyW (szDevicePath, sizeof(szDevicePath), devicePath); - - wchar_t *partionPortion = wcsrchr (szDevicePath, L'\\'); - - if (!partionPortion - || !_wcsicmp (partionPortion, L"\\Partition0")) - { - // Only partitions are supported (not whole drives) - if (!quiet) - Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg); - - return FALSE; - } - - try - { - BootEncStatus = BootEncObj->GetStatus(); - - if (BootEncStatus.DriveMounted) - { - int retCode = 0; - int driveNo; - wchar_t parentDrivePath [TC_MAX_PATH+1]; - - if (swscanf (szDevicePath, L"\\Device\\Harddisk%d\\Partition", &driveNo) != 1) - { - if (!quiet) - Error ("INVALID_PATH", hwndDlg); - - return FALSE; - } - - StringCbPrintfW (parentDrivePath, - sizeof (parentDrivePath), - L"\\Device\\Harddisk%d\\Partition0", - driveNo); - - WaitCursor (); - - // This is critical (re-mounting a mounted system volume as a normal volume could cause data corruption) - // so we force the slower but reliable method - retCode = IsSystemDevicePath (parentDrivePath, MainDlg, TRUE); - - NormalCursor(); - - if (retCode != 2) - return TRUE; - else - { - // The partition is located on active system drive - - if (!quiet) - Warning ("MOUNT_WITHOUT_PBA_VOL_ON_ACTIVE_SYSENC_DRIVE", hwndDlg); - - return FALSE; - } - } - else - return TRUE; - } - catch (Exception &e) - { - NormalCursor(); - e.Show (hwndDlg); - } - - return FALSE; -} - - -// Returns TRUE if the host drive of the specified partition contains a portion of the TrueCrypt Boot Loader -// and if the drive is not within key scope of active system encryption (e.g. the system drive of the running OS). -// If bPrebootPasswordDlgMode is TRUE, this function returns FALSE (because the check would be redundant). -BOOL TCBootLoaderOnInactiveSysEncDrive (wchar_t *szDevicePath) -{ - try - { - int driveNo; - wchar_t parentDrivePath [TC_MAX_PATH+1]; - - if (bPrebootPasswordDlgMode) - return FALSE; - - - if (swscanf (szDevicePath, L"\\Device\\Harddisk%d\\Partition", &driveNo) != 1) - return FALSE; - - StringCbPrintfW (parentDrivePath, - sizeof (parentDrivePath), - L"\\Device\\Harddisk%d\\Partition0", - driveNo); - - BootEncStatus = BootEncObj->GetStatus(); - - if (BootEncStatus.DriveMounted - && IsSystemDevicePath (parentDrivePath, MainDlg, FALSE) == 2) - { - // The partition is within key scope of active system encryption - return FALSE; - } - - return ((BOOL) BootEncObj->IsBootLoaderOnDrive (parentDrivePath)); - } - catch (...) - { - return FALSE; - } - -} - - -BOOL SelectItem (HWND hTree, wchar_t nLetter) -{ - if (nLetter == 0) - { - // The caller specified an invalid drive letter (typically because it is unknown). - // Find out which drive letter is currently selected in the list and use it. - nLetter = (wchar_t) (HIWORD (GetSelectedLong (hTree))); - } - - int i; - LVITEM item; - - for (i = 0; i < ListView_GetItemCount(hTree); i++) - { - memset(&item, 0, sizeof(LVITEM)); - item.mask = LVIF_PARAM; - item.iItem = i; - - if (ListView_GetItem (hTree, &item) == FALSE) - return FALSE; - else - { - if (HIWORD (item.lParam) == nLetter) - { - memset(&item, 0, sizeof(LVITEM)); - item.state = LVIS_FOCUSED|LVIS_SELECTED; - item.stateMask = LVIS_FOCUSED|LVIS_SELECTED; - item.mask = LVIF_STATE; - item.iItem = i; - SendMessage(hTree, LVM_SETITEMSTATE, i, (LPARAM) &item); - return TRUE; - } - } - } - - return TRUE; -} - - -static void LaunchVolCreationWizard (HWND hwndDlg, const wchar_t *arg) -{ - wchar_t t[TC_MAX_PATH + 1024] = {L'"',0}; - wchar_t *tmp; - - GetModuleFileName (NULL, t+1, ARRAYSIZE(t)-1); - - tmp = wcsrchr (t, L'\\'); - if (tmp) - { - STARTUPINFO si; - PROCESS_INFORMATION pi; - wchar_t formatExeName[64]; - wchar_t* suffix = NULL; - ZeroMemory (&si, sizeof (si)); - - StringCbCopyW (formatExeName, sizeof (formatExeName), L"\\VeraCrypt Format"); - - // check if there is a suffix in VeraCrypt file name - // in order to use the same for "VeraCrypt Format" - suffix = wcsrchr (tmp + 1, L'-'); - if (suffix) - { - StringCbCatW (formatExeName, sizeof (formatExeName), suffix); - StringCbCatW (formatExeName, sizeof (formatExeName), L"\""); - } - else - StringCbCatW (formatExeName, sizeof (formatExeName), L".exe\""); - - *tmp = 0; - StringCbCatW (t, sizeof(t), formatExeName); - - if (!FileExists(t)) - Error ("VOL_CREATION_WIZARD_NOT_FOUND", hwndDlg); // Display a user-friendly error message and advise what to do - - if (wcslen (arg) > 0) - { - StringCbCatW (t, sizeof(t), L" "); - StringCbCatW (t, sizeof(t), arg); - } - - if (!CreateProcess (NULL, (LPWSTR) t, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) - { - handleWin32Error (hwndDlg, SRC_POS); - } - else - { - CloseHandle (pi.hProcess); - CloseHandle (pi.hThread); - } - } -} - -static void LaunchVolExpander (HWND hwndDlg) -{ - wchar_t t[TC_MAX_PATH + TC_MAX_PATH] = {L'"',0}; - wchar_t *tmp; - - GetModuleFileName (NULL, t+1, ARRAYSIZE(t)-1); - - tmp = wcsrchr (t, L'\\'); - if (tmp) - { - wchar_t expanderExeName[64]; - wchar_t* suffix = NULL; - - StringCbCopyW (expanderExeName, sizeof (expanderExeName), L"\\VeraCryptExpander"); - - // check if there is a suffix in VeraCrypt file name - // in order to use the same for "VeraCrypt Format" - suffix = wcsrchr (tmp + 1, L'-'); - if (suffix) - { - StringCbCatW (expanderExeName, sizeof (expanderExeName), suffix); - StringCbCatW (expanderExeName, sizeof (expanderExeName), L"\""); - } - else - StringCbCatW (expanderExeName, sizeof (expanderExeName), L".exe\""); - - *tmp = 0; - StringCbCatW (t, sizeof(t), expanderExeName); - - if (!FileExists(t)) - Error ("VOL_EXPANDER_NOT_FOUND", hwndDlg); // Display a user-friendly error message and advise what to do - else if (((int)ShellExecuteW (NULL, (!IsAdmin() && IsUacSupported()) ? L"runas" : L"open", t, NULL, NULL, SW_SHOW)) <= 32) - { - handleWin32Error (hwndDlg, SRC_POS); - } - } -} - - -// Fills drive list -// drive>0 = update only the corresponding drive subitems -void LoadDriveLetters (HWND hwndDlg, HWND hTree, int drive) -{ - // Remember the top-most visible item - int lastTopMostVisibleItem = ListView_GetTopIndex (hTree); - - wchar_t *szDriveLetters[]= - {L"A:", L"B:", L"C:", L"D:", - L"E:", L"F:", L"G:", L"H:", L"I:", L"J:", L"K:", - L"L:", L"M:", L"N:", L"O:", L"P:", L"Q:", L"R:", - L"S:", L"T:", L"U:", L"V:", L"W:", L"X:", L"Y:", - L"Z:"}; - - DWORD dwResult; - BOOL bResult; - DWORD dwUsedDrives; - MOUNT_LIST_STRUCT driver; - VOLUME_PROPERTIES_STRUCT propSysEnc; - wchar_t sysDriveLetter = 0; - - BOOL bSysEnc = FALSE; - BOOL bWholeSysDriveEncryption = FALSE; - - LVITEM listItem; - int item = 0; - char i; - - try - { - BootEncStatus = BootEncObj->GetStatus(); - if (bSysEnc = BootEncStatus.DriveMounted) - { - BootEncObj->GetVolumeProperties (&propSysEnc); - } - } - catch (...) - { - bSysEnc = FALSE; - } - - ZeroMemory (&driver, sizeof (driver)); - bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &driver, - sizeof (driver), &driver, sizeof (driver), &dwResult, - NULL); - memcpy (&LastKnownMountList, &driver, sizeof (driver)); - - if (bResult == FALSE) - { - KillTimer (MainDlg, TIMER_ID_MAIN); - handleWin32Error (hTree, SRC_POS); - AbortProcessSilent(); - } - - LastKnownLogicalDrives = dwUsedDrives = GetUsedLogicalDrives (); - if (dwUsedDrives == 0) - Warning ("DRIVELETTERS", hwndDlg); - - if(drive == 0) - ListView_DeleteAllItems(hTree); - - if (bSysEnc) - { - bWholeSysDriveEncryption = WholeSysDriveEncryption (TRUE); - - sysDriveLetter = GetSystemDriveLetter (); - } - - /* System drive */ - - if (bWholeSysDriveEncryption) - { - int curDrive = 0; - - if (drive > 0) - { - LVITEM tmp; - memset(&tmp, 0, sizeof(LVITEM)); - tmp.mask = LVIF_PARAM; - tmp.iItem = item; - if (ListView_GetItem (hTree, &tmp)) - curDrive = HIWORD(tmp.lParam); - } - - { - wchar_t szTmp[1024]; - wchar_t szTmpW[1024]; - - memset(&listItem, 0, sizeof(listItem)); - - listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; - listItem.iImage = 2; - listItem.iItem = item++; - - listItem.pszText = szTmp; - szTmp[0] = L' '; - szTmp[1] = 0; - - listItem.lParam = MAKELONG (TC_MLIST_ITEM_SYS_DRIVE, ENC_SYSDRIVE_PSEUDO_DRIVE_LETTER); - - if(drive == 0) - ListView_InsertItem (hTree, &listItem); - else - ListView_SetItem (hTree, &listItem); - - listItem.mask=LVIF_TEXT; - - // Fully encrypted - if (SysDriveOrPartitionFullyEncrypted (TRUE)) - { - StringCbCopyW (szTmpW, sizeof(szTmpW), GetString ("SYSTEM_DRIVE")); - } - else - { - // Partially encrypted - - if (BootEncStatus.SetupInProgress) - { - // Currently encrypting/decrypting - - if (BootEncStatus.SetupMode != SetupDecryption) - { - StringCbPrintfW (szTmpW, - sizeof szTmpW, - GetString ("SYSTEM_DRIVE_ENCRYPTING"), - (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); - } - else - { - StringCbPrintfW (szTmpW, - sizeof szTmpW, - GetString ("SYSTEM_DRIVE_DECRYPTING"), - 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0)); - } - } - else - { - StringCbPrintfW (szTmpW, - sizeof szTmpW, - GetString ("SYSTEM_DRIVE_PARTIALLY_ENCRYPTED"), - (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); - } - } - - ListSubItemSet (hTree, listItem.iItem, 1, szTmpW); - - GetSizeString (GetSysEncDeviceSize(TRUE), szTmpW, sizeof(szTmpW)); - ListSubItemSet (hTree, listItem.iItem, 2, szTmpW); - - if (propSysEnc.ea >= EAGetFirst() && propSysEnc.ea <= EAGetCount()) - { - EAGetName (szTmp, propSysEnc.ea, 1); - } - else - { - szTmp[0] = L'?'; - szTmp[1] = 0; - } - listItem.iSubItem = 3; - ListView_SetItem (hTree, &listItem); - - ListSubItemSet (hTree, listItem.iItem, 4, GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE")); - } - } - - /* Drive letters */ - - for (i = 0; i < 26; i++) - { - int curDrive = 0; - - BOOL bSysEncPartition = (bSysEnc && !bWholeSysDriveEncryption && sysDriveLetter == *((wchar_t *) szDriveLetters[i])); - - if (drive > 0) - { - LVITEM tmp; - memset(&tmp, 0, sizeof(LVITEM)); - tmp.mask = LVIF_PARAM; - tmp.iItem = item; - if (ListView_GetItem (hTree, &tmp)) - curDrive = HIWORD(tmp.lParam); - } - - if (driver.ulMountedDrives & (1 << i) - || bSysEncPartition) - { - wchar_t szTmp[1024]; - wchar_t szTmpW[1024]; - wchar_t *ws; - - memset(&listItem, 0, sizeof(listItem)); - - listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; - listItem.iImage = bSysEncPartition ? 2 : 1; - listItem.iItem = item++; - - if (drive > 0 && drive != curDrive) - continue; - - listItem.lParam = MAKELONG ( - bSysEncPartition ? TC_MLIST_ITEM_SYS_PARTITION : TC_MLIST_ITEM_NONSYS_VOL, - i + L'A'); - - listItem.pszText = szDriveLetters[i]; - - if (drive == 0) - ListView_InsertItem (hTree, &listItem); - else - ListView_SetItem (hTree, &listItem); - - listItem.mask=LVIF_TEXT; - listItem.pszText = szTmp; - - if (bSysEncPartition) - { - // Fully encrypted - if (SysDriveOrPartitionFullyEncrypted (TRUE)) - { - StringCbCopyW (szTmpW, sizeof(szTmpW), GetString (IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION")); - } - else - { - // Partially encrypted - - if (BootEncStatus.SetupInProgress) - { - // Currently encrypting/decrypting - - if (BootEncStatus.SetupMode != SetupDecryption) - { - StringCbPrintfW (szTmpW, - sizeof szTmpW, - GetString ("SYSTEM_PARTITION_ENCRYPTING"), - (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); - } - else - { - StringCbPrintfW (szTmpW, - sizeof szTmpW, - GetString ("SYSTEM_PARTITION_DECRYPTING"), - 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0)); - } - } - else - { - StringCbPrintfW (szTmpW, - sizeof szTmpW, - GetString ("SYSTEM_PARTITION_PARTIALLY_ENCRYPTED"), - (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); - } - } - - ListSubItemSet (hTree, listItem.iItem, 1, szTmpW); - } - else - { - wchar_t *path = driver.wszVolume[i]; - - if (wmemcmp (path, L"\\??\\", 4) == 0) - path += 4; - - listItem.iSubItem = 1; - - // first check label used for mounting. If empty, look for it in favorites. - bool useInExplorer = false; - wstring label = (wchar_t *) driver.wszLabel[i]; - if (label.empty()) - label = GetFavoriteVolumeLabel (path, useInExplorer); - if (!label.empty()) - ListSubItemSet (hTree, listItem.iItem, 1, (wchar_t *) label.c_str()); - else - ListSubItemSet (hTree, listItem.iItem, 1, (wchar_t *) FitPathInGfxWidth (hTree, hUserFont, ListView_GetColumnWidth (hTree, 1) - GetTextGfxWidth (hTree, L"___", hUserFont), path).c_str()); - } - - GetSizeString (bSysEncPartition ? GetSysEncDeviceSize(TRUE) : driver.diskLength[i], szTmpW, sizeof(szTmpW)); - ListSubItemSet (hTree, listItem.iItem, 2, szTmpW); - - EAGetName (szTmp, bSysEncPartition ? propSysEnc.ea : driver.ea[i], 1); - listItem.iSubItem = 3; - ListView_SetItem (hTree, &listItem); - - if (bSysEncPartition) - { - ws = GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE"); - VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; - ListSubItemSet (hTree, listItem.iItem, 4, ws); - } - else - { - switch (driver.volumeType[i]) - { - case PROP_VOL_TYPE_NORMAL: - ws = GetString ("NORMAL"); - break; - case PROP_VOL_TYPE_HIDDEN: - ws = GetString ("HIDDEN"); - break; - case PROP_VOL_TYPE_OUTER: - ws = GetString ("OUTER"); // Normal/outer volume (hidden volume protected) - break; - case PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED: - ws = GetString ("OUTER_VOL_WRITE_PREVENTED"); // Normal/outer volume (hidden volume protected AND write denied) - break; - default: - ws = L"?"; - } - - if (driver.truecryptMode[i]) - { - StringCbPrintfW (szTmpW, sizeof(szTmpW), L"TrueCrypt-%s", ws); - ListSubItemSet (hTree, listItem.iItem, 4, szTmpW); - } - else - ListSubItemSet (hTree, listItem.iItem, 4, ws); - - if (driver.volumeType[i] == PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED) // Normal/outer volume (hidden volume protected AND write denied) - { - if (!VolumeNotificationsList.bHidVolDamagePrevReported[i]) - { - wchar_t szTmp[4096]; - - VolumeNotificationsList.bHidVolDamagePrevReported[i] = TRUE; - StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), i+L'A'); - SetForegroundWindow (GetParent(hTree)); - MessageBoxW (GetParent(hTree), szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); - } - } - else - { - VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; - } - } - } - else - { - VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; - - if (!(dwUsedDrives & 1 << i)) - { - if(drive > 0 && drive != HIWORD (GetSelectedLong (hTree))) - { - item++; - continue; - } - - memset(&listItem,0,sizeof(listItem)); - - listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; - listItem.iImage = 0; - listItem.iItem = item++; - listItem.pszText = szDriveLetters[i]; - listItem.lParam = MAKELONG (TC_MLIST_ITEM_FREE, i + 'A'); - - if(drive == 0) - ListView_InsertItem (hTree, &listItem); - else - ListView_SetItem (hTree, &listItem); - - listItem.mask=LVIF_TEXT; - listItem.pszText = L""; - listItem.iSubItem = 1; - ListView_SetItem (hTree, &listItem); - listItem.iSubItem = 2; - ListView_SetItem (hTree, &listItem); - listItem.iSubItem = 3; - ListView_SetItem (hTree, &listItem); - listItem.iSubItem = 4; - ListView_SetItem (hTree, &listItem); - - } - } - } - - // Restore the original scroll position (the topmost item that was visible when we were called) and the - // last selected item. - SetListScrollHPos (hTree, lastTopMostVisibleItem); - SelectItem (hTree, 0); -} - -static void PasswordChangeEnable (HWND hwndDlg, int button, int passwordId, BOOL keyFilesEnabled, - int newPasswordId, int newVerifyId, BOOL newKeyFilesEnabled) -{ - char password[MAX_PASSWORD + 1]; - char newPassword[MAX_PASSWORD + 1]; - char newVerify[MAX_PASSWORD + 1]; - wchar_t tmp[MAX_PASSWORD + 1]; - BOOL bEnable = TRUE; - int passwordUtf8Len, newPasswordUtf8Len, newVerifyUtf8Len; - - GetWindowText (GetDlgItem (hwndDlg, passwordId), tmp, ARRAYSIZE (tmp)); - passwordUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, password, sizeof (password), NULL, NULL); - - if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF) - newKeyFilesEnabled = keyFilesEnabled; - - switch (pwdChangeDlgMode) - { - case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: - case PCDM_ADD_REMOVE_VOL_KEYFILES: - case PCDM_CHANGE_PKCS5_PRF: - memcpy (newPassword, password, sizeof (newPassword)); - memcpy (newVerify, password, sizeof (newVerify)); - newPasswordUtf8Len = passwordUtf8Len; - newVerifyUtf8Len = passwordUtf8Len; - break; - - default: - GetWindowText (GetDlgItem (hwndDlg, newPasswordId), tmp, ARRAYSIZE (tmp)); - newPasswordUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, newPassword, sizeof (newPassword), NULL, NULL); - GetWindowText (GetDlgItem (hwndDlg, newVerifyId), tmp, ARRAYSIZE (tmp)); - newVerifyUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, newVerify, sizeof (newVerify), NULL, NULL); - - } - - if (passwordUtf8Len <= 0 || (!keyFilesEnabled && ((passwordUtf8Len - 1) < MIN_PASSWORD))) - bEnable = FALSE; - else if (strcmp (newPassword, newVerify) != 0) - bEnable = FALSE; - else if ((newPasswordUtf8Len <= 0) || (!newKeyFilesEnabled && ((newPasswordUtf8Len - 1) < MIN_PASSWORD))) - bEnable = FALSE; - - burn (password, sizeof (password)); - burn (newPassword, sizeof (newPassword)); - burn (newVerify, sizeof (newVerify)); - burn (tmp, sizeof (tmp)); - - EnableWindow (GetDlgItem (hwndDlg, button), bEnable); -} - -// implementation for support of change password operation in wait dialog mechanism - -typedef struct -{ - Password *oldPassword; - int old_pkcs5; - int old_pim; - Password *newPassword; - int pkcs5; - int pim; - int wipePassCount; - BOOL truecryptMode; - int* pnStatus; -} ChangePwdThreadParam; - -void CALLBACK ChangePwdWaitThreadProc(void* pArg, HWND hwndDlg) -{ - ChangePwdThreadParam* pThreadParam = (ChangePwdThreadParam*) pArg; - - if (bSysEncPwdChangeDlgMode) - { - // System - - try - { - VOLUME_PROPERTIES_STRUCT properties; - BootEncObj->GetVolumeProperties(&properties); - pThreadParam->old_pkcs5 = properties.pkcs5; - } - catch(...) - {} - - pThreadParam->pkcs5 = 0; // PKCS-5 PRF unchanged (currently we can't change PRF of system encryption) - - try - { - *pThreadParam->pnStatus = BootEncObj->ChangePassword (pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg); - } - catch (Exception &e) - { - e.Show (hwndDlg); - *(pThreadParam->pnStatus) = ERR_OS_ERROR; - } - } - else - { - // Non-system - - *pThreadParam->pnStatus = ChangePwd (szFileName, pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->truecryptMode, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg); - - if (*pThreadParam->pnStatus == ERR_OS_ERROR - && GetLastError () == ERROR_ACCESS_DENIED - && IsUacSupported () - && IsVolumeDeviceHosted (szFileName)) - { - *pThreadParam->pnStatus = UacChangePwd (szFileName, pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->truecryptMode, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg); - } - } -} - -// implementation for support of backup header operation in wait dialog mechanism - -typedef struct -{ - BOOL bRequireConfirmation; - wchar_t *lpszVolume; - size_t cchVolume; - int* iResult; -} BackupHeaderThreadParam; - -void CALLBACK BackupHeaderWaitThreadProc(void* pArg, HWND hwndDlg) -{ - BackupHeaderThreadParam* pThreadParam = (BackupHeaderThreadParam*) pArg; - - if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume)) - { - if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) - *(pThreadParam->iResult) = UacBackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); - else - *(pThreadParam->iResult) = BackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); - } - else - *(pThreadParam->iResult) = ERR_OS_ERROR; -} - -// implementation for support of restoring header operation in wait dialog mechanism - -typedef struct -{ - wchar_t *lpszVolume; - size_t cchVolume; - int* iResult; -} RestoreHeaderThreadParam; - -void CALLBACK RestoreHeaderWaitThreadProc(void* pArg, HWND hwndDlg) -{ - RestoreHeaderThreadParam* pThreadParam = (RestoreHeaderThreadParam*) pArg; - - if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume)) - { - if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) - *(pThreadParam->iResult) = UacRestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); - else - *(pThreadParam->iResult) = RestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); - } - else - *(pThreadParam->iResult) = ERR_OS_ERROR; -} - -/* Except in response to the WM_INITDIALOG message, the dialog box procedure - should return nonzero if it processes the message, and zero if it does - not. - see DialogProc */ -BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static KeyFilesDlgParam newKeyFilesParam; - static BOOL PimValueChangedWarning = FALSE; - static int* NewPimValuePtr = NULL; - - WORD lw = LOWORD (wParam); - WORD hw = HIWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - { - LPARAM nIndex, nSelectedIndex = 0; - HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID); - int i; - WipeAlgorithmId headerWipeMode = TC_WIPE_3_DOD_5220; - int EffectiveVolumePkcs5 = CmdVolumePkcs5; - BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; - int EffectiveVolumePim = CmdVolumePim; - - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (EffectiveVolumePkcs5 == 0) - EffectiveVolumePkcs5 = DefaultVolumePkcs5; - if (!EffectiveVolumeTrueCryptMode) - EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; - - NewPimValuePtr = (int*) lParam; - - PimValueChangedWarning = FALSE; - - ZeroMemory (&newKeyFilesParam, sizeof (newKeyFilesParam)); - if (NewPimValuePtr) - { - /* we are in the case of a volume. Store its name to use it in the key file dialog - * this will help avoid using the current container file as a key file - */ - StringCbCopyW (newKeyFilesParam.VolumeFileName, sizeof (newKeyFilesParam.VolumeFileName), szFileName); - } - - SetWindowTextW (hwndDlg, GetString ("IDD_PASSWORDCHANGE_DLG")); - LocalizeDialog (hwndDlg, "IDD_PASSWORDCHANGE_DLG"); - - SendMessage (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); - SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); - SendMessage (GetDlgItem (hwndDlg, IDC_VERIFY), EM_LIMITTEXT, MAX_PASSWORD, 0); - SendMessage (GetDlgItem (hwndDlg, IDC_OLD_PIM), EM_LIMITTEXT, MAX_PIM, 0); - SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0); - EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE); - - SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE); - EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), TRUE); - - /* Add PRF algorithm list for current password */ - SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); - - nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); - - for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) - { - nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); - if (i == EffectiveVolumePkcs5) - { - nSelectedIndex = nIndex; - } - } - - SendMessage (hComboBox, CB_SETCURSEL, nSelectedIndex, 0); - - /* check TrueCrypt Mode if it was set as default*/ - SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, EffectiveVolumeTrueCryptMode); - - /* set default PIM if set in the command line*/ - if (EffectiveVolumePim > 0) - { - SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE); - ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_OLD_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW); - SetPim (hwndDlg, IDC_OLD_PIM, EffectiveVolumePim); - } - - /* Add PRF algorithm list for new password */ - hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); - SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); - - nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("UNCHANGED")); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); - - for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) - { - if (!HashIsDeprecated (i)) - { - nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); - } - } - - SendMessage (hComboBox, CB_SETCURSEL, 0, 0); - - PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, FALSE, TRUE); - SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &headerWipeMode); - - switch (pwdChangeDlgMode) - { - case PCDM_CHANGE_PKCS5_PRF: - SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_CHANGE_PKCS5_PRF")); - LocalizeDialog (hwndDlg, "IDD_PCDM_CHANGE_PKCS5_PRF"); - EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE); - break; - - case PCDM_ADD_REMOVE_VOL_KEYFILES: - SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_ADD_REMOVE_VOL_KEYFILES")); - LocalizeDialog (hwndDlg, "IDD_PCDM_ADD_REMOVE_VOL_KEYFILES"); - newKeyFilesParam.EnableKeyFiles = TRUE; - EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); - break; - - case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: - newKeyFilesParam.EnableKeyFiles = FALSE; - SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_REMOVE_ALL_KEYFILES_FROM_VOL")); - LocalizeDialog (hwndDlg, "IDD_PCDM_REMOVE_ALL_KEYFILES_FROM_VOL"); - KeyFilesEnable = TRUE; - SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, TRUE); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE); - EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_KEYFILES), TRUE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); - break; - - case PCDM_CHANGE_PASSWORD: - default: - // NOP - break; - }; - - if (bSysEncPwdChangeDlgMode) - { - /* No support for changing the password of TrueCrypt system partition */ - SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE); - - ToBootPwdField (hwndDlg, IDC_PASSWORD); - ToBootPwdField (hwndDlg, IDC_VERIFY); - ToBootPwdField (hwndDlg, IDC_OLD_PASSWORD); - - if ((DWORD) GetKeyboardLayout (NULL) != 0x00000409 && (DWORD) GetKeyboardLayout (NULL) != 0x04090409) - { - DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); - - if (keybLayout != 0x00000409 && keybLayout != 0x04090409) - { - Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 0; - } - - bKeyboardLayoutChanged = TRUE; - } - - - /* for system encryption, we can't change the PRF */ - EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), FALSE); - - if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0) - { - Error ("CANNOT_SET_TIMER", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 0; - } - - newKeyFilesParam.EnableKeyFiles = FALSE; - KeyFilesEnable = FALSE; - SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_KEYFILES), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE); - } - - CheckCapsLock (hwndDlg, FALSE); - - return 0; - } - - case WM_TIMER: - switch (wParam) - { - case TIMER_ID_KEYB_LAYOUT_GUARD: - if (bSysEncPwdChangeDlgMode) - { - DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL); - - /* Watch the keyboard layout */ - - if (keybLayout != 0x00000409 && keybLayout != 0x04090409) - { - // Keyboard layout is not standard US - - // Attempt to wipe passwords stored in the input field buffers - wchar_t tmp[MAX_PASSWORD+1]; - wmemset (tmp, L'X', MAX_PASSWORD); - tmp [MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp); - - SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), L""); - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L""); - SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), L""); - - keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); - - if (keybLayout != 0x00000409 && keybLayout != 0x04090409) - { - KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); - Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - bKeyboardLayoutChanged = TRUE; - - wchar_t szTmp [4096]; - StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED")); - StringCbCatW (szTmp, sizeof(szTmp), L"\n\n"); - StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); - MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); - } - - - /* Watch the right Alt key (which is used to enter various characters on non-US keyboards) */ - - if (bKeyboardLayoutChanged && !bKeybLayoutAltKeyWarningShown) - { - if (GetAsyncKeyState (VK_RMENU) < 0) - { - bKeybLayoutAltKeyWarningShown = TRUE; - - wchar_t szTmp [4096]; - StringCbCopyW (szTmp, sizeof(szTmp), GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION")); - StringCbCatW (szTmp, sizeof(szTmp), L"\n\n"); - StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); - MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST); - } - } - } - return 1; - } - return 0; - - case WM_CTLCOLORSTATIC: - { - if (PimValueChangedWarning && ((HWND)lParam == GetDlgItem(hwndDlg, IDC_PIM_HELP)) ) - { - // we're about to draw the static - // set the text colour in (HDC)lParam - SetBkMode((HDC)wParam,TRANSPARENT); - SetTextColor((HDC)wParam, RGB(255,0,0)); - // NOTE: per documentation as pointed out by selbie, GetSolidBrush would leak a GDI handle. - return (BOOL)GetSysColorBrush(COLOR_MENU); - } - } - return 0; - - case WM_COMMAND: - if (lw == IDCANCEL) - { - // Attempt to wipe passwords stored in the input field buffers - wchar_t tmp[MAX_PASSWORD+1]; - wmemset (tmp, L'X', MAX_PASSWORD); - tmp[MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp); - RestoreDefaultKeyFilesParam (); - - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - if (hw == EN_CHANGE) - { - PasswordChangeEnable (hwndDlg, IDOK, - IDC_OLD_PASSWORD, - KeyFilesEnable && FirstKeyFile != NULL, - IDC_PASSWORD, IDC_VERIFY, - newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); - - if ((lw == IDC_OLD_PIM) && IsWindowEnabled (GetDlgItem (hwndDlg, IDC_PIM))) - { - wchar_t tmp[MAX_PIM+1] = {0}; - GetDlgItemText (hwndDlg, IDC_OLD_PIM, tmp, MAX_PIM + 1); - SetDlgItemText (hwndDlg, IDC_PIM, tmp); - } - - if (lw == IDC_PIM) - { - if(GetPim (hwndDlg, IDC_OLD_PIM) != GetPim (hwndDlg, IDC_PIM)) - { - PimValueChangedWarning = TRUE; - SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, GetString (bSysEncPwdChangeDlgMode? "PIM_SYSENC_CHANGE_WARNING" : "PIM_CHANGE_WARNING")); - } - else - { - PimValueChangedWarning = FALSE; - SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, (wchar_t *) GetDictionaryValueByInt (IDC_PIM_HELP)); - } - } - - return 1; - } - - if (lw == IDC_PIM_ENABLE) - { - ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_OLD_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW); - - // check also the "Use PIM" for the new password if it is enabled - if (IsWindowEnabled (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE))) - { - SetCheckBox (hwndDlg, IDC_NEW_PIM_ENABLE, TRUE); - - ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); - } - - SetFocus (GetDlgItem (hwndDlg, IDC_OLD_PIM)); - - return 1; - } - - if (lw == IDC_NEW_PIM_ENABLE) - { - ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); - - SetFocus (GetDlgItem (hwndDlg, IDC_PIM)); - - return 1; - } - - if (lw == IDC_KEYFILES) - { - if (bSysEncPwdChangeDlgMode) - { - Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); - return 1; - } - - KeyFilesDlgParam param; - param.EnableKeyFiles = KeyFilesEnable; - param.FirstKeyFile = FirstKeyFile; - - if (IDOK == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, - (DLGPROC) KeyFilesDlgProc, (LPARAM) ¶m)) - { - KeyFilesEnable = param.EnableKeyFiles; - FirstKeyFile = param.FirstKeyFile; - - SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable); - } - - PasswordChangeEnable (hwndDlg, IDOK, - IDC_OLD_PASSWORD, - KeyFilesEnable && FirstKeyFile != NULL, - IDC_PASSWORD, IDC_VERIFY, - newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); - - return 1; - } - - - if (lw == IDC_NEW_KEYFILES) - { - if (bSysEncPwdChangeDlgMode) - { - Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); - return 1; - } - - if (IDOK == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, - (DLGPROC) KeyFilesDlgProc, (LPARAM) &newKeyFilesParam)) - { - SetCheckBox (hwndDlg, IDC_ENABLE_NEW_KEYFILES, newKeyFilesParam.EnableKeyFiles); - - VerifyPasswordAndUpdate (hwndDlg, GetDlgItem (hwndDlg, IDOK), GetDlgItem (hwndDlg, IDC_PASSWORD), - GetDlgItem (hwndDlg, IDC_VERIFY), NULL, NULL, - newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); - } - - PasswordChangeEnable (hwndDlg, IDOK, - IDC_OLD_PASSWORD, - KeyFilesEnable && FirstKeyFile != NULL, - IDC_PASSWORD, IDC_VERIFY, - newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); - - return 1; - } - - if (lw == IDC_ENABLE_KEYFILES) - { - KeyFilesEnable = GetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES); - - PasswordChangeEnable (hwndDlg, IDOK, - IDC_OLD_PASSWORD, - KeyFilesEnable && FirstKeyFile != NULL, - IDC_PASSWORD, IDC_VERIFY, - newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); - - return 1; - } - - if (lw == IDC_ENABLE_NEW_KEYFILES) - { - newKeyFilesParam.EnableKeyFiles = GetCheckBox (hwndDlg, IDC_ENABLE_NEW_KEYFILES); - - PasswordChangeEnable (hwndDlg, IDOK, - IDC_OLD_PASSWORD, - KeyFilesEnable && FirstKeyFile != NULL, - IDC_PASSWORD, IDC_VERIFY, - newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); - - return 1; - } - - if (hw == CBN_SELCHANGE) - { - switch (lw) - { - case IDC_PKCS5_PRF_ID: - if (bSysEncPwdChangeDlgMode) - { - int new_hash_algo_id = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, - SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); - - if (new_hash_algo_id != 0 && !HashForSystemEncryption(new_hash_algo_id)) - { - int new_hash_algo_id = DEFAULT_HASH_ALGORITHM_BOOT; - Info ("ALGO_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); - SelectAlgo (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), &new_hash_algo_id); - } - } - break; - } - return 1; - - } - - if (lw == IDC_TRUECRYPT_MODE) - { - BOOL bEnablePim = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE) ? FALSE: TRUE; - EnableWindow (GetDlgItem (hwndDlg, IDT_OLD_PIM), bEnablePim); - EnableWindow (GetDlgItem (hwndDlg, IDC_OLD_PIM), bEnablePim); - EnableWindow (GetDlgItem (hwndDlg, IDC_OLD_PIM_HELP), bEnablePim); - } - - if (lw == IDC_SHOW_PASSWORD_CHPWD_ORI) - { - HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_ORI, IDC_OLD_PASSWORD, IDC_OLD_PIM); - return 1; - } - - if (lw == IDC_SHOW_PASSWORD_CHPWD_NEW) - { - HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PASSWORD, IDC_VERIFY); - HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PIM, 0); - return 1; - } - - if (lw == IDOK) - { - HWND hParent = GetParent (hwndDlg); - Password oldPassword; - Password newPassword; - WipeAlgorithmId headerWiperMode = (WipeAlgorithmId) SendMessage ( - GetDlgItem (hwndDlg, IDC_WIPE_MODE), - CB_GETITEMDATA, - SendMessage (GetDlgItem (hwndDlg, IDC_WIPE_MODE), CB_GETCURSEL, 0, 0), - 0); - int nStatus; - int old_pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETITEMDATA, - SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETCURSEL, 0, 0), 0); - int pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, - SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); - BOOL truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE); - - int old_pim = GetPim (hwndDlg, IDC_OLD_PIM); - int pim = GetPim (hwndDlg, IDC_PIM); - - if (truecryptMode && (old_pkcs5 == SHA256)) - { - Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); - return 1; - } - else if (truecryptMode && (old_pim != 0)) - { - Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); - return 1; - } - - if (bSysEncPwdChangeDlgMode && !CheckPasswordCharEncoding (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL)) - { - Error ("UNSUPPORTED_CHARS_IN_PWD", hwndDlg); - return 1; - } - - if (bSysEncPwdChangeDlgMode && (pim > MAX_BOOT_PIM_VALUE)) - { - SetFocus (GetDlgItem(hwndDlg, IDC_PIM)); - Error ("PIM_SYSENC_TOO_BIG", hwndDlg); - return 1; - } - - if (!bSysEncPwdChangeDlgMode && (pim > MAX_PIM_VALUE)) - { - SetFocus (GetDlgItem(hwndDlg, IDC_PIM)); - Error ("PIM_TOO_BIG", hwndDlg); - return 1; - } - - if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF) - { - newKeyFilesParam.EnableKeyFiles = KeyFilesEnable; - } - else if (!(newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL) - && pwdChangeDlgMode == PCDM_CHANGE_PASSWORD) - { - if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pim, bSysEncPwdChangeDlgMode, FALSE, FALSE)) - return 1; - } - - GetVolumePath (hParent, szFileName, ARRAYSIZE (szFileName)); - - if (GetPassword (hwndDlg, IDC_OLD_PASSWORD, (LPSTR) oldPassword.Text, sizeof (oldPassword.Text), TRUE)) - oldPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text); - else - { - return 1; - } - - switch (pwdChangeDlgMode) - { - case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: - case PCDM_ADD_REMOVE_VOL_KEYFILES: - case PCDM_CHANGE_PKCS5_PRF: - memcpy (newPassword.Text, oldPassword.Text, sizeof (newPassword.Text)); - newPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text); - pim = old_pim; - break; - - default: - if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) newPassword.Text, sizeof (newPassword.Text), TRUE)) - newPassword.Length = (unsigned __int32) strlen ((char *) newPassword.Text); - else - return 1; - } - - WaitCursor (); - - if (KeyFilesEnable) - KeyFilesApply (hwndDlg, &oldPassword, FirstKeyFile, szFileName); - - if (newKeyFilesParam.EnableKeyFiles) - { - if (!KeyFilesApply (hwndDlg, &newPassword, pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? FirstKeyFile : newKeyFilesParam.FirstKeyFile, szFileName)) - { - nStatus = ERR_DONT_REPORT; - goto err; - } - } - - ChangePwdThreadParam changePwdParam; - changePwdParam.oldPassword = &oldPassword; - changePwdParam.old_pkcs5 = old_pkcs5; - changePwdParam.old_pim = old_pim; - changePwdParam.newPassword = &newPassword; - changePwdParam.pkcs5 = pkcs5; - changePwdParam.pim = pim; - changePwdParam.wipePassCount = GetWipePassCount(headerWiperMode); - changePwdParam.pnStatus = &nStatus; - changePwdParam.truecryptMode = truecryptMode; - - ShowWaitDialog(hwndDlg, TRUE, ChangePwdWaitThreadProc, &changePwdParam); - -err: - // notify the caller in case the PIM has changed - if (NewPimValuePtr) - { - if (pim != old_pim) - *NewPimValuePtr = pim; - else - *NewPimValuePtr = -1; - } - - burn (&oldPassword, sizeof (oldPassword)); - burn (&newPassword, sizeof (newPassword)); - burn (&old_pim, sizeof(old_pim)); - burn (&pim, sizeof(pim)); - - NormalCursor (); - - if (nStatus == 0) - { - // Attempt to wipe passwords stored in the input field buffers - wchar_t tmp[MAX_PASSWORD+1]; - wmemset (tmp, L'X', MAX_PASSWORD); - tmp[MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp); - - KeyFileRemoveAll (&newKeyFilesParam.FirstKeyFile); - RestoreDefaultKeyFilesParam (); - - if (bSysEncPwdChangeDlgMode) - { - KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); - } - - EndDialog (hwndDlg, IDOK); - } - return 1; - } - return 0; - } - - return 0; -} - -static wchar_t PasswordDlgVolume[MAX_PATH + 1]; -static BOOL PasswordDialogDisableMountOptions; -static char *PasswordDialogTitleStringId; - -/* Except in response to the WM_INITDIALOG message, the dialog box procedure - should return nonzero if it processes the message, and zero if it does - not. - see DialogProc */ -BOOL CALLBACK PasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - static Password *szXPwd; - static int *pkcs5; - static int *pim; - static BOOL* truecryptMode; - - switch (msg) - { - case WM_INITDIALOG: - { - int i, nIndex, defaultPrfIndex = 0; - szXPwd = ((PasswordDlgParam *) lParam) -> password; - pkcs5 = ((PasswordDlgParam *) lParam) -> pkcs5; - pim = ((PasswordDlgParam *) lParam) -> pim; - truecryptMode = ((PasswordDlgParam *) lParam) -> truecryptMode; - LocalizeDialog (hwndDlg, "IDD_PASSWORD_DLG"); - DragAcceptFiles (hwndDlg, TRUE); - - if (PasswordDialogTitleStringId) - { - SetWindowTextW (hwndDlg, GetString (PasswordDialogTitleStringId)); - } - else if (wcslen (PasswordDlgVolume) > 0) - { - wchar_t s[1024]; - RECT rect; - GetWindowRect (hwndDlg, &rect); - - bool useInExplorer = false; - wstring label = GetFavoriteVolumeLabel (PasswordDlgVolume, useInExplorer); - if (!label.empty()) - { - StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR_LABEL"), label.c_str()); - if (useInExplorer) - StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), label.c_str()); - } - else - { - StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), L"___"); - StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), FitPathInGfxWidth (hwndDlg, WindowTitleBarFont, rect.right - rect.left - GetTextGfxWidth (hwndDlg, s, WindowTitleBarFont), PasswordDlgVolume).c_str()); - } - - SetWindowTextW (hwndDlg, s); - } - - /* Populate the PRF algorithms list */ - HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); - SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); - - nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); - - for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) - { - nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); - if (*pkcs5 && (*pkcs5 == i)) - defaultPrfIndex = nIndex; - } - - /* make autodetection the default unless a specific PRF was specified in the command line */ - SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); - SendMessage (GetDlgItem (hwndDlg, IDC_CACHE), BM_SETCHECK, bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0); - SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0); - - SetPim (hwndDlg, IDC_PIM, *pim); - - /* make PIM field visible if a PIM value has been explicitely specified */ - if (*pim > 0) - { - SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE); - ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); - } - - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); - - mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode; - - if (bPrebootPasswordDlgMode) - { - SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0); - } - - if (PasswordDialogDisableMountOptions) - { - EnableWindow (GetDlgItem (hwndDlg, IDC_CACHE), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_OPTIONS), FALSE); - /* Disable TrueCrypt mode option in case of backup/restore header operation */ - SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE); - } - else if (*truecryptMode) - { - /* Check TrueCryptMode if it is enabled on the command line */ - SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, TRUE); - } - - if (!SetForegroundWindow (hwndDlg) && (FavoriteMountOnArrivalInProgress || LogOn)) - { - SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - - FLASHWINFO flash; - flash.cbSize = sizeof (flash); - flash.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG; - flash.dwTimeout = 0; - flash.hwnd = hwndDlg; - flash.uCount = 0; - - FlashWindowEx (&flash); - - SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } - } - return 0; - - case TC_APPMSG_PREBOOT_PASSWORD_MODE: - { - /* Repopulate the PRF algorithms list with algorithms that support system encryption */ - HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); - SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); - - int i, defaultPrfIndex = 0, nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); - - for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) - { - if (HashForSystemEncryption(i)) - { - nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); - if (*pkcs5 && (*pkcs5 == i)) - defaultPrfIndex = nIndex; - } - } - - /* make autodetection the default unless a specific PRF was specified in the command line */ - SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0); - - ToBootPwdField (hwndDlg, IDC_PASSWORD); - - // Attempt to wipe the password stored in the input field buffer - wchar_t tmp[MAX_PASSWORD+1]; - wmemset (tmp, L'X', MAX_PASSWORD); - tmp [MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L""); - - StringCbPrintfW (OrigKeyboardLayout, sizeof(OrigKeyboardLayout),L"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF); - - DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); - - if (keybLayout != 0x00000409 && keybLayout != 0x04090409) - { - Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0) - { - Error ("CANNOT_SET_TIMER", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - if (GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD)) - { - // simulate hiding password - SetCheckBox (hwndDlg, IDC_SHOW_PASSWORD, FALSE); - - HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD, IDC_PASSWORD, IDC_PIM); - } - - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE), FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEY_FILES), FALSE); - - SetPim (hwndDlg, IDC_PIM, *pim); - - bPrebootPasswordDlgMode = TRUE; - } - return 1; - - case WM_TIMER: - switch (wParam) - { - case TIMER_ID_KEYB_LAYOUT_GUARD: - if (bPrebootPasswordDlgMode) - { - DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL); - - if (keybLayout != 0x00000409 && keybLayout != 0x04090409) - { - // Keyboard layout is not standard US - - // Attempt to wipe the password stored in the input field buffer - wchar_t tmp[MAX_PASSWORD+1]; - wmemset (tmp, L'X', MAX_PASSWORD); - tmp [MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L""); - - keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); - - if (keybLayout != 0x00000409 && keybLayout != 0x04090409) - { - KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); - Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - wchar_t szTmp [4096]; - StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED")); - StringCbCatW (szTmp, sizeof(szTmp), L"\n\n"); - StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); - MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); - } - } - return 1; - } - return 0; - - case WM_COMMAND: - - if (lw == IDC_MOUNT_OPTIONS) - { - /* Use default PRF specified by the user if any */ - if (mountOptions.ProtectedHidVolPkcs5Prf == 0) - mountOptions.ProtectedHidVolPkcs5Prf = *pkcs5; - if (mountOptions.ProtectedHidVolPim == 0) - mountOptions.ProtectedHidVolPim = *pim; - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, - (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions); - - if (!bPrebootPasswordDlgMode && mountOptions.PartitionInInactiveSysEncScope) - SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0); - - return 1; - } - - if (lw == IDC_PIM_ENABLE) - { - ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); - - SetFocus (GetDlgItem (hwndDlg, IDC_PIM)); - return 1; - } - - if (lw == IDC_SHOW_PASSWORD) - { - HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD, IDC_PASSWORD, IDC_PIM); - return 1; - } - - if (lw == IDC_TRUECRYPT_MODE) - { - BOOL bEnablePim = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE) ? FALSE: TRUE; - EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), bEnablePim); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), bEnablePim); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), bEnablePim); - } - - if (lw == IDC_KEY_FILES) - { - KeyFilesDlgParam param; - param.EnableKeyFiles = KeyFilesEnable; - param.FirstKeyFile = FirstKeyFile; - - if (IDOK == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, - (DLGPROC) KeyFilesDlgProc, (LPARAM) ¶m)) - { - KeyFilesEnable = param.EnableKeyFiles; - FirstKeyFile = param.FirstKeyFile; - - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); - } - - return 1; - } - - if (lw == IDC_KEYFILES_ENABLE) - { - KeyFilesEnable = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE); - - return 1; - } - - if (lw == IDCANCEL || lw == IDOK) - { - wchar_t tmp[MAX_PASSWORD+1]; - - if (lw == IDOK) - { - if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) - KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, wcslen (PasswordDlgVolume) > 0 ? PasswordDlgVolume : NULL); - - if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) szXPwd->Text, MAX_PASSWORD + 1, TRUE)) - szXPwd->Length = (unsigned __int32) strlen ((char *) szXPwd->Text); - else - return 1; - - bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_CACHE)); - *pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); - *truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE); - - *pim = GetPim (hwndDlg, IDC_PIM); - - /* SHA-256 is not supported by TrueCrypt */ - if ( (*truecryptMode) - && ((*pkcs5 == SHA256) || (mountOptions.ProtectHiddenVolume && mountOptions.ProtectedHidVolPkcs5Prf == SHA256)) - ) - { - Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); - return 1; - } - - if ( (*truecryptMode) - && (*pim != 0) - ) - { - Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); - return 1; - } - } - - // Attempt to wipe password stored in the input field buffer - wmemset (tmp, L'X', MAX_PASSWORD); - tmp[MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); - - if (hidVolProtKeyFilesParam.FirstKeyFile != NULL) - { - KeyFileRemoveAll (&hidVolProtKeyFilesParam.FirstKeyFile); - hidVolProtKeyFilesParam.EnableKeyFiles = FALSE; - } - - if (bPrebootPasswordDlgMode) - { - KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); - - // Restore the original keyboard layout - if (LoadKeyboardLayout (OrigKeyboardLayout, KLF_ACTIVATE | KLF_SUBSTITUTE_OK) == NULL) - Warning ("CANNOT_RESTORE_KEYBOARD_LAYOUT", hwndDlg); - } - - EndDialog (hwndDlg, lw); - return 1; - } - return 0; - - case WM_CONTEXTMENU: - { - RECT buttonRect; - GetWindowRect (GetDlgItem (hwndDlg, IDC_KEY_FILES), &buttonRect); - - if (LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right - && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom) - { - // The "Keyfiles" button has been right-clicked - - KeyFilesDlgParam param; - param.EnableKeyFiles = KeyFilesEnable; - param.FirstKeyFile = FirstKeyFile; - - POINT popupPos; - popupPos.x = buttonRect.left + 2; - popupPos.y = buttonRect.top + 2; - - if (KeyfilesPopupMenu (hwndDlg, popupPos, ¶m)) - { - KeyFilesEnable = param.EnableKeyFiles; - FirstKeyFile = param.FirstKeyFile; - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); - } - } - } - break; - - case WM_DROPFILES: - { - HDROP hdrop = (HDROP) wParam; - int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); - - while (count-- > 0) - { - KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile)); - if (kf) - { - DragQueryFile (hdrop, i++, kf->FileName, ARRAYSIZE (kf->FileName)); - FirstKeyFile = KeyFileAdd (FirstKeyFile, kf); - KeyFilesEnable = TRUE; - } - } - - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); - DragFinish (hdrop); - } - return 1; - } - - return 0; -} - -static void PreferencesDlgEnableButtons (HWND hwndDlg) -{ - BOOL back = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE)); - BOOL idle = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)); - BOOL installed = !IsNonInstallMode(); - BOOL wtsEnabled = (hWtsLib != NULL) ? TRUE : FALSE; - - EnableWindow (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL), back && installed); - EnableWindow (GetDlgItem (hwndDlg, IDT_LOGON), installed); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START), back && installed); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES), installed); - EnableWindow (GetDlgItem (hwndDlg, IDT_AUTO_DISMOUNT), back); - EnableWindow (GetDlgItem (hwndDlg, IDT_AUTO_DISMOUNT_ON), back); - EnableWindow (GetDlgItem (hwndDlg, IDT_MINUTES), back); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF), back); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED), back && wtsEnabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING), back); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER), back); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE), back); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME), back && idle); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT), back); -} - -BOOL CALLBACK PreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL PreferencesDialogActive = FALSE; - static HWND ActivePreferencesDialogWindow; - - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - { - if (PreferencesDialogActive) - { - ShowWindow (ActivePreferencesDialogWindow, SW_SHOW); - SetForegroundWindow (ActivePreferencesDialogWindow); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - ActivePreferencesDialogWindow = hwndDlg; - PreferencesDialogActive = TRUE; - - LocalizeDialog (hwndDlg, "IDD_PREFERENCES_DLG"); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_OPEN_EXPLORER), BM_SETCHECK, - bExplore ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED), BM_SETCHECK, - bUseDifferentTrayIconIfVolMounted ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PRESERVE_TIMESTAMPS), BM_SETCHECK, - defaultMountOptions.PreserveTimestamp ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_SHOW_DISCONNECTED_NETWORK_DRIVES), BM_SETCHECK, - bShowDisconnectedNetworkDrives ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_HIDE_WAITING_DIALOG), BM_SETCHECK, - bHideWaitingDialog ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_TEMP_CACHE_ON_MULTIPLE_MOUNT), BM_SETCHECK, - bCacheDuringMultipleMount ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_EXIT), BM_SETCHECK, - bWipeCacheOnExit ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT), BM_SETCHECK, - bWipeCacheOnAutoDismount ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PASSWORDS), BM_SETCHECK, - bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM), BM_SETCHECK, - bIncludePimInCache? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_READONLY), BM_SETCHECK, - defaultMountOptions.ReadOnly ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_REMOVABLE), BM_SETCHECK, - defaultMountOptions.Removable ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START), BM_SETCHECK, - bStartOnLogon ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES), BM_SETCHECK, - bMountDevicesOnLogon ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE), BM_SETCHECK, - bEnableBkgTask ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL), BM_SETCHECK, - bCloseBkgTaskWhenNoVolumes || IsNonInstallMode() ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF), BM_SETCHECK, - bDismountOnLogOff ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED), BM_SETCHECK, - bDismountOnSessionLocked ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING), BM_SETCHECK, - bDismountOnPowerSaving ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER), BM_SETCHECK, - bDismountOnScreenSaver ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT), BM_SETCHECK, - bForceAutoDismount ? BST_CHECKED:BST_UNCHECKED, 0); - - SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE), BM_SETCHECK, - MaxVolumeIdleTime > 0 ? BST_CHECKED:BST_UNCHECKED, 0); - - SetDlgItemInt (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME, abs (MaxVolumeIdleTime), FALSE); - - PreferencesDlgEnableButtons (hwndDlg); - } - return 0; - - case WM_COMMAND: - - if (lw == IDC_PREF_BKG_TASK_ENABLE && !IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE))) - { - if (AskWarnNoYes ("CONFIRM_BACKGROUND_TASK_DISABLED", hwndDlg) == IDNO) - SetCheckBox (hwndDlg, IDC_PREF_BKG_TASK_ENABLE, TRUE); - } - - // Forced dismount disabled warning - if (lw == IDC_PREF_DISMOUNT_INACTIVE - || lw == IDC_PREF_DISMOUNT_LOGOFF - || lw == IDC_PREF_DISMOUNT_SESSION_LOCKED - || lw == IDC_PREF_DISMOUNT_POWERSAVING - || lw == IDC_PREF_DISMOUNT_SCREENSAVER - || lw == IDC_PREF_FORCE_AUTO_DISMOUNT) - { - BOOL i = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)); - BOOL l = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF)); - BOOL sl = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED)); - BOOL p = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING)); - BOOL s = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER)); - BOOL q = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT)); - - if (!q) - { - if (lw == IDC_PREF_FORCE_AUTO_DISMOUNT && (i || l || sl || p || s)) - { - if (AskWarnNoYes ("CONFIRM_NO_FORCED_AUTODISMOUNT", hwndDlg) == IDNO) - SetCheckBox (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT, TRUE); - } - else if ((lw == IDC_PREF_DISMOUNT_INACTIVE && i - || lw == IDC_PREF_DISMOUNT_LOGOFF && l - || lw == IDC_PREF_DISMOUNT_SESSION_LOCKED && sl - || lw == IDC_PREF_DISMOUNT_POWERSAVING && p - || lw == IDC_PREF_DISMOUNT_SCREENSAVER && s)) - Warning ("WARN_PREF_AUTO_DISMOUNT", hwndDlg); - } - - if (p && lw == IDC_PREF_DISMOUNT_POWERSAVING) - Warning ("WARN_PREF_AUTO_DISMOUNT_ON_POWER", hwndDlg); - } - - if (lw == IDCANCEL) - { - PreferencesDialogActive = FALSE; - EndDialog (hwndDlg, lw); - return 1; - } - - if (lw == IDOK) - { - WaitCursor (); - - bExplore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_OPEN_EXPLORER)); - bUseDifferentTrayIconIfVolMounted = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED)); - bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PRESERVE_TIMESTAMPS)); - bShowDisconnectedNetworkDrives = IsButtonChecked (GetDlgItem (hwndDlg, IDC_SHOW_DISCONNECTED_NETWORK_DRIVES)); - bHideWaitingDialog = IsButtonChecked (GetDlgItem (hwndDlg, IDC_HIDE_WAITING_DIALOG)); - bCacheDuringMultipleMount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_TEMP_CACHE_ON_MULTIPLE_MOUNT)); - bWipeCacheOnExit = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_EXIT)); - bWipeCacheOnAutoDismount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT)); - bCacheInDriverDefault = bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PASSWORDS)); - bIncludePimInCache = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM)); - defaultMountOptions.ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_READONLY)); - defaultMountOptions.Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_REMOVABLE)); - bEnableBkgTask = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE)); - bCloseBkgTaskWhenNoVolumes = IsNonInstallMode() ? bCloseBkgTaskWhenNoVolumes : IsButtonChecked (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL)); - bDismountOnLogOff = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF)); - bDismountOnSessionLocked = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED)); - bDismountOnPowerSaving = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING)); - bDismountOnScreenSaver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER)); - bForceAutoDismount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT)); - MaxVolumeIdleTime = GetDlgItemInt (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME, NULL, FALSE) - * (IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)) ? 1 : -1); - bStartOnLogon = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START)); - bMountDevicesOnLogon = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES)); - - ManageStartupSeq (); - - SaveSettings (hwndDlg); - - NormalCursor (); - - PreferencesDialogActive = FALSE; - EndDialog (hwndDlg, lw); - return 1; - } - - if (lw == IDC_MORE_SETTINGS) - { - HMENU popup = CreatePopupMenu (); - if (popup) - { - AppendMenuW (popup, MF_STRING, IDM_LANGUAGE, GetString ("IDM_LANGUAGE")); - AppendMenuW (popup, MF_STRING, IDM_HOTKEY_SETTINGS, GetString ("IDM_HOTKEY_SETTINGS")); - AppendMenuW (popup, MF_STRING, IDM_PERFORMANCE_SETTINGS, GetString ("IDM_PERFORMANCE_SETTINGS")); - AppendMenuW (popup, MF_STRING, IDM_SYSENC_SETTINGS, GetString ("IDM_SYSENC_SETTINGS")); - AppendMenuW (popup, MF_STRING, IDM_SYS_FAVORITES_SETTINGS, GetString ("IDM_SYS_FAVORITES_SETTINGS")); - AppendMenuW (popup, MF_STRING, IDM_DEFAULT_KEYFILES, GetString ("IDM_DEFAULT_KEYFILES")); - AppendMenuW (popup, MF_STRING, IDM_DEFAULT_MOUNT_PARAMETERS, GetString ("IDM_DEFAULT_MOUNT_PARAMETERS")); - AppendMenuW (popup, MF_STRING, IDM_TOKEN_PREFERENCES, GetString ("IDM_TOKEN_PREFERENCES")); - - RECT rect; - GetWindowRect (GetDlgItem (hwndDlg, IDC_MORE_SETTINGS), &rect); - - int menuItem = TrackPopupMenu (popup, TPM_RETURNCMD | TPM_LEFTBUTTON, rect.left + 2, rect.top + 2, 0, hwndDlg, NULL); - DestroyMenu (popup); - - SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); - return 1; - } - else - return 0; - } - - if (HIWORD (wParam) == BN_CLICKED) - { - PreferencesDlgEnableButtons (hwndDlg); - return 1; - } - - return 0; - } - - return 0; -} - - -BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static MountOptions *mountOptions; - - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - { - BOOL protect; - - mountOptions = (MountOptions *) lParam; - - LocalizeDialog (hwndDlg, "IDD_MOUNT_OPTIONS"); - - SendDlgItemMessage (hwndDlg, IDC_MOUNT_READONLY, BM_SETCHECK, - mountOptions->ReadOnly ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage (hwndDlg, IDC_MOUNT_REMOVABLE, BM_SETCHECK, - mountOptions->Removable ? BST_CHECKED : BST_UNCHECKED, 0); - SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, - mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0); - - SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, - mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0); - - mountOptions->PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode; - - SendDlgItemMessage (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA, BM_SETCHECK, - bPrebootPasswordDlgMode ? BST_CHECKED : BST_UNCHECKED, 0); - - SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK, - mountOptions->UseBackupHeader ? BST_CHECKED : BST_UNCHECKED, 0); - - EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA), !bPrebootPasswordDlgMode); - - SetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label); - SendDlgItemMessage (hwndDlg, IDC_VOLUME_LABEL, EM_LIMITTEXT, 32, 0); // 32 is the maximum possible length for a drive label in Windows - - /* Add PRF algorithm list for hidden volume password */ - HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); - SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); - - int i, nSelectedIndex = 0, nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); - - for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) - { - nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); - /* if a PRF was selected previously, select it */ - if (i == mountOptions->ProtectedHidVolPkcs5Prf) - nSelectedIndex = nIndex; - } - - SendMessage (hComboBox, CB_SETCURSEL, nSelectedIndex, 0); - - protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); - - EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); - EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); - EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect); - EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT), protect); - EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), protect); - EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), protect); - - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); - - SendDlgItemMessage (hwndDlg, IDC_PASSWORD_PROT_HIDVOL, EM_LIMITTEXT, MAX_PASSWORD, 0); - SendDlgItemMessage (hwndDlg, IDC_PIM, EM_LIMITTEXT, MAX_PIM, 0); - - if (mountOptions->ProtectedHidVolPassword.Length > 0) - { - wchar_t szTmp[MAX_PASSWORD + 1]; - if (0 == MultiByteToWideChar (CP_UTF8, 0, (LPSTR) mountOptions->ProtectedHidVolPassword.Text, -1, szTmp, MAX_PASSWORD + 1)) - szTmp [0] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), szTmp); - burn (szTmp, sizeof (szTmp)); - } - - SetPim (hwndDlg, IDC_PIM, mountOptions->ProtectedHidVolPim); - - /* make PIM field visible if a PIM value has been explicitely specified */ - if (mountOptions->ProtectedHidVolPim > 0) - { - SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE); - ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); - } - - ToHyperlink (hwndDlg, IDC_LINK_HIDVOL_PROTECTION_INFO); - - } - return 0; - - case WM_CONTEXTMENU: - { - RECT buttonRect; - GetWindowRect (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), &buttonRect); - - if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)) - && LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right - && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom) - { - // The "Keyfiles" button has been right-clicked - - POINT popupPos; - popupPos.x = buttonRect.left + 2; - popupPos.y = buttonRect.top + 2; - - if (KeyfilesPopupMenu (hwndDlg, popupPos, &hidVolProtKeyFilesParam)) - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); - } - } - break; - - case WM_COMMAND: - - if (lw == IDC_KEYFILES_HIDVOL_PROT) - { - if (IDOK == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, - (DLGPROC) KeyFilesDlgProc, (LPARAM) &hidVolProtKeyFilesParam)) - { - SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); - } - } - - if (lw == IDC_KEYFILES_ENABLE_HIDVOL_PROT) - { - hidVolProtKeyFilesParam.EnableKeyFiles = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT); - - return 0; - } - - if (lw == IDC_SHOW_PASSWORD_MO) - { - HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_MO, IDC_PASSWORD_PROT_HIDVOL, IDC_PIM); - return 1; - } - - if (lw == IDC_PIM_ENABLE) - { - ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); - ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); - ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); - - SetFocus (GetDlgItem (hwndDlg, IDC_PIM)); - return 1; - } - - if (lw == IDC_LINK_HIDVOL_PROTECTION_INFO) - { - Applink ("hiddenvolprotection", TRUE, ""); - } - - if (lw == IDCANCEL) - { - wchar_t tmp[MAX_PASSWORD+1]; - - // Cleanup - wmemset (tmp, L'X', MAX_PASSWORD); - tmp[MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); - - EndDialog (hwndDlg, lw); - return 1; - } - - if (lw == IDOK) - { - wchar_t tmp[MAX_PASSWORD+1]; - - mountOptions->ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)); - mountOptions->Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_REMOVABLE)); - mountOptions->ProtectHiddenVolume = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); - mountOptions->PartitionInInactiveSysEncScope = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA)); - mountOptions->UseBackupHeader = IsButtonChecked (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK)); - - GetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label, sizeof (mountOptions->Label) /sizeof (wchar_t)); - - if (mountOptions->ProtectHiddenVolume) - { - GetPassword (hwndDlg, IDC_PASSWORD_PROT_HIDVOL, - (LPSTR) mountOptions->ProtectedHidVolPassword.Text, MAX_PASSWORD + 1, - FALSE); - - mountOptions->ProtectedHidVolPassword.Length = (unsigned __int32) strlen ((char *) mountOptions->ProtectedHidVolPassword.Text); - - mountOptions->ProtectedHidVolPkcs5Prf = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, - SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); - - mountOptions->ProtectedHidVolPim = GetPim (hwndDlg, IDC_PIM); - } - - // Cleanup - wmemset (tmp, L'X', MAX_PASSWORD); - tmp[MAX_PASSWORD] = 0; - SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); - - if ((mountOptions->ProtectHiddenVolume && !bEnableBkgTask) - && (AskWarnYesNo ("HIDVOL_PROT_BKG_TASK_WARNING", hwndDlg) == IDYES)) - { - bEnableBkgTask = TRUE; - TaskBarIconAdd (MainDlg); - } - - EndDialog (hwndDlg, lw); - return 1; - } - - if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL) - { - BOOL protect; - - if (lw == IDC_MOUNT_READONLY) - { - SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0); - EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); - EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); - } - - protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); - - EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect); - EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT), protect); - EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), protect); - EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), protect); - EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), protect); - - return 1; - } - - return 0; - } - - return 0; -} - - -// Returns the block size (in bits) of the cipher with which the volume mounted as the -// specified drive letter is encrypted. In case of a cascade of ciphers with different -// block sizes the function returns the smallest block size. -int GetCipherBlockSizeByDriveNo (int nDosDriveNo) -{ - VOLUME_PROPERTIES_STRUCT prop; - DWORD dwResult; - - int blockSize = 0, cipherID; - - memset (&prop, 0, sizeof(prop)); - prop.driveNo = nDosDriveNo; - - if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL)) - { - if ( (prop.driveNo == nDosDriveNo) - && (prop.ea >= EAGetFirst() && prop.ea <= EAGetCount()) - ) - { - for (cipherID = EAGetLastCipher (prop.ea); - cipherID != 0; - cipherID = EAGetPreviousCipher (prop.ea, cipherID)) - { - if (blockSize > 0) - blockSize = min (blockSize, CipherGetBlockSize (cipherID) * 8); - else - blockSize = CipherGetBlockSize (cipherID) * 8; - } - } - } - - return blockSize; -} - - -// Returns the mode of operation in which the volume mounted as the specified drive letter is encrypted. -int GetModeOfOperationByDriveNo (int nDosDriveNo) -{ - VOLUME_PROPERTIES_STRUCT prop; - DWORD dwResult; - - memset (&prop, 0, sizeof(prop)); - prop.driveNo = nDosDriveNo; - - if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL)) - { - if ( (prop.driveNo == nDosDriveNo) - && (prop.ea >= EAGetFirst() && prop.ea <= EAGetCount()) - && (prop.mode >= FIRST_MODE_OF_OPERATION_ID && prop.mode < MODE_ENUM_END_ID) - ) - { - return prop.mode; - } - } - - return 0; -} - -void DisplayVolumePropertiesListContextMenu (HWND hwndDlg, LPARAM lParam) -{ - /* Volume Properties list context menu */ - DWORD mPos; - int menuItem; - HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); - int hItem = ListView_GetSelectionMark (hList); - - SetFocus (hList); - - if (hItem >= 0) - { - HMENU popup = CreatePopupMenu (); - AppendMenuW (popup, MF_STRING, IDPM_COPY_VALUE_TO_CLIPBOARD, GetString ("IDPM_COPY_VALUE_TO_CLIPBOARD")); - - if (lParam) - { - mPos=GetMessagePos(); - } - else - { - POINT pt = {0}; - if (ListView_GetItemPosition (hList, hItem, &pt)) - { - pt.x += 2 + ::GetSystemMetrics(SM_CXICON); - pt.y += 2; - } - ClientToScreen (hList, &pt); - mPos = MAKELONG (pt.x, pt.y); - } - - menuItem = TrackPopupMenu (popup, - TPM_RETURNCMD | TPM_LEFTBUTTON, - GET_X_LPARAM(mPos), - GET_Y_LPARAM(mPos), - 0, - hwndDlg, - NULL); - - DestroyMenu (popup); - - switch (menuItem) - { - case IDPM_COPY_VALUE_TO_CLIPBOARD: - { - wchar_t valueText[256] = {0}; - ListView_GetItemText (hList, hItem, 1, valueText, ARRAYSIZE (valueText)); - CopyTextToClipboard (valueText); - } - break; - } - } -} - - -BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - BOOL bSysEnc = (BOOL) lParam; - BOOL bSysEncWholeDrive = FALSE; - WORD lw = LOWORD (wParam); - int i = 0; - - switch (msg) - { - case WM_INITDIALOG: - { - VOLUME_PROPERTIES_STRUCT prop; - DWORD dwResult; - - LVCOLUMNW lvCol; - HWND list = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); - wchar_t szTmp[1024]; - wchar_t sw[1024]; - wchar_t *s; - - if (bSysEnc) - { - try - { - BootEncStatus = BootEncObj->GetStatus(); - bSysEncWholeDrive = WholeSysDriveEncryption(FALSE); - } - catch (Exception &e) - { - e.Show (MainDlg); - return 0; - } - - if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) - return 0; - } - else - { - switch (LOWORD (GetSelectedLong (GetDlgItem (GetParent(hwndDlg), IDC_DRIVELIST)))) - { - case TC_MLIST_ITEM_FREE: - - // No mounted volume - EndDialog (hwndDlg, IDOK); - return 0; - - case TC_MLIST_ITEM_NONSYS_VOL: - // NOP - break; - - case TC_MLIST_ITEM_SYS_DRIVE: - // Encrypted system drive - bSysEnc = TRUE; - bSysEncWholeDrive = TRUE; - break; - - case TC_MLIST_ITEM_SYS_PARTITION: - // Encrypted system partition - bSysEnc = TRUE; - bSysEncWholeDrive = FALSE; - break; - } - } - - LocalizeDialog (hwndDlg, "IDD_VOLUME_PROPERTIES"); - - SendMessage (list,LVM_SETEXTENDEDLISTVIEWSTYLE, 0, - LVS_EX_FULLROWSELECT - |LVS_EX_HEADERDRAGDROP - |LVS_EX_LABELTIP - ); - - memset (&lvCol,0,sizeof(lvCol)); - lvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; - lvCol.pszText = GetString ("VALUE"); - lvCol.cx = CompensateXDPI (208); - lvCol.fmt = LVCFMT_LEFT; - SendMessage (list,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol); - - lvCol.pszText = GetString ("PROPERTY"); - lvCol.cx = CompensateXDPI (192); - lvCol.fmt = LVCFMT_LEFT; - SendMessage (list,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol); - - memset (&prop, 0, sizeof(prop)); - prop.driveNo = HIWORD (GetSelectedLong (GetDlgItem (GetParent(hwndDlg), IDC_DRIVELIST))) - L'A'; - - if (bSysEnc) - { - try - { - BootEncStatus = BootEncObj->GetStatus(); - if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) - return 0; - - BootEncObj->GetVolumeProperties (&prop); - } - catch (Exception &e) - { - e.Show (MainDlg); - return 0; - } - } - else - { - if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) - return 0; - } - - // Location - ListItemAdd (list, i, GetString ("LOCATION")); - if (bSysEnc) - ListSubItemSet (list, i++, 1, GetString (bSysEncWholeDrive ? "SYSTEM_DRIVE" : IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION")); - else - ListSubItemSet (list, i++, 1, (wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4)); - - if (!bSysEnc && IsVolumeDeviceHosted ((wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4))) - { - // Volume ID - std::wstring hexID = ArrayToHexWideString (prop.volumeID, sizeof (prop.volumeID)); - ListItemAdd (list, i, GetString ("VOLUME_ID")); - - ListSubItemSet (list, i++, 1, hexID.c_str()); - } - - - // Size - ListItemAdd (list, i, GetString ("SIZE")); - StringCbPrintfW (sw, sizeof(sw), L"%I64u %s", prop.diskLength, GetString ("BYTES")); - ListSubItemSet (list, i++, 1, sw); - - // Type - ListItemAdd (list, i, GetString ("TYPE")); - if (bSysEnc) - ListSubItemSet (list, i++, 1, GetString (IsHiddenOSRunning() ? "TYPE_HIDDEN_SYSTEM_ADJECTIVE" : "SYSTEM_VOLUME_TYPE_ADJECTIVE")); - else - { - bool truecryptMode = prop.pkcs5Iterations == get_pkcs5_iteration_count(prop.pkcs5, 0, TRUE, prop.partitionInInactiveSysEncScope); - s = prop.hiddenVolume ? GetString ("HIDDEN") : - (prop.hiddenVolProtection != HIDVOL_PROT_STATUS_NONE ? GetString ("OUTER") : GetString ("NORMAL")); - - if (truecryptMode) - { - StringCbPrintfW (sw, sizeof(sw), L"TrueCrypt - %s", s); - ListSubItemSet (list, i++, 1, sw); - } - else - ListSubItemSet (list, i++, 1, s); - } - - if (!bSysEnc) - { - // Write protection - ListItemAdd (list, i, GetString ("READ_ONLY")); - - if (prop.readOnly || prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN) - s = GetString ("UISTR_YES"); - else - s = GetString ("UISTR_NO"); - - ListSubItemSet (list, i++, 1, s); - - // Hidden Volume Protection - ListItemAdd (list, i, GetString ("HIDDEN_VOL_PROTECTION")); - if (prop.hiddenVolume) - s = GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"); - else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_NONE) - s = GetString ("UISTR_NO"); - else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTIVE) - s = GetString ("UISTR_YES"); - else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN) - s = GetString ("HID_VOL_DAMAGE_PREVENTED"); - - ListSubItemSet (list, i++, 1, s); - } - - // Encryption algorithm - ListItemAdd (list, i, GetString ("ENCRYPTION_ALGORITHM")); - - if (prop.ea < EAGetFirst() || prop.ea > EAGetCount ()) - { - ListSubItemSet (list, i, 1, L"?"); - return 1; - } - - EAGetName (szTmp, prop.ea, 1); - ListSubItemSet (list, i++, 1, szTmp); - - // Key size(s) - { - wchar_t name[128]; - int size = EAGetKeySize (prop.ea); - EAGetName (name, prop.ea, 1); - - // Primary key - ListItemAdd (list, i, GetString ("KEY_SIZE")); - StringCbPrintfW (sw, sizeof(sw), L"%d %s", size * 8, GetString ("BITS")); - ListSubItemSet (list, i++, 1, sw); - - if (wcscmp (EAGetModeName (prop.ea, prop.mode, TRUE), L"XTS") == 0) - { - // Secondary key (XTS) - - ListItemAdd (list, i, GetString ("SECONDARY_KEY_SIZE_XTS")); - ListSubItemSet (list, i++, 1, sw); - } - } - - // Block size - ListItemAdd (list, i, GetString ("BLOCK_SIZE")); - - StringCbPrintfW (sw, sizeof(sw), L"%d ", CipherGetBlockSize (EAGetFirstCipher(prop.ea))*8); - StringCbCatW (sw, sizeof(sw), GetString ("BITS")); - ListSubItemSet (list, i++, 1, sw); - - // Mode - ListItemAdd (list, i, GetString ("MODE_OF_OPERATION")); - ListSubItemSet (list, i++, 1, EAGetModeName (prop.ea, prop.mode, TRUE)); - - // PKCS 5 PRF - ListItemAdd (list, i, GetString ("PKCS5_PRF")); - if (prop.volumePim == 0) - ListSubItemSet (list, i++, 1, get_pkcs5_prf_name (prop.pkcs5)); - else - { - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s (Dynamic)", get_pkcs5_prf_name (prop.pkcs5)); - ListSubItemSet (list, i++, 1, szTmp); - } - -#if 0 - // PCKS 5 iterations - ListItemAdd (list, i, GetString ("PKCS5_ITERATIONS")); - sprintf (szTmp, "%d", prop.pkcs5Iterations); - ListSubItemSet (list, i++, 1, szTmp); -#endif - -#if 0 - { - // Legacy - - FILETIME ft, curFt; - LARGE_INTEGER ft64, curFt64; - SYSTEMTIME st; - wchar_t date[128]; - memset (date, 0, sizeof (date)); - - // Volume date - ListItemAdd (list, i, GetString ("VOLUME_CREATE_DATE")); - *(unsigned __int64 *)(&ft) = prop.volumeCreationTime; - FileTimeToSystemTime (&ft, &st); - GetDateFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); - swprintf (date, L"%s ", sw); - GetTimeFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); - wcscat (date, sw); - ListSubItemSet (list, i++, 1, date); - - // Header date - ListItemAdd (list, i, GetString ("VOLUME_HEADER_DATE")); - *(unsigned __int64 *)(&ft) = prop.headerCreationTime; - FileTimeToSystemTime (&ft, &st); - GetDateFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); - swprintf (date, L"%s ", sw); - GetTimeFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); - wcscat (date, sw); - - GetLocalTime (&st); - SystemTimeToFileTime (&st, &curFt); - curFt64.HighPart = curFt.dwHighDateTime; - curFt64.LowPart = curFt.dwLowDateTime; - ft64.HighPart = ft.dwHighDateTime; - ft64.LowPart = ft.dwLowDateTime; - swprintf (date + wcslen (date), GetString ("VOLUME_HEADER_DAYS") - , (curFt64.QuadPart - ft64.QuadPart)/(24LL*3600*10000000)); - ListSubItemSet (list, i++, 1, date); - } -#endif // 0 - - if (!bSysEnc || IsHiddenOSRunning()) - { - // Volume format version - ListItemAdd (list, i, GetString ("VOLUME_FORMAT_VERSION")); - StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", prop.volFormatVersion); - ListSubItemSet (list, i++, 1, szTmp); - - // Backup header - ListItemAdd (list, i, GetString ("BACKUP_HEADER")); - ListSubItemSet (list, i++, 1, GetString (prop.volFormatVersion > 1 ? "UISTR_YES" : "UISTR_NO")); - } - - // Total data read - ListItemAdd (list, i, GetString ("TOTAL_DATA_READ")); - GetSizeString (prop.totalBytesRead, sw, sizeof(sw)); - ListSubItemSet (list, i++, 1, sw); - - // Total data written - ListItemAdd (list, i, GetString ("TOTAL_DATA_WRITTEN")); - GetSizeString (prop.totalBytesWritten, sw, sizeof(sw)); - ListSubItemSet (list, i++, 1, sw); - - if (bSysEnc) - { - // TrueCrypt Boot Loader version - ListItemAdd (list, i, GetString ("VC_BOOT_LOADER_VERSION")); - ListSubItemSet (list, i++, 1, GetUserFriendlyVersionString (BootEncStatus.BootLoaderVersion).c_str()); - - // Encrypted portion - ListItemAdd (list, i, GetString ("ENCRYPTED_PORTION")); - if (GetSysEncDeviceEncryptedPartSize (FALSE) == GetSysEncDeviceSize (FALSE)) - ListSubItemSet (list, i++, 1, GetString ("ENCRYPTED_PORTION_FULLY_ENCRYPTED")); - else if (GetSysEncDeviceEncryptedPartSize (FALSE) <= 1) - ListSubItemSet (list, i++, 1, GetString ("ENCRYPTED_PORTION_NOT_ENCRYPTED")); - else - { - - StringCbPrintfW (sw, - sizeof sw, - GetString ("PROCESSED_PORTION_X_PERCENT"), - (double) GetSysEncDeviceEncryptedPartSize (FALSE) / (double) GetSysEncDeviceSize (FALSE) * 100.0); - - ListSubItemSet (list, i++, 1, sw); - } - } - - return 0; - } - - case WM_NOTIFY: - - if(wParam == IDC_VOLUME_PROPERTIES_LIST) - { - /* Right click */ - - switch (((NM_LISTVIEW *) lParam)->hdr.code) - { - case NM_RCLICK: - case LVN_BEGINRDRAG: - /* If the mouse was moving while the right mouse button is pressed, popup menu would - not open, because drag&drop operation would be initiated. Therefore, we're handling - RMB drag-and-drop operations as well. */ - { - - DisplayVolumePropertiesListContextMenu (hwndDlg, lParam); - - return 1; - } - } - } - return 0; - - case WM_CONTEXTMENU: - { - HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); - // only handle if it is coming from keyboard and if the drive - // list has focus. The other cases are handled elsewhere - if ( (-1 == GET_X_LPARAM(lParam)) - && (-1 == GET_Y_LPARAM(lParam)) - && (GetFocus () == hList) - ) - { - DisplayVolumePropertiesListContextMenu (hwndDlg, NULL); - } - } - return 0; - - case WM_COMMAND: - if (lw == IDOK) - { - EndDialog (hwndDlg, lw); - return 1; - } - return 0; - - case WM_CLOSE: - EndDialog (hwndDlg, lw); - return 1; - } - - return 0; -} - - -BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - static BOOL bAutoRunWarningDisplayed = FALSE; - - switch (msg) - { - case WM_INITDIALOG: - { - WCHAR i; - int index; - WCHAR drive[] = { 0, L':', 0 }; - - LocalizeDialog (hwndDlg, "IDD_TRAVELER_DLG"); - - SendDlgItemMessage (hwndDlg, IDC_COPY_WIZARD, BM_SETCHECK, - BST_CHECKED, 0); - - SendDlgItemMessage (hwndDlg, IDC_COPY_EXPANDER, BM_SETCHECK, - BST_CHECKED, 0); - - SendDlgItemMessage (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER, BM_SETCHECK, - BST_CHECKED, 0); - - SendDlgItemMessage (hwndDlg, IDC_AUTORUN_DISABLE, BM_SETCHECK, - BST_CHECKED, 0); - - SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_RESETCONTENT, 0, 0); - - index = (int) SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) GetString ("FIRST_AVAILABLE")); - SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) 0); - - for (i = L'A'; i <= L'Z'; i++) - { - if (i == L'C') - continue; - drive[0] = i; - index = (int) SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) drive); - SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) i); - } - - SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_SETCURSEL, 0, 0); - - return 0; - } - - case WM_CTLCOLORSTATIC: - { - HDC hdc = (HDC) wParam; - HWND hw = (HWND) lParam; - if (hw == GetDlgItem(hwndDlg, IDC_DIRECTORY)) - { - // This the directory field. Make its background like normal edit - HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW); - ::SelectObject(hdc, hbr); - return (BOOL) hbr; - } - } - return 0; - - case WM_COMMAND: - - if (HIWORD (wParam) == BN_CLICKED - && (lw == IDC_AUTORUN_DISABLE || lw == IDC_AUTORUN_MOUNT || lw == IDC_AUTORUN_START )) - { - BOOL enabled = IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_MOUNT)); - - EnableWindow (GetDlgItem (hwndDlg, IDC_BROWSE_FILES), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_NAME), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDC_DRIVELIST), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDT_TRAVELER_MOUNT), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDT_MOUNT_LETTER), enabled); - EnableWindow (GetDlgItem (hwndDlg, IDT_MOUNT_SETTINGS), enabled); - - if (!bAutoRunWarningDisplayed - && (lw == IDC_AUTORUN_MOUNT || lw == IDC_AUTORUN_START)) - { - bAutoRunWarningDisplayed = TRUE; - Warning ("AUTORUN_MAY_NOT_ALWAYS_WORK", hwndDlg); - } - - return 1; - } - - if (lw == IDC_BROWSE_FILES) - { - wchar_t dstDir[MAX_PATH]; - wchar_t volName[MAX_PATH] = { 0 }; - - GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstDir, ARRAYSIZE (dstDir)); - - if (BrowseFilesInDir (hwndDlg, "OPEN_TITLE", dstDir, volName, bHistory, FALSE, NULL)) - SetDlgItemText (hwndDlg, IDC_VOLUME_NAME, wcschr (volName, L'\\') + 1); - - return 1; - } - - if (lw == IDC_BROWSE_DIRS) - { - wchar_t dstPath[MAX_PATH * 2]; - GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath, ARRAYSIZE (dstPath)); - - if (BrowseDirectories (hwndDlg, "SELECT_DEST_DIR", dstPath)) - SetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath); - - return 1; - } - - if (lw == IDCANCEL || lw == IDCLOSE) - { - EndDialog (hwndDlg, lw); - return 1; - } - - if (lw == IDC_CREATE) - { - - BOOL copyWizard, copyExpander, bExplore, bCacheInDriver, bIncludePimInCache, bAutoRun, bAutoMount, bMountReadOnly; - WCHAR dstDir[MAX_PATH + 1]; - WCHAR srcPath[1024 + MAX_PATH + 1]; - WCHAR dstPath[2*MAX_PATH + 1]; - WCHAR appDir[1024]; - WCHAR volName[MAX_PATH + 2]; - int drive; - WCHAR* ptr; - - GetDlgItemTextW (hwndDlg, IDC_DIRECTORY, dstDir, array_capacity (dstDir)); - volName[0] = 0; - GetDlgItemTextW (hwndDlg, IDC_VOLUME_NAME, volName + 1, (array_capacity (volName)) - 1); - - drive = (int) SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETCURSEL, 0, 0); - drive = (int) SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETITEMDATA, drive, 0); - - copyWizard = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_WIZARD)); - copyExpander = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_EXPANDER)); - bExplore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER)); - bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS)); - bIncludePimInCache = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM)); - bMountReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)); - bAutoRun = !IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_DISABLE)); - bAutoMount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_MOUNT)); - - if (dstDir[0] == 0) - { - SetFocus (GetDlgItem (hwndDlg, IDC_DIRECTORY)); - MessageBoxW (hwndDlg, GetString ("NO_PATH_SELECTED"), lpszTitle, MB_ICONEXCLAMATION); - return 1; - } - - - if (bAutoMount && volName[1] == 0) - { - SetFocus (GetDlgItem (hwndDlg, IDC_VOLUME_NAME)); - MessageBoxW (hwndDlg, GetString ("NO_FILE_SELECTED"), lpszTitle, MB_ICONEXCLAMATION); - return 1; - } - - if (volName[1] != 0) - { - volName[0] = L'"'; - StringCbCatW (volName, sizeof(volName), L"\""); - } - - GetModuleFileNameW (NULL, appDir, array_capacity (appDir)); - if (ptr = wcsrchr (appDir, L'\\')) - ptr[0] = 0; - - WaitCursor (); - - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt", dstDir); - if (!CreateDirectoryW (dstPath, NULL)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Main app 32-bit - if (Is64BitOs () && !IsNonInstallMode ()) - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt-x86.exe", appDir); - else - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt.exe", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Main app 64-bit - if (Is64BitOs () && !IsNonInstallMode ()) - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt.exe", appDir); - else - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt-x64.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt-x64.exe", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Wizard - if (copyWizard) - { - // Wizard 32-bit - if (Is64BitOs () && !IsNonInstallMode ()) - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format-x86.exe", appDir); - else - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format.exe", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Wizard 64-bit - if (Is64BitOs () && !IsNonInstallMode ()) - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format.exe", appDir); - else - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format-x64.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format-x64.exe", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - } - - // Expander - if (copyExpander) - { - // Expander 32-bit - if (Is64BitOs () && !IsNonInstallMode ()) - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander-x86.exe", appDir); - else - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander.exe", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Expander 64-bit - if (Is64BitOs () && !IsNonInstallMode ()) - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander.exe", appDir); - else - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander-x64.exe", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander-x64.exe", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - } - - // Driver - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt.sys", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt.sys", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - // Driver x64 - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt-x64.sys", appDir); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-x64.sys", dstDir); - if (!TCCopyFile (srcPath, dstPath)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto stop; - } - - if (strcmp (GetPreferredLangId (), "en") != 0) - { - // Language pack - StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\Language.%hs.xml", appDir, GetPreferredLangId ()); - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\Language.%hs.xml", dstDir, GetPreferredLangId ()); - TCCopyFile (srcPath, dstPath); - } - - // AutoRun - StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\autorun.inf", dstDir); - DeleteFileW (dstPath); - if (bAutoRun) - { - FILE *af; - wchar_t autoMount[2*MAX_PATH + 2]; - wchar_t driveLetter[] = { L' ', L'/', L'l', L' ', (wchar_t) drive, 0 }; - - af = _wfopen (dstPath, L"w,ccs=UNICODE"); - - if (af == NULL) - { - MessageBoxW (hwndDlg, GetString ("CANT_CREATE_AUTORUN"), lpszTitle, MB_ICONERROR); - goto stop; - } - - StringCbPrintfW (autoMount, sizeof(autoMount), L"VeraCrypt\\VeraCrypt.exe /q background%s%s%s%s /m rm /v %s", - drive > 0 ? driveLetter : L"", - bExplore ? L" /e" : L"", - bCacheInDriver ? (bIncludePimInCache? L" /c p" : L" /c y") : L"", - bMountReadOnly ? L" /m ro" : L"", - volName); - - fwprintf (af, L"[autorun]\nlabel=%s\nicon=VeraCrypt\\VeraCrypt.exe\n", GetString ("TC_TRAVELER_DISK")); - fwprintf (af, L"action=%s\n", bAutoMount ? GetString ("MOUNT_TC_VOLUME") : GetString ("IDC_PREF_LOGON_START")); - fwprintf (af, L"open=%s\n", bAutoMount ? autoMount : L"VeraCrypt\\VeraCrypt.exe"); - fwprintf (af, L"shell\\start=%s\nshell\\start\\command=VeraCrypt\\VeraCrypt.exe\n", GetString ("IDC_PREF_LOGON_START")); - fwprintf (af, L"shell\\dismount=%s\nshell\\dismount\\command=VeraCrypt\\VeraCrypt.exe /q /d\n", GetString ("DISMOUNT_ALL_TC_VOLUMES")); - - CheckFileStreamWriteErrors (hwndDlg, af, dstPath); - fclose (af); - } - MessageBoxW (hwndDlg, GetString ("TRAVELER_DISK_CREATED"), lpszTitle, MB_ICONINFORMATION); - -stop: - NormalCursor (); - return 1; - } - return 0; - } - - return 0; -} - -void BuildTree (HWND hwndDlg, HWND hTree) -{ - HIMAGELIST hList; - HBITMAP hBitmap, hBitmapMask; - LVCOLUMNW lvCol; - - ListView_DeleteColumn (hTree,0); - ListView_DeleteColumn (hTree,0); - ListView_DeleteColumn (hTree,0); - ListView_DeleteColumn (hTree,0); - ListView_DeleteColumn (hTree,0); - ListView_DeleteColumn (hTree,0); - - SendMessage(hTree,LVM_SETEXTENDEDLISTVIEWSTYLE,0, - LVS_EX_FULLROWSELECT - |LVS_EX_HEADERDRAGDROP - ); - - memset(&lvCol,0,sizeof(lvCol)); - - lvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; - lvCol.pszText = GetString ("DRIVE"); - lvCol.cx = CompensateXDPI (38); - lvCol.fmt = LVCFMT_COL_HAS_IMAGES|LVCFMT_LEFT ; - SendMessage (hTree,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol); - - lvCol.pszText = GetString ("VOLUME"); - lvCol.cx = CompensateXDPI (200); - lvCol.fmt = LVCFMT_LEFT; - SendMessage (hTree,LVM_INSERTCOLUMNW,1,(LPARAM)&lvCol); - LastDriveListVolumeColumnWidth = ListView_GetColumnWidth (hTree, 1); - - lvCol.pszText = GetString ("SIZE"); - lvCol.cx = CompensateXDPI (55); - lvCol.fmt = LVCFMT_RIGHT; - SendMessage (hTree,LVM_INSERTCOLUMNW,2,(LPARAM)&lvCol); - - lvCol.pszText = GetString ("ENCRYPTION_ALGORITHM_LV"); - lvCol.cx = CompensateXDPI (123); - lvCol.fmt = LVCFMT_LEFT; - SendMessage (hTree,LVM_INSERTCOLUMNW,3,(LPARAM)&lvCol); - - lvCol.pszText = GetString ("TYPE"); - lvCol.cx = CompensateXDPI (100); - lvCol.fmt = LVCFMT_LEFT; - SendMessage (hTree,LVM_INSERTCOLUMNW,4,(LPARAM)&lvCol); - - // Regular drive icon - - hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_DRIVEICON)); - if (hBitmap == NULL) - return; - hBitmapMask = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_DRIVEICON_MASK)); - - hList = CreateImageList (16, 12, ILC_COLOR8|ILC_MASK, 2, 2); - if (AddBitmapToImageList (hList, hBitmap, hBitmapMask) == -1) - { - DeleteObject (hBitmap); - DeleteObject (hBitmapMask); - return; - } - else - { - DeleteObject (hBitmap); - DeleteObject (hBitmapMask); - } - - // System drive icon - - hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_SYS_DRIVEICON)); - if (hBitmap == NULL) - return; - hBitmapMask = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_SYS_DRIVEICON_MASK)); - - if (AddBitmapToImageList (hList, hBitmap, hBitmapMask) == -1) - { - DeleteObject (hBitmap); - DeleteObject (hBitmapMask); - return; - } - else - { - DeleteObject (hBitmap); - DeleteObject (hBitmapMask); - } - - ListView_SetImageList (hTree, hList, LVSIL_NORMAL); - ListView_SetImageList (hTree, hList, LVSIL_SMALL); - - LoadDriveLetters (hwndDlg, hTree, 0); -} - -LPARAM GetSelectedLong (HWND hTree) -{ - int hItem = ListView_GetSelectionMark (hTree); - LVITEM item; - - if (nSelectedDriveIndex >= 0) - hItem = nSelectedDriveIndex; - - memset(&item, 0, sizeof(LVITEM)); - item.mask = LVIF_PARAM; - item.iItem = hItem; - - if ( (ListView_GetItemCount (hTree) < 1) - || (ListView_GetItem (hTree, &item) == FALSE) - ) - return MAKELONG (0xffff, 0xffff); - else - return item.lParam; -} - -LPARAM GetItemLong (HWND hTree, int itemNo) -{ - LVITEM item; - - memset(&item, 0, sizeof(LVITEM)); - item.mask = LVIF_PARAM; - item.iItem = itemNo; - - if (ListView_GetItem (hTree, &item) == FALSE) - return MAKELONG (0xffff, 0xffff); - else - return item.lParam; -} - -static int AskVolumePassword (HWND hwndDlg, Password *password, int *pkcs5, int *pim, BOOL* truecryptMode, char *titleStringId, BOOL enableMountOptions) -{ - INT_PTR result; - PasswordDlgParam dlgParam; - - PasswordDialogTitleStringId = titleStringId; - PasswordDialogDisableMountOptions = !enableMountOptions; - - dlgParam.password = password; - dlgParam.pkcs5 = pkcs5; - dlgParam.pim = pim; - dlgParam.truecryptMode = truecryptMode; - - result = DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_PASSWORD_DLG), hwndDlg, - (DLGPROC) PasswordDlgProc, (LPARAM) &dlgParam); - - if (result != IDOK) - { - password->Length = 0; - *pkcs5 = 0; - *pim = -1; - *truecryptMode = FALSE; - burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); - burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); - } - - return result == IDOK; -} - -// GUI actions - -static BOOL Mount (HWND hwndDlg, int nDosDriveNo, wchar_t *szFileName, int pim) -{ - BOOL status = FALSE; - wchar_t fileName[MAX_PATH]; - int mounted = 0, EffectiveVolumePkcs5 = CmdVolumePkcs5; - BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; - int EffectiveVolumePim = (pim < 0)? CmdVolumePim : pim; - BOOL bEffectiveCacheDuringMultipleMount = bCmdCacheDuringMultipleMount? TRUE: bCacheDuringMultipleMount; - BOOL bEffectiveTryEmptyPasswordWhenKeyfileUsed = bCmdTryEmptyPasswordWhenKeyfileUsedValid? bCmdTryEmptyPasswordWhenKeyfileUsed : bTryEmptyPasswordWhenKeyfileUsed; - BOOL bUseCmdVolumePassword = CmdVolumePasswordValid && ((CmdVolumePassword.Length > 0) || (KeyFilesEnable && FirstKeyFile)); - - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (EffectiveVolumePkcs5 == 0) - EffectiveVolumePkcs5 = DefaultVolumePkcs5; - if (!EffectiveVolumeTrueCryptMode) - EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; - - bPrebootPasswordDlgMode = mountOptions.PartitionInInactiveSysEncScope; - - if (nDosDriveNo == -1) - nDosDriveNo = HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))) - L'A'; - - if (!MultipleMountOperationInProgress) - { - VolumePassword.Length = 0; - VolumePkcs5 = 0; - VolumeTrueCryptMode = FALSE; - VolumePim = -1; - } - - if (szFileName == NULL) - { - GetVolumePath (hwndDlg, fileName, ARRAYSIZE (fileName)); - } - else - StringCchCopyW (fileName, ARRAYSIZE (fileName), szFileName); - - if (wcslen(fileName) == 0) - { - status = FALSE; - goto ret; - } - - if (!TranslateVolumeID (hwndDlg, fileName, ARRAYSIZE (fileName))) - { - status = FALSE; - goto ret; - } - - szFileName = fileName; - - if (IsMountedVolume (szFileName)) - { - Warning ("VOL_ALREADY_MOUNTED", hwndDlg); - status = FALSE; - goto ret; - } - - if (!VolumePathExists (szFileName)) - { - if (!MultipleMountOperationInProgress) - handleWin32Error (hwndDlg, SRC_POS); - - status = FALSE; - goto ret; - } - - ResetWrongPwdRetryCount (); - - WaitCursor (); - - if (!bUseCmdVolumePassword) - { - // First try cached passwords and if they fail ask user for a new one - // try TrueCrypt mode first since it is quick, only if no custom pim specified - if (EffectiveVolumePim <= 0) - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, 0, 0, TRUE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - if (!mounted) - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, 0, EffectiveVolumePim, FALSE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - - // If keyfiles are enabled, test empty password first - if (!mounted && KeyFilesEnable && FirstKeyFile && bEffectiveTryEmptyPasswordWhenKeyfileUsed) - { - Password emptyPassword; - emptyPassword.Length = 0; - - KeyFilesApply (hwndDlg, &emptyPassword, FirstKeyFile, szFileName); - // try TrueCrypt mode first since it is quick, only if no custom pim specified - if (EffectiveVolumePim <= 0) - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &emptyPassword, 0, 0, TRUE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - if (!mounted) - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &emptyPassword, 0, EffectiveVolumePim, FALSE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - - burn (&emptyPassword, sizeof (emptyPassword)); - } - } - - // Test password and/or keyfiles used for the previous volume - if (!mounted && bEffectiveCacheDuringMultipleMount && MultipleMountOperationInProgress && VolumePassword.Length != 0) - { - // try TrueCrypt mode first as it is quick, only if no custom pim specified - if (EffectiveVolumePim <= 0) - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, 0, 0, TRUE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - if (!mounted) - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, 0, EffectiveVolumePim, FALSE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - } - - NormalCursor (); - - if (mounted) - { - - // Check for problematic file extensions (exe, dll, sys) - if (CheckFileExtension(szFileName)) - Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING", hwndDlg); - } - - while (mounted == 0) - { - if (bUseCmdVolumePassword) - { - VolumePassword = CmdVolumePassword; - VolumePkcs5 = EffectiveVolumePkcs5; - VolumeTrueCryptMode = EffectiveVolumeTrueCryptMode; - VolumePim = EffectiveVolumePim; - } - else if (!Silent) - { - int GuiPkcs5 = EffectiveVolumePkcs5; - BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode; - int GuiPim = EffectiveVolumePim; - StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume), szFileName); - - if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &GuiTrueCryptMode, NULL, TRUE)) - goto ret; - else - { - VolumePkcs5 = GuiPkcs5; - VolumeTrueCryptMode = GuiTrueCryptMode; - VolumePim = GuiPim; - burn (&GuiPkcs5, sizeof(GuiPkcs5)); - burn (&GuiTrueCryptMode, sizeof(GuiTrueCryptMode)); - burn (&GuiPim, sizeof(GuiPim)); - } - } - - WaitCursor (); - - if (KeyFilesEnable) - KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, szFileName); - - mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, !Silent); - NormalCursor (); - - // Check for problematic file extensions (exe, dll, sys) - if (mounted > 0 && CheckFileExtension (szFileName)) - Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING", hwndDlg); - - if (!MultipleMountOperationInProgress) - { - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&VolumePim, sizeof (VolumePim)); - } - - burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); - burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); - - if (CmdVolumePassword.Length > 0 || Silent) - break; - } - - if (mounted > 0) - { - status = TRUE; - - if (bBeep) - MessageBeep (0xFFFFFFFF); - - RefreshMainDlg(MainDlg); - - if (bExplore) - { - WaitCursor(); - OpenVolumeExplorerWindow (nDosDriveNo); - NormalCursor(); - } - - if (mountOptions.ProtectHiddenVolume) - Info ("HIDVOL_PROT_WARN_AFTER_MOUNT", hwndDlg); - } - -ret: - if (!MultipleMountOperationInProgress) - { - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&VolumePim, sizeof (VolumePim)); - } - - burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); - burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); - - RestoreDefaultKeyFilesParam (); - - if (UsePreferences) - bCacheInDriver = bCacheInDriverDefault; - - if (status && CloseSecurityTokenSessionsAfterMount && !MultipleMountOperationInProgress) - SecurityToken::CloseAllSessions(); - - return status; -} - - -static BOOL Dismount (HWND hwndDlg, int nDosDriveNo) -{ - BOOL status = FALSE; - WaitCursor (); - - if (nDosDriveNo == -2) - nDosDriveNo = (char) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) - L'A'); - - if (bCloseDismountedWindows) - { - CloseVolumeExplorerWindows (hwndDlg, nDosDriveNo); - } - - if (UnmountVolume (hwndDlg, nDosDriveNo, bForceUnmount)) - { - status = TRUE; - - if (bBeep) - MessageBeep (0xFFFFFFFF); - RefreshMainDlg (hwndDlg); - - if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ()) - LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); - } - - NormalCursor (); - return status; -} - -void __cdecl mountThreadFunction (void *hwndDlgArg) -{ - HWND hwndDlg =(HWND) hwndDlgArg; - BOOL bIsForeground = (GetForegroundWindow () == hwndDlg)? TRUE : FALSE; - // Disable parent dialog during processing to avoid user interaction - EnableWindow(hwndDlg, FALSE); - finally_do_arg2 (HWND, hwndDlg, BOOL, bIsForeground, { EnableWindow(finally_arg, TRUE); if (finally_arg2) BringToForeground (finally_arg); bPrebootPasswordDlgMode = FALSE;}); - - Mount (hwndDlg, -1, 0, -1); -} - -typedef struct -{ - UNMOUNT_STRUCT* punmount; - BOOL interact; - int dismountMaxRetries; - int dismountAutoRetryDelay; - BOOL* pbResult; - DWORD* pdwResult; - DWORD dwLastError; - BOOL bReturn; -} DismountAllThreadParam; - -void CALLBACK DismountAllThreadProc(void* pArg, HWND hwndDlg) -{ - DismountAllThreadParam* pThreadParam = (DismountAllThreadParam*) pArg; - UNMOUNT_STRUCT* punmount = pThreadParam->punmount; - BOOL* pbResult = pThreadParam->pbResult; - DWORD* pdwResult = pThreadParam->pdwResult; - int dismountMaxRetries = pThreadParam->dismountMaxRetries; - int dismountAutoRetryDelay = pThreadParam->dismountAutoRetryDelay; - - do - { - *pbResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, punmount, - sizeof (UNMOUNT_STRUCT), punmount, sizeof (UNMOUNT_STRUCT), pdwResult, NULL); - - if ( punmount->nDosDriveNo < 0 || punmount->nDosDriveNo > 25 - || (punmount->ignoreOpenFiles != TRUE && punmount->ignoreOpenFiles != FALSE) - || (punmount->HiddenVolumeProtectionTriggered != TRUE && punmount->HiddenVolumeProtectionTriggered != FALSE) - || (punmount->nReturnCode < 0) - ) - { - if (*pbResult) - SetLastError (ERROR_INTERNAL_ERROR); - *pbResult = FALSE; - } - - if (*pbResult == FALSE) - { - NormalCursor(); - handleWin32Error (hwndDlg, SRC_POS); - pThreadParam->dwLastError = GetLastError (); - pThreadParam->bReturn = FALSE; - return; - } - - if (punmount->nReturnCode == ERR_SUCCESS - && punmount->HiddenVolumeProtectionTriggered - && !VolumeNotificationsList.bHidVolDamagePrevReported [punmount->nDosDriveNo] - && pThreadParam->interact - && !Silent) - { - wchar_t msg[4096]; - - VolumeNotificationsList.bHidVolDamagePrevReported [punmount->nDosDriveNo] = TRUE; - - StringCbPrintfW (msg, sizeof(msg), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), punmount->nDosDriveNo + L'A'); - SetForegroundWindow (hwndDlg); - MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); - - punmount->HiddenVolumeProtectionTriggered = FALSE; - continue; - } - - if (punmount->nReturnCode == ERR_FILES_OPEN) - Sleep (dismountAutoRetryDelay); - else - break; - - } while (--dismountMaxRetries > 0); - - pThreadParam->dwLastError = GetLastError (); - pThreadParam->bReturn = TRUE; -} - -static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay) -{ - BOOL status = TRUE; - MOUNT_LIST_STRUCT mountList = {0}; - DWORD dwResult; - UNMOUNT_STRUCT unmount = {0}; - BOOL bResult; - MOUNT_LIST_STRUCT prevMountList = {0}; - int i; - DismountAllThreadParam dismountAllThreadParam; - -retry: - WaitCursor(); - - DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); - - if (mountList.ulMountedDrives == 0) - { - NormalCursor(); - return TRUE; - } - - BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, 0, mountList.ulMountedDrives); - - memcpy (&prevMountList, &mountList, sizeof (mountList)); - - for (i = 0; i < 26; i++) - { - if (mountList.ulMountedDrives & (1 << i)) - { - if (bCloseDismountedWindows) - CloseVolumeExplorerWindows (hwndDlg, i); - } - } - - unmount.nDosDriveNo = 0; - unmount.ignoreOpenFiles = forceUnmount; - - dismountAllThreadParam.punmount = &unmount; - dismountAllThreadParam.interact = interact; - dismountAllThreadParam.dismountMaxRetries = dismountMaxRetries; - dismountAllThreadParam.dismountAutoRetryDelay = dismountAutoRetryDelay; - dismountAllThreadParam.pbResult = &bResult; - dismountAllThreadParam.pdwResult = &dwResult; - dismountAllThreadParam.dwLastError = ERROR_SUCCESS; - dismountAllThreadParam.bReturn = TRUE; - - if (interact && !Silent) - { - - ShowWaitDialog (hwndDlg, FALSE, DismountAllThreadProc, &dismountAllThreadParam); - } - else - DismountAllThreadProc (&dismountAllThreadParam, hwndDlg); - - SetLastError (dismountAllThreadParam.dwLastError); - - if (!dismountAllThreadParam.bReturn) - return FALSE; - - memset (&mountList, 0, sizeof (mountList)); - DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); - - // remove any custom label from registry - for (i = 0; i < 26; i++) - { - if ((prevMountList.ulMountedDrives & (1 << i)) && (!(mountList.ulMountedDrives & (1 << i))) && wcslen (prevMountList.wszLabel[i])) - { - UpdateDriveCustomLabel (i, prevMountList.wszLabel[i], FALSE); - } - } - - BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, prevMountList.ulMountedDrives & ~mountList.ulMountedDrives); - - RefreshMainDlg (hwndDlg); - - if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ()) - LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); - - NormalCursor(); - - if (unmount.nReturnCode != 0) - { - if (forceUnmount) - status = FALSE; - - if (unmount.nReturnCode == ERR_FILES_OPEN) - { - if (interact && IDYES == AskWarnYesNoTopmost ("UNMOUNTALL_LOCK_FAILED", hwndDlg)) - { - forceUnmount = TRUE; - goto retry; - } - - if (IsOSAtLeast (WIN_7)) - { - // Undo SHCNE_DRIVEREMOVED - DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, NULL, 0, &mountList, sizeof (mountList), &dwResult, NULL); - - for (i = 0; i < 26; i++) - { - if (mountList.ulMountedDrives & (1 << i)) - { - wchar_t root[] = { (wchar_t) i + L'A', L':', L'\\', 0 }; - SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL); - } - } - } - - return FALSE; - } - - if (interact) - MessageBoxW (hwndDlg, GetString ("UNMOUNT_FAILED"), lpszTitle, MB_ICONERROR); - } - else - { - if (bBeep) - MessageBeep (0xFFFFFFFF); - } - - return status; -} - -static BOOL MountAllDevicesThreadCode (HWND hwndDlg, BOOL bPasswordPrompt) -{ - HWND driveList = GetDlgItem (MainDlg, IDC_DRIVELIST); - int selDrive = ListView_GetSelectionMark (driveList); - BOOL shared = FALSE, status = FALSE, bHeaderBakRetry = FALSE; - int mountedVolCount = 0; - vector devices; - int EffectiveVolumePkcs5 = CmdVolumePkcs5; - BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; - - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (EffectiveVolumePkcs5 == 0) - EffectiveVolumePkcs5 = DefaultVolumePkcs5; - if (!EffectiveVolumeTrueCryptMode) - EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; - - VolumePassword.Length = 0; - mountOptions = defaultMountOptions; - bPrebootPasswordDlgMode = FALSE; - VolumePim = -1; - - if (selDrive == -1) - selDrive = 0; - - ResetWrongPwdRetryCount (); - - MultipleMountOperationInProgress = TRUE; - - do - { - if (!bHeaderBakRetry) - { - if (!CmdVolumePasswordValid && bPasswordPrompt) - { - int GuiPkcs5 = EffectiveVolumePkcs5; - BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode; - int GuiPim = CmdVolumePim; - PasswordDlgVolume[0] = '\0'; - if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &GuiTrueCryptMode, NULL, TRUE)) - goto ret; - else - { - VolumePkcs5 = GuiPkcs5; - VolumeTrueCryptMode = GuiTrueCryptMode; - VolumePim = GuiPim; - burn (&GuiPkcs5, sizeof(GuiPkcs5)); - burn (&GuiTrueCryptMode, sizeof(GuiTrueCryptMode)); - burn (&GuiPim, sizeof(GuiPim)); - } - } - else if (CmdVolumePasswordValid) - { - bPasswordPrompt = FALSE; - VolumePassword = CmdVolumePassword; - VolumePkcs5 = EffectiveVolumePkcs5; - VolumeTrueCryptMode = EffectiveVolumeTrueCryptMode; - VolumePim = CmdVolumePim; - } - - WaitCursor(); - - if (FirstCmdKeyFile) - KeyFilesApply (hwndDlg, &VolumePassword, FirstCmdKeyFile, NULL); - else if (KeyFilesEnable) - KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, NULL); - - } - - if (devices.empty()) - devices = GetAvailableHostDevices (true, false, true, true); - foreach (const HostDevice &drive, devices) - { - vector partitions = drive.Partitions; - partitions.insert (partitions.begin(), drive); - - foreach (const HostDevice &device, partitions) - { - wchar_t szFileName[TC_MAX_PATH]; - StringCbCopyW (szFileName, sizeof (szFileName), device.Path.c_str()); - BOOL mounted = IsMountedVolume (szFileName); - - // Skip other partitions of the disk if partition0 (whole disk) is mounted - if (!device.IsPartition && mounted) - break; - - if (device.Floppy) - break; - - if (device.HasUnencryptedFilesystem && !mountOptions.UseBackupHeader && !bHeaderBakRetry) - continue; - - if (!mounted) - { - int nDosDriveNo; - int driveAItem = -1, driveBItem = -1; - - while (LOWORD (GetItemLong (driveList, selDrive)) != 0xffff) - { - if(LOWORD (GetItemLong (driveList, selDrive)) != TC_MLIST_ITEM_FREE) - { - selDrive++; - continue; - } - nDosDriveNo = HIWORD(GetItemLong (driveList, selDrive)) - L'A'; - - /* don't use drives A: and B: for now until no other free drive found */ - if (nDosDriveNo == 0) - { - driveAItem = selDrive; - selDrive++; - continue; - } - if (nDosDriveNo == 1) - { - driveBItem = selDrive; - selDrive++; - continue; - } - break; - } - - if (LOWORD (GetItemLong (driveList, selDrive)) == 0xffff) - { - /* use A: or B: if available as a last resort */ - if (driveAItem >= 0) - { - nDosDriveNo = 0; - selDrive = driveAItem; - } - else if (driveBItem >= 0) - { - nDosDriveNo = 1; - selDrive = driveBItem; - } - else - goto ret; - } - - // First try user password then cached passwords - if ((mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, TRUE, FALSE)) > 0 - || ((VolumePassword.Length > 0) && ((mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, TRUE, FALSE)) > 0))) - { - // A volume has been successfully mounted - - ResetWrongPwdRetryCount (); - - if (mounted == 2) - shared = TRUE; - - LoadDriveLetters (hwndDlg, driveList, (HIWORD (GetItemLong (GetDlgItem (MainDlg, IDC_DRIVELIST), selDrive)))); - selDrive++; - - if (bExplore) - { - WaitCursor(); - OpenVolumeExplorerWindow (nDosDriveNo); - NormalCursor(); - } - - if (bBeep) - MessageBeep (0xFFFFFFFF); - - status = TRUE; - - mountedVolCount++; - - // Skip other partitions of the disk if partition0 (whole disk) has been mounted - if (!device.IsPartition) - break; - } - } - } - } - - if (mountedVolCount < 1) - { - // Failed to mount any volume - - IncreaseWrongPwdRetryCount (1); - - if (WrongPwdRetryCountOverLimit () - && !mountOptions.UseBackupHeader - && !bHeaderBakRetry) - { - // Retry using embedded header backup (if any) - mountOptions.UseBackupHeader = TRUE; - bHeaderBakRetry = TRUE; - } - else if (bHeaderBakRetry) - { - mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; - bHeaderBakRetry = FALSE; - } - - if (!Silent && !bHeaderBakRetry) - { - WCHAR szTmp[4096]; - - StringCbPrintfW (szTmp, sizeof(szTmp), GetString (KeyFilesEnable || FirstCmdKeyFile ? "PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT" : "PASSWORD_WRONG_AUTOMOUNT")); - if (CheckCapsLock (hwndDlg, TRUE)) - StringCbCatW (szTmp, sizeof(szTmp), GetString ("PASSWORD_WRONG_CAPSLOCK_ON")); - - MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONWARNING); - } - } - else if (bHeaderBakRetry) - { - // We have successfully mounted a volume using the header backup embedded in the volume (the header is damaged) - mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; - bHeaderBakRetry = FALSE; - - if (!Silent) - Warning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK", hwndDlg); - } - - if (!bHeaderBakRetry) - { - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); - burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); - } - - } while (bPasswordPrompt && mountedVolCount < 1); - - /* One or more volumes successfully mounted */ - - ResetWrongPwdRetryCount (); - - if (shared) - Warning ("DEVICE_IN_USE_INFO", hwndDlg); - - if (mountOptions.ProtectHiddenVolume) - { - if (mountedVolCount > 1) - Info ("HIDVOL_PROT_WARN_AFTER_MOUNT_PLURAL", hwndDlg); - else if (mountedVolCount == 1) - Info ("HIDVOL_PROT_WARN_AFTER_MOUNT", hwndDlg); - } - - if (status && CloseSecurityTokenSessionsAfterMount) - SecurityToken::CloseAllSessions(); - -ret: - MultipleMountOperationInProgress = FALSE; - - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); - burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); - - mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; - - RestoreDefaultKeyFilesParam (); - - if (UsePreferences) - bCacheInDriver = bCacheInDriverDefault; - - EnableDisableButtons (MainDlg); - - NormalCursor(); - - return status; -} - -typedef struct -{ - BOOL bPasswordPrompt; - BOOL bRet; -} MountAllDevicesThreadParam; - -void CALLBACK mountAllDevicesThreadProc(void* pArg, HWND hwndDlg) -{ - MountAllDevicesThreadParam* threadParam =(MountAllDevicesThreadParam*) pArg; - BOOL bPasswordPrompt = threadParam->bPasswordPrompt; - - threadParam->bRet = MountAllDevicesThreadCode (hwndDlg, bPasswordPrompt); -} - -static BOOL MountAllDevices (HWND hwndDlg, BOOL bPasswordPrompt) -{ - MountAllDevicesThreadParam param; - param.bPasswordPrompt = bPasswordPrompt; - param.bRet = FALSE; - - ShowWaitDialog (hwndDlg, FALSE, mountAllDevicesThreadProc, ¶m); - - return param.bRet; -} - -static void ChangePassword (HWND hwndDlg) -{ - INT_PTR result; - int newPimValue = -1; - - GetVolumePath (hwndDlg, szFileName, ARRAYSIZE (szFileName)); - - if (!TranslateVolumeID (hwndDlg, szFileName, ARRAYSIZE (szFileName))) - { - return; - } - - if (IsMountedVolume (szFileName)) - { - Warning (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE", hwndDlg); - return; - } - - if (!VolumePathExists (szFileName)) - { - handleWin32Error (hwndDlg, SRC_POS); - return; - } - - bSysEncPwdChangeDlgMode = FALSE; - - result = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_PASSWORDCHANGE_DLG), hwndDlg, - (DLGPROC) PasswordChangeDlgProc, (LPARAM) &newPimValue); - - if (result == IDOK) - { - switch (pwdChangeDlgMode) - { - case PCDM_CHANGE_PKCS5_PRF: - Info ("PKCS5_PRF_CHANGED", hwndDlg); - break; - - case PCDM_ADD_REMOVE_VOL_KEYFILES: - case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: - Info ("KEYFILE_CHANGED", hwndDlg); - break; - - case PCDM_CHANGE_PASSWORD: - default: - { - Info ("PASSWORD_CHANGED", hwndDlg); - if (newPimValue != -1) - { - // update the encoded volue in favorite XML if found - bool bFavoriteFound = false; - for (vector ::iterator favorite = FavoriteVolumes.begin(); - favorite != FavoriteVolumes.end(); favorite++) - { - if (favorite->Path == szFileName) - { - bFavoriteFound = true; - favorite->Pim = newPimValue; - SaveFavoriteVolumes (hwndDlg, FavoriteVolumes, false); - break; - } - } - - if (!bFavoriteFound) - { - for (vector ::iterator favorite = SystemFavoriteVolumes.begin(); - favorite != SystemFavoriteVolumes.end(); favorite++) - { - if (favorite->Path == szFileName) - { - bFavoriteFound = true; - favorite->Pim = newPimValue; - - if (AskYesNo("FAVORITE_PIM_CHANGED", hwndDlg) == IDYES) - { - SaveFavoriteVolumes (hwndDlg, SystemFavoriteVolumes, true); - } - break; - } - } - } - } - } - } - } -} - -// Change password of the system partition/drive -static void ChangeSysEncPassword (HWND hwndDlg, BOOL bOnlyChangeKDF) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (!BootEncStatus.DriveEncrypted - && !BootEncStatus.DriveMounted - && !BootEncStatus.VolumeHeaderPresent - && !SysEncryptionOrDecryptionRequired ()) - { - Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); - return; - } - - if (SysEncryptionOrDecryptionRequired () - || BootEncStatus.SetupInProgress) - { - Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED", hwndDlg); - return; - } - - if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption - { - StringCbPrintfW (OrigKeyboardLayout, sizeof(OrigKeyboardLayout), L"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF); - - bSysEncPwdChangeDlgMode = TRUE; - - if (bOnlyChangeKDF) - pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; - else - pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; - - - INT_PTR result = DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_PASSWORDCHANGE_DLG), hwndDlg, (DLGPROC) PasswordChangeDlgProc); - - bSysEncPwdChangeDlgMode = FALSE; - - if (bKeyboardLayoutChanged) - { - // Restore the original keyboard layout - if (LoadKeyboardLayout (OrigKeyboardLayout, KLF_ACTIVATE | KLF_SUBSTITUTE_OK) == NULL) - Warning ("CANNOT_RESTORE_KEYBOARD_LAYOUT", hwndDlg); - else - bKeyboardLayoutChanged = FALSE; - } - - bKeybLayoutAltKeyWarningShown = FALSE; - - if (result == IDOK) - { - switch (pwdChangeDlgMode) - { - case PCDM_CHANGE_PKCS5_PRF: - Info ("PKCS5_PRF_CHANGED", hwndDlg); - - if (!IsHiddenOSRunning()) - { - if (AskWarnYesNo ("SYS_HKD_ALGO_CHANGED_ASK_RESCUE_DISK", hwndDlg) == IDYES) - CreateRescueDisk (hwndDlg); - } - - break; - - case PCDM_ADD_REMOVE_VOL_KEYFILES: - case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: - // NOP - Keyfiles are not supported for system encryption - break; - - case PCDM_CHANGE_PASSWORD: - default: - Info ("PASSWORD_CHANGED", hwndDlg); - - if (!IsHiddenOSRunning()) - { - if (AskWarnYesNo ("SYS_PASSWORD_CHANGED_ASK_RESCUE_DISK", hwndDlg) == IDYES) - CreateRescueDisk (hwndDlg); - } - } - } - - CloseSysEncMutex (); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); -} - -// Initiates or resumes encryption of the system partition/drive -static void EncryptSystemDevice (HWND hwndDlg) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (!BootEncStatus.DriveEncrypted - && !BootEncStatus.DriveMounted - && !SysEncryptionOrDecryptionRequired ()) - { - // System partition/drive is not encrypted (nothing to resume). Initiate the process. - - if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption - { - LaunchVolCreationWizard (hwndDlg, L"/sysenc"); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); - - return; - } - else if (SysEncryptionOrDecryptionRequired ()) - { - // System partition/drive encryption already initiated but is incomplete -- attempt to resume the process. - // Note that this also covers the pretest phase and paused decryption (reverses decrypting and starts encrypting) - - if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption - { - LaunchVolCreationWizard (hwndDlg, L"/sysenc"); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); - } - else if (SysDriveOrPartitionFullyEncrypted (FALSE)) - { - // System partition/drive appears to be fully encrypted - Info ("SYS_PARTITION_OR_DRIVE_APPEARS_FULLY_ENCRYPTED", hwndDlg); - return; - } -} - -// Initiates decryption of the system partition/drive -static void DecryptSystemDevice (HWND hwndDlg) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (!BootEncStatus.DriveEncrypted - && !BootEncStatus.DriveMounted - && !BootEncStatus.DeviceFilterActive - && !BootEncStatus.VolumeHeaderPresent - && !SysEncryptionOrDecryptionRequired ()) - { - Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); - return; - } - - if (IsHiddenOSRunning()) - { - Warning ("CANNOT_DECRYPT_HIDDEN_OS", hwndDlg); - return; - } - - if (AskNoYes ("CONFIRM_DECRYPT_SYS_DEVICE", hwndDlg) == IDNO) - return; - - if (AskWarnNoYes ("CONFIRM_DECRYPT_SYS_DEVICE_CAUTION", hwndDlg) == IDNO) - return; - - if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption - { - try - { - // User-mode app may have crashed and its mutex may have gotten lost, so we need to check the driver status too - if (BootEncStatus.SetupInProgress) - { - int attempts = 20; - - BootEncObj->AbortSetup (); - while (BootEncStatus.SetupInProgress && attempts > 0) - { - Sleep (100); - BootEncStatus = BootEncObj->GetStatus(); - attempts--; - WaitCursor(); - } - } - } - catch (Exception &e) - { - e.Show (MainDlg); - } - NormalCursor (); - - if (BootEncStatus.SetupInProgress) - { - CloseSysEncMutex (); - Error ("SYS_ENCRYPTION_OR_DECRYPTION_IN_PROGRESS", hwndDlg); - return; - } - - CloseSysEncMutex (); - LaunchVolCreationWizard (hwndDlg, L"/dsysenc"); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); -} - -// Initiates the process of creation of a hidden operating system -static void CreateHiddenOS (HWND hwndDlg) -{ - - // Display brief information as to what a hidden operating system is and what it's good for. This needs to be - // done, because if the system partition/drive is currently encrypted, the wizard will not display any - // such information, but will exit (displaying only an error meessage). - Info("HIDDEN_OS_PREINFO", hwndDlg); - - LaunchVolCreationWizard (hwndDlg, L"/isysenc"); -} - -static void DecryptNonSysDevice (HWND hwndDlg, BOOL bResolveAmbiguousSelection, BOOL bUseDriveListSel) -{ - wstring scPath; - - if (bResolveAmbiguousSelection) - { - scPath = ResolveAmbiguousSelection (hwndDlg, NULL); - - if (scPath.empty ()) - { - // The user selected Cancel - return; - } - } - else if (bUseDriveListSel) - { - // Decrypt mounted volume selected in the main drive list - - LPARAM lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); - - if (LOWORD (lLetter) != 0xffff) - { - VOLUME_PROPERTIES_STRUCT prop; - DWORD bytesReturned; - - memset (&prop, 0, sizeof (prop)); - prop.driveNo = (wchar_t) HIWORD (lLetter) - L'A'; - - if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &bytesReturned, NULL)) - { - handleWin32Error (MainDlg, SRC_POS); - return; - } - - scPath = prop.wszVolume; - } - else - return; - } - else - { - // Decrypt volume specified in the input field below the main drive list - - wchar_t volPath [TC_MAX_PATH]; - - GetVolumePath (MainDlg, volPath, ARRAYSIZE (volPath)); - - scPath = volPath; - } - - if (scPath.empty ()) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - return; - } - - WaitCursor(); - - switch (IsSystemDevicePath (scPath.c_str (), MainDlg, TRUE)) - { - case 1: - case 2: - // The user wants to decrypt the system partition/drive. Divert to the appropriate function. - - NormalCursor (); - - DecryptSystemDevice (hwndDlg); - return; - } - - WaitCursor(); - - // Make sure the user is not attempting to decrypt a partition on an entirely encrypted system drive. - if (IsNonSysPartitionOnSysDrive (scPath.c_str ()) == 1) - { - if (WholeSysDriveEncryption (TRUE)) - { - // The system drive is entirely encrypted and the encrypted OS is running - - NormalCursor (); - - Warning ("CANT_DECRYPT_PARTITION_ON_ENTIRELY_ENCRYPTED_SYS_DRIVE", hwndDlg); - return; - } - } - else if (TCBootLoaderOnInactiveSysEncDrive ((wchar_t *) scPath.c_str ())) - { - // The system drive MAY be entirely encrypted (external access without PBA) and the potentially encrypted OS is not running - - NormalCursor (); - - Warning ("CANT_DECRYPT_PARTITION_ON_ENTIRELY_ENCRYPTED_SYS_DRIVE_UNSURE", hwndDlg); - - // We allow the user to continue as we don't know if the drive is really an encrypted system drive. - // If it is, the user has been warned and he will not be able to start decrypting, because the - // format wizard will not enable (nor will it allow the user to enable) the mount option for - // external without-PBA access (the user will receive the 'Incorrect password' error message). - } - - NormalCursor (); - - - if (AskNoYesString ((wstring (GetString ("CONFIRM_DECRYPT_NON_SYS_DEVICE")) + L"\n\n" + scPath).c_str(), hwndDlg) == IDNO) - return; - - if (AskWarnNoYes ("CONFIRM_DECRYPT_NON_SYS_DEVICE_CAUTION", hwndDlg) == IDNO) - return; - - LaunchVolCreationWizard (hwndDlg, (wstring (L"/inplacedec \"") + scPath + L"\"").c_str ()); -} - -// Blindly attempts (without any checks) to instruct the wizard to resume whatever system encryption process -// had been interrupted or not started but scheduled or exptected to start. -static void ResumeInterruptedSysEncProcess (HWND hwndDlg) -{ - if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption - { - LaunchVolCreationWizard (MainDlg, L"/csysenc"); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); -} - -void CreateRescueDisk (HWND hwndDlg) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (IsHiddenOSRunning()) - { - Warning ("CANNOT_CREATE_RESCUE_DISK_ON_HIDDEN_OS", hwndDlg); - return; - } - - if (!BootEncStatus.DriveEncrypted - && !BootEncStatus.DriveMounted - && !BootEncStatus.VolumeHeaderPresent - && !SysEncryptionOrDecryptionRequired ()) - { - Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); - return; - } - - if (SysEncryptionOrDecryptionRequired () - || BootEncStatus.SetupInProgress) - { - Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED", hwndDlg); - return; - } - - if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption - { - try - { - wchar_t szTmp [8096]; - wchar_t szRescueDiskISO [TC_MAX_PATH+1]; - - if (AskOkCancel ("RESCUE_DISK_NON_WIZARD_CREATION_SELECT_PATH", hwndDlg) != IDOK) - { - CloseSysEncMutex (); - return; - } - - wchar_t initialDir[MAX_PATH]; - SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, 0, initialDir); - - if (!BrowseFilesInDir (hwndDlg, "OPEN_TITLE", initialDir, szRescueDiskISO, FALSE, TRUE, NULL, L"VeraCrypt Rescue Disk.iso", L"iso")) - { - CloseSysEncMutex (); - return; - } - - WaitCursor(); - BootEncObj->CreateRescueIsoImage (false, szRescueDiskISO); - - StringCbPrintfW (szTmp, sizeof szTmp, - GetString (IsWindowsIsoBurnerAvailable() ? "RESCUE_DISK_NON_WIZARD_CREATION_WIN_ISOBURN" : "RESCUE_DISK_NON_WIZARD_CREATION_BURN"), - szRescueDiskISO); - - if (IsWindowsIsoBurnerAvailable()) - { - if (AskYesNoString (szTmp, hwndDlg) == IDYES) - LaunchWindowsIsoBurner (MainDlg, szRescueDiskISO); - } - else - InfoDirect (szTmp, hwndDlg); - } - catch (Exception &e) - { - e.Show (hwndDlg); - Error ("ERROR_CREATING_RESCUE_DISK", hwndDlg); - } - CloseSysEncMutex (); - - NormalCursor (); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); -} - -static void VerifyRescueDisk (HWND hwndDlg, bool checkIsoFile) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (!BootEncStatus.DriveEncrypted - && !BootEncStatus.DriveMounted - && !BootEncStatus.VolumeHeaderPresent - && !SysEncryptionOrDecryptionRequired ()) - { - Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); - return; - } - - if (SysEncryptionOrDecryptionRequired () - || BootEncStatus.SetupInProgress) - { - Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED", hwndDlg); - return; - } - - if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption - { - try - { - if (!checkIsoFile && (AskOkCancel ("RESCUE_DISK_NON_WIZARD_CHECK_INSERT", hwndDlg) != IDOK)) - { - CloseSysEncMutex (); - return; - } - - // Create a temporary up-to-date rescue disk image in RAM (with it the CD/DVD content will be compared) - BootEncObj->CreateRescueIsoImage (false, L""); - - - if (checkIsoFile) - { - wchar_t szRescueDiskISO [TC_MAX_PATH+1]; - wchar_t initialDir[MAX_PATH]; - SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, 0, initialDir); - - if (!BrowseFilesInDir (hwndDlg, "OPEN_TITLE", initialDir, szRescueDiskISO, FALSE, FALSE, NULL, L"VeraCrypt Rescue Disk.iso", L"iso")) - { - CloseSysEncMutex (); - return; - } - - WaitCursor(); - if (!BootEncObj->VerifyRescueDiskIsoImage (szRescueDiskISO)) - Error ("RESCUE_DISK_ISO_IMAGE_CHECK_FAILED", hwndDlg); - else - Info ("RESCUE_DISK_ISO_IMAGE_CHECK_PASSED", hwndDlg); - } - else - { - WaitCursor(); - if (!BootEncObj->VerifyRescueDisk ()) - Error ("RESCUE_DISK_NON_WIZARD_CHECK_FAILED", hwndDlg); - else - Info ("RESCUE_DISK_NON_WIZARD_CHECK_PASSED", hwndDlg); - } - } - catch (Exception &e) - { - e.Show (MainDlg); - Error ("RESCUE_DISK_NON_WIZARD_CHECK_FAILED", hwndDlg); - } - CloseSysEncMutex (); - - NormalCursor (); - } - else - Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); -} - -static void ShowSystemEncryptionStatus (HWND hwndDlg) -{ - try - { - BootEncStatus = BootEncObj->GetStatus(); - } - catch (Exception &e) - { - e.Show (MainDlg); - } - - if (GetAsyncKeyState (VK_SHIFT) < 0 && GetAsyncKeyState (VK_CONTROL) < 0) - { - // Ctrl+Shift held (for debugging purposes) - - DebugMsgBox ("Debugging information for system encryption:\n\nDeviceFilterActive: %d\nBootLoaderVersion: %x\nSetupInProgress: %d\nSetupMode: %d\nVolumeHeaderPresent: %d\nDriveMounted: %d\nDriveEncrypted: %d\n" - "HiddenSystem: %d\nHiddenSystemPartitionStart: %I64d\n" - "ConfiguredEncryptedAreaStart: %I64d\nConfiguredEncryptedAreaEnd: %I64d\nEncryptedAreaStart: %I64d\nEncryptedAreaEnd: %I64d\nEncrypted: %I64d%%", - BootEncStatus.DeviceFilterActive, - BootEncStatus.BootLoaderVersion, - BootEncStatus.SetupInProgress, - BootEncStatus.SetupMode, - BootEncStatus.VolumeHeaderPresent, - BootEncStatus.DriveMounted, - BootEncStatus.DriveEncrypted, - BootEncStatus.HiddenSystem ? 1 : 0, - BootEncStatus.HiddenSystemPartitionStart, - BootEncStatus.ConfiguredEncryptedAreaStart, - BootEncStatus.ConfiguredEncryptedAreaEnd, - BootEncStatus.EncryptedAreaStart, - BootEncStatus.EncryptedAreaEnd, - !BootEncStatus.DriveEncrypted ? 0 : (BootEncStatus.EncryptedAreaEnd + 1 - BootEncStatus.EncryptedAreaStart) * 100I64 / (BootEncStatus.ConfiguredEncryptedAreaEnd + 1 - BootEncStatus.ConfiguredEncryptedAreaStart)); - } - - if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) - { - Info ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); - return; - } - - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, - (DLGPROC) VolumePropertiesDlgProc, (LPARAM) TRUE); - -} - -static void ResumeInterruptedNonSysInplaceEncProcess (BOOL bDecrypt) -{ - // IMPORTANT: This function must not check any config files! Otherwise, if a config file was lost or corrupt, - // the user would not be able resume encryption and the data on the volume would be inaccessible. - - LaunchVolCreationWizard (MainDlg, bDecrypt? L"/resumeinplacedec" : L"/zinplace"); -} - -BOOL SelectContainer (HWND hwndDlg) -{ - if (BrowseFiles (hwndDlg, "OPEN_VOL_TITLE", szFileName, bHistory, FALSE, NULL) == FALSE) - return FALSE; - - AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); - EnableDisableButtons (hwndDlg); - SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - return TRUE; -} - -BOOL SelectPartition (HWND hwndDlg) -{ - RawDevicesDlgParam param; - param.pszFileName = szFileName; - INT_PTR nResult = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_RAWDEVICES_DLG), hwndDlg, - (DLGPROC) RawDevicesDlgProc, (LPARAM) & param); - if (nResult == IDOK) - { - AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); - EnableDisableButtons (hwndDlg); - SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - return TRUE; - } - - return FALSE; -} - -static void WipeCache (HWND hwndDlg, BOOL silent) -{ - DWORD dwResult; - BOOL bResult; - - bResult = DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - if (hwndDlg == NULL) - return; - - if (bResult == FALSE) - handleWin32Error (hwndDlg, SRC_POS); - else - { - EnableDisableButtons (hwndDlg); - - if (!silent) - InfoBalloon ("PASSWORD_CACHE_WIPED_SHORT", "PASSWORD_CACHE_WIPED", hwndDlg); - } -} - -static void Benchmark (HWND hwndDlg) -{ - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_BENCHMARK_DLG), hwndDlg, - (DLGPROC) BenchmarkDlgProc, (LPARAM) NULL); -} - - -static BOOL CheckMountList (HWND hwndDlg, BOOL bForceTaskBarUpdate) -{ - MOUNT_LIST_STRUCT current; - static BootEncryptionStatus newBootEncStatus; - static BOOL lastbUseDifferentTrayIconIfVolMounted = bUseDifferentTrayIconIfVolMounted; - static uint32 lastUlMountedDrives = 0; - - GetMountList (¤t); - - if ((bForceTaskBarUpdate || current.ulMountedDrives != lastUlMountedDrives || bUseDifferentTrayIconIfVolMounted != lastbUseDifferentTrayIconIfVolMounted) - && TaskBarIconMutex != NULL) - { - lastUlMountedDrives = current.ulMountedDrives; - lastbUseDifferentTrayIconIfVolMounted = bUseDifferentTrayIconIfVolMounted; - - TaskBarIconChange (MainDlg, current.ulMountedDrives != 0 && bUseDifferentTrayIconIfVolMounted ? IDI_TRUECRYPT_MOUNTED_ICON : IDI_TRUECRYPT_ICON); - } - - if (bForceTaskBarUpdate) - { - return TRUE; - } - - if (LastKnownLogicalDrives != GetUsedLogicalDrives() - || memcmp (&LastKnownMountList, ¤t, sizeof (current)) != 0) - { - wchar_t selDrive; - - WaitCursor (); - LastKnownMountList = current; - - selDrive = (wchar_t) HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))); - LoadDriveLetters (hwndDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0); - NormalCursor (); - - if (selDrive != ((wchar_t) 0xFFFF) && (current.ulMountedDrives & (1 << (selDrive - L'A'))) == 0 && !IsDriveAvailable (selDrive - L'A')) - { - nSelectedDriveIndex = -1; - return FALSE; - } - - if (selDrive != ((wchar_t) 0xFFFF)) - SelectItem (GetDlgItem (MainDlg, IDC_DRIVELIST),selDrive); - } - - try - { - newBootEncStatus = BootEncObj->GetStatus(); - - if (newBootEncStatus.SetupInProgress != RecentBootEncStatus.SetupInProgress - || newBootEncStatus.EncryptedAreaEnd != RecentBootEncStatus.EncryptedAreaEnd - || newBootEncStatus.DriveEncrypted != RecentBootEncStatus.DriveEncrypted - || newBootEncStatus.DriveMounted != RecentBootEncStatus.DriveMounted - || newBootEncStatus.SetupMode != RecentBootEncStatus.SetupMode - || newBootEncStatus.EncryptedAreaStart != RecentBootEncStatus.EncryptedAreaStart) - { - /* System encryption status change */ - - wchar_t selDrive; - int driveLetterToRefresh; - - if (RecentBootEncStatus.DriveMounted == newBootEncStatus.DriveMounted) // If an icon (and whole new line) for a system device isn't to be added/removed - { - // Partial refresh - if (WholeSysDriveEncryption (TRUE)) - { - // System drive (not just partition) - driveLetterToRefresh = ENC_SYSDRIVE_PSEUDO_DRIVE_LETTER; - } - else - { - // System partition - driveLetterToRefresh = GetSystemDriveLetter (); - } - } - else - { - // Full rebuild of the mount list - driveLetterToRefresh = 0; - } - - selDrive = (wchar_t) HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))); - LoadDriveLetters (hwndDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), driveLetterToRefresh); - - RecentBootEncStatus = newBootEncStatus; - - if (selDrive != ((wchar_t) 0xFFFF) && (current.ulMountedDrives & (1 << (selDrive - L'A'))) == 0 && !IsDriveAvailable (selDrive - L'A')) - { - nSelectedDriveIndex = -1; - } - - if (selDrive != ((wchar_t) 0xFFFF)) - { - SelectItem (GetDlgItem (MainDlg, IDC_DRIVELIST),selDrive); - } - } - - /* Miscellaneous notifications */ - - // Hibernation prevention notifications - if (newBootEncStatus.HibernationPreventionCount != RecentBootEncStatus.HibernationPreventionCount - && !bHibernationPreventionNotified) - { - bHibernationPreventionNotified = TRUE; - RecentBootEncStatus.HibernationPreventionCount = newBootEncStatus.HibernationPreventionCount; - - if (IsHiddenOSRunning() && BootEncObj->GetSystemDriveConfiguration().ExtraBootPartitionPresent) - WarningTopMost ("HIDDEN_OS_HIBERNATION_PREVENTED", hwndDlg); - else - WarningTopMost ("SYS_ENC_HIBERNATION_PREVENTED", hwndDlg); - } - - // Write mode prevention (hidden OS leak protection) - if (IsHiddenOSRunning()) - { - if (newBootEncStatus.HiddenSysLeakProtectionCount != RecentBootEncStatus.HiddenSysLeakProtectionCount - && !bHiddenSysLeakProtNotifiedDuringSession) - { - bHiddenSysLeakProtNotifiedDuringSession = TRUE; - - switch (HiddenSysLeakProtectionNotificationStatus) - { - case TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT: - { - char *tmp[] = {0, "HIDDEN_OS_WRITE_PROTECTION_BRIEF_INFO", "SHOW_MORE_INFORMATION", "DO_NOT_SHOW_THIS_AGAIN", "CONTINUE", 0}; - switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg)) - { - case 1: - InfoDirect ((wstring (GetString ("HIDDEN_OS_WRITE_PROTECTION_BRIEF_INFO")) - + L"\n\n" - + GetString ("HIDDEN_OS_WRITE_PROTECTION_EXPLANATION") - + L"\n\n\n" - + GetString ("DECOY_TO_HIDDEN_OS_DATA_TRANSFER_HOWTO")).c_str(), hwndDlg); - break; - - case 2: - // No more warnings will be shown - if (ConfigBuffer == NULL) - { - // We need to load the config file because it is not done automatically when - // launched from the sys startup sequence (and SaveSettings would start by _loading_ - // the settings to cache). - LoadSettings (MainDlg); - } - HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED; - SaveSettings (MainDlg); - break; - - default: - // NOP - break; - } - } - break; - - case TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED: - // NOP - break; - - case TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE: - default: - { - // First time warning -- include technical explanation - InfoDirect ((wstring (GetString ("HIDDEN_OS_WRITE_PROTECTION_BRIEF_INFO")) - + L"\n\n" - + GetString ("HIDDEN_OS_WRITE_PROTECTION_EXPLANATION") - + L"\n\n\n" - + GetString ("DECOY_TO_HIDDEN_OS_DATA_TRANSFER_HOWTO")).c_str(), hwndDlg); - - // Further warnings will not include the explanation (and will allow disabling) - - if (ConfigBuffer == NULL) - { - // We need to load the config file because it is not done automatically when - // launched from the sys startup sequence (and SaveSettings would start by _loading_ - // the settings to cache). - LoadSettings (MainDlg); - } - HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT; - SaveSettings (MainDlg); - } - break; - } - } - } - } - catch (...) - { - // NOP - } - - return TRUE; -} - - -void DisplayDriveListContextMenu (HWND hwndDlg, LPARAM lParam) -{ - /* Drive list context menu */ - DWORD mPos; - int menuItem; - HMENU popup = CreatePopupMenu (); - HWND hList = GetDlgItem (hwndDlg, IDC_DRIVELIST); - - SetFocus (hList); - - switch (LOWORD (GetSelectedLong (hList))) - { - case TC_MLIST_ITEM_FREE: - - // No mounted volume at this drive letter - - AppendMenuW (popup, MF_STRING, IDM_MOUNT_VOLUME, GetString ("IDM_MOUNT_VOLUME")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDPM_SELECT_FILE_AND_MOUNT, GetString ("SELECT_FILE_AND_MOUNT")); - AppendMenuW (popup, MF_STRING, IDPM_SELECT_DEVICE_AND_MOUNT, GetString ("SELECT_DEVICE_AND_MOUNT")); - break; - - case TC_MLIST_ITEM_NONSYS_VOL: - - // There's a mounted non-system volume at this drive letter - - AppendMenuW (popup, MF_STRING, IDM_UNMOUNT_VOLUME, GetString ("DISMOUNT")); - AppendMenuW (popup, MF_STRING, IDPM_OPEN_VOLUME, GetString ("OPEN")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDPM_CHECK_FILESYS, GetString ("IDPM_CHECK_FILESYS")); - AppendMenuW (popup, MF_STRING, IDPM_REPAIR_FILESYS, GetString ("IDPM_REPAIR_FILESYS")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDPM_ADD_TO_FAVORITES, GetString ("IDPM_ADD_TO_FAVORITES")); - AppendMenuW (popup, MF_STRING, IDPM_ADD_TO_SYSTEM_FAVORITES, GetString ("IDPM_ADD_TO_SYSTEM_FAVORITES")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_DECRYPT_NONSYS_VOL, GetString ("IDM_DECRYPT_NONSYS_VOL")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_VOLUME_PROPERTIES, GetString ("IDPM_PROPERTIES")); - break; - - case TC_MLIST_ITEM_SYS_PARTITION: - case TC_MLIST_ITEM_SYS_DRIVE: - - // System partition/drive - - PopulateSysEncContextMenu (popup, FALSE); - break; - } - - if (lParam) - { - mPos=GetMessagePos(); - } - else - { - POINT pt = {0}; - if (ListView_GetItemPosition (hList, nSelectedDriveIndex, &pt)) - { - pt.x += 2 + ::GetSystemMetrics(SM_CXICON); - pt.y += 2; - } - ClientToScreen (hList, &pt); - mPos = MAKELONG (pt.x, pt.y); - } - - menuItem = TrackPopupMenu (popup, - TPM_RETURNCMD | TPM_LEFTBUTTON, - GET_X_LPARAM(mPos), - GET_Y_LPARAM(mPos), - 0, - hwndDlg, - NULL); - - DestroyMenu (popup); - - switch (menuItem) - { - case IDPM_SELECT_FILE_AND_MOUNT: - if (SelectContainer (hwndDlg)) - MountSelectedVolume (hwndDlg, FALSE); - break; - - case IDPM_SELECT_DEVICE_AND_MOUNT: - if (SelectPartition (hwndDlg)) - MountSelectedVolume (hwndDlg, FALSE); - break; - - case IDPM_CHECK_FILESYS: - case IDPM_REPAIR_FILESYS: - { - LPARAM lLetter = GetSelectedLong (hList); - - if (LOWORD (lLetter) != 0xffff) - CheckFilesystem (hwndDlg, (wchar_t) HIWORD (lLetter) - L'A', menuItem == IDPM_REPAIR_FILESYS); - } - break; - - case IDM_UNMOUNT_VOLUME: - if (CheckMountList (hwndDlg, FALSE)) - Dismount (hwndDlg, -2); - break; - - case IDM_DECRYPT_NONSYS_VOL: - if (CheckMountList (hwndDlg, FALSE)) - DecryptNonSysDevice (hwndDlg, FALSE, TRUE); - break; - - case IDPM_OPEN_VOLUME: - { - LPARAM state; - if (lParam) - nSelectedDriveIndex = ((LPNMITEMACTIVATE)lParam)->iItem; - else - nSelectedDriveIndex = ListView_GetSelectionMark (hList); - state = GetItemLong (hList, nSelectedDriveIndex ); - - WaitCursor (); - OpenVolumeExplorerWindow (HIWORD(state) - L'A'); - NormalCursor (); - } - break; - - case IDM_VOLUME_PROPERTIES: - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, - (DLGPROC) VolumePropertiesDlgProc, (LPARAM) FALSE); - break; - - case IDM_MOUNT_VOLUME: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - mountOptions = defaultMountOptions; - bPrebootPasswordDlgMode = FALSE; - - if (CheckMountList (hwndDlg, FALSE)) - _beginthread(mountThreadFunction, 0, hwndDlg); - } - break; - - case IDPM_ADD_TO_FAVORITES: - case IDPM_ADD_TO_SYSTEM_FAVORITES: - { - LPARAM selectedDrive = GetSelectedLong (hList); - - if (LOWORD (selectedDrive) == TC_MLIST_ITEM_NONSYS_VOL) - AddMountedVolumeToFavorites (hwndDlg, HIWORD (selectedDrive) - L'A', menuItem == IDPM_ADD_TO_SYSTEM_FAVORITES); - } - break; - - default: - SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); - break; - } -} - - -/* Except in response to the WM_INITDIALOG and WM_ENDSESSION messages, the dialog box procedure - should return nonzero if it processes a message, and zero if it does not. */ -BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static UINT taskBarCreatedMsg; - WORD lw = LOWORD (wParam); - WORD hw = HIWORD (wParam); - - switch (uMsg) - { - case WM_HOTKEY: - - HandleHotKey (hwndDlg, wParam); - return 1; - - case WM_INITDIALOG: - { - int exitCode = 0; - - MainDlg = hwndDlg; - - if (IsTrueCryptInstallerRunning()) - AbortProcess ("TC_INSTALLER_IS_RUNNING"); - - // Set critical default options in case UsePreferences is false - bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = TRUE; - bShowDisconnectedNetworkDrives = FALSE; - bHideWaitingDialog = FALSE; - - ResetWrongPwdRetryCount (); - - ExtractCommandLine (hwndDlg, (wchar_t *) lParam); - - try - { - BootEncObj->SetParentWindow (hwndDlg); - BootEncStatus = BootEncObj->GetStatus(); - RecentBootEncStatus = BootEncStatus; - } - catch (...) - { - // NOP - } - - if (UsePreferences) - { - // General preferences - LoadSettings (hwndDlg); - - // Keyfiles - LoadDefaultKeyFilesParam (); - RestoreDefaultKeyFilesParam (); - } - - if (ComServerMode) - { - InitDialog (hwndDlg); - - if (!ComServerMain ()) - { - handleWin32Error (hwndDlg, SRC_POS); - exit (1); - } - exit (0); - } - - if (CmdMountOptionsValid) - mountOptions = CmdMountOptions; - - InitMainDialog (hwndDlg); - - try - { - if (IsHiddenOSRunning()) - { - uint32 driverConfig = ReadDriverConfigurationFlags(); - if (BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM) - Warning ("UPDATE_TC_IN_HIDDEN_OS_TOO", hwndDlg); - if ( !(driverConfig & TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION) - && !BootEncObj->CheckBootloaderFingerprint ()) - Warning ("BOOT_LOADER_FINGERPRINT_CHECK_FAILED", hwndDlg); - } - else if (SysDriveOrPartitionFullyEncrypted (TRUE)) - { - uint32 driverConfig = ReadDriverConfigurationFlags(); - if (BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM) - { - Warning ("BOOT_LOADER_VERSION_DIFFERENT_FROM_DRIVER_VERSION", hwndDlg); - } - if ( !(driverConfig & TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION) - && !BootEncObj->CheckBootloaderFingerprint ()) - Warning ("BOOT_LOADER_FINGERPRINT_CHECK_FAILED", hwndDlg); - } - } - catch (...) { } - - // Automount - if (bAuto || (Quit && szFileName[0] != 0)) - { - // No drive letter specified on command line - if (commandLineDrive == 0) - szDriveLetter[0] = (wchar_t) GetFirstAvailableDrive () + L'A'; - - if (bAutoMountDevices) - { - defaultMountOptions = mountOptions; - if (FirstCmdKeyFile) - { - KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles = TRUE; - KeyFileCloneAll (FirstCmdKeyFile, &FirstKeyFile); - KeyFileCloneAll (FirstCmdKeyFile, &defaultKeyFilesParam.FirstKeyFile); - } - - if (!MountAllDevices (hwndDlg, !Silent && !CmdVolumePasswordValid && IsPasswordCacheEmpty())) - exitCode = 1; - } - - if (bAutoMountFavorites) - { - defaultMountOptions = mountOptions; - if (FirstCmdKeyFile) - { - KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles = TRUE; - KeyFileCloneAll (FirstCmdKeyFile, &FirstKeyFile); - KeyFileCloneAll (FirstCmdKeyFile, &defaultKeyFilesParam.FirstKeyFile); - } - - if (!MountFavoriteVolumes (hwndDlg, FALSE, LogOn)) - exitCode = 1; - } - - if (szFileName[0] != 0 && !TranslateVolumeID (hwndDlg, szFileName, ARRAYSIZE (szFileName))) - { - exitCode = 1; - } - else if (szFileName[0] != 0 && !IsMountedVolume (szFileName)) - { - BOOL mounted = FALSE; - int EffectiveVolumePkcs5 = CmdVolumePkcs5; - BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; - BOOL bEffectiveTryEmptyPasswordWhenKeyfileUsed = bCmdTryEmptyPasswordWhenKeyfileUsedValid? bCmdTryEmptyPasswordWhenKeyfileUsed : bTryEmptyPasswordWhenKeyfileUsed; - - if (!VolumePathExists (szFileName)) - { - handleWin32Error (hwndDlg, SRC_POS); - } - else - { - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (EffectiveVolumePkcs5 == 0) - EffectiveVolumePkcs5 = DefaultVolumePkcs5; - if (!EffectiveVolumeTrueCryptMode) - EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; - - // Command line password or keyfiles - if (CmdVolumePassword.Length != 0 || (FirstCmdKeyFile && (CmdVolumePasswordValid || bEffectiveTryEmptyPasswordWhenKeyfileUsed))) - { - BOOL reportBadPasswd = CmdVolumePassword.Length > 0; - - if (FirstCmdKeyFile) - KeyFilesApplyWithPin (hwndDlg, &CmdVolumePassword, CmdTokenPin, FirstCmdKeyFile, szFileName); - - mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', - szFileName, &CmdVolumePassword, EffectiveVolumePkcs5, CmdVolumePim, EffectiveVolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, - &mountOptions, Silent, reportBadPasswd); - - burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); - } - else - { - // Cached password - mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, NULL, EffectiveVolumePkcs5, CmdVolumePim, EffectiveVolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); - } - - if (FirstCmdKeyFile) - { - KeyFileRemoveAll (&FirstKeyFile); - FirstKeyFile = FirstCmdKeyFile; - KeyFilesEnable = TRUE; - } - - // Ask user for password - while (!mounted && !Silent) - { - int GuiPkcs5 = EffectiveVolumePkcs5; - int GuiPim = CmdVolumePim; - BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode; - VolumePassword.Length = 0; - - StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume),szFileName); - if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &GuiTrueCryptMode, NULL, TRUE)) - break; - else - { - VolumePkcs5 = GuiPkcs5; - VolumePim = GuiPim; - VolumeTrueCryptMode = GuiTrueCryptMode; - burn (&GuiPkcs5, sizeof(GuiPkcs5)); - burn (&GuiPim, sizeof(GuiPim)); - burn (&GuiTrueCryptMode, sizeof(GuiTrueCryptMode)); - } - - WaitCursor (); - - if (KeyFilesEnable && FirstKeyFile) - KeyFilesApplyWithPin (hwndDlg, &VolumePassword, CmdTokenPin, FirstKeyFile, szFileName); - - mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, FALSE, TRUE); - - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); - burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); - - NormalCursor (); - } - } - - if (UsePreferences) - { - RestoreDefaultKeyFilesParam (); - bCacheInDriver = bCacheInDriverDefault; - } - - if (mounted > 0) - { - if (bBeep) - MessageBeep (0xFFFFFFFF); - - if (bExplore) - OpenVolumeExplorerWindow (szDriveLetter[0] - L'A'); - - RefreshMainDlg(hwndDlg); - - if(!Silent) - { - // Check for problematic file extensions (exe, dll, sys) - if (CheckFileExtension (szFileName)) - Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING", hwndDlg); - } - } - else - exitCode = 1; - } - else if (bExplore && GetMountedVolumeDriveNo (szFileName) != -1) - OpenVolumeExplorerWindow (GetMountedVolumeDriveNo (szFileName)); - else if (szFileName[0] != 0 && IsMountedVolume (szFileName)) - Warning ("VOL_ALREADY_MOUNTED", hwndDlg); - - if (!Quit) - RefreshMainDlg(hwndDlg); - } - - // Wipe cache - if (bWipe) - WipeCache (hwndDlg, Silent); - - // Wipe command line password - if (CmdVolumePassword.Length != 0) - { - burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); - CmdVolumePassword.Length = 0; - } - - // Wipe command line keyfiles - if (FirstCmdKeyFile) - { - if (defaultKeyFilesParam.FirstKeyFile) - KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); - - defaultKeyFilesParam.EnableKeyFiles = FALSE; - - if (!Quit) - { - LoadSettings (hwndDlg); - LoadDefaultKeyFilesParam (); - RestoreDefaultKeyFilesParam (); - } - } - - // Dismount - if (cmdUnmountDrive >= 0) - { - MOUNT_LIST_STRUCT mountList; - DWORD bytesReturned; - - if (DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, NULL, 0, &mountList, sizeof (mountList), &bytesReturned, NULL) - && (mountList.ulMountedDrives & (1 << cmdUnmountDrive)) == 0) - { - Error ("NO_VOLUME_MOUNTED_TO_DRIVE", hwndDlg); - exitCode = 1; - } - else if (!Dismount (hwndDlg, cmdUnmountDrive)) - exitCode = 1; - } - else if (cmdUnmountDrive == -1) - { - if (!DismountAll (hwndDlg, bForceUnmount, !Silent, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY)) - exitCode = 1; - } - - // TaskBar icon - if (bEnableBkgTask) - TaskBarIconAdd (hwndDlg); - - // Quit - if (Quit) - { - if (TaskBarIconMutex == NULL) - exit (exitCode); - - MainWindowHidden = TRUE; - - LoadSettings (hwndDlg); - LoadDefaultKeyFilesParam (); - RestoreDefaultKeyFilesParam (); - - if (!bEnableBkgTask) - { - if (TaskBarIconMutex) - TaskBarIconRemove (hwndDlg); - exit (exitCode); - } - } - - // No command line arguments or only /volume => bring active instance - // to foreground if available - if (NoCmdLineArgs == 0 || (CmdLineVolumeSpecified && NoCmdLineArgs <= 2)) - { - HWND h = hwndDlg; - EnumWindows (FindTCWindowEnum, (LPARAM) &h); - - if (h != hwndDlg - && (!IsAdmin() || (GetWindowLongPtrW (h, DWLP_USER) & TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES) != 0)) - { - if (CmdLineVolumeSpecified) - { - COPYDATASTRUCT cd; - memcpy (&cd.dwData, WM_COPY_SET_VOLUME_NAME, 4); - cd.lpData = szFileName; - cd.cbData = (DWORD) ((wcslen (szFileName) + 1) * sizeof (wchar_t)); - - SendMessage (h, WM_COPYDATA, (WPARAM)hwndDlg, (LPARAM)&cd); - } - - SendMessage (h, TC_APPMSG_MOUNT_SHOW_WINDOW, 0, 0); - - ShowWindow (h, SW_SHOW); - SetForegroundWindow (h); - - if (TaskBarIconMutex == NULL) - exit (0); - } - } - - HookMouseWheel (hwndDlg, IDC_VOLUME); - - // Register hot keys - if (!RegisterAllHotkeys (hwndDlg, Hotkeys) - && TaskBarIconMutex != NULL) // Warn only if we are the first instance of TrueCrypt - Warning("HOTKEY_REGISTRATION_ERROR", hwndDlg); - - Silent = FALSE; - - GetMountList (&LastKnownMountList); - SetTimer (hwndDlg, TIMER_ID_MAIN, TIMER_INTERVAL_MAIN, NULL); - - taskBarCreatedMsg = RegisterWindowMessage (L"TaskbarCreated"); - - AllowMessageInUIPI (taskBarCreatedMsg); - - SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - - /* Check system encryption status */ - - if (!Quit) // Do not care about system encryption or in-place encryption if we were launched from the system startup sequence (the wizard was added to it too). - { - if (SysEncryptionOrDecryptionRequired ()) - { - if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption - { - // We shouldn't block the mutex at this point - - if (SystemEncryptionStatus == SYSENC_STATUS_PRETEST - || AskWarnYesNo ("SYSTEM_ENCRYPTION_RESUME_PROMPT", hwndDlg) == IDYES) - { - // The wizard was not launched during the system startup seq, or the user may have forgotten - // to resume the encryption/decryption process. - - - LaunchVolCreationWizard (hwndDlg, L"/csysenc"); - } - } - } - - if (bInPlaceEncNonSysPending && !NonSysInplaceEncInProgressElsewhere()) - { - BOOL bDecrypt = FALSE; - if (AskNonSysInPlaceEncryptionResume(hwndDlg, &bDecrypt) == IDYES) - ResumeInterruptedNonSysInplaceEncProcess (bDecrypt); - } - } - - if (TaskBarIconMutex != NULL) - RegisterWtsNotification(hwndDlg); - DoPostInstallTasks (hwndDlg); - ResetCurrentDirectory (); - } - return 0; - - case WM_MOUSEWHEEL: - return HandleDriveListMouseWheelEvent (uMsg, wParam, lParam, FALSE); - - case WM_CONTEXTMENU: - { - HWND hList = GetDlgItem (hwndDlg, IDC_DRIVELIST); - // only handle if it is coming from keyboard and if the drive - // list has focus. The other cases are handled elsewhere - if ( (-1 == GET_X_LPARAM(lParam)) - && (-1 == GET_Y_LPARAM(lParam)) - && (GetFocus () == hList) - ) - { - INT item = ListView_GetSelectionMark (hList); - if (item >= 0) - { - nSelectedDriveIndex = item; - DisplayDriveListContextMenu (hwndDlg, NULL); - } - } - } - break; - - case WM_WINDOWPOSCHANGING: - if (MainWindowHidden) - { - // Prevent window from being shown - PWINDOWPOS wp = (PWINDOWPOS)lParam; - wp->flags &= ~SWP_SHOWWINDOW; - return 0; - } - return 1; - - case WM_SYSCOMMAND: - if (lw == IDC_ABOUT) - { - DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc); - return 1; - } - return 0; - - case WM_HELP: - OpenPageHelp (hwndDlg, 0); - return 1; - - case WM_WTSSESSION_CHANGE: - if (TaskBarIconMutex != NULL) - { - if (bDismountOnSessionLocked && ((WTS_SESSION_LOCK == wParam) || (WTS_CONSOLE_DISCONNECT == wParam) || (WTS_REMOTE_DISCONNECT == wParam))) - { - // Auto-dismount when session is locked - DWORD dwResult; - - if (bWipeCacheOnAutoDismount) - { - DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); - } - - DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); - } - } - return 0; - - case WM_ENDSESSION: - if (TaskBarIconMutex != NULL) - { - if (bDismountOnLogOff) - { - // Auto-dismount when user logs off - DWORD dwResult; - - if (bWipeCacheOnAutoDismount) - DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - - DismountAll (hwndDlg, bForceAutoDismount, FALSE, 1, 0); - } - - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - } - EndMainDlg (hwndDlg); - localcleanup (); - return 0; - - case WM_POWERBROADCAST: - if (wParam == PBT_APMSUSPEND - && TaskBarIconMutex != NULL && bDismountOnPowerSaving) - { - // Auto-dismount when entering power-saving mode - DWORD dwResult; - - if (bWipeCacheOnAutoDismount) - { - DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); - } - - DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); - } - return 0; - - case WM_TIMER: - { - // Check mount list and update GUI if needed - CheckMountList (hwndDlg, FALSE); - - // Cache status - if (IsPasswordCacheEmpty() == IsWindowEnabled (GetDlgItem (hwndDlg, IDC_WIPE_CACHE))) - EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty()); - - // Check driver warning flags - DWORD bytesOut; - GetWarningFlagsRequest warnings; - if (DeviceIoControl (hDriver, TC_IOCTL_GET_WARNING_FLAGS, NULL, 0, &warnings, sizeof (warnings), &bytesOut, NULL)) - { - if (warnings.SystemFavoriteVolumeDirty) - WarningTopMost ("SYS_FAVORITE_VOLUME_DIRTY", hwndDlg); - - if (warnings.PagingFileCreationPrevented) - WarningTopMost ("PAGING_FILE_CREATION_PREVENTED", hwndDlg); - } - - if (TaskBarIconMutex != NULL) - { - - // Idle auto-dismount - if (MaxVolumeIdleTime > 0) - DismountIdleVolumes (); - - // Screen saver auto-dismount - if (bDismountOnScreenSaver) - { - static BOOL previousState = FALSE; - BOOL running = FALSE; - SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0); - - if (running && !previousState) - { - DWORD dwResult; - previousState = TRUE; - - if (bWipeCacheOnAutoDismount) - { - DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); - } - - DismountAll (hwndDlg, bForceAutoDismount, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); - } - else - { - previousState = running; - } - } - - // Auto-mount favorite volumes on arrival -#if TIMER_INTERVAL_MAIN != 500 -#error TIMER_INTERVAL_MAIN != 500 -#endif - static int favoritesAutoMountTimerDivisor = 0; - if ((++favoritesAutoMountTimerDivisor & 1) && !FavoritesOnArrivalMountRequired.empty()) - { - static bool reentry = false; - if (reentry) - break; - - reentry = true; - - foreach (FavoriteVolume favorite, FavoritesOnArrivalMountRequired) - { - if (favorite.UseVolumeID) - { - if (IsMountedVolumeID (favorite.VolumeID)) - continue; - - std::wstring volDevPath = FindDeviceByVolumeID (favorite.VolumeID); - if (volDevPath.length() > 0) - { - favorite.Path = volDevPath; - favorite.DisconnectedDevice = false; - } - else - continue; - } - else if (!favorite.VolumePathId.empty()) - { - if (IsMountedVolume (favorite.Path.c_str())) - continue; - - wchar_t volDevPath[TC_MAX_PATH]; - if (QueryDosDevice (favorite.VolumePathId.substr (4, favorite.VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) == 0) - continue; - - favorite.DisconnectedDevice = false; - } - else if (favorite.Path.find (L"\\\\?\\Volume{") == 0) - { - wstring resolvedPath = VolumeGuidPathToDevicePath (favorite.Path); - if (resolvedPath.empty()) - continue; - - favorite.DisconnectedDevice = false; - favorite.VolumePathId = favorite.Path; - favorite.Path = resolvedPath; - } - - if (IsMountedVolume (favorite.Path.c_str())) - continue; - - if (!IsVolumeDeviceHosted (favorite.Path.c_str())) - { - if (!FileExists (favorite.Path.c_str())) - continue; - } - else if (favorite.VolumePathId.empty()) - continue; - - bool mountedAndNotDisconnected = false; - foreach (FavoriteVolume mountedFavorite, FavoritesMountedOnArrivalStillConnected) - { - if (favorite.Path == mountedFavorite.Path) - { - mountedAndNotDisconnected = true; - break; - } - } - - if (!mountedAndNotDisconnected) - { - FavoriteMountOnArrivalInProgress = TRUE; - MountFavoriteVolumes (hwndDlg, FALSE, FALSE, FALSE, favorite); - FavoriteMountOnArrivalInProgress = FALSE; - - FavoritesMountedOnArrivalStillConnected.push_back (favorite); - } - } - - bool deleted; - for (list ::iterator favorite = FavoritesMountedOnArrivalStillConnected.begin(); - favorite != FavoritesMountedOnArrivalStillConnected.end(); - deleted ? favorite : ++favorite) - { - deleted = false; - - if (IsMountedVolume (favorite->Path.c_str())) - continue; - - if (!IsVolumeDeviceHosted (favorite->Path.c_str())) - { - if (FileExists (favorite->Path.c_str())) - continue; - } - - wchar_t volDevPath[TC_MAX_PATH]; - if (favorite->VolumePathId.size() > 5 - && QueryDosDevice (favorite->VolumePathId.substr (4, favorite->VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) != 0) - { - continue; - } - - // set DisconnectedDevice field on FavoritesOnArrivalMountRequired element - foreach (FavoriteVolume onArrivalFavorite, FavoritesOnArrivalMountRequired) - { - if (onArrivalFavorite.Path == favorite->Path) - { - onArrivalFavorite.DisconnectedDevice = true; - break; - } - } - - favorite = FavoritesMountedOnArrivalStillConnected.erase (favorite); - deleted = true; - } - - reentry = false; - } - } - - // Exit background process in non-install mode or if no volume mounted - // and no other instance active - if (LastKnownMountList.ulMountedDrives == 0 - && MainWindowHidden -#ifndef _DEBUG - && (bCloseBkgTaskWhenNoVolumes || IsNonInstallMode ()) - && !SysEncDeviceActive (TRUE) -#endif - && GetDriverRefCount () < 2) - { - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - EndMainDlg (hwndDlg); - } - } - return 1; - - case TC_APPMSG_TASKBAR_ICON: - { - switch (lParam) - { - case WM_LBUTTONDOWN: - SetForegroundWindow (hwndDlg); - MainWindowHidden = FALSE; - ShowWindow (hwndDlg, SW_SHOW); - ShowWindow (hwndDlg, SW_RESTORE); - return 1; - - case WM_RBUTTONUP: - { - POINT pos; - HMENU popup = CreatePopupMenu (); - int sel, i, n; - - if (MainWindowHidden) - { - AppendMenuW (popup, MF_STRING, IDM_SHOW_HIDE, GetString ("SHOW_TC")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - } - else if (bEnableBkgTask - && (!(LastKnownMountList.ulMountedDrives == 0 - && (bCloseBkgTaskWhenNoVolumes || IsNonInstallMode ()) - && !SysEncDeviceActive (TRUE) - && GetDriverRefCount () < 2))) - { - AppendMenuW (popup, MF_STRING, IDM_SHOW_HIDE, GetString ("HIDE_TC")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - } - AppendMenuW (popup, MF_STRING, IDM_MOUNTALL, GetString ("IDC_MOUNTALL")); - AppendMenuW (popup, MF_STRING, IDM_MOUNT_FAVORITE_VOLUMES, GetString ("IDM_MOUNT_FAVORITE_VOLUMES")); - AppendMenuW (popup, MF_STRING, IDM_UNMOUNTALL, GetString ("IDC_UNMOUNTALL")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - - for (n = 0; n < 2; n++) - { - for (i = 0; i < 26; i++) - { - if (LastKnownMountList.ulMountedDrives & (1 << i)) - { - wchar_t s[1024]; - wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[i]; - - if (wcsstr (vol, L"\\??\\")) vol += 4; - - // first check label used for mounting. If empty, look for it in favorites. - bool useInExplorer = false; - wstring label = (wchar_t *) LastKnownMountList.wszLabel[i]; - if (label.empty()) - label = GetFavoriteVolumeLabel (vol, useInExplorer); - - StringCbPrintfW (s, sizeof(s), L"%s %c: (%s)", - GetString (n==0 ? "OPEN" : "DISMOUNT"), - i + L'A', - label.empty() ? vol : label.c_str()); - AppendMenuW (popup, MF_STRING, n*26 + TRAYICON_MENU_DRIVE_OFFSET + i, s); - } - } - if (LastKnownMountList.ulMountedDrives != 0) - AppendMenu (popup, MF_SEPARATOR, 0, L""); - } - - AppendMenuW (popup, MF_STRING, IDM_HELP, GetString ("MENU_HELP")); - AppendMenuW (popup, MF_STRING, IDM_HOMEPAGE_SYSTRAY, GetString ("HOMEPAGE")); - AppendMenuW (popup, MF_STRING, IDM_PREFERENCES, GetString ("IDM_PREFERENCES")); - AppendMenuW (popup, MF_STRING, IDM_ABOUT, GetString ("IDM_ABOUT")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDCANCEL, GetString ("EXIT")); - - GetCursorPos (&pos); - - SetForegroundWindow(hwndDlg); - - sel = TrackPopupMenu (popup, - TPM_RETURNCMD | TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, - pos.x, - pos.y, - 0, - hwndDlg, - NULL); - - if (sel >= TRAYICON_MENU_DRIVE_OFFSET && sel < TRAYICON_MENU_DRIVE_OFFSET + 26) - { - OpenVolumeExplorerWindow (sel - TRAYICON_MENU_DRIVE_OFFSET); - } - else if (sel >= TRAYICON_MENU_DRIVE_OFFSET + 26 && sel < TRAYICON_MENU_DRIVE_OFFSET + 26*2) - { - if (CheckMountList (hwndDlg, FALSE)) - { - if (Dismount (hwndDlg, sel - TRAYICON_MENU_DRIVE_OFFSET - 26)) - { - wchar_t txt [2048]; - StringCbPrintfW (txt, sizeof(txt), GetString ("VOLUME_MOUNTED_AS_DRIVE_LETTER_X_DISMOUNTED"), sel - TRAYICON_MENU_DRIVE_OFFSET - 26 + L'A'); - - InfoBalloonDirect (GetString ("SUCCESSFULLY_DISMOUNTED"), txt, hwndDlg); - } - } - } - else if (sel == IDM_SHOW_HIDE) - { - ChangeMainWindowVisibility (); - } - else if (sel == IDM_HOMEPAGE_SYSTRAY) - { - Applink ("home", TRUE, ""); - } - else if (sel == IDCANCEL) - { - if ((LastKnownMountList.ulMountedDrives == 0 - && !SysEncDeviceActive (TRUE)) - || AskWarnNoYes ("CONFIRM_EXIT", hwndDlg) == IDYES) - { - // Close all other TC windows - EnumWindows (CloseTCWindowsEnum, 0); - - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - SendMessage (hwndDlg, WM_COMMAND, sel, 0); - } - } - else - { - SendMessage (hwndDlg, WM_COMMAND, sel, 0); - } - - PostMessage(hwndDlg, WM_NULL, 0, 0); - DestroyMenu (popup); - } - return 1; - } - } - - return 0; - - case TC_APPMSG_CLOSE_BKG_TASK: - if (TaskBarIconMutex != NULL) - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - - return 1; - - case TC_APPMSG_SYSENC_CONFIG_UPDATE: - LoadSysEncSettings (); - - // The wizard added VeraCrypt.exe to the system startup sequence or performed other operations that - // require us to update our cached settings. - LoadSettings (hwndDlg); - - return 1; - - case WM_DEVICECHANGE: - if (!IgnoreWmDeviceChange && wParam != DBT_DEVICEARRIVAL) - { - // Check if any host device has been removed and force dismount of volumes accordingly - PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR) lParam; - int m; - - GetMountList (&LastKnownMountList); - - if (wParam == DBT_DEVICEREMOVECOMPLETE && hdr->dbch_devicetype == DBT_DEVTYP_VOLUME) - { - // File-hosted volumes - PDEV_BROADCAST_VOLUME vol = (PDEV_BROADCAST_VOLUME) lParam; - int i; - - for (i = 0; i < 26; i++) - { - if ((vol->dbcv_unitmask & (1 << i)) && !(GetUsedLogicalDrives() & (1 << i))) - { - for (m = 0; m < 26; m++) - { - if (LastKnownMountList.ulMountedDrives & (1 << m)) - { - wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[m]; - - if (wcsstr (vol, L"\\??\\") == vol) - vol += 4; - - if (vol[1] == L':' && i == (vol[0] - (vol[0] <= L'Z' ? L'A' : L'a'))) - { - UnmountVolume (hwndDlg, m, TRUE); - WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN", hwndDlg); - } - } - } - } - } - } - - // Device-hosted volumes - for (m = 0; m < 26; m++) - { - if (LastKnownMountList.ulMountedDrives & (1 << m)) - { - wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[m]; - - if (wcsstr (vol, L"\\??\\") == vol) - vol += 4; - - if (IsVolumeDeviceHosted (vol)) - { - OPEN_TEST_STRUCT ots = {0}; - - if (!OpenDevice (vol, &ots, FALSE, FALSE, NULL)) - { - UnmountVolume (hwndDlg, m, TRUE); - WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN", hwndDlg); - } - } - } - } - - // Favorite volumes - UpdateDeviceHostedFavoriteVolumes(); - - return 1; - } - return 0; - - case WM_NOTIFY: - - if(wParam == IDC_DRIVELIST) - { - if (((LPNMHDR) lParam)->code == NM_CUSTOMDRAW) - { - int width = ListView_GetColumnWidth (GetDlgItem (hwndDlg, IDC_DRIVELIST), 1); - if (width != LastDriveListVolumeColumnWidth) - { - LastDriveListVolumeColumnWidth = width; - LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); - } - return 0; - } - - /* Single click within drive list */ - if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED )) - { - nSelectedDriveIndex = ((LPNMLISTVIEW) lParam)->iItem; - EnableDisableButtons (hwndDlg); - return 1; - } - - /* Double click within drive list */ - if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE) - { - LPARAM state = GetItemLong (GetDlgItem (hwndDlg, IDC_DRIVELIST), ((LPNMITEMACTIVATE)lParam)->iItem ); - nSelectedDriveIndex = ((LPNMITEMACTIVATE)lParam)->iItem; - if (LOWORD(state) == TC_MLIST_ITEM_NONSYS_VOL || LOWORD(state) == TC_MLIST_ITEM_SYS_PARTITION) - { - // Open explorer window for mounted volume - WaitCursor (); - OpenVolumeExplorerWindow (HIWORD(state) - L'A'); - NormalCursor (); - } - else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) - { - mountOptions = defaultMountOptions; - bPrebootPasswordDlgMode = FALSE; - - if (GetAsyncKeyState (VK_CONTROL) < 0) - { - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (CmdVolumePkcs5 == 0) - mountOptions.ProtectedHidVolPkcs5Prf = DefaultVolumePkcs5; - else - mountOptions.ProtectedHidVolPkcs5Prf = CmdVolumePkcs5; - mountOptions.ProtectedHidVolPim = CmdVolumePim; - - if (IDCANCEL == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, - (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions)) - return 1; - - if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) - { - wchar_t selectedVolume [TC_MAX_PATH + 1]; - GetVolumePath (hwndDlg, selectedVolume, ARRAYSIZE (selectedVolume)); - KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, selectedVolume); - } - } - - if (CheckMountList (hwndDlg, FALSE)) - _beginthread(mountThreadFunction, 0, hwndDlg); - } - return 1; - } - - /* Right click and drag&drop operations */ - - switch (((NM_LISTVIEW *) lParam)->hdr.code) - { - case NM_RCLICK: - case LVN_BEGINRDRAG: - /* If the mouse was moving while the right mouse button is pressed, popup menu would - not open, because drag&drop operation would be initiated. Therefore, we're handling - RMB drag-and-drop operations as well. */ - { - - DisplayDriveListContextMenu (hwndDlg, lParam); - - return 1; - } - } - } - return 0; - - case WM_ERASEBKGND: - return 0; - - case WM_COMMAND: - - if (lw == IDCANCEL || lw == IDC_EXIT) - { - EndMainDlg (hwndDlg); - return 1; - } - - if (lw == IDHELP || lw == IDM_HELP) - { - OpenPageHelp (hwndDlg, 0); - return 1; - } - - if (lw == IDM_ABOUT || lw == IDC_LOGO) - { - DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc); - return 1; - } - - if (lw == IDOK && LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_NONSYS_VOL - || lw == IDM_UNMOUNT_VOLUME) - { - if (lw == IDM_UNMOUNT_VOLUME && LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) != TC_MLIST_ITEM_NONSYS_VOL) - { - Warning ("SELECT_A_MOUNTED_VOLUME", hwndDlg); - return 1; - } - - if (CheckMountList (hwndDlg, FALSE)) - Dismount (hwndDlg, -2); - return 1; - } - - if ((lw == IDOK || lw == IDM_MOUNT_VOLUME || lw == IDM_MOUNT_VOLUME_OPTIONS || lw == IDC_MOUNTALL || lw == IDM_MOUNTALL) - && LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == 0xffff) - { - MessageBoxW (hwndDlg, GetString ("SELECT_FREE_DRIVE"), L"VeraCrypt", MB_ICONEXCLAMATION); - return 1; - } - - if ((lw == IDOK || lw == IDM_MOUNT_VOLUME || lw == IDM_MOUNT_VOLUME_OPTIONS)) - { - MountSelectedVolume (hwndDlg, lw == IDM_MOUNT_VOLUME_OPTIONS); - return 1; - } - - if (lw == IDC_UNMOUNTALL || lw == IDM_UNMOUNTALL) - { - if (DismountAll (hwndDlg, bForceUnmount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY) - && lw == IDM_UNMOUNTALL) // If initiated via the systray menu - { - InfoBalloon ("SUCCESSFULLY_DISMOUNTED", "MOUNTED_VOLUMES_DISMOUNTED", hwndDlg); - } - - return 1; - } - - if (lw == IDC_MOUNTALL || lw == IDM_MOUNTALL) - { - // If Shift key is down and the password cache isn't empty, bypass password prompt - MountAllDevices (hwndDlg, !(GetAsyncKeyState (VK_SHIFT) < 0 && !IsPasswordCacheEmpty())); - return 1; - } - - if (lw == IDC_SELECT_FILE || lw == IDM_SELECT_FILE) - { - SelectContainer (hwndDlg); - return 1; - } - - if (lw == IDC_SELECT_DEVICE || lw == IDM_SELECT_DEVICE) - { - SelectPartition (hwndDlg); - return 1; - } - - // System Encryption menu - switch (lw) - { - case IDM_ENCRYPT_SYSTEM_DEVICE: - EncryptSystemDevice (hwndDlg); - break; - case IDM_PERMANENTLY_DECRYPT_SYS: - DecryptSystemDevice (hwndDlg); - break; - case IDM_CREATE_HIDDEN_OS: - CreateHiddenOS (hwndDlg); - break; - case IDM_SYSENC_RESUME: - ResumeInterruptedSysEncProcess (hwndDlg); - break; - case IDM_SYSTEM_ENCRYPTION_STATUS: - ShowSystemEncryptionStatus (hwndDlg); - break; - case IDM_CHANGE_SYS_PASSWORD: - ChangeSysEncPassword (hwndDlg, FALSE); - break; - case IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO: - ChangeSysEncPassword (hwndDlg, TRUE); - break; - case IDM_CREATE_RESCUE_DISK: - CreateRescueDisk (hwndDlg); - break; - case IDM_VERIFY_RESCUE_DISK: - VerifyRescueDisk (hwndDlg, false); - break; - case IDM_VERIFY_RESCUE_DISK_ISO: - VerifyRescueDisk (hwndDlg, true); - break; - case IDM_MOUNT_SYSENC_PART_WITHOUT_PBA: - - if (CheckSysEncMountWithoutPBA (hwndDlg, L"", FALSE)) - { - mountOptions = defaultMountOptions; - mountOptions.PartitionInInactiveSysEncScope = TRUE; - bPrebootPasswordDlgMode = TRUE; - - if (CheckMountList (hwndDlg, FALSE)) - _beginthread(mountThreadFunction, 0, hwndDlg); - } - break; - } - - if (lw == IDC_VOLUME_TOOLS) - { - /* Volume Tools popup menu */ - - int menuItem; - wchar_t volPath[TC_MAX_PATH]; /* Volume to mount */ - HMENU popup = CreatePopupMenu (); - RECT rect; - - if (ActiveSysEncDeviceSelected ()) - { - PopulateSysEncContextMenu (popup, TRUE); - } - else - { - AppendMenuW (popup, MF_STRING, IDM_CHANGE_PASSWORD, GetString ("IDM_CHANGE_PASSWORD")); - AppendMenuW (popup, MF_STRING, IDM_CHANGE_HEADER_KEY_DERIV_ALGO, GetString ("IDM_CHANGE_HEADER_KEY_DERIV_ALGO")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_ADD_REMOVE_VOL_KEYFILES, GetString ("IDM_ADD_REMOVE_VOL_KEYFILES")); - AppendMenuW (popup, MF_STRING, IDM_REMOVE_ALL_KEYFILES_FROM_VOL, GetString ("IDM_REMOVE_ALL_KEYFILES_FROM_VOL")); - AppendMenu (popup, MF_SEPARATOR, 0, L""); - AppendMenuW (popup, MF_STRING, IDM_DECRYPT_NONSYS_VOL, GetString ("IDM_DECRYPT_NONSYS_VOL")); - AppendMenu (popup, MF_SEPARATOR, 0, NULL); - AppendMenuW (popup, MF_STRING, IDM_BACKUP_VOL_HEADER, GetString ("IDM_BACKUP_VOL_HEADER")); - AppendMenuW (popup, MF_STRING, IDM_RESTORE_VOL_HEADER, GetString ("IDM_RESTORE_VOL_HEADER")); - } - - GetWindowRect (GetDlgItem (hwndDlg, IDC_VOLUME_TOOLS), &rect); - - menuItem = TrackPopupMenu (popup, - TPM_RETURNCMD | TPM_LEFTBUTTON, - rect.left + 2, - rect.top + 2, - 0, - hwndDlg, - NULL); - - DestroyMenu (popup); - - switch (menuItem) - { - case IDM_DECRYPT_NONSYS_VOL: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - DecryptNonSysDevice (hwndDlg, TRUE, FALSE); - } - break; - - case IDM_CHANGE_PASSWORD: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; - ChangePassword (hwndDlg); - } - break; - - case IDM_CHANGE_HEADER_KEY_DERIV_ALGO: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; - ChangePassword (hwndDlg); - } - break; - - case IDM_ADD_REMOVE_VOL_KEYFILES: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - pwdChangeDlgMode = PCDM_ADD_REMOVE_VOL_KEYFILES; - ChangePassword (hwndDlg); - } - break; - - case IDM_REMOVE_ALL_KEYFILES_FROM_VOL: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - pwdChangeDlgMode = PCDM_REMOVE_ALL_KEYFILES_FROM_VOL; - ChangePassword (hwndDlg); - } - break; - - case IDM_BACKUP_VOL_HEADER: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); - - WaitCursor (); - - int iStatus = 0; - BackupHeaderThreadParam threadParam; - threadParam.bRequireConfirmation = TRUE; - threadParam.lpszVolume = volPath; - threadParam.cchVolume = ARRAYSIZE (volPath); - threadParam.iResult = &iStatus; - - ShowWaitDialog (hwndDlg, TRUE, BackupHeaderWaitThreadProc, &threadParam); - - NormalCursor (); - } - break; - - case IDM_RESTORE_VOL_HEADER: - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); - - WaitCursor (); - - int iStatus = 0; - RestoreHeaderThreadParam threadParam; - threadParam.lpszVolume = volPath; - threadParam.cchVolume = ARRAYSIZE (volPath); - threadParam.iResult = &iStatus; - - ShowWaitDialog(hwndDlg, TRUE, RestoreHeaderWaitThreadProc, &threadParam); - - NormalCursor (); - } - break; - - default: - SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); - break; - } - return 1; - } - - if (lw == IDM_DECRYPT_NONSYS_VOL) - { - LPARAM selectedDrive = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - - if (LOWORD (selectedDrive) == TC_MLIST_ITEM_FREE && !VolumeSelected (MainDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - DecryptNonSysDevice (hwndDlg, TRUE, FALSE); - } - - return 1; - } - - if (lw == IDM_CHANGE_PASSWORD) - { - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - if (ActiveSysEncDeviceSelected ()) - { - ChangeSysEncPassword (hwndDlg, FALSE); - } - else - { - pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; - ChangePassword (hwndDlg); - } - } - return 1; - } - - if (lw == IDM_CHANGE_HEADER_KEY_DERIV_ALGO) - { - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - if (ActiveSysEncDeviceSelected ()) - { - ChangeSysEncPassword (hwndDlg, TRUE); - } - else - { - pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; - ChangePassword (hwndDlg); - } - } - return 1; - } - - if (lw == IDC_WIPE_CACHE || lw == IDM_WIPE_CACHE) - { - WipeCache (hwndDlg, FALSE); - return 1; - } - - if (lw == IDM_CLEAR_HISTORY) - { - ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); - EnableDisableButtons (hwndDlg); - return 1; - } - - if (lw == IDC_CREATE_VOLUME || lw == IDM_CREATE_VOLUME || lw == IDM_VOLUME_WIZARD) - { - LaunchVolCreationWizard (hwndDlg, L""); - return 1; - } - - if (lw == IDM_VOLUME_EXPANDER) - { - LaunchVolExpander (hwndDlg); - return 1; - } - - if (lw == IDM_ADD_REMOVE_VOL_KEYFILES) - { - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - pwdChangeDlgMode = PCDM_ADD_REMOVE_VOL_KEYFILES; - ChangePassword (hwndDlg); - } - return 1; - } - - if (lw == IDM_REMOVE_ALL_KEYFILES_FROM_VOL) - { - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - pwdChangeDlgMode = PCDM_REMOVE_ALL_KEYFILES_FROM_VOL; - ChangePassword (hwndDlg); - } - return 1; - } - - if (lw == IDM_MANAGE_TOKEN_KEYFILES) - { - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, NULL); - return 1; - } - - if (lw == IDM_CLOSE_ALL_TOKEN_SESSIONS) - { - { - WaitCursor(); - finally_do ({ NormalCursor(); }); - - SecurityToken::CloseAllSessions(); - } - - InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg); - - return 1; - } - - if (lw == IDM_KEYFILE_GENERATOR) - { - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_KEYFILE_GENERATOR), hwndDlg, - (DLGPROC) KeyfileGeneratorDlgProc, (LPARAM) 0); - - return 1; - } - - if (lw == IDM_DONATE) - { - Applink ("donate", TRUE, ""); - return 1; - } - - if (lw == IDM_LICENSE) - { - TextInfoDialogBox (TC_TBXID_LEGAL_NOTICES); - return 1; - } - - if (lw == IDM_WEBSITE) - { - Applink ("website", TRUE, ""); - return 1; - } - else if (lw == IDM_HOMEPAGE) - { - Applink ("homepage", TRUE, ""); - return 1; - } - else if (lw == IDM_ONLINE_TUTORIAL) - { - Applink ("tutorial", TRUE, ""); - return 1; - } - else if (lw == IDM_ONLINE_HELP) - { - OpenOnlineHelp (); - return 1; - } - else if (lw == IDM_FAQ) - { - Applink ("faq", TRUE, ""); - return 1; - } - else if (lw == IDM_TC_DOWNLOADS) - { - Applink ("downloads", TRUE, ""); - return 1; - } - else if (lw == IDM_NEWS) - { - Applink ("news", TRUE, ""); - return 1; - } - else if (lw == IDM_VERSION_HISTORY) - { - Applink ("history", TRUE, ""); - return 1; - } - else if (lw == IDM_CONTACT) - { - Applink ("contact", FALSE, ""); - return 1; - } - - if (lw == IDM_PREFERENCES) - { - if (IDOK == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_PREFERENCES_DLG), hwndDlg, - (DLGPROC) PreferencesDlgProc, (LPARAM) 0)) - { - if (bEnableBkgTask) - { - TaskBarIconAdd (hwndDlg); - RegisterWtsNotification(hwndDlg); - } - else - { - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - if (MainWindowHidden) - EndMainDlg (hwndDlg); - } - } - return 1; - } - - if (lw == IDM_HOTKEY_SETTINGS) - { - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_HOTKEYS_DLG), hwndDlg, - (DLGPROC) HotkeysDlgProc, (LPARAM) 0); - return 1; - } - - if (lw == IDM_PERFORMANCE_SETTINGS) - { - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_PERFORMANCE_SETTINGS), hwndDlg, (DLGPROC) PerformanceSettingsDlgProc, 0); - return 1; - } - - if (lw == IDM_DEFAULT_KEYFILES) - { - KeyfileDefaultsDlg (hwndDlg); - return 1; - } - - if (lw == IDM_DEFAULT_MOUNT_PARAMETERS) - { - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_DEFAULT_MOUNT_PARAMETERS), hwndDlg, (DLGPROC) DefaultMountParametersDlgProc, 0); - return 1; - } - - if (lw == IDM_ADD_VOLUME_TO_FAVORITES || lw == IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES) - { - LPARAM selectedDrive = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - - wchar_t volPathLower[TC_MAX_PATH]; - - // volPathLower will contain the volume path (if any) from the input field below the drive list - GetVolumePath (hwndDlg, volPathLower, ARRAYSIZE (volPathLower)); - - if (LOWORD (selectedDrive) != TC_MLIST_ITEM_NONSYS_VOL - && !(VolumeSelected (hwndDlg) && IsMountedVolume (volPathLower))) - { - Warning ("SELECT_A_MOUNTED_VOLUME", hwndDlg); - - return 1; - } - - int driveNo; - - if (VolumeSelected (hwndDlg) - && IsMountedVolume (volPathLower)) - { - TranslateVolumeID (hwndDlg, volPathLower, ARRAYSIZE (volPathLower)); - - if (LOWORD (selectedDrive) != TC_MLIST_ITEM_NONSYS_VOL) - { - driveNo = GetMountedVolumeDriveNo (volPathLower); - } - else - { - /* We need to resolve selection ambiguity. Two different mounted volumes are currently - selected (one in the drive letter list and the other in the input field below the list). */ - - VOLUME_PROPERTIES_STRUCT prop; - DWORD dwResult; - - memset (&prop, 0, sizeof(prop)); - prop.driveNo = HIWORD (selectedDrive) - L'A'; - - if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) - { - Warning ("SELECT_A_MOUNTED_VOLUME", hwndDlg); - return 1; - } - - // volPathHigher will contain the volume path selected in the main drive list - wstring volPathHigher (prop.wszVolume); - - if (wcscmp (((wmemcmp (prop.wszVolume, L"\\??\\", 4) == 0) ? (wchar_t *) prop.wszVolume + 4 : prop.wszVolume), volPathLower) != 0) - { - // The path selected in the input field is different from the path to the volume selected - // in the drive lettter list. We have to resolve possible ambiguity. - - wchar_t *tmp[] = {L"", L"", L"", L"", L"", 0}; - const int maxVolPathLen = 80; - - if (volPathHigher.length () > maxVolPathLen) - { - volPathHigher = wstring (L"...") + volPathHigher.substr (volPathHigher.length () - maxVolPathLen, maxVolPathLen); - } - - wstring volPathLowerWStr (volPathLower); - - if (volPathLowerWStr.length () > maxVolPathLen) - { - volPathLowerWStr = wstring (L"...") + volPathLowerWStr.substr (volPathLowerWStr.length () - maxVolPathLen, maxVolPathLen); - } - - tmp[1] = GetString ("AMBIGUOUS_VOL_SELECTION"); - tmp[2] = (wchar_t *) volPathHigher.c_str(); - tmp[3] = (wchar_t *) volPathLowerWStr.c_str(); - tmp[4] = GetString ("IDCANCEL"); - - switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg)) - { - case 1: - driveNo = HIWORD (selectedDrive) - L'A'; - break; - - case 2: - driveNo = GetMountedVolumeDriveNo (volPathLower); - break; - - default: - return 1; - } - } - else - { - driveNo = HIWORD (selectedDrive) - L'A'; - } - } - } - else - { - driveNo = HIWORD (selectedDrive) - L'A'; - } - - AddMountedVolumeToFavorites (hwndDlg, driveNo, lw == IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES); - - return 1; - } - - if (lw == IDM_ORGANIZE_FAVORITES || lw == IDM_ORGANIZE_SYSTEM_FAVORITES) - { - OrganizeFavoriteVolumes (hwndDlg, lw == IDM_ORGANIZE_SYSTEM_FAVORITES); - return 1; - } - - if (lw == IDM_TOKEN_PREFERENCES) - { - SecurityTokenPreferencesDialog (hwndDlg); - return 1; - } - - if (lw == IDM_SYSENC_SETTINGS || lw == IDM_SYS_ENC_SETTINGS) - { - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_SETTINGS), hwndDlg, (DLGPROC) BootLoaderPreferencesDlgProc, 0); - return 1; - } - - if (lw == IDM_SYS_FAVORITES_SETTINGS) - { - OrganizeFavoriteVolumes (hwndDlg, true); - return 1; - } - - if (lw == IDM_BENCHMARK) - { - Benchmark (hwndDlg); - return 1; - } - - if (lw == IDM_TRAVELER) - { - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_TRAVELER_DLG), hwndDlg, - (DLGPROC) TravelerDlgProc, (LPARAM) 0); - return 1; - } - - if (lw == IDM_BACKUP_VOL_HEADER) - { - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - wchar_t volPath[TC_MAX_PATH]; /* Volume to mount */ - - GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); - - WaitCursor (); - - int iStatus = 0; - BackupHeaderThreadParam threadParam; - threadParam.bRequireConfirmation = TRUE; - threadParam.lpszVolume = volPath; - threadParam.cchVolume = ARRAYSIZE (volPath); - threadParam.iResult = &iStatus; - - ShowWaitDialog (hwndDlg, TRUE, BackupHeaderWaitThreadProc, &threadParam); - - NormalCursor (); - } - return 1; - } - - if (lw == IDM_RESTORE_VOL_HEADER) - { - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else - { - wchar_t volPath[TC_MAX_PATH]; /* Volume to mount */ - - GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); - - WaitCursor (); - - int iStatus = 0; - RestoreHeaderThreadParam threadParam; - threadParam.lpszVolume = volPath; - threadParam.cchVolume = ARRAYSIZE (volPath); - threadParam.iResult = &iStatus; - - ShowWaitDialog(hwndDlg, TRUE, RestoreHeaderWaitThreadProc, &threadParam); - - NormalCursor (); - } - return 1; - } - - if (lw == IDM_LANGUAGE) - { - BOOL p; - if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_LANGUAGE), hwndDlg, - (DLGPROC) LanguageDlgProc, (LPARAM) 0) == IDOK) - { - LoadLanguageFile (); - SaveSettings (hwndDlg); - - p = LocalizationActive; - LocalizationActive = TRUE; - InitMainDialog (hwndDlg); - InvalidateRect (hwndDlg, NULL, FALSE); - LocalizationActive = p; - DrawMenuBar (hwndDlg); - } - return 1; - } - - if (lw == IDM_TEST_VECTORS) - { - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_CIPHER_TEST_DLG), hwndDlg, (DLGPROC) CipherTestDialogProc, (LPARAM) 1); - return 1; - } - - if (lw == IDM_REFRESH_DRIVE_LETTERS) - { - DWORD driveMap = GetUsedLogicalDrives (); - - WaitCursor (); - - if (!(nCurrentOS == WIN_2000 && RemoteSession)) - { - BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, ~driveMap); - Sleep (100); - BroadcastDeviceChange (DBT_DEVICEARRIVAL, 0, driveMap); - } - - LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); - - if (nSelectedDriveIndex >= 0) - { - SelectItem (GetDlgItem (hwndDlg, IDC_DRIVELIST), - (wchar_t) HIWORD (GetItemLong (GetDlgItem (hwndDlg, IDC_DRIVELIST), nSelectedDriveIndex))); - } - - NormalCursor (); - return 1; - } - - if (lw == IDM_MOUNT_FAVORITE_VOLUMES) - { - _beginthread(mountFavoriteVolumeThreadFunction, 0, NULL); - return 1; - } - - if (lw == IDM_RESUME_INTERRUPTED_PROC) - { - // Ask the user to select encryption, decryption, or cancel - BOOL bDecrypt = FALSE; - char *tmpStr[] = {0, - "CHOOSE_ENCRYPT_OR_DECRYPT", - "ENCRYPT", - "DECRYPT", - "IDCANCEL", - 0}; - - switch (AskMultiChoice ((void **) tmpStr, FALSE, hwndDlg)) - { - case 1: - bDecrypt = FALSE; - break; - case 2: - bDecrypt = TRUE; - break; - default: - return 1; - } - ResumeInterruptedNonSysInplaceEncProcess (bDecrypt); - return 1; - } - - if (lw == IDC_VOLUME_PROPERTIES || lw == IDM_VOLUME_PROPERTIES) - { - DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, - (DLGPROC) VolumePropertiesDlgProc, (LPARAM) 0); - return 1; - } - - if (lw == IDC_VOLUME && hw == CBN_EDITCHANGE) - { - EnableDisableButtons (hwndDlg); - return 1; - } - - if (lw == IDC_VOLUME && hw == CBN_SELCHANGE) - { - UpdateComboOrder (GetDlgItem (hwndDlg, IDC_VOLUME)); - MoveEditToCombo ((HWND) lParam, bHistory); - PostMessage (hwndDlg, TC_APPMSG_MOUNT_ENABLE_DISABLE_CONTROLS, 0, 0); - return 1; - } - - if (lw == IDC_NO_HISTORY) - { - if (!(bHistory = !IsButtonChecked (GetDlgItem (hwndDlg, IDC_NO_HISTORY)))) - ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); - - return 1; - } - - if (lw >= TC_FAVORITE_MENU_CMD_ID_OFFSET && lw < TC_FAVORITE_MENU_CMD_ID_OFFSET_END) - { - size_t favoriteIndex = lw - TC_FAVORITE_MENU_CMD_ID_OFFSET; - - if (favoriteIndex < FavoriteVolumes.size()) - { - if ((FavoriteVolumes[favoriteIndex].UseVolumeID && IsMountedVolumeID (FavoriteVolumes[favoriteIndex].VolumeID)) - || (!FavoriteVolumes[favoriteIndex].UseVolumeID && IsMountedVolume (FavoriteVolumes[favoriteIndex].Path.c_str())) - ) - { - std::wstring volName; - WaitCursor(); - if (FavoriteVolumes[favoriteIndex].UseVolumeID) - volName = FindDeviceByVolumeID (FavoriteVolumes[favoriteIndex].VolumeID); - else - volName = FavoriteVolumes[favoriteIndex].Path; - OpenVolumeExplorerWindow (GetMountedVolumeDriveNo ((wchar_t*) FavoriteVolumes[favoriteIndex].Path.c_str())); - NormalCursor(); - } - else - { - mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) calloc(1, sizeof(mountFavoriteVolumeThreadParam)); - pParam->systemFavorites = FALSE; - pParam->logOnMount = FALSE; - pParam->hotKeyMount = FALSE; - pParam->favoriteVolumeToMount = &FavoriteVolumes[favoriteIndex]; - - _beginthread(mountFavoriteVolumeThreadFunction, 0, pParam); - } - } - - return 1; - } - - return 0; - - case WM_DROPFILES: - { - HDROP hdrop = (HDROP) wParam; - DragQueryFile (hdrop, 0, szFileName, ARRAYSIZE (szFileName)); - DragFinish (hdrop); - - AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); - EnableDisableButtons (hwndDlg); - SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - } - return 1; - - case TC_APPMSG_MOUNT_ENABLE_DISABLE_CONTROLS: - EnableDisableButtons (hwndDlg); - return 1; - - case TC_APPMSG_MOUNT_SHOW_WINDOW: - MainWindowHidden = FALSE; - ShowWindow (hwndDlg, SW_SHOW); - ShowWindow (hwndDlg, SW_RESTORE); - return 1; - - case WM_COPYDATA: - { - PCOPYDATASTRUCT cd = (PCOPYDATASTRUCT)lParam; - if (memcmp (&cd->dwData, WM_COPY_SET_VOLUME_NAME, 4) == 0) - { - if (cd->cbData > 0) - { - ((wchar_t *) cd->lpData)[(cd->cbData / sizeof (wchar_t)) - 1] = 0; - AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), (wchar_t *)cd->lpData, bHistory); - } - - EnableDisableButtons (hwndDlg); - SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); - } - } - return 1; - - case WM_CLOSE: - EndMainDlg (hwndDlg); - return 1; - - case WM_INITMENUPOPUP: - { - // disable "Set Header Key Derivation Algorithm" entry in "Volumes" menu - // "Volumes" menu is the first (index 0) submenu of the main menu - if ((HMENU) wParam == GetSubMenu (GetMenu (hwndDlg), 0)) - { - if (ActiveSysEncDeviceSelected ()) - EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_HEADER_KEY_DERIV_ALGO, MF_GRAYED); - else - EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_HEADER_KEY_DERIV_ALGO, MF_ENABLED); - } - } - return 1; - - default: - // Recreate tray icon if Explorer restarted - if (taskBarCreatedMsg != 0 && uMsg == taskBarCreatedMsg && TaskBarIconMutex != NULL) - { - TaskBarIconRemove (hwndDlg); - TaskBarIconAdd (hwndDlg); - CheckMountList(hwndDlg, TRUE); - return 1; - } - } - - return 0; -} - -void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) -{ - wchar_t **lpszCommandLineArgs = NULL; /* Array of command line arguments */ - int nNoCommandLineArgs; /* The number of arguments in the array */ - wchar_t tmpPath[MAX_PATH * 2]; - - /* Defaults */ - mountOptions.PreserveTimestamp = TRUE; - - if (_wcsicmp (lpszCommandLine, L"-Embedding") == 0) - { - ComServerMode = TRUE; - return; - } - - /* Extract command line arguments */ - NoCmdLineArgs = nNoCommandLineArgs = Win32CommandLine (&lpszCommandLineArgs); - - if (nNoCommandLineArgs > 0) - { - int i; - - for (i = 0; i < nNoCommandLineArgs; i++) - { - enum - { - OptionAuto, - OptionBeep, - OptionCache, - CommandDismount, - OptionExplore, - OptionForce, - CommandHelp, - OptionHistory, - OptionKeyfile, - OptionLetter, - OptionMountOption, - OptionPassword, - OptionQuit, - OptionSilent, - OptionTokenLib, - OptionTokenPin, - OptionVolume, - CommandWipeCache, - OptionPkcs5, - OptionTrueCryptMode, - OptionPim, - OptionTryEmptyPassword, - OptionNoWaitDlg, - }; - - argument args[]= - { - { OptionAuto, L"/auto", L"/a", FALSE }, - { OptionBeep, L"/beep", L"/b", FALSE }, - { OptionCache, L"/cache", L"/c", FALSE }, - { CommandDismount, L"/dismount", L"/d", FALSE }, - { OptionExplore, L"/explore", L"/e", FALSE }, - { OptionForce, L"/force", L"/f", FALSE }, - { OptionPkcs5, L"/hash", NULL , FALSE }, - { CommandHelp, L"/help", L"/?", FALSE }, - { OptionHistory, L"/history", L"/h", FALSE }, - { OptionKeyfile, L"/keyfile", L"/k", FALSE }, - { OptionLetter, L"/letter", L"/l", FALSE }, - { OptionMountOption, L"/mountoption", L"/m", FALSE }, - { OptionPassword, L"/password", L"/p", FALSE }, - { OptionPim, L"/pim", NULL, FALSE }, - { OptionQuit, L"/quit", L"/q", FALSE }, - { OptionSilent, L"/silent", L"/s", FALSE }, - { OptionTokenLib, L"/tokenlib", NULL, FALSE }, - { OptionTokenPin, L"/tokenpin", NULL, FALSE }, - { OptionTrueCryptMode, L"/truecrypt", L"/tc", FALSE }, - { OptionVolume, L"/volume", L"/v", FALSE }, - { CommandWipeCache, L"/wipecache", L"/w", FALSE }, - { OptionTryEmptyPassword, L"/tryemptypass", NULL, FALSE }, - { OptionNoWaitDlg, L"/nowaitdlg", NULL, FALSE }, - }; - - argumentspec as; - - as.args = args; - as.arg_cnt = sizeof(args)/ sizeof(args[0]); - - switch (GetArgumentID (&as, lpszCommandLineArgs[i])) - { - case OptionAuto: - { - wchar_t szTmp[32] = {0}; - bAuto = TRUE; - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, - &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp (szTmp, L"devices")) - bAutoMountDevices = TRUE; - else if (!_wcsicmp (szTmp, L"favorites")) - bAutoMountFavorites = TRUE; - else if (!_wcsicmp (szTmp, L"logon")) - LogOn = TRUE; - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - } - break; - - case OptionBeep: - bBeep = TRUE; - break; - - case OptionTryEmptyPassword: - { - wchar_t szTmp[16] = {0}; - bCmdTryEmptyPasswordWhenKeyfileUsed = TRUE; - bCmdTryEmptyPasswordWhenKeyfileUsedValid = TRUE; - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) - bCmdTryEmptyPasswordWhenKeyfileUsed = FALSE; - else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) - bCmdTryEmptyPasswordWhenKeyfileUsed = TRUE; - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - } - break; - - case OptionNoWaitDlg: - { - wchar_t szTmp[16] = {0}; - bCmdHideWaitingDialog = TRUE; - bCmdHideWaitingDialogValid = TRUE; - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) - bCmdHideWaitingDialog = FALSE; - else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) - bCmdHideWaitingDialog = TRUE; - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - } - break; - - case OptionCache: - { - wchar_t szTmp[16] = {0}; - bCacheInDriver = TRUE; - bIncludePimInCache = FALSE; - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) - bCacheInDriver = FALSE; - else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) - bCacheInDriver = TRUE; - else if (!_wcsicmp(szTmp,L"p") || !_wcsicmp(szTmp,L"pim")) - { - bCacheInDriver = TRUE; - bIncludePimInCache = TRUE; - } - else if (!_wcsicmp(szTmp,L"f") || !_wcsicmp(szTmp,L"favorites")) - { - bCacheInDriver = FALSE; - bCmdCacheDuringMultipleMount = TRUE; - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - } - break; - - case CommandDismount: - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szDriveLetter, ARRAYSIZE (szDriveLetter))) - { - if ( (wcslen(szDriveLetter) == 1) - || (wcslen(szDriveLetter) == 2 && szDriveLetter[1] == L':') - ) - { - cmdUnmountDrive = towupper(szDriveLetter[0]) - L'A'; - if ((cmdUnmountDrive < 0) || (cmdUnmountDrive > (L'Z' - L'A'))) - AbortProcess ("BAD_DRIVE_LETTER"); - } - else - AbortProcess ("BAD_DRIVE_LETTER"); - - } - else - cmdUnmountDrive = -1; - - break; - - case OptionExplore: - bExplore = TRUE; - break; - - case OptionForce: - bForceMount = TRUE; - bForceUnmount = TRUE; - break; - - case OptionKeyfile: - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, - nNoCommandLineArgs, tmpPath, ARRAYSIZE (tmpPath))) - { - KeyFile *kf; - RelativePath2Absolute (tmpPath); - kf = (KeyFile *) malloc (sizeof (KeyFile)); - if (kf) - { - StringCchCopyW (kf->FileName, ARRAYSIZE(kf->FileName), tmpPath); - FirstCmdKeyFile = KeyFileAdd (FirstCmdKeyFile, kf); - } - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - - break; - - case OptionLetter: - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szDriveLetter, ARRAYSIZE (szDriveLetter))) - { - if ( (wcslen(szDriveLetter) == 1) - || (wcslen(szDriveLetter) == 2 && szDriveLetter[1] == L':') - ) - { - commandLineDrive = *szDriveLetter = (wchar_t) towupper (*szDriveLetter); - - if (commandLineDrive < L'A' || commandLineDrive > L'Z') - AbortProcess ("BAD_DRIVE_LETTER"); - } - else - AbortProcess ("BAD_DRIVE_LETTER"); - } - else - AbortProcess ("BAD_DRIVE_LETTER"); - - break; - - case OptionHistory: - { - wchar_t szTmp[8] = {0}; - bHistory = bHistoryCmdLine = TRUE; - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) - bHistory = FALSE; - else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) - bHistory = TRUE; - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - } - break; - - case OptionMountOption: - { - wchar_t szTmp[64] = {0}; - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, - &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp (szTmp, L"ro") || !_wcsicmp (szTmp, L"readonly")) - mountOptions.ReadOnly = TRUE; - - else if (!_wcsicmp (szTmp, L"rm") || !_wcsicmp (szTmp, L"removable")) - mountOptions.Removable = TRUE; - - else if (!_wcsicmp (szTmp, L"ts") || !_wcsicmp (szTmp, L"timestamp")) - mountOptions.PreserveTimestamp = FALSE; - - else if (!_wcsicmp (szTmp, L"sm") || !_wcsicmp (szTmp, L"system")) - mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode = TRUE; - - else if (!_wcsicmp (szTmp, L"bk") || !_wcsicmp (szTmp, L"headerbak")) - mountOptions.UseBackupHeader = TRUE; - - else if (!_wcsicmp (szTmp, L"recovery")) - mountOptions.RecoveryMode = TRUE; - else if ((wcslen(szTmp) > 6) && (wcslen(szTmp) <= 38) && !_wcsnicmp (szTmp, L"label=", 6)) - { - // get the label - StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), &szTmp[6]); - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - - CmdMountOptions = mountOptions; - CmdMountOptionsValid = TRUE; - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - break; - - case OptionPassword: - { - wchar_t szTmp[MAX_PASSWORD + 1]; - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, - szTmp, ARRAYSIZE (szTmp))) - { - int iLen = WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, (char*) CmdVolumePassword.Text, MAX_PASSWORD + 1, NULL, NULL); - burn (szTmp, sizeof (szTmp)); - if (iLen > 0) - { - CmdVolumePassword.Length = (unsigned __int32) (iLen - 1); - CmdVolumePasswordValid = TRUE; - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - break; - - case OptionVolume: - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, - nNoCommandLineArgs, szFileName, ARRAYSIZE (szFileName))) - { - RelativePath2Absolute (szFileName); - AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); - CmdLineVolumeSpecified = TRUE; - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - break; - - case OptionQuit: - { - wchar_t szTmp[32] = {0}; - - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, - &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) - { - if (!_wcsicmp (szTmp, L"UAC")) // Used to indicate non-install elevation - break; - - else if (!_wcsicmp (szTmp, L"preferences")) - { - Quit = TRUE; - UsePreferences = TRUE; - break; - } - - else if (!_wcsicmp (szTmp, L"background")) - bEnableBkgTask = TRUE; - - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - - Quit = TRUE; - UsePreferences = FALSE; - } - break; - - case OptionSilent: - Silent = TRUE; - break; - - case OptionTokenLib: - if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, SecurityTokenLibraryPath, ARRAYSIZE (SecurityTokenLibraryPath)) == HAS_ARGUMENT) - InitSecurityTokenLibrary(hwndDlg); - else - AbortProcess ("COMMAND_LINE_ERROR"); - - break; - - case OptionTokenPin: - { - wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; - if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT) - { - if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, array_capacity (CmdTokenPin), nullptr, nullptr)) - AbortProcess ("COMMAND_LINE_ERROR"); - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - - break; - - case CommandWipeCache: - bWipe = TRUE; - break; - - case CommandHelp: - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_COMMANDHELP_DLG), hwndDlg, (DLGPROC) - CommandHelpDlgProc, (LPARAM) &as); - exit(0); - break; - - case OptionPkcs5: - { - wchar_t szTmp[32] = {0}; - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, - &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) - { - if (_wcsicmp(szTmp, L"sha512") == 0 || _wcsicmp(szTmp, L"sha-512") == 0) - CmdVolumePkcs5 = SHA512; - else if (_wcsicmp(szTmp, L"whirlpool") == 0) - CmdVolumePkcs5 = WHIRLPOOL; - else if (_wcsicmp(szTmp, L"sha256") == 0 || _wcsicmp(szTmp, L"sha-256") == 0) - CmdVolumePkcs5 = SHA256; - else if (_wcsicmp(szTmp, L"ripemd160") == 0 || _wcsicmp(szTmp, L"ripemd-160") == 0) - CmdVolumePkcs5 = RIPEMD160; - else - { - CmdVolumePkcs5 = 0; - AbortProcess ("COMMAND_LINE_ERROR"); - } - - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - break; - - case OptionPim: - { - wchar_t szTmp[32] = {0}; - if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, - &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) - { - wchar_t* endPtr = NULL; - CmdVolumePim = (int) wcstol(szTmp, &endPtr, 0); - if (CmdVolumePim < 0 || CmdVolumePim > MAX_PIM_VALUE || endPtr == szTmp || *endPtr != L'\0') - { - CmdVolumePim = 0; - AbortProcess ("COMMAND_LINE_ERROR"); - } - - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - break; - - case OptionTrueCryptMode: - CmdVolumeTrueCryptMode = TRUE; - break; - - // no option = file name if there is only one argument - default: - { - if (nNoCommandLineArgs == 1) - { - StringCbCopyW (szFileName, array_capacity (szFileName), lpszCommandLineArgs[i]); - RelativePath2Absolute (szFileName); - - CmdLineVolumeSpecified = TRUE; - AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); - } - else - AbortProcess ("COMMAND_LINE_ERROR"); - } - } - } - } - - /* Free up the command line arguments */ - while (--nNoCommandLineArgs >= 0) - { - free (lpszCommandLineArgs[nNoCommandLineArgs]); - } - - if (lpszCommandLineArgs) - free (lpszCommandLineArgs); -} - - -static SERVICE_STATUS SystemFavoritesServiceStatus; -static SERVICE_STATUS_HANDLE SystemFavoritesServiceStatusHandle; - -static void SystemFavoritesServiceLogMessage (const wstring &errorMessage, WORD wType) -{ - HANDLE eventSource = RegisterEventSource (NULL, TC_SYSTEM_FAVORITES_SERVICE_NAME); - - if (eventSource) - { - LPCTSTR strings[] = { TC_SYSTEM_FAVORITES_SERVICE_NAME, errorMessage.c_str() }; - ReportEvent (eventSource, wType, 0, 0xC0000000 + wType, NULL, array_capacity (strings), 0, strings, NULL); - - DeregisterEventSource (eventSource); - } -} - -static void SystemFavoritesServiceLogError (const wstring &errorMessage) -{ - SystemFavoritesServiceLogMessage (errorMessage, EVENTLOG_ERROR_TYPE); -} - -static void SystemFavoritesServiceLogWarning (const wstring &warningMessage) -{ - SystemFavoritesServiceLogMessage (warningMessage, EVENTLOG_WARNING_TYPE); -} - -static void SystemFavoritesServiceLogInfo (const wstring &infoMessage) -{ - SystemFavoritesServiceLogMessage (infoMessage, EVENTLOG_INFORMATION_TYPE); -} - - -static void SystemFavoritesServiceSetStatus (DWORD status, DWORD waitHint = 0) -{ - SystemFavoritesServiceStatus.dwCurrentState = status; - SystemFavoritesServiceStatus.dwWaitHint = waitHint; - SystemFavoritesServiceStatus.dwWin32ExitCode = NO_ERROR; - - SetServiceStatus (SystemFavoritesServiceStatusHandle, &SystemFavoritesServiceStatus); -} - - -static VOID WINAPI SystemFavoritesServiceCtrlHandler (DWORD control) -{ - if (control == SERVICE_CONTROL_STOP) - SystemFavoritesServiceSetStatus (SERVICE_STOP_PENDING); - else - SystemFavoritesServiceSetStatus (SystemFavoritesServiceStatus.dwCurrentState); -} - - -static VOID WINAPI SystemFavoritesServiceMain (DWORD argc, LPTSTR *argv) -{ - BOOL status = FALSE; - memset (&SystemFavoritesServiceStatus, 0, sizeof (SystemFavoritesServiceStatus)); - SystemFavoritesServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - - SystemFavoritesServiceStatusHandle = RegisterServiceCtrlHandler (TC_SYSTEM_FAVORITES_SERVICE_NAME, SystemFavoritesServiceCtrlHandler); - if (!SystemFavoritesServiceStatusHandle) - return; - - SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000); - - SystemFavoritesServiceLogInfo (wstring (L"Starting System Favorites mounting process")); - - try - { - status = MountFavoriteVolumes (NULL, TRUE); - } - catch (...) { } - - if (status) - { - SystemFavoritesServiceLogInfo (wstring (L"System Favorites mounting process finished")); - } - else - { - SystemFavoritesServiceLogError (wstring (L"System Favorites mounting process failed.")); - } - - SystemFavoritesServiceSetStatus (SERVICE_RUNNING); - SystemFavoritesServiceSetStatus (SERVICE_STOPPED); -} - - -static BOOL StartSystemFavoritesService () -{ - ServiceMode = TRUE; - Silent = TRUE; - DeviceChangeBroadcastDisabled = TRUE; - bShowDisconnectedNetworkDrives = TRUE; - bHideWaitingDialog = TRUE; - - InitOSVersionInfo(); - - if (DriverAttach() != ERR_SUCCESS) - return FALSE; - - SERVICE_TABLE_ENTRY serviceTable[2]; - serviceTable[0].lpServiceName = TC_SYSTEM_FAVORITES_SERVICE_NAME; - serviceTable[0].lpServiceProc = SystemFavoritesServiceMain; - - serviceTable[1].lpServiceName = NULL; - serviceTable[1].lpServiceProc = NULL; - - BOOL result = StartServiceCtrlDispatcher (serviceTable); - - if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD)) - WipeCache (NULL, TRUE); - - return result; -} - -#ifndef VCEXPANDER -int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpszCommandLine, int nCmdShow) -{ - int argc; - LPWSTR *argv = CommandLineToArgvW (GetCommandLineW(), &argc); - - if (argv && argc == 2 && wstring (TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION) == argv[1]) - return StartSystemFavoritesService() ? 0 : 1; - - int status; - atexit (localcleanup); - SetProcessShutdownParameters (0x100, 0); - - VirtualLock (&VolumePassword, sizeof (VolumePassword)); - VirtualLock (&CmdVolumePassword, sizeof (CmdVolumePassword)); - VirtualLock (&mountOptions, sizeof (mountOptions)); - VirtualLock (&defaultMountOptions, sizeof (defaultMountOptions)); - VirtualLock (&szFileName, sizeof(szFileName)); - VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin)); - - DetectX86Features (); - - try - { - BootEncObj = new BootEncryption (NULL); - } - catch (Exception &e) - { - e.Show (NULL); - } - - if (BootEncObj == NULL) - AbortProcess ("INIT_SYS_ENC"); - - InitApp (hInstance, lpszCommandLine); - - RegisterRedTick(hInstance); - - /* Allocate, dup, then store away the application title */ - lpszTitle = L"VeraCrypt"; - - status = DriverAttach (); - if (status != 0) - { - if (status == ERR_OS_ERROR) - handleWin32Error (NULL, SRC_POS); - else - handleError (NULL, status, SRC_POS); - - AbortProcess ("NODRIVER"); - } - - /* Create the main dialog box */ - DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_MOUNT_DLG), NULL, (DLGPROC) MainDialogProc, - (LPARAM) lpszCommandLine); - - FinalizeApp (); - /* Terminate */ - return 0; -} -#endif - - -BOOL TaskBarIconAdd (HWND hwnd) -{ - NOTIFYICONDATAW tnid; - - ZeroMemory (&tnid, sizeof (tnid)); - - // Only one icon may be created - if (TaskBarIconMutex != NULL) return TRUE; - - TaskBarIconMutex = CreateMutex (NULL, TRUE, L"VeraCryptTaskBarIcon"); - if (TaskBarIconMutex == NULL || GetLastError () == ERROR_ALREADY_EXISTS) - { - if (TaskBarIconMutex != NULL) - { - CloseHandle(TaskBarIconMutex); - TaskBarIconMutex = NULL; - } - return FALSE; - } - - tnid.cbSize = sizeof (NOTIFYICONDATAW); - tnid.hWnd = hwnd; - tnid.uID = IDI_TRUECRYPT_ICON; - tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; - tnid.uCallbackMessage = TC_APPMSG_TASKBAR_ICON; - tnid.hIcon = (HICON) LoadImage (hInst, MAKEINTRESOURCE (IDI_TRUECRYPT_ICON), - IMAGE_ICON, - ScreenDPI >= 120 ? 0 : 16, - ScreenDPI >= 120 ? 0 : 16, - (ScreenDPI >= 120 ? LR_DEFAULTSIZE : 0) - | LR_SHARED - | (nCurrentOS != WIN_2000 ? LR_DEFAULTCOLOR : LR_VGACOLOR)); // Windows 2000 cannot display more than 16 fixed colors in notification tray - - StringCbCopyW (tnid.szTip, sizeof(tnid.szTip), L"VeraCrypt"); - - return Shell_NotifyIconW (NIM_ADD, &tnid); -} - - -BOOL TaskBarIconRemove (HWND hwnd) -{ - if (TaskBarIconMutex != NULL) - { - NOTIFYICONDATA tnid; - BOOL res; - - ZeroMemory (&tnid, sizeof (tnid)); - tnid.cbSize = sizeof(NOTIFYICONDATA); - tnid.hWnd = hwnd; - tnid.uID = IDI_TRUECRYPT_ICON; - - res = Shell_NotifyIcon (NIM_DELETE, &tnid); - if (TaskBarIconMutex) - { - CloseHandle (TaskBarIconMutex); - TaskBarIconMutex = NULL; - } - return res; - } - else - return FALSE; -} - - -BOOL TaskBarIconChange (HWND hwnd, int iconId) -{ - if (TaskBarIconMutex == NULL) - return FALSE; - - NOTIFYICONDATA tnid; - - ZeroMemory (&tnid, sizeof (tnid)); - - tnid.cbSize = sizeof (tnid); - tnid.hWnd = hwnd; - tnid.uID = IDI_TRUECRYPT_ICON; - tnid.uFlags = NIF_ICON; - tnid.hIcon = (HICON) LoadImage (hInst, MAKEINTRESOURCE (iconId), - IMAGE_ICON, - ScreenDPI >= 120 ? 0 : 16, - ScreenDPI >= 120 ? 0 : 16, - (ScreenDPI >= 120 ? LR_DEFAULTSIZE : 0) - | LR_SHARED - | (nCurrentOS != WIN_2000 ? LR_DEFAULTCOLOR : LR_VGACOLOR)); // Windows 2000 cannot display more than 16 fixed colors in notification tray - - return Shell_NotifyIcon (NIM_MODIFY, &tnid); -} - - -void DismountIdleVolumes () -{ - static DWORD lastMinTickCount; - static int InactivityTime[26]; - static unsigned __int64 LastRead[26], LastWritten[26]; - static int LastId[26]; - - VOLUME_PROPERTIES_STRUCT prop; - DWORD dwResult; - BOOL bResult; - int i; - - if (GetTickCount() > lastMinTickCount && GetTickCount() - lastMinTickCount < 60 * 1000) - return; - - lastMinTickCount = GetTickCount(); - - for (i = 0; i < 26; i++) - { - if (LastKnownMountList.ulMountedDrives & (1 << i)) - { - memset (&prop, 0, sizeof(prop)); - prop.driveNo = i; - - bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, - sizeof (prop), &prop, sizeof (prop), &dwResult, NULL); - - if ( bResult - && ( (prop.driveNo == i) && prop.uniqueId >= 0 - && prop.ea >= EAGetFirst() && prop.ea <= EAGetCount() - && prop.mode >= FIRST_MODE_OF_OPERATION_ID && prop.mode <= LAST_MODE_OF_OPERATION - && prop.pkcs5 >= FIRST_PRF_ID && prop.pkcs5 <= LAST_PRF_ID - && prop.pkcs5Iterations > 0 - && prop.hiddenVolProtection >= 0 && prop.volFormatVersion >= 0 - && prop.volumePim >= 0 - ) - ) - { - if (LastRead[i] == prop.totalBytesRead - && LastWritten[i] == prop.totalBytesWritten - && LastId[i] == prop.uniqueId) - { - if (++InactivityTime[i] >= MaxVolumeIdleTime) - { - BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, i, 0); - - if (bCloseDismountedWindows && CloseVolumeExplorerWindows (MainDlg, i)) - Sleep (250); - - if (DriverUnmountVolume (MainDlg, i, bForceAutoDismount) == 0) - { - InactivityTime[i] = 0; - BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, i, 0); - - if (bWipeCacheOnAutoDismount) - { - DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - SecurityToken::CloseAllSessions(); - } - } - } - } - else - { - InactivityTime[i] = 0; - LastRead[i] = prop.totalBytesRead; - LastWritten[i] = prop.totalBytesWritten; - LastId[i] = prop.uniqueId; - } - } - } - } -} - -static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, BOOL& lastbExplore, BOOL& userForcedReadOnly, BOOL systemFavorites, BOOL logOnMount, BOOL hotKeyMount, const FavoriteVolume &favoriteVolumeToMount) -{ - BOOL status = TRUE; - int drive; - std::wstring effectiveVolumePath; - drive = towupper (favorite.MountPoint[0]) - L'A'; - - if ((drive < MIN_MOUNTED_VOLUME_DRIVE_NUMBER) || (drive > MAX_MOUNTED_VOLUME_DRIVE_NUMBER)) - { - if (!systemFavorites) - Error ("DRIVE_LETTER_UNAVAILABLE", MainDlg); - else if (ServiceMode && systemFavorites) - { - SystemFavoritesServiceLogError (wstring (L"The drive letter ") + (wchar_t) (drive + L'A') + wstring (L" used by favorite \"") + favorite.Path + L"\" is invalid.\nThis system favorite will not be mounted"); - } - return FALSE; - } - - mountOptions.ReadOnly = favorite.ReadOnly || userForcedReadOnly; - mountOptions.Removable = favorite.Removable; - if (favorite.UseLabelInExplorer && !favorite.Label.empty()) - StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), favorite.Label.c_str()); - else - ZeroMemory (mountOptions.Label, sizeof (mountOptions.Label)); - - if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID))) - { - effectiveVolumePath = FindDeviceByVolumeID (favorite.VolumeID); - } - else - effectiveVolumePath = favorite.Path; - - if (favorite.SystemEncryption) - { - mountOptions.PartitionInInactiveSysEncScope = TRUE; - bPrebootPasswordDlgMode = TRUE; - } - else - { - mountOptions.PartitionInInactiveSysEncScope = FALSE; - bPrebootPasswordDlgMode = FALSE; - } - - if ((LastKnownMountList.ulMountedDrives & (1 << drive)) == 0) - { - MountVolumesAsSystemFavorite = systemFavorites; - - wstring mountPoint = (wchar_t) (drive + L'A') + wstring (L":\\"); - wchar_t prevVolumeAtMountPoint[MAX_PATH] = { 0 }; - - if (systemFavorites) - { - // Partitions of new drives are assigned free drive letters by Windows on boot. Make sure this does not prevent system favorite volumes - // from being mounted. Each partition (using the same drive letter as a system favorite volume) is assigned another free drive letter. - - if (GetVolumeNameForVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint, ARRAYSIZE (prevVolumeAtMountPoint))) - DeleteVolumeMountPoint (mountPoint.c_str()); - else - prevVolumeAtMountPoint[0] = 0; - } - - lastbExplore = bExplore; - - bExplore = (BOOL) favorite.OpenExplorerWindow; - - if (!systemFavorites - && !logOnMount - && !hotKeyMount - && !favoriteVolumeToMount.Path.empty() - && GetAsyncKeyState (VK_CONTROL) < 0) - { - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (CmdVolumePkcs5 == 0) - mountOptions.ProtectedHidVolPkcs5Prf = DefaultVolumePkcs5; - else - mountOptions.ProtectedHidVolPkcs5Prf = CmdVolumePkcs5; - mountOptions.ProtectedHidVolPim = CmdVolumePim; - if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwnd, (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions) == IDCANCEL) - { - status = FALSE; - goto skipMount; - } - } - - BOOL prevReadOnly = mountOptions.ReadOnly; - - if (ServiceMode) - SystemFavoritesServiceLogInfo (wstring (L"Mounting system favorite \"") + effectiveVolumePath + L"\""); - - status = Mount (hwnd, drive, (wchar_t *) effectiveVolumePath.c_str(), favorite.Pim); - - if (ServiceMode) - { - // Update the service status to avoid being killed - SystemFavoritesServiceStatus.dwCheckPoint++; - SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000); - - if (status) - { - SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + effectiveVolumePath + wstring (L"\" mounted successfully as ") + (wchar_t) (drive + L'A') + L":"); - } - else - { - SystemFavoritesServiceLogError (wstring (L"Favorite \"") + effectiveVolumePath + L"\" failed to mount"); - } - } - - if (status && mountOptions.ReadOnly != prevReadOnly) - userForcedReadOnly = mountOptions.ReadOnly; - -skipMount: - bExplore = lastbExplore; - - if (systemFavorites && prevVolumeAtMountPoint[0]) - { - if (status) - { - int freeDrive = GetFirstAvailableDrive(); - if (freeDrive != -1) - { - mountPoint[0] = (wchar_t) (freeDrive + L'A'); - SetVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint); - } - } - else - SetVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint); - } - - LoadDriveLetters (MainDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0); - - MountVolumesAsSystemFavorite = FALSE; - - if (ServiceMode && LastMountedVolumeDirty) - { - DWORD bytesOut; - DeviceIoControl (hDriver, TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY, NULL, 0, NULL, 0, &bytesOut, NULL); - - SystemFavoritesServiceLogError (wstring (L"The filesystem of the volume mounted as ") + (wchar_t) (drive + L'A') + L": was not cleanly dismounted and needs to be checked for errors."); - } - } - else if (!systemFavorites && !favoriteVolumeToMount.Path.empty()) - Error ("DRIVE_LETTER_UNAVAILABLE", MainDlg); - else if (ServiceMode && systemFavorites) - { - SystemFavoritesServiceLogError (wstring (L"The drive letter ") + (wchar_t) (drive + L'A') + wstring (L" used by favorite \"") + effectiveVolumePath + L"\" is already taken.\nThis system favorite will not be mounted"); - } - - return status; -} - - -BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOOL hotKeyMount, const FavoriteVolume &favoriteVolumeToMount) -{ - BOOL bRet = TRUE, status = TRUE; - BOOL lastbExplore; - BOOL userForcedReadOnly = FALSE; - - if (ServiceMode) - { - // in service case, intialize some global variable here. - LastKnownMountList.ulMountedDrives = 0; - LoadDriveLetters (MainDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0); - } - - mountOptions = defaultMountOptions; - - VolumePassword.Length = 0; - MultipleMountOperationInProgress = (favoriteVolumeToMount.Path.empty() || FavoriteMountOnArrivalInProgress); - - vector favorites, skippedSystemFavorites; - - if (systemFavorites) - { - try - { - if (ServiceMode) - SystemFavoritesServiceLogInfo (wstring (L"Reading System Favorites XML file")); - LoadFavoriteVolumes (favorites, true); - - if (ServiceMode) - { - wchar_t szTmp[32]; - StringCbPrintf (szTmp, sizeof(szTmp), L"%d", (int) favorites.size()); - SystemFavoritesServiceLogInfo (wstring (L"Loaded ") + szTmp + wstring (L" favorites from the file")); - - /* correct set the connected state of the system favorites */ - for (vector ::iterator favorite = favorites.begin(); - favorite != favorites.end(); favorite++) - { - if (favorite->UseVolumeID) - { - std::wstring path = FindDeviceByVolumeID (favorite->VolumeID); - if (path.empty ()) - { - favorite->DisconnectedDevice = true; - } - else - { - favorite->DisconnectedDevice = false; - favorite->Path = path; - favorite->UseVolumeID = false; /* force the use of real path to avoid calling FindDeviceByVolumeID again */ - } - } - } - } - } - catch (...) - { - if (ServiceMode) - SystemFavoritesServiceLogError (wstring (L"An error occured while reading System Favorites XML file")); - return false; - } - } - else if (!favoriteVolumeToMount.Path.empty()) - favorites.push_back (favoriteVolumeToMount); - else - favorites = FavoriteVolumes; - - foreach (const FavoriteVolume &favorite, favorites) - { - if (ServiceMode && systemFavorites && favorite.DisconnectedDevice) - { - skippedSystemFavorites.push_back (favorite); - if (favorite.UseVolumeID) - SystemFavoritesServiceLogWarning (wstring (L"Favorite \"ID:") + ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)) + L"\" is disconnected. It will be ignored."); - else - SystemFavoritesServiceLogWarning (wstring (L"Favorite \"") + favorite.Path + L"\" is disconnected. It will be ignored."); - } - - if (favorite.DisconnectedDevice - || (logOnMount && !favorite.MountOnLogOn) - || (hotKeyMount && favorite.DisableHotkeyMount)) - { - continue; - } - - status = MountFavoriteVolumeBase (hwnd, favorite, lastbExplore, userForcedReadOnly, systemFavorites, logOnMount, hotKeyMount, favoriteVolumeToMount); - if (!status) - bRet = FALSE; - } - - if (systemFavorites && ServiceMode && !skippedSystemFavorites.empty()) - { - // Some drives need more time to initialize correctly. - // We retry 4 times after sleeping 5 seconds - int retryCounter = 0; - size_t remainingFavorites = skippedSystemFavorites.size(); - while ((remainingFavorites > 0) && (retryCounter++ < 4)) - { - Sleep (5000); - - SystemFavoritesServiceLogInfo (wstring (L"Trying to mount skipped system favorites")); - - // Update the service status to avoid being killed - SystemFavoritesServiceStatus.dwCheckPoint++; - SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000); - - for (vector ::iterator favorite = skippedSystemFavorites.begin(); - favorite != skippedSystemFavorites.end(); favorite++) - { - if (favorite->DisconnectedDevice) - { - // check if the favorite is here and get its path - wstring resolvedPath; - if (favorite->UseVolumeID) - { - resolvedPath = FindDeviceByVolumeID (favorite->VolumeID); - } - else - resolvedPath = VolumeGuidPathToDevicePath (favorite->Path); - if (!resolvedPath.empty()) - { - favorite->DisconnectedDevice = false; - favorite->VolumePathId = favorite->Path; - favorite->Path = resolvedPath; - - remainingFavorites--; - - // favorite OK. - if (favorite->UseVolumeID) - SystemFavoritesServiceLogInfo (wstring (L"Favorite \"ID:") + ArrayToHexWideString (favorite->VolumeID, sizeof (favorite->VolumeID)) + L"\" is connected. Performing mount."); - else - SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + favorite->VolumePathId + L"\" is connected. Performing mount."); - - status = MountFavoriteVolumeBase (hwnd, *favorite, lastbExplore, userForcedReadOnly, systemFavorites, logOnMount, hotKeyMount, favoriteVolumeToMount); - if (!status) - bRet = FALSE; - } - } - } - - if (remainingFavorites == 0) - SystemFavoritesServiceLogInfo (wstring (L"All skipped system favorites have been processed")); - else - { - wchar_t szTmp[32]; - StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", (int) remainingFavorites); - SystemFavoritesServiceLogWarning (wstring (L"Number of unprocessed system favorites is ") + szTmp); - } - } - } - - MultipleMountOperationInProgress = FALSE; - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - - if (bRet && CloseSecurityTokenSessionsAfterMount) - SecurityToken::CloseAllSessions(); - - return bRet; -} - -void CALLBACK mountFavoriteVolumeCallbackFunction (void *pArg, HWND hwnd) -{ - mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) pArg; - - if (pParam) - { - if (pParam->favoriteVolumeToMount) - MountFavoriteVolumes (hwnd, pParam->systemFavorites, pParam->logOnMount, pParam->hotKeyMount, *(pParam->favoriteVolumeToMount)); - else - MountFavoriteVolumes (hwnd, pParam->systemFavorites, pParam->logOnMount, pParam->hotKeyMount); - - free (pParam); - } - else - MountFavoriteVolumes (hwnd); -} - -void __cdecl mountFavoriteVolumeThreadFunction (void *pArg) -{ - ShowWaitDialog (MainDlg, FALSE, mountFavoriteVolumeCallbackFunction, pArg); -} - -static void SaveDefaultKeyFilesParam (HWND hwnd) -{ - if (defaultKeyFilesParam.FirstKeyFile == NULL) - { - /* No keyfiles selected */ - _wremove (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES)); - } - else - { - FILE *f; - KeyFile *kf = FirstKeyFile; - - f = _wfopen (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES), L"w,ccs=UTF-8"); - if (f == NULL) - { - handleWin32Error (MainDlg, SRC_POS); - return; - } - - XmlWriteHeader (f); - - fputws (L"\n\t", f); - - while (kf != NULL) - { - wchar_t q[TC_MAX_PATH * 2]; - - XmlQuoteTextW (kf->FileName, q, ARRAYSIZE (q)); - fwprintf (f, L"\n\t\t%s", q); - - kf = kf->Next; - } - - fputws (L"\n\t", f); - - XmlWriteFooter (f); - - CheckFileStreamWriteErrors (hwnd, f, TC_APPD_FILENAME_DEFAULT_KEYFILES); - fclose (f); - return; - } -} - - -static void KeyfileDefaultsDlg (HWND hwndDlg) -{ - KeyFilesDlgParam param; - - param.EnableKeyFiles = defaultKeyFilesParam.EnableKeyFiles; - param.FirstKeyFile = defaultKeyFilesParam.FirstKeyFile; - - if (DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, - (DLGPROC) KeyFilesDlgProc, (LPARAM) ¶m) == IDOK) - { - if (!param.EnableKeyFiles || AskWarnYesNo ("CONFIRM_SAVE_DEFAULT_KEYFILES", hwndDlg) == IDYES) - { - KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); - defaultKeyFilesParam.EnableKeyFiles = param.EnableKeyFiles; - defaultKeyFilesParam.FirstKeyFile = param.FirstKeyFile; - - RestoreDefaultKeyFilesParam (); - SaveDefaultKeyFilesParam (hwndDlg); - } - } -} - - -static void HandleHotKey (HWND hwndDlg, WPARAM wParam) -{ - DWORD dwResult; - BOOL success = TRUE; - - switch (wParam) - { - case HK_AUTOMOUNT_DEVICES: - MountAllDevices (hwndDlg, TRUE); - break; - - case HK_DISMOUNT_ALL: - case HK_DISMOUNT_ALL_AND_WIPE: - - if (wParam == HK_DISMOUNT_ALL_AND_WIPE) - WipeCache (hwndDlg, TRUE); - - if (DismountAll (hwndDlg, FALSE, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY)) - { - if (bDisplayBalloonOnSuccessfulHkDismount) - InfoBalloon ("SUCCESSFULLY_DISMOUNTED", (wParam == HK_DISMOUNT_ALL_AND_WIPE ? "VOLUMES_DISMOUNTED_CACHE_WIPED" : "MOUNTED_VOLUMES_DISMOUNTED"), hwndDlg); - - if (bPlaySoundOnSuccessfulHkDismount) - MessageBeep (0xFFFFFFFF); - } - - break; - - case HK_WIPE_CACHE: - WipeCache (hwndDlg, FALSE); - - break; - - case HK_FORCE_DISMOUNT_ALL_AND_WIPE: - success = DismountAll (hwndDlg, TRUE, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); - success &= DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - if (success) - { - if (bDisplayBalloonOnSuccessfulHkDismount) - InfoBalloon ("SUCCESSFULLY_DISMOUNTED", "VOLUMES_DISMOUNTED_CACHE_WIPED", hwndDlg); - - if (bPlaySoundOnSuccessfulHkDismount) - MessageBeep (0xFFFFFFFF); - } - break; - - case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT: - success = DismountAll (hwndDlg, TRUE, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); - success &= DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); - if (success) - { - if (bDisplayBalloonOnSuccessfulHkDismount) - InfoBalloon ("SUCCESSFULLY_DISMOUNTED", "VOLUMES_DISMOUNTED_CACHE_WIPED", hwndDlg); - - if (bPlaySoundOnSuccessfulHkDismount) - MessageBeep (0xFFFFFFFF); - } - TaskBarIconRemove (hwndDlg); - UnregisterWtsNotification(hwndDlg); - EndMainDlg (hwndDlg); - break; - - case HK_MOUNT_FAVORITE_VOLUMES: - { - mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) calloc(1, sizeof(mountFavoriteVolumeThreadParam)); - pParam->systemFavorites = FALSE; - pParam->logOnMount = FALSE; - pParam->hotKeyMount = TRUE; - pParam->favoriteVolumeToMount = NULL; - - _beginthread(mountFavoriteVolumeThreadFunction, 0, pParam); - } - break; - - case HK_SHOW_HIDE_MAIN_WINDOW: - ChangeMainWindowVisibility (); - break; - - case HK_CLOSE_SECURITY_TOKEN_SESSIONS: - SecurityToken::CloseAllSessions(); - - InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg); - - break; - } -} - - -void ChangeMainWindowVisibility () -{ - MainWindowHidden = !MainWindowHidden; - - if (!MainWindowHidden) - SetForegroundWindow (MainDlg); - - ShowWindow (MainDlg, !MainWindowHidden ? SW_SHOW : SW_HIDE); - - if (!MainWindowHidden) - ShowWindow (MainDlg, SW_RESTORE); -} - - -int BackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, const wchar_t *lpszVolume) -{ - int nStatus = ERR_OS_ERROR; - wchar_t szTmp[4096]; - int fBackup = -1; - OpenVolumeContext volume; - OpenVolumeContext hiddenVolume; - Password hiddenVolPassword; - int hiddenVolPkcs5 = 0, hiddenVolPim = 0; - byte temporaryKey[MASTER_KEYDATA_SIZE]; - byte originalK2[MASTER_KEYDATA_SIZE]; - int EffectiveVolumePkcs5 = CmdVolumePkcs5; - int EffectiveVolumePim = CmdVolumePim; - - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (EffectiveVolumePkcs5 == 0) - EffectiveVolumePkcs5 = DefaultVolumePkcs5; - - if (!lpszVolume) - { - nStatus = ERR_OUTOFMEMORY; - handleError (hwndDlg, nStatus, SRC_POS); - return nStatus; - } - - volume.VolumeIsOpen = FALSE; - hiddenVolume.VolumeIsOpen = FALSE; - - switch (IsSystemDevicePath (lpszVolume, hwndDlg, TRUE)) - { - case 1: - case 2: - if (AskErrNoYes ("BACKUP_HEADER_NOT_FOR_SYS_DEVICE", hwndDlg) == IDYES) - CreateRescueDisk (hwndDlg); - - return 0; - } - - if (IsMountedVolume (lpszVolume)) - { - Warning ("DISMOUNT_FIRST", hwndDlg); - goto ret; - } - - if (!VolumePathExists (lpszVolume)) - { - handleWin32Error (hwndDlg, SRC_POS); - goto ret; - } - - Info ("EXTERNAL_VOL_HEADER_BAK_FIRST_INFO", hwndDlg); - - - WaitCursor(); - - // Open both types of volumes - for (int type = TC_VOLUME_TYPE_NORMAL; type <= TC_VOLUME_TYPE_HIDDEN; ++type) - { - OpenVolumeContext *askVol = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolume : &volume); - Password *askPassword = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolPassword : &VolumePassword); - int* askPkcs5 = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolPkcs5 : &VolumePkcs5); - int* askPim = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolPim : &VolumePim); - - while (TRUE) - { - int GuiPkcs5 = ((EffectiveVolumePkcs5 > 0) && (*askPkcs5 == 0))? EffectiveVolumePkcs5 : *askPkcs5; - int GuiPim = ((EffectiveVolumePim > 0) && (*askPim <= 0))? EffectiveVolumePim : *askPim; - if (!AskVolumePassword (hwndDlg, askPassword, &GuiPkcs5, &GuiPim, &VolumeTrueCryptMode, type == TC_VOLUME_TYPE_HIDDEN ? "ENTER_HIDDEN_VOL_PASSWORD" : "ENTER_NORMAL_VOL_PASSWORD", FALSE)) - { - nStatus = ERR_SUCCESS; - goto ret; - } - else - { - *askPkcs5 = GuiPkcs5; - *askPim = GuiPim; - burn (&GuiPkcs5, sizeof (GuiPkcs5)); - burn (&GuiPim, sizeof (GuiPim)); - } - - WaitCursor(); - - if (KeyFilesEnable && FirstKeyFile) - KeyFilesApply (hwndDlg, askPassword, FirstKeyFile, lpszVolume); - - nStatus = OpenVolume (askVol, lpszVolume, askPassword, *askPkcs5, *askPim, VolumeTrueCryptMode, FALSE, bPreserveTimestamp, FALSE); - - NormalCursor(); - - if (nStatus == ERR_SUCCESS) - { - if ((type == TC_VOLUME_TYPE_NORMAL && askVol->CryptoInfo->hiddenVolume) - || (type == TC_VOLUME_TYPE_HIDDEN && !askVol->CryptoInfo->hiddenVolume)) - { - CloseVolume (askVol); - handleError (hwndDlg, ERR_PASSWORD_WRONG, SRC_POS); - continue; - } - - RandSetHashFunction (askVol->CryptoInfo->pkcs5); - - if (type == TC_VOLUME_TYPE_NORMAL) - { - // Ask the user if there is a hidden volume - char *volTypeChoices[] = {0, "DOES_VOLUME_CONTAIN_HIDDEN", "VOLUME_CONTAINS_HIDDEN", "VOLUME_DOES_NOT_CONTAIN_HIDDEN", "IDCANCEL", 0}; - switch (AskMultiChoice ((void **) volTypeChoices, FALSE, hwndDlg)) - { - case 1: - break; - case 2: - goto noHidden; - - default: - nStatus = ERR_SUCCESS; - goto ret; - } - } - - break; - } - - if (nStatus != ERR_PASSWORD_WRONG) - goto error; - - handleError (hwndDlg, nStatus, SRC_POS); - } - } -noHidden: - - if (hiddenVolume.VolumeIsOpen && volume.CryptoInfo->LegacyVolume != hiddenVolume.CryptoInfo->LegacyVolume) - { - nStatus = ERR_PARAMETER_INCORRECT; - goto error; - } - - StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CONFIRM_VOL_HEADER_BAK"), lpszVolume); - - if (bRequireConfirmation - && (MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDNO)) - goto ret; - - /* Select backup file */ - if (!BrowseFiles (hwndDlg, "OPEN_TITLE", szFileName, bHistory, TRUE, NULL)) - goto ret; - - /* Conceive the backup file */ - if ((fBackup = _wopen(szFileName, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) == -1) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - // Backup headers - - byte backup[TC_VOLUME_HEADER_GROUP_SIZE]; - - bool legacyVolume = volume.CryptoInfo->LegacyVolume ? true : false; - int backupFileSize = legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY * 2 : TC_VOLUME_HEADER_GROUP_SIZE; - - // Fill backup buffer with random data - memcpy (originalK2, volume.CryptoInfo->k2, sizeof (volume.CryptoInfo->k2)); - - if (Randinit() != ERR_SUCCESS) - { - if (CryptoAPILastError == ERROR_SUCCESS) - nStatus = ERR_RAND_INIT_FAILED; - else - nStatus = ERR_CAPI_INIT_FAILED; - goto error; - } - - /* force the display of the random enriching dialog */ - SetRandomPoolEnrichedByUserStatus (FALSE); - - NormalCursor(); - UserEnrichRandomPool (hwndDlg); - WaitCursor(); - - // Temporary keys - if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (volume.CryptoInfo->ea), TRUE) - || !RandgetBytes (hwndDlg, volume.CryptoInfo->k2, sizeof (volume.CryptoInfo->k2), FALSE)) - { - nStatus = ERR_PARAMETER_INCORRECT; - goto error; - } - - if (EAInit (volume.CryptoInfo->ea, temporaryKey, volume.CryptoInfo->ks) != ERR_SUCCESS || !EAInitMode (volume.CryptoInfo)) - { - nStatus = ERR_PARAMETER_INCORRECT; - goto error; - } - - EncryptBuffer (backup, backupFileSize, volume.CryptoInfo); - - memcpy (volume.CryptoInfo->k2, originalK2, sizeof (volume.CryptoInfo->k2)); - if (EAInit (volume.CryptoInfo->ea, volume.CryptoInfo->master_keydata, volume.CryptoInfo->ks) != ERR_SUCCESS || !EAInitMode (volume.CryptoInfo)) - { - nStatus = ERR_PARAMETER_INCORRECT; - goto error; - } - - // Store header encrypted with a new key - nStatus = ReEncryptVolumeHeader (hwndDlg, (char *) backup, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); - if (nStatus != ERR_SUCCESS) - goto error; - - if (hiddenVolume.VolumeIsOpen) - { - nStatus = ReEncryptVolumeHeader (hwndDlg, (char *) backup + (legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE), - FALSE, hiddenVolume.CryptoInfo, &hiddenVolPassword, hiddenVolPim, FALSE); - - if (nStatus != ERR_SUCCESS) - goto error; - } - - if (_write (fBackup, backup, backupFileSize) == -1) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - /* Backup has been successfully created */ - Warning("VOL_HEADER_BACKED_UP", hwndDlg); - -ret: - nStatus = ERR_SUCCESS; - -error: - DWORD dwError = GetLastError (); - - CloseVolume (&volume); - CloseVolume (&hiddenVolume); - - if (fBackup != -1) - _close (fBackup); - - SetLastError (dwError); - if (nStatus != 0) - handleError (hwndDlg, nStatus, SRC_POS); - - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - burn (&hiddenVolPassword, sizeof (hiddenVolPassword)); - burn (temporaryKey, sizeof (temporaryKey)); - burn (originalK2, sizeof (originalK2)); - - RestoreDefaultKeyFilesParam(); - RandStop (FALSE); - NormalCursor(); - - return nStatus; -} - - -int RestoreVolumeHeader (HWND hwndDlg, const wchar_t *lpszVolume) -{ - int nDosLinkCreated = -1, nStatus = ERR_OS_ERROR; - wchar_t szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; - wchar_t szFileName[TC_MAX_PATH]; - wchar_t szDosDevice[TC_MAX_PATH]; - void *dev = INVALID_HANDLE_VALUE; - DWORD dwError; - BOOL bDevice; - unsigned __int64 hostSize = 0; - FILETIME ftCreationTime; - FILETIME ftLastWriteTime; - FILETIME ftLastAccessTime; - wchar_t szTmp[4096]; - BOOL bTimeStampValid = FALSE; - HANDLE fBackup = INVALID_HANDLE_VALUE; - LARGE_INTEGER headerOffset; - CRYPTO_INFO *restoredCryptoInfo = NULL; - int EffectiveVolumePkcs5 = CmdVolumePkcs5; - int EffectiveVolumePim = CmdVolumePim; - - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (EffectiveVolumePkcs5 == 0) - EffectiveVolumePkcs5 = DefaultVolumePkcs5; - - if (!lpszVolume) - { - nStatus = ERR_OUTOFMEMORY; - handleError (hwndDlg, nStatus, SRC_POS); - return nStatus; - } - - switch (IsSystemDevicePath (lpszVolume, hwndDlg, TRUE)) - { - case 1: - case 2: - if (AskErrNoYes ("RESTORE_HEADER_NOT_FOR_SYS_DEVICE", hwndDlg) == IDYES) - CreateRescueDisk (hwndDlg); - - return 0; - - case -1: - // In some environments (such as PE), the system volume is not located on a hard drive. - // Therefore, we must interpret this return code as "Not a system device path" (otherwise, - // it would not be possible to restore headers on non-system devices in such environments). - // Note that this is rather safe, because bReliableRequired is set to TRUE. - - // NOP - break; - } - - if (IsMountedVolume (lpszVolume)) - { - Warning ("DISMOUNT_FIRST", hwndDlg); - return 0; - } - - if (!VolumePathExists (lpszVolume)) - { - handleWin32Error (hwndDlg, SRC_POS); - return 0; - } - - BOOL restoreInternalBackup; - - // Ask the user to select the type of backup (internal/external) - char *volTypeChoices[] = {0, "HEADER_RESTORE_EXTERNAL_INTERNAL", "HEADER_RESTORE_INTERNAL", "HEADER_RESTORE_EXTERNAL", "IDCANCEL", 0}; - switch (AskMultiChoice ((void **) volTypeChoices, FALSE, hwndDlg)) - { - case 1: - restoreInternalBackup = TRUE; - break; - case 2: - restoreInternalBackup = FALSE; - break; - default: - return 0; - } - - OpenVolumeContext volume; - volume.VolumeIsOpen = FALSE; - - /* force the display of the random enriching dialog */ - SetRandomPoolEnrichedByUserStatus (FALSE); - - WaitCursor(); - - if (restoreInternalBackup) - { - // Restore header from the internal backup - - // Open the volume using backup header - while (TRUE) - { - int GuiPkcs5 = ((EffectiveVolumePkcs5 > 0) && (VolumePkcs5 == 0))? EffectiveVolumePkcs5 : VolumePkcs5; - int GuiPim = ((EffectiveVolumePim > 0) && (VolumePim <= 0))? EffectiveVolumePim : VolumePim; - StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume), lpszVolume); - if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &VolumeTrueCryptMode, NULL, FALSE)) - { - nStatus = ERR_SUCCESS; - goto ret; - } - else - { - VolumePkcs5 = GuiPkcs5; - VolumePim = GuiPim; - burn (&GuiPkcs5, sizeof (GuiPkcs5)); - burn (&GuiPim, sizeof (GuiPim)); - } - - WaitCursor(); - - if (KeyFilesEnable && FirstKeyFile) - KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, lpszVolume); - - nStatus = OpenVolume (&volume, lpszVolume, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode,TRUE, bPreserveTimestamp, TRUE); - - NormalCursor(); - - if (nStatus == ERR_SUCCESS) - break; - - if (nStatus != ERR_PASSWORD_WRONG) - goto error; - - handleError (hwndDlg, nStatus, SRC_POS); - } - - if (volume.CryptoInfo->LegacyVolume) - { - Error ("VOLUME_HAS_NO_BACKUP_HEADER", hwndDlg); - nStatus = ERROR_SUCCESS; - goto error; - } - - // Create a new header with a new salt - char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; - - nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); - if (nStatus != 0) - goto error; - - headerOffset.QuadPart = volume.CryptoInfo->hiddenVolume ? TC_HIDDEN_VOLUME_HEADER_OFFSET : TC_VOLUME_HEADER_OFFSET; - if (!SetFilePointerEx (volume.HostFileHandle, headerOffset, NULL, FILE_BEGIN)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - if (!WriteEffectiveVolumeHeader (volume.IsDevice, volume.HostFileHandle, (byte *) buffer)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - } - else - { - // Restore header from an external backup - - StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CONFIRM_VOL_HEADER_RESTORE"), lpszVolume); - - if (MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2) == IDNO) - { - nStatus = ERR_SUCCESS; - goto ret; - } - - /* Select backup file */ - if (!BrowseFiles (hwndDlg, "OPEN_TITLE", szFileName, bHistory, FALSE, NULL)) - { - nStatus = ERR_SUCCESS; - goto ret; - } - - /* Open the backup file */ - fBackup = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (fBackup == INVALID_HANDLE_VALUE) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - // Determine size of the backup file - LARGE_INTEGER backupSize; - if (!GetFileSizeEx (fBackup, &backupSize)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), lpszVolume, &bDevice); - - if (bDevice == FALSE) - StringCbCopyW (szCFDevice, sizeof(szCFDevice), szDiskFile); - else - { - nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, sizeof(szDosDevice),szCFDevice, sizeof(szCFDevice),FALSE); - if (nDosLinkCreated != 0) - goto error; - } - - // Open the volume - dev = CreateFile (szCFDevice, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - - if (dev == INVALID_HANDLE_VALUE) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - // Determine volume host size - if (bDevice) - { - PARTITION_INFORMATION diskInfo; - DWORD dwResult; - BOOL bResult; - - bResult = GetPartitionInfo (lpszVolume, &diskInfo); - - if (bResult) - { - hostSize = diskInfo.PartitionLength.QuadPart; - } - else - { - DISK_GEOMETRY driveInfo; - - bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, - &driveInfo, sizeof (driveInfo), &dwResult, NULL); - - if (!bResult) - goto error; - - hostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector * - driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder; - } - - if (hostSize == 0) - { - nStatus = ERR_VOL_SIZE_WRONG; - goto error; - } - } - else - { - LARGE_INTEGER fileSize; - if (!GetFileSizeEx (dev, &fileSize)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - hostSize = fileSize.QuadPart; - } - - if (!bDevice && bPreserveTimestamp) - { - /* Remember the container modification/creation date and time. */ - - if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0) - bTimeStampValid = FALSE; - else - bTimeStampValid = TRUE; - } - - /* Read the volume header from the backup file */ - char buffer[TC_VOLUME_HEADER_GROUP_SIZE]; - - DWORD bytesRead; - if (!ReadFile (fBackup, buffer, sizeof (buffer), &bytesRead, NULL)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - if (bytesRead != backupSize.QuadPart) - { - nStatus = ERR_VOL_SIZE_WRONG; - goto error; - } - - LARGE_INTEGER headerOffset; - LARGE_INTEGER headerBackupOffset; - bool legacyBackup; - int headerOffsetBackupFile; - - // Determine the format of the backup file - switch (backupSize.QuadPart) - { - case TC_VOLUME_HEADER_GROUP_SIZE: - legacyBackup = false; - break; - - case TC_VOLUME_HEADER_SIZE_LEGACY * 2: - legacyBackup = true; - break; - - default: - Error ("HEADER_BACKUP_SIZE_INCORRECT", hwndDlg); - nStatus = ERR_SUCCESS; - goto error; - } - - // Open the header - while (TRUE) - { - int GuiPkcs5 = ((EffectiveVolumePkcs5 > 0) && (VolumePkcs5 == 0))? EffectiveVolumePkcs5 : VolumePkcs5; - int GuiPim = ((EffectiveVolumePim > 0) && (VolumePim <= 0))? EffectiveVolumePim : VolumePim; - if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &VolumeTrueCryptMode, "ENTER_HEADER_BACKUP_PASSWORD", FALSE)) - { - nStatus = ERR_SUCCESS; - goto ret; - } - else - { - VolumePkcs5 = GuiPkcs5; - VolumePim = GuiPim; - burn (&GuiPkcs5, sizeof (GuiPkcs5)); - burn (&GuiPim, sizeof (GuiPim)); - } - - if (KeyFilesEnable && FirstKeyFile) - KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, bDevice? NULL : lpszVolume); - - // Decrypt volume header - headerOffsetBackupFile = 0; - for (int type = TC_VOLUME_TYPE_NORMAL; type <= TC_VOLUME_TYPE_HIDDEN; ++type) - { - if (type == TC_VOLUME_TYPE_HIDDEN) - headerOffsetBackupFile += (legacyBackup ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE); - - nStatus = ReadVolumeHeader (FALSE, buffer + headerOffsetBackupFile, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, &restoredCryptoInfo, NULL); - if (nStatus == ERR_SUCCESS) - break; - } - - if (nStatus == ERR_SUCCESS) - break; - - if (nStatus != ERR_PASSWORD_WRONG) - goto error; - - handleError (hwndDlg, nStatus, SRC_POS); - } - - BOOL hiddenVol = restoredCryptoInfo->hiddenVolume; - - if (legacyBackup) - { - headerOffset.QuadPart = hiddenVol ? hostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY : TC_VOLUME_HEADER_OFFSET; - } - else - { - headerOffset.QuadPart = hiddenVol ? TC_HIDDEN_VOLUME_HEADER_OFFSET : TC_VOLUME_HEADER_OFFSET; - headerBackupOffset.QuadPart = hiddenVol ? hostSize - TC_VOLUME_HEADER_SIZE : hostSize - TC_VOLUME_HEADER_GROUP_SIZE; - } - - WaitCursor(); - - // Restore header encrypted with a new key - nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, restoredCryptoInfo, &VolumePassword, VolumePim, FALSE); - if (nStatus != ERR_SUCCESS) - goto error; - - if (!SetFilePointerEx (dev, headerOffset, NULL, FILE_BEGIN)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - if (!WriteEffectiveVolumeHeader (bDevice, dev, (byte *) buffer)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - if (!restoredCryptoInfo->LegacyVolume) - { - // Restore backup header encrypted with a new key - nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, restoredCryptoInfo, &VolumePassword, VolumePim, FALSE); - if (nStatus != ERR_SUCCESS) - goto error; - - if (!SetFilePointerEx (dev, headerBackupOffset, NULL, FILE_BEGIN)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - - if (!WriteEffectiveVolumeHeader (bDevice, dev, (byte *) buffer)) - { - nStatus = ERR_OS_ERROR; - goto error; - } - } - } - - - /* Volume header has been successfully restored */ - - Info("VOL_HEADER_RESTORED", hwndDlg); -ret: - nStatus = ERR_SUCCESS; - -error: - dwError = GetLastError (); - NormalCursor(); - - if (restoreInternalBackup) - { - CloseVolume (&volume); - } - else - { - if (restoredCryptoInfo) - crypto_close (restoredCryptoInfo); - - if (bTimeStampValid) - SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime); - - if (dev != INVALID_HANDLE_VALUE) - CloseHandle (dev); - - if (fBackup != INVALID_HANDLE_VALUE) - CloseHandle (fBackup); - - if (nDosLinkCreated == 0) - RemoveFakeDosName (szDiskFile, szDosDevice); - } - - SetLastError (dwError); - if (nStatus != 0) - handleError (hwndDlg, nStatus, SRC_POS); - - burn (&VolumePassword, sizeof (VolumePassword)); - burn (&VolumePkcs5, sizeof (VolumePkcs5)); - burn (&VolumePim, sizeof (VolumePim)); - burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); - RestoreDefaultKeyFilesParam(); - RandStop (FALSE); - NormalCursor(); - - return nStatus; -} - - -void SetDriverConfigurationFlag (uint32 flag, BOOL state) -{ - BootEncObj->SetDriverConfigurationFlag (flag, state ? true : false); -} - - -static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - { - LocalizeDialog (hwndDlg, "IDD_PERFORMANCE_SETTINGS"); - - uint32 driverConfig = ReadDriverConfigurationFlags(); - CheckDlgButton (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION, (driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? BST_UNCHECKED : BST_CHECKED); - CheckDlgButton (hwndDlg, IDC_ENABLE_EXTENDED_IOCTL_SUPPORT, (driverConfig & TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL) ? BST_CHECKED : BST_UNCHECKED); - - SYSTEM_INFO sysInfo; - GetSystemInfo (&sysInfo); - - HWND freeCpuCombo = GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT); - uint32 encryptionFreeCpuCount = ReadEncryptionThreadPoolFreeCpuCountLimit(); - - if (encryptionFreeCpuCount > sysInfo.dwNumberOfProcessors - 1) - encryptionFreeCpuCount = sysInfo.dwNumberOfProcessors - 1; - - for (uint32 i = 1; i < sysInfo.dwNumberOfProcessors; ++i) - { - wstringstream s; - s << i; - AddComboPair (freeCpuCombo, s.str().c_str(), i); - } - - if (sysInfo.dwNumberOfProcessors < 2 || encryptionFreeCpuCount == 0) - EnableWindow (freeCpuCombo, FALSE); - - if (sysInfo.dwNumberOfProcessors < 2) - EnableWindow (GetDlgItem (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL), FALSE); - - if (encryptionFreeCpuCount != 0) - { - CheckDlgButton (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL, BST_CHECKED); - SendMessage (freeCpuCombo, CB_SETCURSEL, encryptionFreeCpuCount - 1, 0); - } - - SetWindowTextW (GetDlgItem (hwndDlg, IDT_LIMIT_ENC_THREAD_POOL_NOTE), GetString("LIMIT_ENC_THREAD_POOL_NOTE")); - - SetDlgItemTextW (hwndDlg, IDC_HW_AES_SUPPORTED_BY_CPU, (wstring (L" ") + (GetString (is_aes_hw_cpu_supported() ? "UISTR_YES" : "UISTR_NO"))).c_str()); - - ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_HW_ACCELERATION); - ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION); - } - return 0; - - case WM_COMMAND: - - switch (lw) - { - case IDCANCEL: - EndDialog (hwndDlg, lw); - return 1; - - case IDOK: - { - if (IsNonInstallMode()) - { - Error ("FEATURE_REQUIRES_INSTALLATION", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - BOOL disableHW = !IsDlgButtonChecked (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION); - BOOL enableExtendedIOCTL = IsDlgButtonChecked (hwndDlg, IDC_ENABLE_EXTENDED_IOCTL_SUPPORT); - - try - { - VOLUME_PROPERTIES_STRUCT prop; - try - { - BootEncStatus = BootEncObj->GetStatus(); - BootEncObj->GetVolumeProperties (&prop); - } - catch (...) - { - BootEncStatus.DriveMounted = false; - } - - if (BootEncStatus.DriveMounted) - { - byte userConfig; - string customUserMessage; - uint16 bootLoaderVersion; - - BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig, &customUserMessage, &bootLoaderVersion); - - if (bootLoaderVersion != VERSION_NUM) - Warning ("BOOT_LOADER_VERSION_INCORRECT_PREFERENCES", hwndDlg); - - if (disableHW) - userConfig |= TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION; - else - userConfig &= ~TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION; - - BootEncObj->WriteBootSectorUserConfig (userConfig, customUserMessage, prop.volumePim); - } - - SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION, disableHW); - SetDriverConfigurationFlag (TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL, enableExtendedIOCTL); - - DWORD bytesReturned; - if (!DeviceIoControl (hDriver, TC_IOCTL_REREAD_DRIVER_CONFIG, NULL, 0, NULL, 0, &bytesReturned, NULL)) - handleWin32Error (hwndDlg, SRC_POS); - - EnableHwEncryption (!disableHW); - - uint32 cpuFreeCount = 0; - if (IsDlgButtonChecked (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL)) - { - LRESULT cpuFreeItem = SendMessage (GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT), CB_GETCURSEL, 0, 0); - if (cpuFreeItem != CB_ERR) - cpuFreeCount = (uint32) (cpuFreeItem + 1); - } - - if (ReadEncryptionThreadPoolFreeCpuCountLimit() != cpuFreeCount) - { - BootEncObj->WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME, cpuFreeCount); - Warning ("SETTING_REQUIRES_REBOOT", hwndDlg); - } - - EndDialog (hwndDlg, lw); - return 1; - } - catch (Exception &e) - { - e.Show (hwndDlg); - } - } - return 1; - - case IDC_ENABLE_HARDWARE_ENCRYPTION: - if (!IsDlgButtonChecked (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION) - && AskWarnYesNo ("CONFIRM_SETTING_DEGRADES_PERFORMANCE", hwndDlg) == IDNO) - { - CheckDlgButton (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION, BST_CHECKED); - } - return 1; - - case IDC_LIMIT_ENC_THREAD_POOL: - if (IsDlgButtonChecked (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL) - && AskWarnYesNo ("CONFIRM_SETTING_DEGRADES_PERFORMANCE", hwndDlg) == IDNO) - { - CheckDlgButton (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL, BST_UNCHECKED); - } - else - { - SendMessage (GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT), CB_SETCURSEL, 0, 0); - Warning ("SETTING_REQUIRES_REBOOT", hwndDlg); // Warn the user before he thinks about benchmarking - } - - EnableWindow (GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT), IsDlgButtonChecked (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL)); - return 1; - - case IDC_BENCHMARK: - Benchmark (hwndDlg); - return 1; - - case IDC_MORE_INFO_ON_HW_ACCELERATION: - Applink ("hwacceleration", TRUE, ""); - return 1; - - case IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION: - Applink ("parallelization", TRUE, ""); - return 1; - } - - return 0; - } - - return 0; -} - - -static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - LocalizeDialog (hwndDlg, "IDD_TOKEN_PREFERENCES"); - SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, SecurityTokenLibraryPath); - CheckDlgButton (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT, CloseSecurityTokenSessionsAfterMount ? BST_CHECKED : BST_UNCHECKED); - - SetWindowTextW (GetDlgItem (hwndDlg, IDT_PKCS11_LIB_HELP), GetString("PKCS11_LIB_LOCATION_HELP")); - - return 0; - - case WM_COMMAND: - - switch (lw) - { - case IDCANCEL: - EndDialog (hwndDlg, lw); - return 1; - - case IDOK: - { - wchar_t securityTokenLibraryPath[MAX_PATH]; - GetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, securityTokenLibraryPath, ARRAYSIZE (securityTokenLibraryPath)); - - if (securityTokenLibraryPath[0] == 0) - { - try - { - SecurityToken::CloseLibrary(); - } - catch (...) { } - - SecurityTokenLibraryPath[0] = 0; - } - else - { - wchar_t prevSecurityTokenLibraryPath[MAX_PATH]; - StringCbCopyW (prevSecurityTokenLibraryPath, sizeof(prevSecurityTokenLibraryPath), SecurityTokenLibraryPath); - StringCbCopyW (SecurityTokenLibraryPath, sizeof(SecurityTokenLibraryPath), securityTokenLibraryPath); - - if (!InitSecurityTokenLibrary(hwndDlg)) - { - StringCbCopyW (SecurityTokenLibraryPath, sizeof(SecurityTokenLibraryPath), prevSecurityTokenLibraryPath); - return 1; - } - } - - CloseSecurityTokenSessionsAfterMount = (IsDlgButtonChecked (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT) == BST_CHECKED); - - WaitCursor (); - SaveSettings (hwndDlg); - NormalCursor (); - - EndDialog (hwndDlg, lw); - return 1; - } - - case IDC_AUTO_DETECT_PKCS11_MODULE: - { - wchar_t systemDir[MAX_PATH]; - GetSystemDirectory (systemDir, ARRAYSIZE (systemDir)); - WIN32_FIND_DATA findData; - bool found = false; - - WaitCursor(); - - HANDLE find = FindFirstFile ((wstring (systemDir) + L"\\*.dll").c_str(), &findData); - while (!found && find != INVALID_HANDLE_VALUE) - { - wstring dllPathname = wstring (systemDir) + L"\\" + findData.cFileName; - DWORD fileSize; - - char *file = LoadFile (dllPathname.c_str(), &fileSize); - if (file) - { - const char *functionName = "C_GetFunctionList"; - size_t strLen = strlen (functionName); - - if (fileSize > strLen) - { - for (size_t i = 0; i < fileSize - strLen; ++i) - { - if (memcmp (file + i, functionName, strLen) == 0) - { - HMODULE module = LoadLibrary (dllPathname.c_str()); - if (module) - { - if (GetProcAddress (module, functionName)) - { - SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, dllPathname.c_str()); - found = true; - - FreeLibrary (module); - break; - } - - FreeLibrary (module); - } - } - } - } - - free (file); - } - - if (!FindNextFile (find, &findData)) - break; - } - - if (find != INVALID_HANDLE_VALUE) - FindClose (find); - - NormalCursor(); - - if (!found) - Warning ("PKCS11_MODULE_AUTO_DETECTION_FAILED", hwndDlg); - - return 1; - } - - case IDC_SELECT_PKCS11_MODULE: - { - wchar_t securityTokenLibraryPath[MAX_PATH]; - wchar_t systemDir[MAX_PATH]; - wchar_t browseFilter[1024]; - - Info ("SELECT_PKCS11_MODULE_HELP", hwndDlg); - - StringCbPrintfW (browseFilter, sizeof(browseFilter), L"%ls (*.dll)%c*.dll%c%c", GetString ("DLL_FILES"), 0, 0, 0); - GetSystemDirectory (systemDir, ARRAYSIZE (systemDir)); - - if (BrowseFilesInDir (hwndDlg, "SELECT_PKCS11_MODULE", systemDir, securityTokenLibraryPath, TRUE, FALSE, browseFilter)) - SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, securityTokenLibraryPath); - return 1; - } - } - return 0; - } - - return 0; -} - -static BOOL CALLBACK DefaultMountParametersDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - { - LocalizeDialog (hwndDlg, "IDD_DEFAULT_MOUNT_PARAMETERS"); - - SendMessage (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), BM_SETCHECK, - DefaultVolumeTrueCryptMode ? BST_CHECKED:BST_UNCHECKED, 0); - - /* Populate the PRF algorithms list */ - int i, nIndex, defaultPrfIndex = 0; - HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); - SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); - - nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); - - for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) - { - nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); - SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); - if (DefaultVolumePkcs5 && (DefaultVolumePkcs5 == i)) - defaultPrfIndex = nIndex; - } - - /* make autodetection the default unless a specific PRF was specified in the command line */ - SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0); - - return 0; - } - - case WM_COMMAND: - - switch (lw) - { - case IDCANCEL: - EndDialog (hwndDlg, lw); - return 1; - - case IDOK: - { - int pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); - BOOL truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE); - /* SHA-256 is not supported by TrueCrypt */ - if ( (truecryptMode) - && (pkcs5 == SHA256) - ) - { - Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); - } - else - { - WaitCursor (); - DefaultVolumeTrueCryptMode = truecryptMode; - DefaultVolumePkcs5 = pkcs5; - - SaveSettings (hwndDlg); - - NormalCursor (); - EndDialog (hwndDlg, lw); - } - return 1; - } - - } - return 0; - } - - return 0; -} - -void SecurityTokenPreferencesDialog (HWND hwndDlg) -{ - DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PREFERENCES), hwndDlg, (DLGPROC) SecurityTokenPreferencesDlgProc, 0); -} - - -static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - { - if (!BootEncObj->GetStatus().DriveMounted) - { - Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - try - { - LocalizeDialog (hwndDlg, "IDD_SYSENC_SETTINGS"); - - uint32 driverConfig = ReadDriverConfigurationFlags(); - byte userConfig; - string customUserMessage; - uint16 bootLoaderVersion; - BOOL bPasswordCacheEnabled = (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD)? TRUE : FALSE; - BOOL bPimCacheEnabled = (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PIM)? TRUE : FALSE; - - BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig, &customUserMessage, &bootLoaderVersion); - - if (bootLoaderVersion != VERSION_NUM) - Warning ("BOOT_LOADER_VERSION_INCORRECT_PREFERENCES", hwndDlg); - - SendMessage (GetDlgItem (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE), EM_LIMITTEXT, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, 0); - SetDlgItemTextA (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE, customUserMessage.c_str()); - - CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT, (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT, (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton (hwndDlg, IDC_ALLOW_ESC_PBA_BYPASS, (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC) ? BST_UNCHECKED : BST_CHECKED); - CheckDlgButton (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD, bPasswordCacheEnabled ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton (hwndDlg, IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION, (driverConfig & TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION) ? BST_CHECKED : BST_UNCHECKED); - EnableWindow (GetDlgItem (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM), bPasswordCacheEnabled); - CheckDlgButton (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM, (bPasswordCacheEnabled && bPimCacheEnabled)? BST_CHECKED : BST_UNCHECKED); - - SetWindowTextW (GetDlgItem (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE_HELP), GetString("CUSTOM_BOOT_LOADER_MESSAGE_HELP")); - } - catch (Exception &e) - { - e.Show (hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - } - return 0; - - case WM_COMMAND: - - switch (lw) - { - case IDCANCEL: - EndDialog (hwndDlg, lw); - return 1; - - case IDOK: - { - VOLUME_PROPERTIES_STRUCT prop; - - if (!BootEncObj->GetStatus().DriveMounted) - { - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - try - { - BootEncObj->GetVolumeProperties (&prop); - } - catch (Exception &e) - { - e.Show (hwndDlg); - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - char customUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; - GetDlgItemTextA (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE, customUserMessage, sizeof (customUserMessage)); - - byte userConfig; - try - { - BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig); - } - catch (Exception &e) - { - e.Show (hwndDlg); - return 1; - } - - if (IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT)) - userConfig |= TC_BOOT_USER_CFG_FLAG_DISABLE_PIM; - else - userConfig &= ~TC_BOOT_USER_CFG_FLAG_DISABLE_PIM; - - if (IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT)) - userConfig |= TC_BOOT_USER_CFG_FLAG_SILENT_MODE; - else - userConfig &= ~TC_BOOT_USER_CFG_FLAG_SILENT_MODE; - - if (!IsDlgButtonChecked (hwndDlg, IDC_ALLOW_ESC_PBA_BYPASS)) - userConfig |= TC_BOOT_USER_CFG_FLAG_DISABLE_ESC; - else - userConfig &= ~TC_BOOT_USER_CFG_FLAG_DISABLE_ESC; - - try - { - BOOL bPasswordCacheEnabled = IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD); - BOOL bPimCacheEnabled = IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM); - BootEncObj->WriteBootSectorUserConfig (userConfig, customUserMessage, prop.volumePim); - SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD, bPasswordCacheEnabled); - SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PIM, (bPasswordCacheEnabled && bPimCacheEnabled)? TRUE : FALSE); - SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION, IsDlgButtonChecked (hwndDlg, IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION)); - } - catch (Exception &e) - { - e.Show (hwndDlg); - return 1; - } - - EndDialog (hwndDlg, lw); - return 1; - } - - case IDC_DISABLE_BOOT_LOADER_PIM_PROMPT: - if ((IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT)) - && AskWarnYesNo ("DISABLE_BOOT_LOADER_PIM_PROMPT", hwndDlg) == IDNO) - { - CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT, BST_UNCHECKED); - } - - case IDC_DISABLE_BOOT_LOADER_OUTPUT: - if ((IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT)) - && AskWarnYesNo ("CUSTOM_BOOT_LOADER_MESSAGE_PROMPT", hwndDlg) == IDNO) - { - CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT, BST_UNCHECKED); - } - - break; - - case IDC_BOOT_LOADER_CACHE_PASSWORD: - if (IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD)) - { - Warning ("BOOT_PASSWORD_CACHE_KEYBOARD_WARNING", hwndDlg); - EnableWindow (GetDlgItem (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM), TRUE); - } - else - { - EnableWindow (GetDlgItem (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM), FALSE); - } - - break; - } - return 0; - } - - return 0; -} - - -void MountSelectedVolume (HWND hwndDlg, BOOL mountWithOptions) -{ - if (!VolumeSelected(hwndDlg)) - { - Warning ("NO_VOLUME_SELECTED", hwndDlg); - } - else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) - { - mountOptions = defaultMountOptions; - bPrebootPasswordDlgMode = FALSE; - - if (mountWithOptions || GetAsyncKeyState (VK_CONTROL) < 0) - { - /* Priority is given to command line parameters - * Default values used only when nothing specified in command line - */ - if (CmdVolumePkcs5 == 0) - mountOptions.ProtectedHidVolPkcs5Prf = DefaultVolumePkcs5; - else - mountOptions.ProtectedHidVolPkcs5Prf = CmdVolumePkcs5; - mountOptions.ProtectedHidVolPim = CmdVolumePim; - if (IDCANCEL == DialogBoxParamW (hInst, - MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, - (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions)) - return; - - if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) - { - wchar_t selectedVolume [TC_MAX_PATH + 1]; - GetVolumePath (hwndDlg, selectedVolume, ARRAYSIZE (selectedVolume)); - KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, selectedVolume); - } - } - - if (CheckMountList (hwndDlg, FALSE)) - _beginthread (mountThreadFunction, 0, hwndDlg); - } - else - Warning ("SELECT_FREE_DRIVE", hwndDlg); -} - -static BOOL HandleDriveListMouseWheelEvent (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bListMustBePointed) -{ - static BOOL eventHandlerActive = FALSE; - if (eventHandlerActive) - return 0; - - RECT listRect; - int mouseX = GET_X_LPARAM (lParam); - int mouseY = GET_Y_LPARAM (lParam); - - GetWindowRect (GetDlgItem (MainDlg, IDC_DRIVELIST), &listRect); - - // Determine if the mouse pointer is within the main drive list - bool bListPointed = (mouseX >= listRect.left && mouseX <= listRect.right - && mouseY >= listRect.top && mouseY <= listRect.bottom); - - if (bListMustBePointed && bListPointed - || !bListMustBePointed) - { - eventHandlerActive = TRUE; - - if (!bListMustBePointed && bListPointed) - SetFocus (GetDlgItem (MainDlg, IDC_DRIVELIST)); - - SendMessage (GetDlgItem (MainDlg, IDC_DRIVELIST), uMsg, wParam, lParam); - - eventHandlerActive = FALSE; - return 0; // Do not process this event any further e.g. to prevent two lists from being scrolled at once - } - - return 1; -} - - -static LRESULT CALLBACK MouseWheelProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - WNDPROC wp = (WNDPROC) GetWindowLongPtrW (hwnd, GWLP_USERDATA); - - switch (message) - { - case WM_MOUSEWHEEL: - - if (HandleDriveListMouseWheelEvent (message, wParam, lParam, TRUE) == 0) - return 0; // Do not process this event any further e.g. to prevent two lists from being scrolled at once - } - - return CallWindowProcW (wp, hwnd, message, wParam, lParam); -} - - -void HookMouseWheel (HWND hwndDlg, UINT ctrlId) -{ - HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); - - SetWindowLongPtrW (hwndCtrl, GWLP_USERDATA, (LONG_PTR) GetWindowLongPtrW (hwndCtrl, GWLP_WNDPROC)); - SetWindowLongPtrW (hwndCtrl, GWLP_WNDPROC, (LONG_PTR) MouseWheelProc); -} +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + governed by the TrueCrypt License 3.0, also 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) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. */ + +#include "Tcdefs.h" +#include "cpu.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Apidrvr.h" +#include "BootEncryption.h" +#include "Cmdline.h" +#include "Crypto.h" +#include "Dlgcode.h" +#include "Combo.h" +#include "Favorites.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" + +#include + +#include + +typedef BOOL (WINAPI *WTSREGISTERSESSIONNOTIFICATION)(HWND, DWORD); +typedef BOOL (WINAPI *WTSUNREGISTERSESSIONNOTIFICATION)(HWND); + +using namespace VeraCrypt; + +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 */ +wchar_t szFileName[TC_MAX_PATH+1]; /* Volume to mount */ +wchar_t szDriveLetter[3]; /* Drive Letter to mount */ +wchar_t commandLineDrive = 0; +BOOL bCacheInDriver = FALSE; /* Cache any passwords we see */ +BOOL bCacheInDriverDefault = FALSE; +BOOL bCacheDuringMultipleMount = FALSE; +BOOL bCmdCacheDuringMultipleMount = FALSE; +BOOL bIncludePimInCache = FALSE; +BOOL bTryEmptyPasswordWhenKeyfileUsed = FALSE; +BOOL bCmdTryEmptyPasswordWhenKeyfileUsed = FALSE; +BOOL bCmdTryEmptyPasswordWhenKeyfileUsedValid = FALSE; +BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */ +BOOL bUseDifferentTrayIconIfVolMounted = TRUE; +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 bDismountOnSessionLocked = 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 LogOn = FALSE; +BOOL bAutoMountDevices = FALSE; /* Auto-mount devices */ +BOOL bAutoMountFavorites = FALSE; +BOOL bPlaySoundOnSuccessfulHkDismount = TRUE; +BOOL bDisplayBalloonOnSuccessfulHkDismount = TRUE; +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 Quit = FALSE; /* Exit after processing command line */ +BOOL ComServerMode = FALSE; +BOOL ServiceMode = 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 = -2; /* Volume drive letter to unmount (-1 = all) */ +Password VolumePassword; /* Password used for mounting volumes */ +Password CmdVolumePassword; /* Password passed from command line */ +char CmdTokenPin [SecurityToken::MaxPasswordLength + 1] = {0}; +int VolumePkcs5 = 0; +int CmdVolumePkcs5 = 0; +int VolumePim = -1; +int CmdVolumePim = -1; +int DefaultVolumePkcs5 = 0; +BOOL VolumeTrueCryptMode = FALSE; +BOOL CmdVolumeTrueCryptMode = FALSE; +BOOL DefaultVolumeTrueCryptMode = FALSE; +BOOL CmdVolumePasswordValid = FALSE; +MountOptions CmdMountOptions; +BOOL CmdMountOptionsValid = FALSE; +MountOptions mountOptions; +MountOptions defaultMountOptions; +KeyFile *FirstCmdKeyFile; + +HBITMAP hbmLogoBitmapRescaled = NULL; +wchar_t OrigKeyboardLayout [8+1] = L"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 int LastDriveListVolumeColumnWidth; +// WTS handling +static HMODULE hWtsLib = NULL; +static WTSREGISTERSESSIONNOTIFICATION fnWtsRegisterSessionNotification = NULL; +static WTSUNREGISTERSESSIONNOTIFICATION fnWtsUnRegisterSessionNotification = NULL; + +static void RegisterWtsNotification(HWND hWnd) +{ + if (!hWtsLib) + { + wchar_t dllPath[MAX_PATH]; + if (GetSystemDirectory(dllPath, MAX_PATH)) + StringCbCatW(dllPath, sizeof(dllPath), L"\\wtsapi32.dll"); + else + StringCbCopyW(dllPath, sizeof(dllPath), L"c:\\Windows\\System32\\wtsapi32.dll"); + + hWtsLib = LoadLibrary(dllPath); + if (hWtsLib) + { + fnWtsRegisterSessionNotification = (WTSREGISTERSESSIONNOTIFICATION) GetProcAddress(hWtsLib, "WTSRegisterSessionNotification" ); + fnWtsUnRegisterSessionNotification = (WTSUNREGISTERSESSIONNOTIFICATION) GetProcAddress(hWtsLib, "WTSUnRegisterSessionNotification" ); + if ( !fnWtsRegisterSessionNotification + || !fnWtsUnRegisterSessionNotification + || !fnWtsRegisterSessionNotification( hWnd, NOTIFY_FOR_THIS_SESSION ) + ) + { + fnWtsRegisterSessionNotification = NULL; + fnWtsUnRegisterSessionNotification = NULL; + FreeLibrary(hWtsLib); + hWtsLib = NULL; + } + } + } +} + +static void UnregisterWtsNotification(HWND hWnd) +{ + if (hWtsLib && fnWtsUnRegisterSessionNotification) + { + fnWtsUnRegisterSessionNotification(hWnd); + FreeLibrary(hWtsLib); + hWtsLib = NULL; + fnWtsRegisterSessionNotification = NULL; + fnWtsUnRegisterSessionNotification = NULL; + } +} + +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 (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&CmdVolumePkcs5, sizeof (CmdVolumePkcs5)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&CmdVolumePim, sizeof (CmdVolumePim)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&CmdVolumeTrueCryptMode, sizeof (CmdVolumeTrueCryptMode)); + burn (&mountOptions, sizeof (mountOptions)); + burn (&defaultMountOptions, sizeof (defaultMountOptions)); + burn (szFileName, sizeof(szFileName)); + burn (&CmdTokenPin, sizeof (CmdTokenPin)); + + /* Cleanup common code resources */ + cleanup (); + + if (BootEncObj != NULL) + { + delete BootEncObj; + BootEncObj = NULL; + } + + RandStop (TRUE); +} + +void RefreshMainDlg (HWND hwndDlg) +{ + int drive = (wchar_t) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)))); + + MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory); + LoadDriveLetters (hwndDlg, 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), L""); + ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); + } + + if (TaskBarIconMutex != NULL) + { + MainWindowHidden = TRUE; + ShowWindow (hwndDlg, SW_HIDE); + } + else + { + KillTimer (hwndDlg, TIMER_ID_MAIN); + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + EndDialog (hwndDlg, 0); + } +} + +static void InitMainDialog (HWND hwndDlg) +{ + MENUITEMINFOW info; + char *popupTexts[] = {"MENU_VOLUMES", "MENU_SYSTEM_ENCRYPTION", "MENU_FAVORITES", "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); + + SetWindowLongPtrW (hwndDlg, DWLP_USER, (LONG_PTR) (IsAdmin() ? TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES : 0)); + + DragAcceptFiles (hwndDlg, TRUE); + + SendMessageW (GetDlgItem (hwndDlg, IDC_VOLUME), CB_LIMITTEXT, TC_MAX_PATH, 0); + SetWindowTextW (hwndDlg, (IsAdmin() && !IsBuiltInAdmin() && IsUacSupported() && !IsNonInstallMode()) ? (wstring (lpszTitle) + L" [" + GetString ("ADMINISTRATOR") + L"]").c_str() : 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 = (UINT) 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 (strcmp (popupTexts[i], "MENU_WEBSITE") == 0) + info.fType = MFT_STRING | MFT_RIGHTJUSTIFY; + else + info.fType = MFT_STRING; + + if (strcmp (popupTexts[i], "MENU_FAVORITES") == 0) + FavoriteVolumesMenu = GetSubMenu (GetMenu (hwndDlg), i); + + info.dwTypeData = str; + info.cch = (UINT) wcslen (str); + + SetMenuItemInfoW (GetMenu (hwndDlg), i, TRUE, &info); + } + + // Disable menu item for changing system header key derivation algorithm until it's implemented + EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO, MF_GRAYED); + + try + { + LoadFavoriteVolumes(); + } + catch (Exception &e) + { + e.Show (NULL); + } + + // 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 (hwndDlg, 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, 10000); + } + else + { + SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_DRIVELIST), 1L); + } + + 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); +} + +void GetVolumePath (HWND hwndDlg, LPWSTR szPath, int nMaxCount) +{ + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), szPath, nMaxCount); + CorrectFileName (szPath); +} + +/* 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; + + GetVolumePath (MainDlg, szFileName, ARRAYSIZE (szFileName)); + + retCode = IsSystemDevicePath (szFileName, MainDlg, FALSE); + + return (WholeSysDriveEncryption(FALSE) ? (retCode == 2 || retCode == 1) : (retCode == 1)); + } + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + return FALSE; +} + +// When a function does not require the affected volume to be dismounted, there may be cases where we have two valid +// paths selected in the main window and we cannot be sure which of them the user really intends to apply the function to. +// This function asks the user to explicitly select either the volume path specified in the input field below the main +// drive list (whether mounted or not), or the path to the volume selected in the main drive list. If, however, both +// of the GUI elements contain the same volume (or one of them does not contain any path), this function does not +// ask the user and returns the volume path directly (no selection ambiguity). +// If driveNoPtr is not NULL, and the volume is mounted, its drive letter is returned in *driveNoPtr (if no valid drive +// letter is resolved, -1 is stored instead). +static wstring ResolveAmbiguousSelection (HWND hwndDlg, int *driveNoPtr) +{ + LPARAM selectedDrive = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); + + wchar_t volPathInputField [TC_MAX_PATH]; + + wchar_t volPathDriveListW [TC_MAX_PATH]; + wstring volPathDriveListStr; + + wstring retPath; + + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + + BOOL useInputField = TRUE; + + memset (&prop, 0, sizeof(prop)); + + BOOL ambig = (LOWORD (selectedDrive) != TC_MLIST_ITEM_FREE && LOWORD (selectedDrive) != 0xffff && HIWORD (selectedDrive) != 0xffff + && VolumeSelected (MainDlg)); + + if (VolumeSelected (MainDlg)) + { + // volPathInputField will contain the volume path (if any) from the input field below the drive list + GetVolumePath (MainDlg, volPathInputField, ARRAYSIZE (volPathInputField)); + + if (!ambig) + retPath = (wstring) volPathInputField; + } + + if (LOWORD (selectedDrive) != TC_MLIST_ITEM_FREE && LOWORD (selectedDrive) != 0xffff && HIWORD (selectedDrive) != 0xffff) + { + // A volume is selected in the main drive list. + + switch (LOWORD (selectedDrive)) + { + case TC_MLIST_ITEM_NONSYS_VOL: + prop.driveNo = HIWORD (selectedDrive) - L'A'; + + if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) + { + // The driver did not return any path for this drive letter (the volume may have been dismounted). + + // Return whatever is in the input field below the drive list (even if empty) + return ((wstring) volPathInputField); + } + + // volPathDriveListWStr will contain the volume path selected in the main drive list + volPathDriveListStr = (wstring) prop.wszVolume; + break; + + case TC_MLIST_ITEM_SYS_PARTITION: + + GetSysDevicePaths (MainDlg); + + if (bCachedSysDevicePathsValid) + { + volPathDriveListStr = (wstring) SysPartitionDevicePath; + } + + break; + + case TC_MLIST_ITEM_SYS_DRIVE: + + GetSysDevicePaths (MainDlg); + + if (bCachedSysDevicePathsValid) + { + volPathDriveListStr = (wstring) SysDriveDevicePath; + } + + break; + } + + if (!ambig) + { + useInputField = FALSE; + retPath = volPathDriveListStr; + } + } + + if (ambig) + { + /* We have two paths. Compare them and if they don't match, ask the user to select one of them. Otherwise, return the path without asking. */ + + if (wmemcmp (volPathDriveListStr.c_str (), L"\\??\\", 4) == 0) + { + // The volume path starts with "\\??\\" which is used for file-hosted containers. We're going to strip this prefix. + + volPathDriveListStr = (wstring) (volPathDriveListStr.c_str () + 4); + } + + StringCbCopyW (volPathDriveListW, sizeof(volPathDriveListW), volPathDriveListStr.c_str ()); + + if (wcscmp (((wmemcmp (volPathDriveListW, L"\\??\\", 4) == 0) ? volPathDriveListW + 4 : volPathDriveListW), volPathInputField) != 0) + { + // The path selected in the input field is different from the path to the volume selected + // in the drive lettter list. We have to resolve possible ambiguity. + + wchar_t *tmp[] = {L"", L"", L"", L"", L"", 0}; + const int maxVolPathLen = 80; + + if (volPathDriveListStr.length () > maxVolPathLen) + { + // Ellipsis (path too long) + volPathDriveListStr = wstring (L"...") + volPathDriveListStr.substr (volPathDriveListStr.length () - maxVolPathLen, maxVolPathLen); + } + + wstring volPathInputFieldWStr (volPathInputField); + + if (volPathInputFieldWStr.length () > maxVolPathLen) + { + // Ellipsis (path too long) + volPathInputFieldWStr = wstring (L"...") + volPathInputFieldWStr.substr (volPathInputFieldWStr.length () - maxVolPathLen, maxVolPathLen); + } + + tmp[1] = GetString ("AMBIGUOUS_VOL_SELECTION"); + tmp[2] = (wchar_t *) volPathDriveListStr.c_str(); + tmp[3] = (wchar_t *) volPathInputFieldWStr.c_str(); + tmp[4] = GetString ("IDCANCEL"); + + switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg)) + { + case 1: + retPath = volPathDriveListStr; + break; + + case 2: + retPath = (wstring) volPathInputField; + break; + + default: + if (driveNoPtr != NULL) + *driveNoPtr = -1; + + return wstring (L""); + } + } + else + { + // Both selected paths are the same + retPath = (wstring) volPathInputField; + } + } + + if (driveNoPtr != NULL) + *driveNoPtr = GetMountedVolumeDriveNo ((wchar_t *) retPath.c_str ()); + + + if (wmemcmp (retPath.c_str (), L"\\??\\", 4) == 0) + { + // The selected volume path starts with "\\??\\" which is used for file-hosted containers. We're going to strip this prefix. + + retPath = (wstring) (retPath.c_str () + 4); + } + + return retPath; +} + +void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL* pbSettingsModified, BOOL* pbHistoryModified) +{ + char langid[6] = {0}; + if (!bOnlyCheckModified) + EnableHwEncryption ((ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE); + + WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE; + + if (!bOnlyCheckModified) + LoadSysEncSettings (); + + if (!bOnlyCheckModified && LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0) + bInPlaceEncNonSysPending = TRUE; + + // If the config file has already been loaded during this session + if (ConfigBuffer != NULL) + { + free (ConfigBuffer); + ConfigBuffer = NULL; + } + + // Options + ConfigReadCompareInt ("OpenExplorerWindowAfterMount", FALSE, &bExplore, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("UseDifferentTrayIconIfVolumesMounted", TRUE, &bUseDifferentTrayIconIfVolMounted, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("SaveVolumeHistory", FALSE, &bHistory, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("CachePasswords", FALSE, &bCacheInDriverDefault, bOnlyCheckModified, pbSettingsModified); + if (!bOnlyCheckModified) + bCacheInDriver = bCacheInDriverDefault; + + ConfigReadCompareInt ("CachePasswordDuringMultipleMount", FALSE, &bCacheDuringMultipleMount, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("WipePasswordCacheOnExit", FALSE, &bWipeCacheOnExit, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("WipeCacheOnAutoDismount", TRUE, &bWipeCacheOnAutoDismount, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("IncludePimInCache", FALSE, &bIncludePimInCache, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("TryEmptyPasswordWhenKeyfileUsed",FALSE, &bTryEmptyPasswordWhenKeyfileUsed, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("StartOnLogon", FALSE, &bStartOnLogon, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("MountDevicesOnLogon", FALSE, &bMountDevicesOnLogon, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("MountFavoritesOnLogon", FALSE, &bMountFavoritesOnLogon, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("EnableBackgroundTask", TRUE, &bEnableBkgTask, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("CloseBackgroundTaskOnNoVolumes", FALSE, &bCloseBkgTaskWhenNoVolumes, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("DismountOnLogOff", !(IsServerOS() && IsAdmin()), &bDismountOnLogOff, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("DismountOnSessionLocked", FALSE, &bDismountOnSessionLocked, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("DismountOnPowerSaving", FALSE, &bDismountOnPowerSaving, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("DismountOnScreenSaver", FALSE, &bDismountOnScreenSaver, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("ForceAutoDismount", TRUE, &bForceAutoDismount, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("MaxVolumeIdleTime", -60, &MaxVolumeIdleTime, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("HiddenSectorDetectionStatus", 0, &HiddenSectorDetectionStatus, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("UseKeyfiles", FALSE, &defaultKeyFilesParam.EnableKeyFiles, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("PreserveTimestamps", TRUE, &defaultMountOptions.PreserveTimestamp, bOnlyCheckModified, pbSettingsModified); + if (!bOnlyCheckModified) + bPreserveTimestamp = defaultMountOptions.PreserveTimestamp; + + ConfigReadCompareInt ("ShowDisconnectedNetworkDrives", FALSE, &bShowDisconnectedNetworkDrives, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("HideWaitingDialog", FALSE, &bHideWaitingDialog, bOnlyCheckModified, pbSettingsModified); + + ConfigReadCompareInt ("MountVolumesRemovable", FALSE, &defaultMountOptions.Removable, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("MountVolumesReadOnly", FALSE, &defaultMountOptions.ReadOnly, bOnlyCheckModified, pbSettingsModified); + + if (!bOnlyCheckModified) + { + defaultMountOptions.ProtectHiddenVolume = FALSE; + defaultMountOptions.ProtectedHidVolPkcs5Prf = 0; + defaultMountOptions.ProtectedHidVolPim = 0; + defaultMountOptions.PartitionInInactiveSysEncScope = FALSE; + defaultMountOptions.RecoveryMode = FALSE; + defaultMountOptions.UseBackupHeader = FALSE; + + mountOptions = defaultMountOptions; + } + + ConfigReadCompareInt ("CloseSecurityTokenSessionsAfterMount", 0, &CloseSecurityTokenSessionsAfterMount, bOnlyCheckModified, pbSettingsModified); + + if (IsHiddenOSRunning()) + ConfigReadCompareInt ("HiddenSystemLeakProtNotifStatus", TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE, &HiddenSysLeakProtectionNotificationStatus, bOnlyCheckModified, pbSettingsModified); + + // Drive letter - command line arg overrides registry + if (!bOnlyCheckModified && bHistory && szDriveLetter[0] == 0) + { + char szTmp[3] = {0}; + ConfigReadString ("LastSelectedDrive", "", szTmp, sizeof (szTmp)); + MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, szDriveLetter, ARRAYSIZE (szDriveLetter)); + } + if (bHistory && pbSettingsModified) + { + // only check for last drive modification if history enabled + char szTmp[32] = {0}; + LPARAM lLetter; + lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); + if (LOWORD (lLetter) != 0xffff) + StringCbPrintfA (szTmp, sizeof(szTmp), "%lc:", (wchar_t) HIWORD (lLetter)); + + ConfigReadCompareString ("LastSelectedDrive", "", szTmp, sizeof (szTmp), bOnlyCheckModified, pbSettingsModified); + } + + { + char szTmp[MAX_PATH]; + WideCharToMultiByte (CP_UTF8, 0, SecurityTokenLibraryPath, -1, szTmp, MAX_PATH, NULL, NULL); + ConfigReadCompareString ("SecurityTokenLibrary", "", szTmp, sizeof (szTmp) - 1, bOnlyCheckModified, pbSettingsModified); + MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, SecurityTokenLibraryPath, ARRAYSIZE (SecurityTokenLibraryPath)); + if (!bOnlyCheckModified && SecurityTokenLibraryPath[0]) + { + InitSecurityTokenLibrary(hwndDlg); + } + } + + // Hotkeys + ConfigReadCompareInt ("PlaySoundOnHotkeyMountDismount", TRUE, &bPlaySoundOnSuccessfulHkDismount, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("DisplayMsgBoxOnHotkeyDismount", TRUE, &bDisplayBalloonOnSuccessfulHkDismount, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModAutoMountDevices", 0, (int*) &Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeAutoMountDevices", 0, (int*) &Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModDismountAll", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeDismountAll", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModWipeCache", 0, (int*) &Hotkeys [HK_WIPE_CACHE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeWipeCache", 0, (int*) &Hotkeys [HK_WIPE_CACHE].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModDismountAllWipe", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeDismountAllWipe", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModForceDismountAllWipe", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeForceDismountAllWipe", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModForceDismountAllWipeExit", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeForceDismountAllWipeExit", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModMountFavoriteVolumes", 0, (int*) &Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeMountFavoriteVolumes", 0, (int*) &Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModShowHideMainWindow", 0, (int*) &Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeShowHideMainWindow", 0, (int*) &Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyModCloseSecurityTokenSessions", 0, (int*) &Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("HotkeyCodeCloseSecurityTokenSessions", 0, (int*) &Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode, bOnlyCheckModified, pbSettingsModified); + + // History + if (bHistoryCmdLine != TRUE) + { + LoadCombo (GetDlgItem (MainDlg, IDC_VOLUME), bHistory, bOnlyCheckModified, pbHistoryModified); + if (!bOnlyCheckModified && CmdLineVolumeSpecified) + SetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szFileName); + } + + // Mount Options + ConfigReadCompareInt ("DefaultPRF", 0, &DefaultVolumePkcs5, bOnlyCheckModified, pbSettingsModified); + ConfigReadCompareInt ("DefaultTrueCryptMode", FALSE, &DefaultVolumeTrueCryptMode, bOnlyCheckModified, pbSettingsModified); + + if (bOnlyCheckModified) + { + if (!IsNonInstallMode ()) + { + ConfigReadString ("Language", "", langid, sizeof (langid)); + // when installed, if no preferred language set by user, English is set default + // + if (langid [0] == 0) + StringCbCopyA (langid, sizeof(langid), "en"); + + if (pbSettingsModified && strcmp (langid, GetPreferredLangId ())) + *pbSettingsModified = TRUE; + } + else + { + StringCbCopyA (langid, sizeof(langid), GetPreferredLangId ()); + ConfigReadCompareString ("Language", "", langid, sizeof (langid), TRUE, pbSettingsModified); + } + } + + if (DefaultVolumePkcs5 < 0 || DefaultVolumePkcs5 > LAST_PRF_ID) + DefaultVolumePkcs5 = 0; + if (DefaultVolumeTrueCryptMode != TRUE && DefaultVolumeTrueCryptMode != FALSE) + DefaultVolumeTrueCryptMode = FALSE; + +} + +void LoadSettings ( HWND hwndDlg ) +{ + LoadSettingsAndCheckModified (hwndDlg, FALSE, NULL, NULL); +} + +void SaveSettings (HWND hwndDlg) +{ + WaitCursor (); + + // Check first if modifications ocurred before writing to the settings and history files + // This avoids leaking information about VeraCrypt usage when user only mount volumes without changing setttings or history + BOOL bSettingsChanged = FALSE; + BOOL bHistoryChanged = FALSE; + + LoadSettingsAndCheckModified (hwndDlg, TRUE, &bSettingsChanged, &bHistoryChanged); + + if (bSettingsChanged) + { + char szTmp[32] = {0}; + LPARAM lLetter; + + // Options + ConfigWriteBegin (); + + ConfigWriteInt ("OpenExplorerWindowAfterMount", bExplore); + ConfigWriteInt ("UseDifferentTrayIconIfVolumesMounted", bUseDifferentTrayIconIfVolMounted); + ConfigWriteInt ("SaveVolumeHistory", bHistory); + + ConfigWriteInt ("CachePasswords", bCacheInDriverDefault); + ConfigWriteInt ("CachePasswordDuringMultipleMount", bCacheDuringMultipleMount); + ConfigWriteInt ("WipePasswordCacheOnExit", bWipeCacheOnExit); + ConfigWriteInt ("WipeCacheOnAutoDismount", bWipeCacheOnAutoDismount); + + ConfigWriteInt ("IncludePimInCache", bIncludePimInCache); + + ConfigWriteInt ("TryEmptyPasswordWhenKeyfileUsed", bTryEmptyPasswordWhenKeyfileUsed); + + ConfigWriteInt ("StartOnLogon", bStartOnLogon); + ConfigWriteInt ("MountDevicesOnLogon", bMountDevicesOnLogon); + ConfigWriteInt ("MountFavoritesOnLogon", bMountFavoritesOnLogon); + + ConfigWriteInt ("MountVolumesReadOnly", defaultMountOptions.ReadOnly); + ConfigWriteInt ("MountVolumesRemovable", defaultMountOptions.Removable); + ConfigWriteInt ("PreserveTimestamps", defaultMountOptions.PreserveTimestamp); + ConfigWriteInt ("ShowDisconnectedNetworkDrives",bShowDisconnectedNetworkDrives); + ConfigWriteInt ("HideWaitingDialog", bHideWaitingDialog); + + ConfigWriteInt ("EnableBackgroundTask", bEnableBkgTask); + ConfigWriteInt ("CloseBackgroundTaskOnNoVolumes", bCloseBkgTaskWhenNoVolumes); + + ConfigWriteInt ("DismountOnLogOff", bDismountOnLogOff); + ConfigWriteInt ("DismountOnSessionLocked", bDismountOnSessionLocked); + ConfigWriteInt ("DismountOnPowerSaving", bDismountOnPowerSaving); + ConfigWriteInt ("DismountOnScreenSaver", bDismountOnScreenSaver); + ConfigWriteInt ("ForceAutoDismount", bForceAutoDismount); + ConfigWriteInt ("MaxVolumeIdleTime", MaxVolumeIdleTime); + + ConfigWriteInt ("HiddenSectorDetectionStatus", HiddenSectorDetectionStatus); + + ConfigWriteInt ("UseKeyfiles", defaultKeyFilesParam.EnableKeyFiles); + + if (IsHiddenOSRunning()) + ConfigWriteInt ("HiddenSystemLeakProtNotifStatus", HiddenSysLeakProtectionNotificationStatus); + + // save last selected drive only when history enabled + if (bHistory) + { + // Drive Letter + lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); + if (LOWORD (lLetter) != 0xffff) + StringCbPrintfA (szTmp, sizeof(szTmp), "%lc:", (wchar_t) HIWORD (lLetter)); + ConfigWriteString ("LastSelectedDrive", szTmp); + } + + ConfigWriteInt ("CloseSecurityTokenSessionsAfterMount", CloseSecurityTokenSessionsAfterMount); + + // Hotkeys + ConfigWriteInt ("HotkeyModAutoMountDevices", Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeAutoMountDevices", Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyCode); + ConfigWriteInt ("HotkeyModDismountAll", Hotkeys[HK_DISMOUNT_ALL].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeDismountAll", Hotkeys[HK_DISMOUNT_ALL].vKeyCode); + ConfigWriteInt ("HotkeyModWipeCache", Hotkeys[HK_WIPE_CACHE].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeWipeCache", Hotkeys[HK_WIPE_CACHE].vKeyCode); + ConfigWriteInt ("HotkeyModDismountAllWipe", Hotkeys[HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeDismountAllWipe", Hotkeys[HK_DISMOUNT_ALL_AND_WIPE].vKeyCode); + ConfigWriteInt ("HotkeyModForceDismountAllWipe", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeForceDismountAllWipe", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode); + ConfigWriteInt ("HotkeyModForceDismountAllWipeExit", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeForceDismountAllWipeExit", Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode); + ConfigWriteInt ("HotkeyModMountFavoriteVolumes", Hotkeys[HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeMountFavoriteVolumes", Hotkeys[HK_MOUNT_FAVORITE_VOLUMES].vKeyCode); + ConfigWriteInt ("HotkeyModShowHideMainWindow", Hotkeys[HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeShowHideMainWindow", Hotkeys[HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode); + ConfigWriteInt ("HotkeyModCloseSecurityTokenSessions", Hotkeys[HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers); + ConfigWriteInt ("HotkeyCodeCloseSecurityTokenSessions", Hotkeys[HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode); + ConfigWriteInt ("PlaySoundOnHotkeyMountDismount", bPlaySoundOnSuccessfulHkDismount); + ConfigWriteInt ("DisplayMsgBoxOnHotkeyDismount", bDisplayBalloonOnSuccessfulHkDismount); + + // Language + ConfigWriteString ("Language", GetPreferredLangId ()); + + // PKCS#11 Library Path + ConfigWriteStringW ("SecurityTokenLibrary", SecurityTokenLibraryPath[0] ? SecurityTokenLibraryPath : L""); + + // Mount Options + ConfigWriteInt ("DefaultPRF", DefaultVolumePkcs5); + ConfigWriteInt ("DefaultTrueCryptMode", DefaultVolumeTrueCryptMode); + + ConfigWriteEnd (hwndDlg); + } + + if (bHistoryChanged) + { + // History + DumpCombo (GetDlgItem (MainDlg, IDC_VOLUME), IsButtonChecked (GetDlgItem (MainDlg, IDC_NO_HISTORY))); + } + + NormalCursor (); +} + +// Returns TRUE if system encryption or decryption had been or is in progress and has not been completed +static BOOL SysEncryptionOrDecryptionRequired (void) +{ + /* If you update this function, revise SysEncryptionOrDecryptionRequired() in Tcformat.c as well. */ + + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + return (SystemEncryptionStatus == SYSENC_STATUS_ENCRYPTING + || SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING + || + ( + BootEncStatus.DriveMounted + && + ( + BootEncStatus.ConfiguredEncryptedAreaStart != BootEncStatus.EncryptedAreaStart + || BootEncStatus.ConfiguredEncryptedAreaEnd != BootEncStatus.EncryptedAreaEnd + ) + ) + ); +} + +// Returns TRUE if the system partition/drive is completely encrypted +static BOOL SysDriveOrPartitionFullyEncrypted (BOOL bSilent) +{ + /* If you update this function, revise SysDriveOrPartitionFullyEncrypted() in Tcformat.c as well. */ + + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + if (!bSilent) + e.Show (MainDlg); + } + + return (!BootEncStatus.SetupInProgress + && BootEncStatus.ConfiguredEncryptedAreaEnd != 0 + && BootEncStatus.ConfiguredEncryptedAreaEnd != -1 + && BootEncStatus.ConfiguredEncryptedAreaStart == BootEncStatus.EncryptedAreaStart + && BootEncStatus.ConfiguredEncryptedAreaEnd == BootEncStatus.EncryptedAreaEnd); +} + +// Returns TRUE if the system partition/drive is being filtered by the TrueCrypt driver and the key data +// was successfully decrypted (the device is fully ready to be encrypted or decrypted). Note that this +// function does not examine whether the system device is encrypted or not (or to what extent). +static BOOL SysEncDeviceActive (BOOL bSilent) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + if (!bSilent) + e.Show (MainDlg); + + return FALSE; + } + + return (BootEncStatus.DriveMounted); +} + +// Returns TRUE if the entire system drive (as opposed to the system partition only) of the currently running OS is (or is to be) encrypted +BOOL WholeSysDriveEncryption (BOOL bSilent) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + + if (BootEncStatus.BootDriveLength.QuadPart < 1) // paranoid check + return FALSE; + else + return (BootEncStatus.ConfiguredEncryptedAreaStart == TC_BOOT_LOADER_AREA_SIZE + && BootEncStatus.ConfiguredEncryptedAreaEnd >= BootEncStatus.BootDriveLength.QuadPart - 1); + } + catch (Exception &e) + { + if (!bSilent) + e.Show (MainDlg); + + return FALSE; + } +} + +// Returns the size of the system drive/partition (if encrypted) in bytes +unsigned __int64 GetSysEncDeviceSize (BOOL bSilent) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + if (!bSilent) + e.Show (MainDlg); + return 1; + } + + if ( BootEncStatus.ConfiguredEncryptedAreaEnd < 0 + || BootEncStatus.ConfiguredEncryptedAreaStart < 0 + || BootEncStatus.ConfiguredEncryptedAreaEnd < BootEncStatus.ConfiguredEncryptedAreaStart + ) + return 1; // we return 1 to avoid devision by zero + else + return ((unsigned __int64)(BootEncStatus.ConfiguredEncryptedAreaEnd - BootEncStatus.ConfiguredEncryptedAreaStart)) + 1; +} + +// Returns the current size of the encrypted area of the system drive/partition in bytes +unsigned __int64 GetSysEncDeviceEncryptedPartSize (BOOL bSilent) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + if (!bSilent) + e.Show (MainDlg); + return 0; + } + + if ( BootEncStatus.EncryptedAreaEnd < 0 + || BootEncStatus.EncryptedAreaStart < 0 + || BootEncStatus.EncryptedAreaEnd < BootEncStatus.EncryptedAreaStart + ) + return 0; + else + return ((unsigned __int64)(BootEncStatus.EncryptedAreaEnd - BootEncStatus.EncryptedAreaStart)) + 1; +} + + +static void PopulateSysEncContextMenu (HMENU popup, BOOL bToolsOnly) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (!bToolsOnly && !IsHiddenOSRunning()) + { + if (SysEncryptionOrDecryptionRequired ()) + { + if (!BootEncStatus.SetupInProgress) + AppendMenuW (popup, MF_STRING, IDM_SYSENC_RESUME, GetString ("IDM_SYSENC_RESUME")); + + if (SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING) + AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT")); + + AppendMenuW (popup, MF_STRING, IDM_ENCRYPT_SYSTEM_DEVICE, GetString ("ENCRYPT")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + } + } + + AppendMenuW (popup, MF_STRING, IDM_CHANGE_SYS_PASSWORD, GetString ("IDM_CHANGE_SYS_PASSWORD")); + // AppendMenuW (popup, MF_STRING, IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO, GetString ("IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO")); + + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_SYS_ENC_SETTINGS, GetString ("IDM_SYS_ENC_SETTINGS")); + + if (!IsHiddenOSRunning()) + { + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_CREATE_RESCUE_DISK, GetString ("IDM_CREATE_RESCUE_DISK")); + AppendMenuW (popup, MF_STRING, IDM_VERIFY_RESCUE_DISK, GetString ("IDM_VERIFY_RESCUE_DISK")); + AppendMenuW (popup, MF_STRING, IDM_VERIFY_RESCUE_DISK_ISO, GetString ("IDM_VERIFY_RESCUE_DISK_ISO")); + } + + if (!bToolsOnly) + { + if (SysDriveOrPartitionFullyEncrypted (FALSE) && !IsHiddenOSRunning()) + { + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT")); + } + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_VOLUME_PROPERTIES, GetString ("IDPM_PROPERTIES")); + } +} + + +// WARNING: This function may take a long time to complete. To prevent data corruption, it MUST be called before +// mounting a partition (as a regular volume) that is within key scope of system encryption. +// Returns TRUE if the partition can be mounted as a partition within key scope of inactive system encryption. +// If devicePath is empty, the currently selected partition in the GUI is checked. +BOOL CheckSysEncMountWithoutPBA (HWND hwndDlg, const wchar_t *devicePath, BOOL quiet) +{ + BOOL tmpbDevice; + wchar_t szDevicePath [TC_MAX_PATH+1]; + wchar_t szDiskFile [TC_MAX_PATH+1]; + + if (wcslen (devicePath) < 2) + { + GetVolumePath (MainDlg, szDevicePath, ARRAYSIZE (szDevicePath)); + CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), szDevicePath, &tmpbDevice); + + if (!tmpbDevice) + { + if (!quiet) + Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg); + + return FALSE; + } + + if (LOWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))) != TC_MLIST_ITEM_FREE) + { + if (!quiet) + Warning ("SELECT_FREE_DRIVE", hwndDlg); + + return FALSE; + } + } + else + StringCbCopyW (szDevicePath, sizeof(szDevicePath), devicePath); + + wchar_t *partionPortion = wcsrchr (szDevicePath, L'\\'); + + if (!partionPortion + || !_wcsicmp (partionPortion, L"\\Partition0")) + { + // Only partitions are supported (not whole drives) + if (!quiet) + Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg); + + return FALSE; + } + + try + { + BootEncStatus = BootEncObj->GetStatus(); + + if (BootEncStatus.DriveMounted) + { + int retCode = 0; + int driveNo; + wchar_t parentDrivePath [TC_MAX_PATH+1]; + + if (swscanf (szDevicePath, L"\\Device\\Harddisk%d\\Partition", &driveNo) != 1) + { + if (!quiet) + Error ("INVALID_PATH", hwndDlg); + + return FALSE; + } + + StringCbPrintfW (parentDrivePath, + sizeof (parentDrivePath), + L"\\Device\\Harddisk%d\\Partition0", + driveNo); + + WaitCursor (); + + // This is critical (re-mounting a mounted system volume as a normal volume could cause data corruption) + // so we force the slower but reliable method + retCode = IsSystemDevicePath (parentDrivePath, MainDlg, TRUE); + + NormalCursor(); + + if (retCode != 2) + return TRUE; + else + { + // The partition is located on active system drive + + if (!quiet) + Warning ("MOUNT_WITHOUT_PBA_VOL_ON_ACTIVE_SYSENC_DRIVE", hwndDlg); + + return FALSE; + } + } + else + return TRUE; + } + catch (Exception &e) + { + NormalCursor(); + e.Show (hwndDlg); + } + + return FALSE; +} + + +// Returns TRUE if the host drive of the specified partition contains a portion of the TrueCrypt Boot Loader +// and if the drive is not within key scope of active system encryption (e.g. the system drive of the running OS). +// If bPrebootPasswordDlgMode is TRUE, this function returns FALSE (because the check would be redundant). +BOOL TCBootLoaderOnInactiveSysEncDrive (wchar_t *szDevicePath) +{ + try + { + int driveNo; + wchar_t parentDrivePath [TC_MAX_PATH+1]; + + if (bPrebootPasswordDlgMode) + return FALSE; + + + if (swscanf (szDevicePath, L"\\Device\\Harddisk%d\\Partition", &driveNo) != 1) + return FALSE; + + StringCbPrintfW (parentDrivePath, + sizeof (parentDrivePath), + L"\\Device\\Harddisk%d\\Partition0", + driveNo); + + BootEncStatus = BootEncObj->GetStatus(); + + if (BootEncStatus.DriveMounted + && IsSystemDevicePath (parentDrivePath, MainDlg, FALSE) == 2) + { + // The partition is within key scope of active system encryption + return FALSE; + } + + return ((BOOL) BootEncObj->IsBootLoaderOnDrive (parentDrivePath)); + } + catch (...) + { + return FALSE; + } + +} + + +BOOL SelectItem (HWND hTree, wchar_t nLetter) +{ + if (nLetter == 0) + { + // The caller specified an invalid drive letter (typically because it is unknown). + // Find out which drive letter is currently selected in the list and use it. + nLetter = (wchar_t) (HIWORD (GetSelectedLong (hTree))); + } + + int i; + LVITEM item; + + for (i = 0; i < ListView_GetItemCount(hTree); i++) + { + memset(&item, 0, sizeof(LVITEM)); + item.mask = LVIF_PARAM; + item.iItem = i; + + if (ListView_GetItem (hTree, &item) == FALSE) + return FALSE; + else + { + if (HIWORD (item.lParam) == nLetter) + { + memset(&item, 0, sizeof(LVITEM)); + item.state = LVIS_FOCUSED|LVIS_SELECTED; + item.stateMask = LVIS_FOCUSED|LVIS_SELECTED; + item.mask = LVIF_STATE; + item.iItem = i; + SendMessage(hTree, LVM_SETITEMSTATE, i, (LPARAM) &item); + return TRUE; + } + } + } + + return TRUE; +} + + +static void LaunchVolCreationWizard (HWND hwndDlg, const wchar_t *arg) +{ + wchar_t t[TC_MAX_PATH + 1024] = {L'"',0}; + wchar_t *tmp; + + GetModuleFileName (NULL, t+1, ARRAYSIZE(t)-1); + + tmp = wcsrchr (t, L'\\'); + if (tmp) + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + wchar_t formatExeName[64]; + wchar_t* suffix = NULL; + ZeroMemory (&si, sizeof (si)); + + StringCbCopyW (formatExeName, sizeof (formatExeName), L"\\VeraCrypt Format"); + + // check if there is a suffix in VeraCrypt file name + // in order to use the same for "VeraCrypt Format" + suffix = wcsrchr (tmp + 1, L'-'); + if (suffix) + { + StringCbCatW (formatExeName, sizeof (formatExeName), suffix); + StringCbCatW (formatExeName, sizeof (formatExeName), L"\""); + } + else + StringCbCatW (formatExeName, sizeof (formatExeName), L".exe\""); + + *tmp = 0; + StringCbCatW (t, sizeof(t), formatExeName); + + if (!FileExists(t)) + Error ("VOL_CREATION_WIZARD_NOT_FOUND", hwndDlg); // Display a user-friendly error message and advise what to do + + if (wcslen (arg) > 0) + { + StringCbCatW (t, sizeof(t), L" "); + StringCbCatW (t, sizeof(t), arg); + } + + if (!CreateProcess (NULL, (LPWSTR) t, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) + { + handleWin32Error (hwndDlg, SRC_POS); + } + else + { + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + } + } +} + +static void LaunchVolExpander (HWND hwndDlg) +{ + wchar_t t[TC_MAX_PATH + TC_MAX_PATH] = {L'"',0}; + wchar_t *tmp; + + GetModuleFileName (NULL, t+1, ARRAYSIZE(t)-1); + + tmp = wcsrchr (t, L'\\'); + if (tmp) + { + wchar_t expanderExeName[64]; + wchar_t* suffix = NULL; + + StringCbCopyW (expanderExeName, sizeof (expanderExeName), L"\\VeraCryptExpander"); + + // check if there is a suffix in VeraCrypt file name + // in order to use the same for "VeraCrypt Format" + suffix = wcsrchr (tmp + 1, L'-'); + if (suffix) + { + StringCbCatW (expanderExeName, sizeof (expanderExeName), suffix); + StringCbCatW (expanderExeName, sizeof (expanderExeName), L"\""); + } + else + StringCbCatW (expanderExeName, sizeof (expanderExeName), L".exe\""); + + *tmp = 0; + StringCbCatW (t, sizeof(t), expanderExeName); + + if (!FileExists(t)) + Error ("VOL_EXPANDER_NOT_FOUND", hwndDlg); // Display a user-friendly error message and advise what to do + else if (((int)ShellExecuteW (NULL, (!IsAdmin() && IsUacSupported()) ? L"runas" : L"open", t, NULL, NULL, SW_SHOW)) <= 32) + { + handleWin32Error (hwndDlg, SRC_POS); + } + } +} + + +// Fills drive list +// drive>0 = update only the corresponding drive subitems +void LoadDriveLetters (HWND hwndDlg, HWND hTree, int drive) +{ + // Remember the top-most visible item + int lastTopMostVisibleItem = ListView_GetTopIndex (hTree); + + wchar_t *szDriveLetters[]= + {L"A:", L"B:", L"C:", L"D:", + L"E:", L"F:", L"G:", L"H:", L"I:", L"J:", L"K:", + L"L:", L"M:", L"N:", L"O:", L"P:", L"Q:", L"R:", + L"S:", L"T:", L"U:", L"V:", L"W:", L"X:", L"Y:", + L"Z:"}; + + DWORD dwResult; + BOOL bResult; + DWORD dwUsedDrives; + MOUNT_LIST_STRUCT driver; + VOLUME_PROPERTIES_STRUCT propSysEnc; + wchar_t sysDriveLetter = 0; + + BOOL bSysEnc = FALSE; + BOOL bWholeSysDriveEncryption = FALSE; + + LVITEM listItem; + int item = 0; + char i; + + try + { + BootEncStatus = BootEncObj->GetStatus(); + if (bSysEnc = BootEncStatus.DriveMounted) + { + BootEncObj->GetVolumeProperties (&propSysEnc); + } + } + catch (...) + { + bSysEnc = FALSE; + } + + ZeroMemory (&driver, sizeof (driver)); + bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &driver, + sizeof (driver), &driver, sizeof (driver), &dwResult, + NULL); + memcpy (&LastKnownMountList, &driver, sizeof (driver)); + + if (bResult == FALSE) + { + KillTimer (MainDlg, TIMER_ID_MAIN); + handleWin32Error (hTree, SRC_POS); + AbortProcessSilent(); + } + + LastKnownLogicalDrives = dwUsedDrives = GetUsedLogicalDrives (); + if (dwUsedDrives == 0) + Warning ("DRIVELETTERS", hwndDlg); + + if(drive == 0) + ListView_DeleteAllItems(hTree); + + if (bSysEnc) + { + bWholeSysDriveEncryption = WholeSysDriveEncryption (TRUE); + + sysDriveLetter = GetSystemDriveLetter (); + } + + /* System drive */ + + if (bWholeSysDriveEncryption) + { + int curDrive = 0; + + if (drive > 0) + { + LVITEM tmp; + memset(&tmp, 0, sizeof(LVITEM)); + tmp.mask = LVIF_PARAM; + tmp.iItem = item; + if (ListView_GetItem (hTree, &tmp)) + curDrive = HIWORD(tmp.lParam); + } + + { + wchar_t szTmp[1024]; + wchar_t szTmpW[1024]; + + memset(&listItem, 0, sizeof(listItem)); + + listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + listItem.iImage = 2; + listItem.iItem = item++; + + listItem.pszText = szTmp; + szTmp[0] = L' '; + szTmp[1] = 0; + + listItem.lParam = MAKELONG (TC_MLIST_ITEM_SYS_DRIVE, ENC_SYSDRIVE_PSEUDO_DRIVE_LETTER); + + if(drive == 0) + ListView_InsertItem (hTree, &listItem); + else + ListView_SetItem (hTree, &listItem); + + listItem.mask=LVIF_TEXT; + + // Fully encrypted + if (SysDriveOrPartitionFullyEncrypted (TRUE)) + { + StringCbCopyW (szTmpW, sizeof(szTmpW), GetString ("SYSTEM_DRIVE")); + } + else + { + // Partially encrypted + + if (BootEncStatus.SetupInProgress) + { + // Currently encrypting/decrypting + + if (BootEncStatus.SetupMode != SetupDecryption) + { + StringCbPrintfW (szTmpW, + sizeof szTmpW, + GetString ("SYSTEM_DRIVE_ENCRYPTING"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + else + { + StringCbPrintfW (szTmpW, + sizeof szTmpW, + GetString ("SYSTEM_DRIVE_DECRYPTING"), + 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0)); + } + } + else + { + StringCbPrintfW (szTmpW, + sizeof szTmpW, + GetString ("SYSTEM_DRIVE_PARTIALLY_ENCRYPTED"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + } + + ListSubItemSet (hTree, listItem.iItem, 1, szTmpW); + + GetSizeString (GetSysEncDeviceSize(TRUE), szTmpW, sizeof(szTmpW)); + ListSubItemSet (hTree, listItem.iItem, 2, szTmpW); + + if (propSysEnc.ea >= EAGetFirst() && propSysEnc.ea <= EAGetCount()) + { + EAGetName (szTmp, propSysEnc.ea, 1); + } + else + { + szTmp[0] = L'?'; + szTmp[1] = 0; + } + listItem.iSubItem = 3; + ListView_SetItem (hTree, &listItem); + + ListSubItemSet (hTree, listItem.iItem, 4, GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE")); + } + } + + /* Drive letters */ + + for (i = 0; i < 26; i++) + { + int curDrive = 0; + + BOOL bSysEncPartition = (bSysEnc && !bWholeSysDriveEncryption && sysDriveLetter == *((wchar_t *) szDriveLetters[i])); + + if (drive > 0) + { + LVITEM tmp; + memset(&tmp, 0, sizeof(LVITEM)); + tmp.mask = LVIF_PARAM; + tmp.iItem = item; + if (ListView_GetItem (hTree, &tmp)) + curDrive = HIWORD(tmp.lParam); + } + + if (driver.ulMountedDrives & (1 << i) + || bSysEncPartition) + { + wchar_t szTmp[1024]; + wchar_t szTmpW[1024]; + wchar_t *ws; + + memset(&listItem, 0, sizeof(listItem)); + + listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + listItem.iImage = bSysEncPartition ? 2 : 1; + listItem.iItem = item++; + + if (drive > 0 && drive != curDrive) + continue; + + listItem.lParam = MAKELONG ( + bSysEncPartition ? TC_MLIST_ITEM_SYS_PARTITION : TC_MLIST_ITEM_NONSYS_VOL, + i + L'A'); + + listItem.pszText = szDriveLetters[i]; + + if (drive == 0) + ListView_InsertItem (hTree, &listItem); + else + ListView_SetItem (hTree, &listItem); + + listItem.mask=LVIF_TEXT; + listItem.pszText = szTmp; + + if (bSysEncPartition) + { + // Fully encrypted + if (SysDriveOrPartitionFullyEncrypted (TRUE)) + { + StringCbCopyW (szTmpW, sizeof(szTmpW), GetString (IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION")); + } + else + { + // Partially encrypted + + if (BootEncStatus.SetupInProgress) + { + // Currently encrypting/decrypting + + if (BootEncStatus.SetupMode != SetupDecryption) + { + StringCbPrintfW (szTmpW, + sizeof szTmpW, + GetString ("SYSTEM_PARTITION_ENCRYPTING"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + else + { + StringCbPrintfW (szTmpW, + sizeof szTmpW, + GetString ("SYSTEM_PARTITION_DECRYPTING"), + 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0)); + } + } + else + { + StringCbPrintfW (szTmpW, + sizeof szTmpW, + GetString ("SYSTEM_PARTITION_PARTIALLY_ENCRYPTED"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + } + + ListSubItemSet (hTree, listItem.iItem, 1, szTmpW); + } + else + { + wchar_t *path = driver.wszVolume[i]; + + if (wmemcmp (path, L"\\??\\", 4) == 0) + path += 4; + + listItem.iSubItem = 1; + + // first check label used for mounting. If empty, look for it in favorites. + bool useInExplorer = false; + wstring label = (wchar_t *) driver.wszLabel[i]; + if (label.empty()) + label = GetFavoriteVolumeLabel (path, useInExplorer); + if (!label.empty()) + ListSubItemSet (hTree, listItem.iItem, 1, (wchar_t *) label.c_str()); + else + ListSubItemSet (hTree, listItem.iItem, 1, (wchar_t *) FitPathInGfxWidth (hTree, hUserFont, ListView_GetColumnWidth (hTree, 1) - GetTextGfxWidth (hTree, L"___", hUserFont), path).c_str()); + } + + GetSizeString (bSysEncPartition ? GetSysEncDeviceSize(TRUE) : driver.diskLength[i], szTmpW, sizeof(szTmpW)); + ListSubItemSet (hTree, listItem.iItem, 2, szTmpW); + + EAGetName (szTmp, bSysEncPartition ? propSysEnc.ea : driver.ea[i], 1); + listItem.iSubItem = 3; + ListView_SetItem (hTree, &listItem); + + if (bSysEncPartition) + { + ws = GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE"); + VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; + ListSubItemSet (hTree, listItem.iItem, 4, ws); + } + else + { + switch (driver.volumeType[i]) + { + case PROP_VOL_TYPE_NORMAL: + ws = GetString ("NORMAL"); + break; + case PROP_VOL_TYPE_HIDDEN: + ws = GetString ("HIDDEN"); + break; + case PROP_VOL_TYPE_OUTER: + ws = GetString ("OUTER"); // Normal/outer volume (hidden volume protected) + break; + case PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED: + ws = GetString ("OUTER_VOL_WRITE_PREVENTED"); // Normal/outer volume (hidden volume protected AND write denied) + break; + default: + ws = L"?"; + } + + if (driver.truecryptMode[i]) + { + StringCbPrintfW (szTmpW, sizeof(szTmpW), L"TrueCrypt-%s", ws); + ListSubItemSet (hTree, listItem.iItem, 4, szTmpW); + } + else + ListSubItemSet (hTree, listItem.iItem, 4, ws); + + if (driver.volumeType[i] == PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED) // Normal/outer volume (hidden volume protected AND write denied) + { + if (!VolumeNotificationsList.bHidVolDamagePrevReported[i]) + { + wchar_t szTmp[4096]; + + VolumeNotificationsList.bHidVolDamagePrevReported[i] = TRUE; + StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), i+L'A'); + SetForegroundWindow (GetParent(hTree)); + MessageBoxW (GetParent(hTree), szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); + } + } + else + { + VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; + } + } + } + else + { + VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; + + if (!(dwUsedDrives & 1 << i)) + { + if(drive > 0 && drive != HIWORD (GetSelectedLong (hTree))) + { + item++; + continue; + } + + memset(&listItem,0,sizeof(listItem)); + + listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + listItem.iImage = 0; + listItem.iItem = item++; + listItem.pszText = szDriveLetters[i]; + listItem.lParam = MAKELONG (TC_MLIST_ITEM_FREE, i + 'A'); + + if(drive == 0) + ListView_InsertItem (hTree, &listItem); + else + ListView_SetItem (hTree, &listItem); + + listItem.mask=LVIF_TEXT; + listItem.pszText = L""; + listItem.iSubItem = 1; + ListView_SetItem (hTree, &listItem); + listItem.iSubItem = 2; + ListView_SetItem (hTree, &listItem); + listItem.iSubItem = 3; + ListView_SetItem (hTree, &listItem); + listItem.iSubItem = 4; + ListView_SetItem (hTree, &listItem); + + } + } + } + + // Restore the original scroll position (the topmost item that was visible when we were called) and the + // last selected item. + SetListScrollHPos (hTree, lastTopMostVisibleItem); + SelectItem (hTree, 0); +} + +static void PasswordChangeEnable (HWND hwndDlg, int button, int passwordId, BOOL keyFilesEnabled, + int newPasswordId, int newVerifyId, BOOL newKeyFilesEnabled) +{ + char password[MAX_PASSWORD + 1]; + char newPassword[MAX_PASSWORD + 1]; + char newVerify[MAX_PASSWORD + 1]; + wchar_t tmp[MAX_PASSWORD + 1]; + BOOL bEnable = TRUE; + int passwordUtf8Len, newPasswordUtf8Len, newVerifyUtf8Len; + + GetWindowText (GetDlgItem (hwndDlg, passwordId), tmp, ARRAYSIZE (tmp)); + passwordUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, password, sizeof (password), NULL, NULL); + + if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF) + newKeyFilesEnabled = keyFilesEnabled; + + switch (pwdChangeDlgMode) + { + case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: + case PCDM_ADD_REMOVE_VOL_KEYFILES: + case PCDM_CHANGE_PKCS5_PRF: + memcpy (newPassword, password, sizeof (newPassword)); + memcpy (newVerify, password, sizeof (newVerify)); + newPasswordUtf8Len = passwordUtf8Len; + newVerifyUtf8Len = passwordUtf8Len; + break; + + default: + GetWindowText (GetDlgItem (hwndDlg, newPasswordId), tmp, ARRAYSIZE (tmp)); + newPasswordUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, newPassword, sizeof (newPassword), NULL, NULL); + GetWindowText (GetDlgItem (hwndDlg, newVerifyId), tmp, ARRAYSIZE (tmp)); + newVerifyUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, newVerify, sizeof (newVerify), NULL, NULL); + + } + + if (passwordUtf8Len <= 0 || (!keyFilesEnabled && ((passwordUtf8Len - 1) < MIN_PASSWORD))) + bEnable = FALSE; + else if (strcmp (newPassword, newVerify) != 0) + bEnable = FALSE; + else if ((newPasswordUtf8Len <= 0) || (!newKeyFilesEnabled && ((newPasswordUtf8Len - 1) < MIN_PASSWORD))) + bEnable = FALSE; + + burn (password, sizeof (password)); + burn (newPassword, sizeof (newPassword)); + burn (newVerify, sizeof (newVerify)); + burn (tmp, sizeof (tmp)); + + EnableWindow (GetDlgItem (hwndDlg, button), bEnable); +} + +// implementation for support of change password operation in wait dialog mechanism + +typedef struct +{ + Password *oldPassword; + int old_pkcs5; + int old_pim; + Password *newPassword; + int pkcs5; + int pim; + int wipePassCount; + BOOL truecryptMode; + int* pnStatus; +} ChangePwdThreadParam; + +void CALLBACK ChangePwdWaitThreadProc(void* pArg, HWND hwndDlg) +{ + ChangePwdThreadParam* pThreadParam = (ChangePwdThreadParam*) pArg; + + if (bSysEncPwdChangeDlgMode) + { + // System + + try + { + VOLUME_PROPERTIES_STRUCT properties; + BootEncObj->GetVolumeProperties(&properties); + pThreadParam->old_pkcs5 = properties.pkcs5; + } + catch(...) + {} + + pThreadParam->pkcs5 = 0; // PKCS-5 PRF unchanged (currently we can't change PRF of system encryption) + + try + { + *pThreadParam->pnStatus = BootEncObj->ChangePassword (pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg); + } + catch (Exception &e) + { + e.Show (hwndDlg); + *(pThreadParam->pnStatus) = ERR_OS_ERROR; + } + } + else + { + // Non-system + + *pThreadParam->pnStatus = ChangePwd (szFileName, pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->truecryptMode, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg); + + if (*pThreadParam->pnStatus == ERR_OS_ERROR + && GetLastError () == ERROR_ACCESS_DENIED + && IsUacSupported () + && IsVolumeDeviceHosted (szFileName)) + { + *pThreadParam->pnStatus = UacChangePwd (szFileName, pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->truecryptMode, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg); + } + } +} + +// implementation for support of backup header operation in wait dialog mechanism + +typedef struct +{ + BOOL bRequireConfirmation; + wchar_t *lpszVolume; + size_t cchVolume; + int* iResult; +} BackupHeaderThreadParam; + +void CALLBACK BackupHeaderWaitThreadProc(void* pArg, HWND hwndDlg) +{ + BackupHeaderThreadParam* pThreadParam = (BackupHeaderThreadParam*) pArg; + + if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume)) + { + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) + *(pThreadParam->iResult) = UacBackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); + else + *(pThreadParam->iResult) = BackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); + } + else + *(pThreadParam->iResult) = ERR_OS_ERROR; +} + +// implementation for support of restoring header operation in wait dialog mechanism + +typedef struct +{ + wchar_t *lpszVolume; + size_t cchVolume; + int* iResult; +} RestoreHeaderThreadParam; + +void CALLBACK RestoreHeaderWaitThreadProc(void* pArg, HWND hwndDlg) +{ + RestoreHeaderThreadParam* pThreadParam = (RestoreHeaderThreadParam*) pArg; + + if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume)) + { + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) + *(pThreadParam->iResult) = UacRestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); + else + *(pThreadParam->iResult) = RestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); + } + else + *(pThreadParam->iResult) = ERR_OS_ERROR; +} + +/* Except in response to the WM_INITDIALOG message, the dialog box procedure + should return nonzero if it processes the message, and zero if it does + not. - see DialogProc */ +BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static KeyFilesDlgParam newKeyFilesParam; + static BOOL PimValueChangedWarning = FALSE; + static int* NewPimValuePtr = NULL; + + WORD lw = LOWORD (wParam); + WORD hw = HIWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + LPARAM nIndex, nSelectedIndex = 0; + HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID); + int i; + WipeAlgorithmId headerWipeMode = TC_WIPE_3_DOD_5220; + int EffectiveVolumePkcs5 = CmdVolumePkcs5; + BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; + int EffectiveVolumePim = CmdVolumePim; + + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (EffectiveVolumePkcs5 == 0) + EffectiveVolumePkcs5 = DefaultVolumePkcs5; + if (!EffectiveVolumeTrueCryptMode) + EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; + + NewPimValuePtr = (int*) lParam; + + PimValueChangedWarning = FALSE; + + ZeroMemory (&newKeyFilesParam, sizeof (newKeyFilesParam)); + if (NewPimValuePtr) + { + /* we are in the case of a volume. Store its name to use it in the key file dialog + * this will help avoid using the current container file as a key file + */ + StringCbCopyW (newKeyFilesParam.VolumeFileName, sizeof (newKeyFilesParam.VolumeFileName), szFileName); + } + + SetWindowTextW (hwndDlg, GetString ("IDD_PASSWORDCHANGE_DLG")); + LocalizeDialog (hwndDlg, "IDD_PASSWORDCHANGE_DLG"); + + SendMessage (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_VERIFY), EM_LIMITTEXT, MAX_PASSWORD, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_OLD_PIM), EM_LIMITTEXT, MAX_PIM, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0); + EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE); + + SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), TRUE); + + /* Add PRF algorithm list for current password */ + SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); + + nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); + + for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) + { + nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); + if (i == EffectiveVolumePkcs5) + { + nSelectedIndex = nIndex; + } + } + + SendMessage (hComboBox, CB_SETCURSEL, nSelectedIndex, 0); + + /* check TrueCrypt Mode if it was set as default*/ + SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, EffectiveVolumeTrueCryptMode); + + /* set default PIM if set in the command line*/ + if (EffectiveVolumePim > 0) + { + SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE); + ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_OLD_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW); + SetPim (hwndDlg, IDC_OLD_PIM, EffectiveVolumePim); + } + + /* Add PRF algorithm list for new password */ + hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); + SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); + + nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("UNCHANGED")); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); + + for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) + { + if (!HashIsDeprecated (i)) + { + nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); + } + } + + SendMessage (hComboBox, CB_SETCURSEL, 0, 0); + + PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, FALSE, TRUE); + SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &headerWipeMode); + + switch (pwdChangeDlgMode) + { + case PCDM_CHANGE_PKCS5_PRF: + SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_CHANGE_PKCS5_PRF")); + LocalizeDialog (hwndDlg, "IDD_PCDM_CHANGE_PKCS5_PRF"); + EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE); + break; + + case PCDM_ADD_REMOVE_VOL_KEYFILES: + SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_ADD_REMOVE_VOL_KEYFILES")); + LocalizeDialog (hwndDlg, "IDD_PCDM_ADD_REMOVE_VOL_KEYFILES"); + newKeyFilesParam.EnableKeyFiles = TRUE; + EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); + break; + + case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: + newKeyFilesParam.EnableKeyFiles = FALSE; + SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_REMOVE_ALL_KEYFILES_FROM_VOL")); + LocalizeDialog (hwndDlg, "IDD_PCDM_REMOVE_ALL_KEYFILES_FROM_VOL"); + KeyFilesEnable = TRUE; + SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, TRUE); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE); + EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_KEYFILES), TRUE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); + break; + + case PCDM_CHANGE_PASSWORD: + default: + // NOP + break; + }; + + if (bSysEncPwdChangeDlgMode) + { + /* No support for changing the password of TrueCrypt system partition */ + SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE); + + ToBootPwdField (hwndDlg, IDC_PASSWORD); + ToBootPwdField (hwndDlg, IDC_VERIFY); + ToBootPwdField (hwndDlg, IDC_OLD_PASSWORD); + + if ((DWORD) GetKeyboardLayout (NULL) != 0x00000409 && (DWORD) GetKeyboardLayout (NULL) != 0x04090409) + { + DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 0; + } + + bKeyboardLayoutChanged = TRUE; + } + + + /* for system encryption, we can't change the PRF */ + EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), FALSE); + + if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0) + { + Error ("CANNOT_SET_TIMER", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 0; + } + + newKeyFilesParam.EnableKeyFiles = FALSE; + KeyFilesEnable = FALSE; + SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_KEYFILES), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE); + } + + CheckCapsLock (hwndDlg, FALSE); + + return 0; + } + + case WM_TIMER: + switch (wParam) + { + case TIMER_ID_KEYB_LAYOUT_GUARD: + if (bSysEncPwdChangeDlgMode) + { + DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL); + + /* Watch the keyboard layout */ + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + // Keyboard layout is not standard US + + // Attempt to wipe passwords stored in the input field buffers + wchar_t tmp[MAX_PASSWORD+1]; + wmemset (tmp, L'X', MAX_PASSWORD); + tmp [MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp); + + SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), L""); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L""); + SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), L""); + + keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + bKeyboardLayoutChanged = TRUE; + + wchar_t szTmp [4096]; + StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED")); + StringCbCatW (szTmp, sizeof(szTmp), L"\n\n"); + StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); + MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); + } + + + /* Watch the right Alt key (which is used to enter various characters on non-US keyboards) */ + + if (bKeyboardLayoutChanged && !bKeybLayoutAltKeyWarningShown) + { + if (GetAsyncKeyState (VK_RMENU) < 0) + { + bKeybLayoutAltKeyWarningShown = TRUE; + + wchar_t szTmp [4096]; + StringCbCopyW (szTmp, sizeof(szTmp), GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION")); + StringCbCatW (szTmp, sizeof(szTmp), L"\n\n"); + StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); + MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST); + } + } + } + return 1; + } + return 0; + + case WM_CTLCOLORSTATIC: + { + if (PimValueChangedWarning && ((HWND)lParam == GetDlgItem(hwndDlg, IDC_PIM_HELP)) ) + { + // we're about to draw the static + // set the text colour in (HDC)lParam + SetBkMode((HDC)wParam,TRANSPARENT); + SetTextColor((HDC)wParam, RGB(255,0,0)); + // NOTE: per documentation as pointed out by selbie, GetSolidBrush would leak a GDI handle. + return (BOOL)GetSysColorBrush(COLOR_MENU); + } + } + return 0; + + case WM_COMMAND: + if (lw == IDCANCEL) + { + // Attempt to wipe passwords stored in the input field buffers + wchar_t tmp[MAX_PASSWORD+1]; + wmemset (tmp, L'X', MAX_PASSWORD); + tmp[MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp); + RestoreDefaultKeyFilesParam (); + + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + if (hw == EN_CHANGE) + { + PasswordChangeEnable (hwndDlg, IDOK, + IDC_OLD_PASSWORD, + KeyFilesEnable && FirstKeyFile != NULL, + IDC_PASSWORD, IDC_VERIFY, + newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); + + if ((lw == IDC_OLD_PIM) && IsWindowEnabled (GetDlgItem (hwndDlg, IDC_PIM))) + { + wchar_t tmp[MAX_PIM+1] = {0}; + GetDlgItemText (hwndDlg, IDC_OLD_PIM, tmp, MAX_PIM + 1); + SetDlgItemText (hwndDlg, IDC_PIM, tmp); + } + + if (lw == IDC_PIM) + { + if(GetPim (hwndDlg, IDC_OLD_PIM) != GetPim (hwndDlg, IDC_PIM)) + { + PimValueChangedWarning = TRUE; + SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, GetString (bSysEncPwdChangeDlgMode? "PIM_SYSENC_CHANGE_WARNING" : "PIM_CHANGE_WARNING")); + } + else + { + PimValueChangedWarning = FALSE; + SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, (wchar_t *) GetDictionaryValueByInt (IDC_PIM_HELP)); + } + } + + return 1; + } + + if (lw == IDC_PIM_ENABLE) + { + ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_OLD_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW); + + // check also the "Use PIM" for the new password if it is enabled + if (IsWindowEnabled (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE))) + { + SetCheckBox (hwndDlg, IDC_NEW_PIM_ENABLE, TRUE); + + ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); + } + + SetFocus (GetDlgItem (hwndDlg, IDC_OLD_PIM)); + + return 1; + } + + if (lw == IDC_NEW_PIM_ENABLE) + { + ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); + + SetFocus (GetDlgItem (hwndDlg, IDC_PIM)); + + return 1; + } + + if (lw == IDC_KEYFILES) + { + if (bSysEncPwdChangeDlgMode) + { + Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); + return 1; + } + + KeyFilesDlgParam param; + param.EnableKeyFiles = KeyFilesEnable; + param.FirstKeyFile = FirstKeyFile; + + if (IDOK == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, + (DLGPROC) KeyFilesDlgProc, (LPARAM) ¶m)) + { + KeyFilesEnable = param.EnableKeyFiles; + FirstKeyFile = param.FirstKeyFile; + + SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable); + } + + PasswordChangeEnable (hwndDlg, IDOK, + IDC_OLD_PASSWORD, + KeyFilesEnable && FirstKeyFile != NULL, + IDC_PASSWORD, IDC_VERIFY, + newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); + + return 1; + } + + + if (lw == IDC_NEW_KEYFILES) + { + if (bSysEncPwdChangeDlgMode) + { + Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); + return 1; + } + + if (IDOK == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, + (DLGPROC) KeyFilesDlgProc, (LPARAM) &newKeyFilesParam)) + { + SetCheckBox (hwndDlg, IDC_ENABLE_NEW_KEYFILES, newKeyFilesParam.EnableKeyFiles); + + VerifyPasswordAndUpdate (hwndDlg, GetDlgItem (hwndDlg, IDOK), GetDlgItem (hwndDlg, IDC_PASSWORD), + GetDlgItem (hwndDlg, IDC_VERIFY), NULL, NULL, + newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); + } + + PasswordChangeEnable (hwndDlg, IDOK, + IDC_OLD_PASSWORD, + KeyFilesEnable && FirstKeyFile != NULL, + IDC_PASSWORD, IDC_VERIFY, + newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); + + return 1; + } + + if (lw == IDC_ENABLE_KEYFILES) + { + KeyFilesEnable = GetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES); + + PasswordChangeEnable (hwndDlg, IDOK, + IDC_OLD_PASSWORD, + KeyFilesEnable && FirstKeyFile != NULL, + IDC_PASSWORD, IDC_VERIFY, + newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); + + return 1; + } + + if (lw == IDC_ENABLE_NEW_KEYFILES) + { + newKeyFilesParam.EnableKeyFiles = GetCheckBox (hwndDlg, IDC_ENABLE_NEW_KEYFILES); + + PasswordChangeEnable (hwndDlg, IDOK, + IDC_OLD_PASSWORD, + KeyFilesEnable && FirstKeyFile != NULL, + IDC_PASSWORD, IDC_VERIFY, + newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL); + + return 1; + } + + if (hw == CBN_SELCHANGE) + { + switch (lw) + { + case IDC_PKCS5_PRF_ID: + if (bSysEncPwdChangeDlgMode) + { + int new_hash_algo_id = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, + SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); + + if (new_hash_algo_id != 0 && !HashForSystemEncryption(new_hash_algo_id)) + { + int new_hash_algo_id = DEFAULT_HASH_ALGORITHM_BOOT; + Info ("ALGO_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg); + SelectAlgo (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), &new_hash_algo_id); + } + } + break; + } + return 1; + + } + + if (lw == IDC_TRUECRYPT_MODE) + { + BOOL bEnablePim = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE) ? FALSE: TRUE; + EnableWindow (GetDlgItem (hwndDlg, IDT_OLD_PIM), bEnablePim); + EnableWindow (GetDlgItem (hwndDlg, IDC_OLD_PIM), bEnablePim); + EnableWindow (GetDlgItem (hwndDlg, IDC_OLD_PIM_HELP), bEnablePim); + } + + if (lw == IDC_SHOW_PASSWORD_CHPWD_ORI) + { + HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_ORI, IDC_OLD_PASSWORD, IDC_OLD_PIM); + return 1; + } + + if (lw == IDC_SHOW_PASSWORD_CHPWD_NEW) + { + HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PASSWORD, IDC_VERIFY); + HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PIM, 0); + return 1; + } + + if (lw == IDOK) + { + HWND hParent = GetParent (hwndDlg); + Password oldPassword; + Password newPassword; + WipeAlgorithmId headerWiperMode = (WipeAlgorithmId) SendMessage ( + GetDlgItem (hwndDlg, IDC_WIPE_MODE), + CB_GETITEMDATA, + SendMessage (GetDlgItem (hwndDlg, IDC_WIPE_MODE), CB_GETCURSEL, 0, 0), + 0); + int nStatus; + int old_pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETITEMDATA, + SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETCURSEL, 0, 0), 0); + int pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, + SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); + BOOL truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE); + + int old_pim = GetPim (hwndDlg, IDC_OLD_PIM); + int pim = GetPim (hwndDlg, IDC_PIM); + + if (truecryptMode && (old_pkcs5 == SHA256)) + { + Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); + return 1; + } + else if (truecryptMode && (old_pim != 0)) + { + Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); + return 1; + } + + if (bSysEncPwdChangeDlgMode && !CheckPasswordCharEncoding (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL)) + { + Error ("UNSUPPORTED_CHARS_IN_PWD", hwndDlg); + return 1; + } + + if (bSysEncPwdChangeDlgMode && (pim > MAX_BOOT_PIM_VALUE)) + { + SetFocus (GetDlgItem(hwndDlg, IDC_PIM)); + Error ("PIM_SYSENC_TOO_BIG", hwndDlg); + return 1; + } + + if (!bSysEncPwdChangeDlgMode && (pim > MAX_PIM_VALUE)) + { + SetFocus (GetDlgItem(hwndDlg, IDC_PIM)); + Error ("PIM_TOO_BIG", hwndDlg); + return 1; + } + + if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF) + { + newKeyFilesParam.EnableKeyFiles = KeyFilesEnable; + } + else if (!(newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL) + && pwdChangeDlgMode == PCDM_CHANGE_PASSWORD) + { + if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pim, bSysEncPwdChangeDlgMode, FALSE, FALSE)) + return 1; + } + + GetVolumePath (hParent, szFileName, ARRAYSIZE (szFileName)); + + if (GetPassword (hwndDlg, IDC_OLD_PASSWORD, (LPSTR) oldPassword.Text, sizeof (oldPassword.Text), TRUE)) + oldPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text); + else + { + return 1; + } + + switch (pwdChangeDlgMode) + { + case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: + case PCDM_ADD_REMOVE_VOL_KEYFILES: + case PCDM_CHANGE_PKCS5_PRF: + memcpy (newPassword.Text, oldPassword.Text, sizeof (newPassword.Text)); + newPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text); + pim = old_pim; + break; + + default: + if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) newPassword.Text, sizeof (newPassword.Text), TRUE)) + newPassword.Length = (unsigned __int32) strlen ((char *) newPassword.Text); + else + return 1; + } + + WaitCursor (); + + if (KeyFilesEnable) + KeyFilesApply (hwndDlg, &oldPassword, FirstKeyFile, szFileName); + + if (newKeyFilesParam.EnableKeyFiles) + { + if (!KeyFilesApply (hwndDlg, &newPassword, pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? FirstKeyFile : newKeyFilesParam.FirstKeyFile, szFileName)) + { + nStatus = ERR_DONT_REPORT; + goto err; + } + } + + ChangePwdThreadParam changePwdParam; + changePwdParam.oldPassword = &oldPassword; + changePwdParam.old_pkcs5 = old_pkcs5; + changePwdParam.old_pim = old_pim; + changePwdParam.newPassword = &newPassword; + changePwdParam.pkcs5 = pkcs5; + changePwdParam.pim = pim; + changePwdParam.wipePassCount = GetWipePassCount(headerWiperMode); + changePwdParam.pnStatus = &nStatus; + changePwdParam.truecryptMode = truecryptMode; + + ShowWaitDialog(hwndDlg, TRUE, ChangePwdWaitThreadProc, &changePwdParam); + +err: + // notify the caller in case the PIM has changed + if (NewPimValuePtr) + { + if (pim != old_pim) + *NewPimValuePtr = pim; + else + *NewPimValuePtr = -1; + } + + burn (&oldPassword, sizeof (oldPassword)); + burn (&newPassword, sizeof (newPassword)); + burn (&old_pim, sizeof(old_pim)); + burn (&pim, sizeof(pim)); + + NormalCursor (); + + if (nStatus == 0) + { + // Attempt to wipe passwords stored in the input field buffers + wchar_t tmp[MAX_PASSWORD+1]; + wmemset (tmp, L'X', MAX_PASSWORD); + tmp[MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp); + + KeyFileRemoveAll (&newKeyFilesParam.FirstKeyFile); + RestoreDefaultKeyFilesParam (); + + if (bSysEncPwdChangeDlgMode) + { + KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); + } + + EndDialog (hwndDlg, IDOK); + } + return 1; + } + return 0; + } + + return 0; +} + +static wchar_t PasswordDlgVolume[MAX_PATH + 1]; +static BOOL PasswordDialogDisableMountOptions; +static char *PasswordDialogTitleStringId; + +/* Except in response to the WM_INITDIALOG message, the dialog box procedure + should return nonzero if it processes the message, and zero if it does + not. - see DialogProc */ +BOOL CALLBACK PasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + static Password *szXPwd; + static int *pkcs5; + static int *pim; + static BOOL* truecryptMode; + + switch (msg) + { + case WM_INITDIALOG: + { + int i, nIndex, defaultPrfIndex = 0; + szXPwd = ((PasswordDlgParam *) lParam) -> password; + pkcs5 = ((PasswordDlgParam *) lParam) -> pkcs5; + pim = ((PasswordDlgParam *) lParam) -> pim; + truecryptMode = ((PasswordDlgParam *) lParam) -> truecryptMode; + LocalizeDialog (hwndDlg, "IDD_PASSWORD_DLG"); + DragAcceptFiles (hwndDlg, TRUE); + + if (PasswordDialogTitleStringId) + { + SetWindowTextW (hwndDlg, GetString (PasswordDialogTitleStringId)); + } + else if (wcslen (PasswordDlgVolume) > 0) + { + wchar_t s[1024]; + RECT rect; + GetWindowRect (hwndDlg, &rect); + + bool useInExplorer = false; + wstring label = GetFavoriteVolumeLabel (PasswordDlgVolume, useInExplorer); + if (!label.empty()) + { + StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR_LABEL"), label.c_str()); + if (useInExplorer) + StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), label.c_str()); + } + else + { + StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), L"___"); + StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), FitPathInGfxWidth (hwndDlg, WindowTitleBarFont, rect.right - rect.left - GetTextGfxWidth (hwndDlg, s, WindowTitleBarFont), PasswordDlgVolume).c_str()); + } + + SetWindowTextW (hwndDlg, s); + } + + /* Populate the PRF algorithms list */ + HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); + SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); + + nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); + + for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) + { + nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); + if (*pkcs5 && (*pkcs5 == i)) + defaultPrfIndex = nIndex; + } + + /* make autodetection the default unless a specific PRF was specified in the command line */ + SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_CACHE), BM_SETCHECK, bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0); + + SetPim (hwndDlg, IDC_PIM, *pim); + + /* make PIM field visible if a PIM value has been explicitely specified */ + if (*pim > 0) + { + SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE); + ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); + } + + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); + + mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode; + + if (bPrebootPasswordDlgMode) + { + SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0); + } + + if (PasswordDialogDisableMountOptions) + { + EnableWindow (GetDlgItem (hwndDlg, IDC_CACHE), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_OPTIONS), FALSE); + /* Disable TrueCrypt mode option in case of backup/restore header operation */ + SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE); + } + else if (*truecryptMode) + { + /* Check TrueCryptMode if it is enabled on the command line */ + SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, TRUE); + } + + if (!SetForegroundWindow (hwndDlg) && (FavoriteMountOnArrivalInProgress || LogOn)) + { + SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + + FLASHWINFO flash; + flash.cbSize = sizeof (flash); + flash.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG; + flash.dwTimeout = 0; + flash.hwnd = hwndDlg; + flash.uCount = 0; + + FlashWindowEx (&flash); + + SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } + } + return 0; + + case TC_APPMSG_PREBOOT_PASSWORD_MODE: + { + /* Repopulate the PRF algorithms list with algorithms that support system encryption */ + HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); + SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); + + int i, defaultPrfIndex = 0, nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); + + for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) + { + if (HashForSystemEncryption(i)) + { + nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); + if (*pkcs5 && (*pkcs5 == i)) + defaultPrfIndex = nIndex; + } + } + + /* make autodetection the default unless a specific PRF was specified in the command line */ + SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0); + + ToBootPwdField (hwndDlg, IDC_PASSWORD); + + // Attempt to wipe the password stored in the input field buffer + wchar_t tmp[MAX_PASSWORD+1]; + wmemset (tmp, L'X', MAX_PASSWORD); + tmp [MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L""); + + StringCbPrintfW (OrigKeyboardLayout, sizeof(OrigKeyboardLayout),L"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF); + + DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0) + { + Error ("CANNOT_SET_TIMER", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + if (GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD)) + { + // simulate hiding password + SetCheckBox (hwndDlg, IDC_SHOW_PASSWORD, FALSE); + + HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD, IDC_PASSWORD, IDC_PIM); + } + + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEY_FILES), FALSE); + + SetPim (hwndDlg, IDC_PIM, *pim); + + bPrebootPasswordDlgMode = TRUE; + } + return 1; + + case WM_TIMER: + switch (wParam) + { + case TIMER_ID_KEYB_LAYOUT_GUARD: + if (bPrebootPasswordDlgMode) + { + DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + // Keyboard layout is not standard US + + // Attempt to wipe the password stored in the input field buffer + wchar_t tmp[MAX_PASSWORD+1]; + wmemset (tmp, L'X', MAX_PASSWORD); + tmp [MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L""); + + keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + wchar_t szTmp [4096]; + StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED")); + StringCbCatW (szTmp, sizeof(szTmp), L"\n\n"); + StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); + MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); + } + } + return 1; + } + return 0; + + case WM_COMMAND: + + if (lw == IDC_MOUNT_OPTIONS) + { + /* Use default PRF specified by the user if any */ + if (mountOptions.ProtectedHidVolPkcs5Prf == 0) + mountOptions.ProtectedHidVolPkcs5Prf = *pkcs5; + if (mountOptions.ProtectedHidVolPim == 0) + mountOptions.ProtectedHidVolPim = *pim; + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, + (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions); + + if (!bPrebootPasswordDlgMode && mountOptions.PartitionInInactiveSysEncScope) + SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0); + + return 1; + } + + if (lw == IDC_PIM_ENABLE) + { + ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); + + SetFocus (GetDlgItem (hwndDlg, IDC_PIM)); + return 1; + } + + if (lw == IDC_SHOW_PASSWORD) + { + HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD, IDC_PASSWORD, IDC_PIM); + return 1; + } + + if (lw == IDC_TRUECRYPT_MODE) + { + BOOL bEnablePim = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE) ? FALSE: TRUE; + EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), bEnablePim); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), bEnablePim); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), bEnablePim); + } + + if (lw == IDC_KEY_FILES) + { + KeyFilesDlgParam param; + param.EnableKeyFiles = KeyFilesEnable; + param.FirstKeyFile = FirstKeyFile; + + if (IDOK == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, + (DLGPROC) KeyFilesDlgProc, (LPARAM) ¶m)) + { + KeyFilesEnable = param.EnableKeyFiles; + FirstKeyFile = param.FirstKeyFile; + + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); + } + + return 1; + } + + if (lw == IDC_KEYFILES_ENABLE) + { + KeyFilesEnable = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE); + + return 1; + } + + if (lw == IDCANCEL || lw == IDOK) + { + wchar_t tmp[MAX_PASSWORD+1]; + + if (lw == IDOK) + { + if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) + KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, wcslen (PasswordDlgVolume) > 0 ? PasswordDlgVolume : NULL); + + if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) szXPwd->Text, MAX_PASSWORD + 1, TRUE)) + szXPwd->Length = (unsigned __int32) strlen ((char *) szXPwd->Text); + else + return 1; + + bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_CACHE)); + *pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); + *truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE); + + *pim = GetPim (hwndDlg, IDC_PIM); + + /* SHA-256 is not supported by TrueCrypt */ + if ( (*truecryptMode) + && ((*pkcs5 == SHA256) || (mountOptions.ProtectHiddenVolume && mountOptions.ProtectedHidVolPkcs5Prf == SHA256)) + ) + { + Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); + return 1; + } + + if ( (*truecryptMode) + && (*pim != 0) + ) + { + Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); + return 1; + } + } + + // Attempt to wipe password stored in the input field buffer + wmemset (tmp, L'X', MAX_PASSWORD); + tmp[MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); + + if (hidVolProtKeyFilesParam.FirstKeyFile != NULL) + { + KeyFileRemoveAll (&hidVolProtKeyFilesParam.FirstKeyFile); + hidVolProtKeyFilesParam.EnableKeyFiles = FALSE; + } + + if (bPrebootPasswordDlgMode) + { + KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); + + // Restore the original keyboard layout + if (LoadKeyboardLayout (OrigKeyboardLayout, KLF_ACTIVATE | KLF_SUBSTITUTE_OK) == NULL) + Warning ("CANNOT_RESTORE_KEYBOARD_LAYOUT", hwndDlg); + } + + EndDialog (hwndDlg, lw); + return 1; + } + return 0; + + case WM_CONTEXTMENU: + { + RECT buttonRect; + GetWindowRect (GetDlgItem (hwndDlg, IDC_KEY_FILES), &buttonRect); + + if (LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right + && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom) + { + // The "Keyfiles" button has been right-clicked + + KeyFilesDlgParam param; + param.EnableKeyFiles = KeyFilesEnable; + param.FirstKeyFile = FirstKeyFile; + + POINT popupPos; + popupPos.x = buttonRect.left + 2; + popupPos.y = buttonRect.top + 2; + + if (KeyfilesPopupMenu (hwndDlg, popupPos, ¶m)) + { + KeyFilesEnable = param.EnableKeyFiles; + FirstKeyFile = param.FirstKeyFile; + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); + } + } + } + break; + + case WM_DROPFILES: + { + HDROP hdrop = (HDROP) wParam; + int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0); + + while (count-- > 0) + { + KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile)); + if (kf) + { + DragQueryFile (hdrop, i++, kf->FileName, ARRAYSIZE (kf->FileName)); + FirstKeyFile = KeyFileAdd (FirstKeyFile, kf); + KeyFilesEnable = TRUE; + } + } + + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable); + DragFinish (hdrop); + } + return 1; + } + + return 0; +} + +static void PreferencesDlgEnableButtons (HWND hwndDlg) +{ + BOOL back = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE)); + BOOL idle = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)); + BOOL installed = !IsNonInstallMode(); + BOOL wtsEnabled = (hWtsLib != NULL) ? TRUE : FALSE; + + EnableWindow (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL), back && installed); + EnableWindow (GetDlgItem (hwndDlg, IDT_LOGON), installed); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START), back && installed); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES), installed); + EnableWindow (GetDlgItem (hwndDlg, IDT_AUTO_DISMOUNT), back); + EnableWindow (GetDlgItem (hwndDlg, IDT_AUTO_DISMOUNT_ON), back); + EnableWindow (GetDlgItem (hwndDlg, IDT_MINUTES), back); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF), back); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED), back && wtsEnabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING), back); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER), back); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE), back); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME), back && idle); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT), back); +} + +BOOL CALLBACK PreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL PreferencesDialogActive = FALSE; + static HWND ActivePreferencesDialogWindow; + + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + if (PreferencesDialogActive) + { + ShowWindow (ActivePreferencesDialogWindow, SW_SHOW); + SetForegroundWindow (ActivePreferencesDialogWindow); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + ActivePreferencesDialogWindow = hwndDlg; + PreferencesDialogActive = TRUE; + + LocalizeDialog (hwndDlg, "IDD_PREFERENCES_DLG"); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_OPEN_EXPLORER), BM_SETCHECK, + bExplore ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED), BM_SETCHECK, + bUseDifferentTrayIconIfVolMounted ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PRESERVE_TIMESTAMPS), BM_SETCHECK, + defaultMountOptions.PreserveTimestamp ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_SHOW_DISCONNECTED_NETWORK_DRIVES), BM_SETCHECK, + bShowDisconnectedNetworkDrives ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_HIDE_WAITING_DIALOG), BM_SETCHECK, + bHideWaitingDialog ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_TEMP_CACHE_ON_MULTIPLE_MOUNT), BM_SETCHECK, + bCacheDuringMultipleMount ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_EXIT), BM_SETCHECK, + bWipeCacheOnExit ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT), BM_SETCHECK, + bWipeCacheOnAutoDismount ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PASSWORDS), BM_SETCHECK, + bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM), BM_SETCHECK, + bIncludePimInCache? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_READONLY), BM_SETCHECK, + defaultMountOptions.ReadOnly ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_REMOVABLE), BM_SETCHECK, + defaultMountOptions.Removable ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START), BM_SETCHECK, + bStartOnLogon ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES), BM_SETCHECK, + bMountDevicesOnLogon ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE), BM_SETCHECK, + bEnableBkgTask ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL), BM_SETCHECK, + bCloseBkgTaskWhenNoVolumes || IsNonInstallMode() ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF), BM_SETCHECK, + bDismountOnLogOff ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED), BM_SETCHECK, + bDismountOnSessionLocked ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING), BM_SETCHECK, + bDismountOnPowerSaving ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER), BM_SETCHECK, + bDismountOnScreenSaver ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT), BM_SETCHECK, + bForceAutoDismount ? BST_CHECKED:BST_UNCHECKED, 0); + + SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE), BM_SETCHECK, + MaxVolumeIdleTime > 0 ? BST_CHECKED:BST_UNCHECKED, 0); + + SetDlgItemInt (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME, abs (MaxVolumeIdleTime), FALSE); + + PreferencesDlgEnableButtons (hwndDlg); + } + return 0; + + case WM_COMMAND: + + if (lw == IDC_PREF_BKG_TASK_ENABLE && !IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE))) + { + if (AskWarnNoYes ("CONFIRM_BACKGROUND_TASK_DISABLED", hwndDlg) == IDNO) + SetCheckBox (hwndDlg, IDC_PREF_BKG_TASK_ENABLE, TRUE); + } + + // Forced dismount disabled warning + if (lw == IDC_PREF_DISMOUNT_INACTIVE + || lw == IDC_PREF_DISMOUNT_LOGOFF + || lw == IDC_PREF_DISMOUNT_SESSION_LOCKED + || lw == IDC_PREF_DISMOUNT_POWERSAVING + || lw == IDC_PREF_DISMOUNT_SCREENSAVER + || lw == IDC_PREF_FORCE_AUTO_DISMOUNT) + { + BOOL i = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)); + BOOL l = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF)); + BOOL sl = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED)); + BOOL p = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING)); + BOOL s = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER)); + BOOL q = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT)); + + if (!q) + { + if (lw == IDC_PREF_FORCE_AUTO_DISMOUNT && (i || l || sl || p || s)) + { + if (AskWarnNoYes ("CONFIRM_NO_FORCED_AUTODISMOUNT", hwndDlg) == IDNO) + SetCheckBox (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT, TRUE); + } + else if ((lw == IDC_PREF_DISMOUNT_INACTIVE && i + || lw == IDC_PREF_DISMOUNT_LOGOFF && l + || lw == IDC_PREF_DISMOUNT_SESSION_LOCKED && sl + || lw == IDC_PREF_DISMOUNT_POWERSAVING && p + || lw == IDC_PREF_DISMOUNT_SCREENSAVER && s)) + Warning ("WARN_PREF_AUTO_DISMOUNT", hwndDlg); + } + + if (p && lw == IDC_PREF_DISMOUNT_POWERSAVING) + Warning ("WARN_PREF_AUTO_DISMOUNT_ON_POWER", hwndDlg); + } + + if (lw == IDCANCEL) + { + PreferencesDialogActive = FALSE; + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDOK) + { + WaitCursor (); + + bExplore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_OPEN_EXPLORER)); + bUseDifferentTrayIconIfVolMounted = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED)); + bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PRESERVE_TIMESTAMPS)); + bShowDisconnectedNetworkDrives = IsButtonChecked (GetDlgItem (hwndDlg, IDC_SHOW_DISCONNECTED_NETWORK_DRIVES)); + bHideWaitingDialog = IsButtonChecked (GetDlgItem (hwndDlg, IDC_HIDE_WAITING_DIALOG)); + bCacheDuringMultipleMount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_TEMP_CACHE_ON_MULTIPLE_MOUNT)); + bWipeCacheOnExit = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_EXIT)); + bWipeCacheOnAutoDismount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT)); + bCacheInDriverDefault = bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PASSWORDS)); + bIncludePimInCache = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM)); + defaultMountOptions.ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_READONLY)); + defaultMountOptions.Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_REMOVABLE)); + bEnableBkgTask = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE)); + bCloseBkgTaskWhenNoVolumes = IsNonInstallMode() ? bCloseBkgTaskWhenNoVolumes : IsButtonChecked (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL)); + bDismountOnLogOff = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF)); + bDismountOnSessionLocked = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED)); + bDismountOnPowerSaving = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING)); + bDismountOnScreenSaver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER)); + bForceAutoDismount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT)); + MaxVolumeIdleTime = GetDlgItemInt (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME, NULL, FALSE) + * (IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)) ? 1 : -1); + bStartOnLogon = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START)); + bMountDevicesOnLogon = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES)); + + ManageStartupSeq (); + + SaveSettings (hwndDlg); + + NormalCursor (); + + PreferencesDialogActive = FALSE; + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDC_MORE_SETTINGS) + { + HMENU popup = CreatePopupMenu (); + if (popup) + { + AppendMenuW (popup, MF_STRING, IDM_LANGUAGE, GetString ("IDM_LANGUAGE")); + AppendMenuW (popup, MF_STRING, IDM_HOTKEY_SETTINGS, GetString ("IDM_HOTKEY_SETTINGS")); + AppendMenuW (popup, MF_STRING, IDM_PERFORMANCE_SETTINGS, GetString ("IDM_PERFORMANCE_SETTINGS")); + AppendMenuW (popup, MF_STRING, IDM_SYSENC_SETTINGS, GetString ("IDM_SYSENC_SETTINGS")); + AppendMenuW (popup, MF_STRING, IDM_SYS_FAVORITES_SETTINGS, GetString ("IDM_SYS_FAVORITES_SETTINGS")); + AppendMenuW (popup, MF_STRING, IDM_DEFAULT_KEYFILES, GetString ("IDM_DEFAULT_KEYFILES")); + AppendMenuW (popup, MF_STRING, IDM_DEFAULT_MOUNT_PARAMETERS, GetString ("IDM_DEFAULT_MOUNT_PARAMETERS")); + AppendMenuW (popup, MF_STRING, IDM_TOKEN_PREFERENCES, GetString ("IDM_TOKEN_PREFERENCES")); + + RECT rect; + GetWindowRect (GetDlgItem (hwndDlg, IDC_MORE_SETTINGS), &rect); + + int menuItem = TrackPopupMenu (popup, TPM_RETURNCMD | TPM_LEFTBUTTON, rect.left + 2, rect.top + 2, 0, hwndDlg, NULL); + DestroyMenu (popup); + + SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); + return 1; + } + else + return 0; + } + + if (HIWORD (wParam) == BN_CLICKED) + { + PreferencesDlgEnableButtons (hwndDlg); + return 1; + } + + return 0; + } + + return 0; +} + + +BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static MountOptions *mountOptions; + + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + BOOL protect; + + mountOptions = (MountOptions *) lParam; + + LocalizeDialog (hwndDlg, "IDD_MOUNT_OPTIONS"); + + SendDlgItemMessage (hwndDlg, IDC_MOUNT_READONLY, BM_SETCHECK, + mountOptions->ReadOnly ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage (hwndDlg, IDC_MOUNT_REMOVABLE, BM_SETCHECK, + mountOptions->Removable ? BST_CHECKED : BST_UNCHECKED, 0); + SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, + mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0); + + SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, + mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0); + + mountOptions->PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode; + + SendDlgItemMessage (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA, BM_SETCHECK, + bPrebootPasswordDlgMode ? BST_CHECKED : BST_UNCHECKED, 0); + + SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK, + mountOptions->UseBackupHeader ? BST_CHECKED : BST_UNCHECKED, 0); + + EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA), !bPrebootPasswordDlgMode); + + SetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label); + SendDlgItemMessage (hwndDlg, IDC_VOLUME_LABEL, EM_LIMITTEXT, 32, 0); // 32 is the maximum possible length for a drive label in Windows + + /* Add PRF algorithm list for hidden volume password */ + HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); + SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); + + int i, nSelectedIndex = 0, nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); + + for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) + { + nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); + /* if a PRF was selected previously, select it */ + if (i == mountOptions->ProtectedHidVolPkcs5Prf) + nSelectedIndex = nIndex; + } + + SendMessage (hComboBox, CB_SETCURSEL, nSelectedIndex, 0); + + protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); + + EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); + EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); + EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT), protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), protect); + + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); + + SendDlgItemMessage (hwndDlg, IDC_PASSWORD_PROT_HIDVOL, EM_LIMITTEXT, MAX_PASSWORD, 0); + SendDlgItemMessage (hwndDlg, IDC_PIM, EM_LIMITTEXT, MAX_PIM, 0); + + if (mountOptions->ProtectedHidVolPassword.Length > 0) + { + wchar_t szTmp[MAX_PASSWORD + 1]; + if (0 == MultiByteToWideChar (CP_UTF8, 0, (LPSTR) mountOptions->ProtectedHidVolPassword.Text, -1, szTmp, MAX_PASSWORD + 1)) + szTmp [0] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), szTmp); + burn (szTmp, sizeof (szTmp)); + } + + SetPim (hwndDlg, IDC_PIM, mountOptions->ProtectedHidVolPim); + + /* make PIM field visible if a PIM value has been explicitely specified */ + if (mountOptions->ProtectedHidVolPim > 0) + { + SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE); + ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); + } + + ToHyperlink (hwndDlg, IDC_LINK_HIDVOL_PROTECTION_INFO); + + } + return 0; + + case WM_CONTEXTMENU: + { + RECT buttonRect; + GetWindowRect (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), &buttonRect); + + if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)) + && LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right + && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom) + { + // The "Keyfiles" button has been right-clicked + + POINT popupPos; + popupPos.x = buttonRect.left + 2; + popupPos.y = buttonRect.top + 2; + + if (KeyfilesPopupMenu (hwndDlg, popupPos, &hidVolProtKeyFilesParam)) + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); + } + } + break; + + case WM_COMMAND: + + if (lw == IDC_KEYFILES_HIDVOL_PROT) + { + if (IDOK == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, + (DLGPROC) KeyFilesDlgProc, (LPARAM) &hidVolProtKeyFilesParam)) + { + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); + } + } + + if (lw == IDC_KEYFILES_ENABLE_HIDVOL_PROT) + { + hidVolProtKeyFilesParam.EnableKeyFiles = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT); + + return 0; + } + + if (lw == IDC_SHOW_PASSWORD_MO) + { + HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_MO, IDC_PASSWORD_PROT_HIDVOL, IDC_PIM); + return 1; + } + + if (lw == IDC_PIM_ENABLE) + { + ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE); + ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW); + ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW); + + SetFocus (GetDlgItem (hwndDlg, IDC_PIM)); + return 1; + } + + if (lw == IDC_LINK_HIDVOL_PROTECTION_INFO) + { + Applink ("hiddenvolprotection", TRUE, ""); + } + + if (lw == IDCANCEL) + { + wchar_t tmp[MAX_PASSWORD+1]; + + // Cleanup + wmemset (tmp, L'X', MAX_PASSWORD); + tmp[MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); + + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDOK) + { + wchar_t tmp[MAX_PASSWORD+1]; + + mountOptions->ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)); + mountOptions->Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_REMOVABLE)); + mountOptions->ProtectHiddenVolume = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); + mountOptions->PartitionInInactiveSysEncScope = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA)); + mountOptions->UseBackupHeader = IsButtonChecked (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK)); + + GetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label, sizeof (mountOptions->Label) /sizeof (wchar_t)); + + if (mountOptions->ProtectHiddenVolume) + { + GetPassword (hwndDlg, IDC_PASSWORD_PROT_HIDVOL, + (LPSTR) mountOptions->ProtectedHidVolPassword.Text, MAX_PASSWORD + 1, + FALSE); + + mountOptions->ProtectedHidVolPassword.Length = (unsigned __int32) strlen ((char *) mountOptions->ProtectedHidVolPassword.Text); + + mountOptions->ProtectedHidVolPkcs5Prf = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, + SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); + + mountOptions->ProtectedHidVolPim = GetPim (hwndDlg, IDC_PIM); + } + + // Cleanup + wmemset (tmp, L'X', MAX_PASSWORD); + tmp[MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); + + if ((mountOptions->ProtectHiddenVolume && !bEnableBkgTask) + && (AskWarnYesNo ("HIDVOL_PROT_BKG_TASK_WARNING", hwndDlg) == IDYES)) + { + bEnableBkgTask = TRUE; + TaskBarIconAdd (MainDlg); + } + + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL) + { + BOOL protect; + + if (lw == IDC_MOUNT_READONLY) + { + SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0); + EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); + EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY))); + } + + protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL)); + + EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT), protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), protect); + EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), protect); + EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), protect); + + return 1; + } + + return 0; + } + + return 0; +} + + +// Returns the block size (in bits) of the cipher with which the volume mounted as the +// specified drive letter is encrypted. In case of a cascade of ciphers with different +// block sizes the function returns the smallest block size. +int GetCipherBlockSizeByDriveNo (int nDosDriveNo) +{ + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + + int blockSize = 0, cipherID; + + memset (&prop, 0, sizeof(prop)); + prop.driveNo = nDosDriveNo; + + if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL)) + { + if ( (prop.driveNo == nDosDriveNo) + && (prop.ea >= EAGetFirst() && prop.ea <= EAGetCount()) + ) + { + for (cipherID = EAGetLastCipher (prop.ea); + cipherID != 0; + cipherID = EAGetPreviousCipher (prop.ea, cipherID)) + { + if (blockSize > 0) + blockSize = min (blockSize, CipherGetBlockSize (cipherID) * 8); + else + blockSize = CipherGetBlockSize (cipherID) * 8; + } + } + } + + return blockSize; +} + + +// Returns the mode of operation in which the volume mounted as the specified drive letter is encrypted. +int GetModeOfOperationByDriveNo (int nDosDriveNo) +{ + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + + memset (&prop, 0, sizeof(prop)); + prop.driveNo = nDosDriveNo; + + if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL)) + { + if ( (prop.driveNo == nDosDriveNo) + && (prop.ea >= EAGetFirst() && prop.ea <= EAGetCount()) + && (prop.mode >= FIRST_MODE_OF_OPERATION_ID && prop.mode < MODE_ENUM_END_ID) + ) + { + return prop.mode; + } + } + + return 0; +} + +void DisplayVolumePropertiesListContextMenu (HWND hwndDlg, LPARAM lParam) +{ + /* Volume Properties list context menu */ + DWORD mPos; + int menuItem; + HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); + int hItem = ListView_GetSelectionMark (hList); + + SetFocus (hList); + + if (hItem >= 0) + { + HMENU popup = CreatePopupMenu (); + AppendMenuW (popup, MF_STRING, IDPM_COPY_VALUE_TO_CLIPBOARD, GetString ("IDPM_COPY_VALUE_TO_CLIPBOARD")); + + if (lParam) + { + mPos=GetMessagePos(); + } + else + { + POINT pt = {0}; + if (ListView_GetItemPosition (hList, hItem, &pt)) + { + pt.x += 2 + ::GetSystemMetrics(SM_CXICON); + pt.y += 2; + } + ClientToScreen (hList, &pt); + mPos = MAKELONG (pt.x, pt.y); + } + + menuItem = TrackPopupMenu (popup, + TPM_RETURNCMD | TPM_LEFTBUTTON, + GET_X_LPARAM(mPos), + GET_Y_LPARAM(mPos), + 0, + hwndDlg, + NULL); + + DestroyMenu (popup); + + switch (menuItem) + { + case IDPM_COPY_VALUE_TO_CLIPBOARD: + { + wchar_t valueText[256] = {0}; + ListView_GetItemText (hList, hItem, 1, valueText, ARRAYSIZE (valueText)); + CopyTextToClipboard (valueText); + } + break; + } + } +} + + +BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + BOOL bSysEnc = (BOOL) lParam; + BOOL bSysEncWholeDrive = FALSE; + WORD lw = LOWORD (wParam); + int i = 0; + + switch (msg) + { + case WM_INITDIALOG: + { + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + + LVCOLUMNW lvCol; + HWND list = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); + wchar_t szTmp[1024]; + wchar_t sw[1024]; + wchar_t *s; + + if (bSysEnc) + { + try + { + BootEncStatus = BootEncObj->GetStatus(); + bSysEncWholeDrive = WholeSysDriveEncryption(FALSE); + } + catch (Exception &e) + { + e.Show (MainDlg); + return 0; + } + + if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) + return 0; + } + else + { + switch (LOWORD (GetSelectedLong (GetDlgItem (GetParent(hwndDlg), IDC_DRIVELIST)))) + { + case TC_MLIST_ITEM_FREE: + + // No mounted volume + EndDialog (hwndDlg, IDOK); + return 0; + + case TC_MLIST_ITEM_NONSYS_VOL: + // NOP + break; + + case TC_MLIST_ITEM_SYS_DRIVE: + // Encrypted system drive + bSysEnc = TRUE; + bSysEncWholeDrive = TRUE; + break; + + case TC_MLIST_ITEM_SYS_PARTITION: + // Encrypted system partition + bSysEnc = TRUE; + bSysEncWholeDrive = FALSE; + break; + } + } + + LocalizeDialog (hwndDlg, "IDD_VOLUME_PROPERTIES"); + + SendMessage (list,LVM_SETEXTENDEDLISTVIEWSTYLE, 0, + LVS_EX_FULLROWSELECT + |LVS_EX_HEADERDRAGDROP + |LVS_EX_LABELTIP + ); + + memset (&lvCol,0,sizeof(lvCol)); + lvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; + lvCol.pszText = GetString ("VALUE"); + lvCol.cx = CompensateXDPI (208); + lvCol.fmt = LVCFMT_LEFT; + SendMessage (list,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol); + + lvCol.pszText = GetString ("PROPERTY"); + lvCol.cx = CompensateXDPI (192); + lvCol.fmt = LVCFMT_LEFT; + SendMessage (list,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol); + + memset (&prop, 0, sizeof(prop)); + prop.driveNo = HIWORD (GetSelectedLong (GetDlgItem (GetParent(hwndDlg), IDC_DRIVELIST))) - L'A'; + + if (bSysEnc) + { + try + { + BootEncStatus = BootEncObj->GetStatus(); + if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) + return 0; + + BootEncObj->GetVolumeProperties (&prop); + } + catch (Exception &e) + { + e.Show (MainDlg); + return 0; + } + } + else + { + if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) + return 0; + } + + // Location + ListItemAdd (list, i, GetString ("LOCATION")); + if (bSysEnc) + ListSubItemSet (list, i++, 1, GetString (bSysEncWholeDrive ? "SYSTEM_DRIVE" : IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION")); + else + ListSubItemSet (list, i++, 1, (wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4)); + + if (!bSysEnc && IsVolumeDeviceHosted ((wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4))) + { + // Volume ID + std::wstring hexID = ArrayToHexWideString (prop.volumeID, sizeof (prop.volumeID)); + ListItemAdd (list, i, GetString ("VOLUME_ID")); + + ListSubItemSet (list, i++, 1, hexID.c_str()); + } + + + // Size + ListItemAdd (list, i, GetString ("SIZE")); + StringCbPrintfW (sw, sizeof(sw), L"%I64u %s", prop.diskLength, GetString ("BYTES")); + ListSubItemSet (list, i++, 1, sw); + + // Type + ListItemAdd (list, i, GetString ("TYPE")); + if (bSysEnc) + ListSubItemSet (list, i++, 1, GetString (IsHiddenOSRunning() ? "TYPE_HIDDEN_SYSTEM_ADJECTIVE" : "SYSTEM_VOLUME_TYPE_ADJECTIVE")); + else + { + bool truecryptMode = prop.pkcs5Iterations == get_pkcs5_iteration_count(prop.pkcs5, 0, TRUE, prop.partitionInInactiveSysEncScope); + s = prop.hiddenVolume ? GetString ("HIDDEN") : + (prop.hiddenVolProtection != HIDVOL_PROT_STATUS_NONE ? GetString ("OUTER") : GetString ("NORMAL")); + + if (truecryptMode) + { + StringCbPrintfW (sw, sizeof(sw), L"TrueCrypt - %s", s); + ListSubItemSet (list, i++, 1, sw); + } + else + ListSubItemSet (list, i++, 1, s); + } + + if (!bSysEnc) + { + // Write protection + ListItemAdd (list, i, GetString ("READ_ONLY")); + + if (prop.readOnly || prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN) + s = GetString ("UISTR_YES"); + else + s = GetString ("UISTR_NO"); + + ListSubItemSet (list, i++, 1, s); + + // Hidden Volume Protection + ListItemAdd (list, i, GetString ("HIDDEN_VOL_PROTECTION")); + if (prop.hiddenVolume) + s = GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"); + else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_NONE) + s = GetString ("UISTR_NO"); + else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTIVE) + s = GetString ("UISTR_YES"); + else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN) + s = GetString ("HID_VOL_DAMAGE_PREVENTED"); + + ListSubItemSet (list, i++, 1, s); + } + + // Encryption algorithm + ListItemAdd (list, i, GetString ("ENCRYPTION_ALGORITHM")); + + if (prop.ea < EAGetFirst() || prop.ea > EAGetCount ()) + { + ListSubItemSet (list, i, 1, L"?"); + return 1; + } + + EAGetName (szTmp, prop.ea, 1); + ListSubItemSet (list, i++, 1, szTmp); + + // Key size(s) + { + wchar_t name[128]; + int size = EAGetKeySize (prop.ea); + EAGetName (name, prop.ea, 1); + + // Primary key + ListItemAdd (list, i, GetString ("KEY_SIZE")); + StringCbPrintfW (sw, sizeof(sw), L"%d %s", size * 8, GetString ("BITS")); + ListSubItemSet (list, i++, 1, sw); + + if (wcscmp (EAGetModeName (prop.ea, prop.mode, TRUE), L"XTS") == 0) + { + // Secondary key (XTS) + + ListItemAdd (list, i, GetString ("SECONDARY_KEY_SIZE_XTS")); + ListSubItemSet (list, i++, 1, sw); + } + } + + // Block size + ListItemAdd (list, i, GetString ("BLOCK_SIZE")); + + StringCbPrintfW (sw, sizeof(sw), L"%d ", CipherGetBlockSize (EAGetFirstCipher(prop.ea))*8); + StringCbCatW (sw, sizeof(sw), GetString ("BITS")); + ListSubItemSet (list, i++, 1, sw); + + // Mode + ListItemAdd (list, i, GetString ("MODE_OF_OPERATION")); + ListSubItemSet (list, i++, 1, EAGetModeName (prop.ea, prop.mode, TRUE)); + + // PKCS 5 PRF + ListItemAdd (list, i, GetString ("PKCS5_PRF")); + if (prop.volumePim == 0) + ListSubItemSet (list, i++, 1, get_pkcs5_prf_name (prop.pkcs5)); + else + { + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s (Dynamic)", get_pkcs5_prf_name (prop.pkcs5)); + ListSubItemSet (list, i++, 1, szTmp); + } + +#if 0 + // PCKS 5 iterations + ListItemAdd (list, i, GetString ("PKCS5_ITERATIONS")); + sprintf (szTmp, "%d", prop.pkcs5Iterations); + ListSubItemSet (list, i++, 1, szTmp); +#endif + +#if 0 + { + // Legacy + + FILETIME ft, curFt; + LARGE_INTEGER ft64, curFt64; + SYSTEMTIME st; + wchar_t date[128]; + memset (date, 0, sizeof (date)); + + // Volume date + ListItemAdd (list, i, GetString ("VOLUME_CREATE_DATE")); + *(unsigned __int64 *)(&ft) = prop.volumeCreationTime; + FileTimeToSystemTime (&ft, &st); + GetDateFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); + swprintf (date, L"%s ", sw); + GetTimeFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); + wcscat (date, sw); + ListSubItemSet (list, i++, 1, date); + + // Header date + ListItemAdd (list, i, GetString ("VOLUME_HEADER_DATE")); + *(unsigned __int64 *)(&ft) = prop.headerCreationTime; + FileTimeToSystemTime (&ft, &st); + GetDateFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); + swprintf (date, L"%s ", sw); + GetTimeFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2); + wcscat (date, sw); + + GetLocalTime (&st); + SystemTimeToFileTime (&st, &curFt); + curFt64.HighPart = curFt.dwHighDateTime; + curFt64.LowPart = curFt.dwLowDateTime; + ft64.HighPart = ft.dwHighDateTime; + ft64.LowPart = ft.dwLowDateTime; + swprintf (date + wcslen (date), GetString ("VOLUME_HEADER_DAYS") + , (curFt64.QuadPart - ft64.QuadPart)/(24LL*3600*10000000)); + ListSubItemSet (list, i++, 1, date); + } +#endif // 0 + + if (!bSysEnc || IsHiddenOSRunning()) + { + // Volume format version + ListItemAdd (list, i, GetString ("VOLUME_FORMAT_VERSION")); + StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", prop.volFormatVersion); + ListSubItemSet (list, i++, 1, szTmp); + + // Backup header + ListItemAdd (list, i, GetString ("BACKUP_HEADER")); + ListSubItemSet (list, i++, 1, GetString (prop.volFormatVersion > 1 ? "UISTR_YES" : "UISTR_NO")); + } + + // Total data read + ListItemAdd (list, i, GetString ("TOTAL_DATA_READ")); + GetSizeString (prop.totalBytesRead, sw, sizeof(sw)); + ListSubItemSet (list, i++, 1, sw); + + // Total data written + ListItemAdd (list, i, GetString ("TOTAL_DATA_WRITTEN")); + GetSizeString (prop.totalBytesWritten, sw, sizeof(sw)); + ListSubItemSet (list, i++, 1, sw); + + if (bSysEnc) + { + // TrueCrypt Boot Loader version + ListItemAdd (list, i, GetString ("VC_BOOT_LOADER_VERSION")); + ListSubItemSet (list, i++, 1, GetUserFriendlyVersionString (BootEncStatus.BootLoaderVersion).c_str()); + + // Encrypted portion + ListItemAdd (list, i, GetString ("ENCRYPTED_PORTION")); + if (GetSysEncDeviceEncryptedPartSize (FALSE) == GetSysEncDeviceSize (FALSE)) + ListSubItemSet (list, i++, 1, GetString ("ENCRYPTED_PORTION_FULLY_ENCRYPTED")); + else if (GetSysEncDeviceEncryptedPartSize (FALSE) <= 1) + ListSubItemSet (list, i++, 1, GetString ("ENCRYPTED_PORTION_NOT_ENCRYPTED")); + else + { + + StringCbPrintfW (sw, + sizeof sw, + GetString ("PROCESSED_PORTION_X_PERCENT"), + (double) GetSysEncDeviceEncryptedPartSize (FALSE) / (double) GetSysEncDeviceSize (FALSE) * 100.0); + + ListSubItemSet (list, i++, 1, sw); + } + } + + return 0; + } + + case WM_NOTIFY: + + if(wParam == IDC_VOLUME_PROPERTIES_LIST) + { + /* Right click */ + + switch (((NM_LISTVIEW *) lParam)->hdr.code) + { + case NM_RCLICK: + case LVN_BEGINRDRAG: + /* If the mouse was moving while the right mouse button is pressed, popup menu would + not open, because drag&drop operation would be initiated. Therefore, we're handling + RMB drag-and-drop operations as well. */ + { + + DisplayVolumePropertiesListContextMenu (hwndDlg, lParam); + + return 1; + } + } + } + return 0; + + case WM_CONTEXTMENU: + { + HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); + // only handle if it is coming from keyboard and if the drive + // list has focus. The other cases are handled elsewhere + if ( (-1 == GET_X_LPARAM(lParam)) + && (-1 == GET_Y_LPARAM(lParam)) + && (GetFocus () == hList) + ) + { + DisplayVolumePropertiesListContextMenu (hwndDlg, NULL); + } + } + return 0; + + case WM_COMMAND: + if (lw == IDOK) + { + EndDialog (hwndDlg, lw); + return 1; + } + return 0; + + case WM_CLOSE: + EndDialog (hwndDlg, lw); + return 1; + } + + return 0; +} + + +BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + static BOOL bAutoRunWarningDisplayed = FALSE; + + switch (msg) + { + case WM_INITDIALOG: + { + WCHAR i; + int index; + WCHAR drive[] = { 0, L':', 0 }; + + LocalizeDialog (hwndDlg, "IDD_TRAVELER_DLG"); + + SendDlgItemMessage (hwndDlg, IDC_COPY_WIZARD, BM_SETCHECK, + BST_CHECKED, 0); + + SendDlgItemMessage (hwndDlg, IDC_COPY_EXPANDER, BM_SETCHECK, + BST_CHECKED, 0); + + SendDlgItemMessage (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER, BM_SETCHECK, + BST_CHECKED, 0); + + SendDlgItemMessage (hwndDlg, IDC_AUTORUN_DISABLE, BM_SETCHECK, + BST_CHECKED, 0); + + SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_RESETCONTENT, 0, 0); + + index = (int) SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) GetString ("FIRST_AVAILABLE")); + SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) 0); + + for (i = L'A'; i <= L'Z'; i++) + { + if (i == L'C') + continue; + drive[0] = i; + index = (int) SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) drive); + SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) i); + } + + SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_SETCURSEL, 0, 0); + + return 0; + } + + case WM_CTLCOLORSTATIC: + { + HDC hdc = (HDC) wParam; + HWND hw = (HWND) lParam; + if (hw == GetDlgItem(hwndDlg, IDC_DIRECTORY)) + { + // This the directory field. Make its background like normal edit + HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW); + ::SelectObject(hdc, hbr); + return (BOOL) hbr; + } + } + return 0; + + case WM_COMMAND: + + if (HIWORD (wParam) == BN_CLICKED + && (lw == IDC_AUTORUN_DISABLE || lw == IDC_AUTORUN_MOUNT || lw == IDC_AUTORUN_START )) + { + BOOL enabled = IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_MOUNT)); + + EnableWindow (GetDlgItem (hwndDlg, IDC_BROWSE_FILES), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_NAME), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDC_DRIVELIST), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDT_TRAVELER_MOUNT), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDT_MOUNT_LETTER), enabled); + EnableWindow (GetDlgItem (hwndDlg, IDT_MOUNT_SETTINGS), enabled); + + if (!bAutoRunWarningDisplayed + && (lw == IDC_AUTORUN_MOUNT || lw == IDC_AUTORUN_START)) + { + bAutoRunWarningDisplayed = TRUE; + Warning ("AUTORUN_MAY_NOT_ALWAYS_WORK", hwndDlg); + } + + return 1; + } + + if (lw == IDC_BROWSE_FILES) + { + wchar_t dstDir[MAX_PATH]; + wchar_t volName[MAX_PATH] = { 0 }; + + GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstDir, ARRAYSIZE (dstDir)); + + if (BrowseFilesInDir (hwndDlg, "OPEN_TITLE", dstDir, volName, bHistory, FALSE, NULL)) + SetDlgItemText (hwndDlg, IDC_VOLUME_NAME, wcschr (volName, L'\\') + 1); + + return 1; + } + + if (lw == IDC_BROWSE_DIRS) + { + wchar_t dstPath[MAX_PATH * 2]; + GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath, ARRAYSIZE (dstPath)); + + if (BrowseDirectories (hwndDlg, "SELECT_DEST_DIR", dstPath)) + SetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath); + + return 1; + } + + if (lw == IDCANCEL || lw == IDCLOSE) + { + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDC_CREATE) + { + + BOOL copyWizard, copyExpander, bExplore, bCacheInDriver, bIncludePimInCache, bAutoRun, bAutoMount, bMountReadOnly; + WCHAR dstDir[MAX_PATH + 1]; + WCHAR srcPath[1024 + MAX_PATH + 1]; + WCHAR dstPath[2*MAX_PATH + 1]; + WCHAR appDir[1024]; + WCHAR volName[MAX_PATH + 2]; + int drive; + WCHAR* ptr; + + GetDlgItemTextW (hwndDlg, IDC_DIRECTORY, dstDir, array_capacity (dstDir)); + volName[0] = 0; + GetDlgItemTextW (hwndDlg, IDC_VOLUME_NAME, volName + 1, (array_capacity (volName)) - 1); + + drive = (int) SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETCURSEL, 0, 0); + drive = (int) SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETITEMDATA, drive, 0); + + copyWizard = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_WIZARD)); + copyExpander = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_EXPANDER)); + bExplore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER)); + bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS)); + bIncludePimInCache = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM)); + bMountReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)); + bAutoRun = !IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_DISABLE)); + bAutoMount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_MOUNT)); + + if (dstDir[0] == 0) + { + SetFocus (GetDlgItem (hwndDlg, IDC_DIRECTORY)); + MessageBoxW (hwndDlg, GetString ("NO_PATH_SELECTED"), lpszTitle, MB_ICONEXCLAMATION); + return 1; + } + + + if (bAutoMount && volName[1] == 0) + { + SetFocus (GetDlgItem (hwndDlg, IDC_VOLUME_NAME)); + MessageBoxW (hwndDlg, GetString ("NO_FILE_SELECTED"), lpszTitle, MB_ICONEXCLAMATION); + return 1; + } + + if (volName[1] != 0) + { + volName[0] = L'"'; + StringCbCatW (volName, sizeof(volName), L"\""); + } + + GetModuleFileNameW (NULL, appDir, array_capacity (appDir)); + if (ptr = wcsrchr (appDir, L'\\')) + ptr[0] = 0; + + WaitCursor (); + + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt", dstDir); + if (!CreateDirectoryW (dstPath, NULL)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + // Main app 32-bit + if (Is64BitOs () && !IsNonInstallMode ()) + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt-x86.exe", appDir); + else + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt.exe", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + // Main app 64-bit + if (Is64BitOs () && !IsNonInstallMode ()) + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt.exe", appDir); + else + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt-x64.exe", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt-x64.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + // Wizard + if (copyWizard) + { + // Wizard 32-bit + if (Is64BitOs () && !IsNonInstallMode ()) + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format-x86.exe", appDir); + else + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format.exe", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + // Wizard 64-bit + if (Is64BitOs () && !IsNonInstallMode ()) + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format.exe", appDir); + else + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format-x64.exe", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format-x64.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + } + + // Expander + if (copyExpander) + { + // Expander 32-bit + if (Is64BitOs () && !IsNonInstallMode ()) + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander-x86.exe", appDir); + else + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander.exe", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + // Expander 64-bit + if (Is64BitOs () && !IsNonInstallMode ()) + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander.exe", appDir); + else + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander-x64.exe", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander-x64.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + } + + // Driver + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt.sys", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt.sys", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + // Driver x64 + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt-x64.sys", appDir); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-x64.sys", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto stop; + } + + if (strcmp (GetPreferredLangId (), "en") != 0) + { + // Language pack + StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\Language.%hs.xml", appDir, GetPreferredLangId ()); + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\Language.%hs.xml", dstDir, GetPreferredLangId ()); + TCCopyFile (srcPath, dstPath); + } + + // AutoRun + StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\autorun.inf", dstDir); + DeleteFileW (dstPath); + if (bAutoRun) + { + FILE *af; + wchar_t autoMount[2*MAX_PATH + 2]; + wchar_t driveLetter[] = { L' ', L'/', L'l', L' ', (wchar_t) drive, 0 }; + + af = _wfopen (dstPath, L"w,ccs=UNICODE"); + + if (af == NULL) + { + MessageBoxW (hwndDlg, GetString ("CANT_CREATE_AUTORUN"), lpszTitle, MB_ICONERROR); + goto stop; + } + + StringCbPrintfW (autoMount, sizeof(autoMount), L"VeraCrypt\\VeraCrypt.exe /q background%s%s%s%s /m rm /v %s", + drive > 0 ? driveLetter : L"", + bExplore ? L" /e" : L"", + bCacheInDriver ? (bIncludePimInCache? L" /c p" : L" /c y") : L"", + bMountReadOnly ? L" /m ro" : L"", + volName); + + fwprintf (af, L"[autorun]\nlabel=%s\nicon=VeraCrypt\\VeraCrypt.exe\n", GetString ("TC_TRAVELER_DISK")); + fwprintf (af, L"action=%s\n", bAutoMount ? GetString ("MOUNT_TC_VOLUME") : GetString ("IDC_PREF_LOGON_START")); + fwprintf (af, L"open=%s\n", bAutoMount ? autoMount : L"VeraCrypt\\VeraCrypt.exe"); + fwprintf (af, L"shell\\start=%s\nshell\\start\\command=VeraCrypt\\VeraCrypt.exe\n", GetString ("IDC_PREF_LOGON_START")); + fwprintf (af, L"shell\\dismount=%s\nshell\\dismount\\command=VeraCrypt\\VeraCrypt.exe /q /d\n", GetString ("DISMOUNT_ALL_TC_VOLUMES")); + + CheckFileStreamWriteErrors (hwndDlg, af, dstPath); + fclose (af); + } + MessageBoxW (hwndDlg, GetString ("TRAVELER_DISK_CREATED"), lpszTitle, MB_ICONINFORMATION); + +stop: + NormalCursor (); + return 1; + } + return 0; + } + + return 0; +} + +void BuildTree (HWND hwndDlg, HWND hTree) +{ + HIMAGELIST hList; + HBITMAP hBitmap, hBitmapMask; + LVCOLUMNW lvCol; + + ListView_DeleteColumn (hTree,0); + ListView_DeleteColumn (hTree,0); + ListView_DeleteColumn (hTree,0); + ListView_DeleteColumn (hTree,0); + ListView_DeleteColumn (hTree,0); + ListView_DeleteColumn (hTree,0); + + SendMessage(hTree,LVM_SETEXTENDEDLISTVIEWSTYLE,0, + LVS_EX_FULLROWSELECT + |LVS_EX_HEADERDRAGDROP + ); + + memset(&lvCol,0,sizeof(lvCol)); + + lvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; + lvCol.pszText = GetString ("DRIVE"); + lvCol.cx = CompensateXDPI (38); + lvCol.fmt = LVCFMT_COL_HAS_IMAGES|LVCFMT_LEFT ; + SendMessage (hTree,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol); + + lvCol.pszText = GetString ("VOLUME"); + lvCol.cx = CompensateXDPI (200); + lvCol.fmt = LVCFMT_LEFT; + SendMessage (hTree,LVM_INSERTCOLUMNW,1,(LPARAM)&lvCol); + LastDriveListVolumeColumnWidth = ListView_GetColumnWidth (hTree, 1); + + lvCol.pszText = GetString ("SIZE"); + lvCol.cx = CompensateXDPI (55); + lvCol.fmt = LVCFMT_RIGHT; + SendMessage (hTree,LVM_INSERTCOLUMNW,2,(LPARAM)&lvCol); + + lvCol.pszText = GetString ("ENCRYPTION_ALGORITHM_LV"); + lvCol.cx = CompensateXDPI (123); + lvCol.fmt = LVCFMT_LEFT; + SendMessage (hTree,LVM_INSERTCOLUMNW,3,(LPARAM)&lvCol); + + lvCol.pszText = GetString ("TYPE"); + lvCol.cx = CompensateXDPI (100); + lvCol.fmt = LVCFMT_LEFT; + SendMessage (hTree,LVM_INSERTCOLUMNW,4,(LPARAM)&lvCol); + + // Regular drive icon + + hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_DRIVEICON)); + if (hBitmap == NULL) + return; + hBitmapMask = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_DRIVEICON_MASK)); + + hList = CreateImageList (16, 12, ILC_COLOR8|ILC_MASK, 2, 2); + if (AddBitmapToImageList (hList, hBitmap, hBitmapMask) == -1) + { + DeleteObject (hBitmap); + DeleteObject (hBitmapMask); + return; + } + else + { + DeleteObject (hBitmap); + DeleteObject (hBitmapMask); + } + + // System drive icon + + hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_SYS_DRIVEICON)); + if (hBitmap == NULL) + return; + hBitmapMask = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_SYS_DRIVEICON_MASK)); + + if (AddBitmapToImageList (hList, hBitmap, hBitmapMask) == -1) + { + DeleteObject (hBitmap); + DeleteObject (hBitmapMask); + return; + } + else + { + DeleteObject (hBitmap); + DeleteObject (hBitmapMask); + } + + ListView_SetImageList (hTree, hList, LVSIL_NORMAL); + ListView_SetImageList (hTree, hList, LVSIL_SMALL); + + LoadDriveLetters (hwndDlg, hTree, 0); +} + +LPARAM GetSelectedLong (HWND hTree) +{ + int hItem = ListView_GetSelectionMark (hTree); + LVITEM item; + + if (nSelectedDriveIndex >= 0) + hItem = nSelectedDriveIndex; + + memset(&item, 0, sizeof(LVITEM)); + item.mask = LVIF_PARAM; + item.iItem = hItem; + + if ( (ListView_GetItemCount (hTree) < 1) + || (ListView_GetItem (hTree, &item) == FALSE) + ) + return MAKELONG (0xffff, 0xffff); + else + return item.lParam; +} + +LPARAM GetItemLong (HWND hTree, int itemNo) +{ + LVITEM item; + + memset(&item, 0, sizeof(LVITEM)); + item.mask = LVIF_PARAM; + item.iItem = itemNo; + + if (ListView_GetItem (hTree, &item) == FALSE) + return MAKELONG (0xffff, 0xffff); + else + return item.lParam; +} + +static int AskVolumePassword (HWND hwndDlg, Password *password, int *pkcs5, int *pim, BOOL* truecryptMode, char *titleStringId, BOOL enableMountOptions) +{ + INT_PTR result; + PasswordDlgParam dlgParam; + + PasswordDialogTitleStringId = titleStringId; + PasswordDialogDisableMountOptions = !enableMountOptions; + + dlgParam.password = password; + dlgParam.pkcs5 = pkcs5; + dlgParam.pim = pim; + dlgParam.truecryptMode = truecryptMode; + + result = DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_PASSWORD_DLG), hwndDlg, + (DLGPROC) PasswordDlgProc, (LPARAM) &dlgParam); + + if (result != IDOK) + { + password->Length = 0; + *pkcs5 = 0; + *pim = -1; + *truecryptMode = FALSE; + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); + } + + return result == IDOK; +} + +// GUI actions + +static BOOL Mount (HWND hwndDlg, int nDosDriveNo, wchar_t *szFileName, int pim) +{ + BOOL status = FALSE; + wchar_t fileName[MAX_PATH]; + int mounted = 0, EffectiveVolumePkcs5 = CmdVolumePkcs5; + BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; + int EffectiveVolumePim = (pim < 0)? CmdVolumePim : pim; + BOOL bEffectiveCacheDuringMultipleMount = bCmdCacheDuringMultipleMount? TRUE: bCacheDuringMultipleMount; + BOOL bEffectiveTryEmptyPasswordWhenKeyfileUsed = bCmdTryEmptyPasswordWhenKeyfileUsedValid? bCmdTryEmptyPasswordWhenKeyfileUsed : bTryEmptyPasswordWhenKeyfileUsed; + BOOL bUseCmdVolumePassword = CmdVolumePasswordValid && ((CmdVolumePassword.Length > 0) || (KeyFilesEnable && FirstKeyFile)); + + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (EffectiveVolumePkcs5 == 0) + EffectiveVolumePkcs5 = DefaultVolumePkcs5; + if (!EffectiveVolumeTrueCryptMode) + EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; + + bPrebootPasswordDlgMode = mountOptions.PartitionInInactiveSysEncScope; + + if (nDosDriveNo == -1) + nDosDriveNo = HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))) - L'A'; + + if (!MultipleMountOperationInProgress) + { + VolumePassword.Length = 0; + VolumePkcs5 = 0; + VolumeTrueCryptMode = FALSE; + VolumePim = -1; + } + + if (szFileName == NULL) + { + GetVolumePath (hwndDlg, fileName, ARRAYSIZE (fileName)); + } + else + StringCchCopyW (fileName, ARRAYSIZE (fileName), szFileName); + + if (wcslen(fileName) == 0) + { + status = FALSE; + goto ret; + } + + if (!TranslateVolumeID (hwndDlg, fileName, ARRAYSIZE (fileName))) + { + status = FALSE; + goto ret; + } + + szFileName = fileName; + + if (IsMountedVolume (szFileName)) + { + Warning ("VOL_ALREADY_MOUNTED", hwndDlg); + status = FALSE; + goto ret; + } + + if (!VolumePathExists (szFileName)) + { + if (!MultipleMountOperationInProgress) + handleWin32Error (hwndDlg, SRC_POS); + + status = FALSE; + goto ret; + } + + ResetWrongPwdRetryCount (); + + WaitCursor (); + + if (!bUseCmdVolumePassword) + { + // First try cached passwords and if they fail ask user for a new one + // try TrueCrypt mode first since it is quick, only if no custom pim specified + if (EffectiveVolumePim <= 0) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, 0, 0, TRUE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + if (!mounted) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, 0, EffectiveVolumePim, FALSE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + + // If keyfiles are enabled, test empty password first + if (!mounted && KeyFilesEnable && FirstKeyFile && bEffectiveTryEmptyPasswordWhenKeyfileUsed) + { + Password emptyPassword; + emptyPassword.Length = 0; + + KeyFilesApply (hwndDlg, &emptyPassword, FirstKeyFile, szFileName); + // try TrueCrypt mode first since it is quick, only if no custom pim specified + if (EffectiveVolumePim <= 0) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &emptyPassword, 0, 0, TRUE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + if (!mounted) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &emptyPassword, 0, EffectiveVolumePim, FALSE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + + burn (&emptyPassword, sizeof (emptyPassword)); + } + } + + // Test password and/or keyfiles used for the previous volume + if (!mounted && bEffectiveCacheDuringMultipleMount && MultipleMountOperationInProgress && VolumePassword.Length != 0) + { + // try TrueCrypt mode first as it is quick, only if no custom pim specified + if (EffectiveVolumePim <= 0) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, 0, 0, TRUE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + if (!mounted) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, 0, EffectiveVolumePim, FALSE, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + } + + NormalCursor (); + + if (mounted) + { + + // Check for problematic file extensions (exe, dll, sys) + if (CheckFileExtension(szFileName)) + Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING", hwndDlg); + } + + while (mounted == 0) + { + if (bUseCmdVolumePassword) + { + VolumePassword = CmdVolumePassword; + VolumePkcs5 = EffectiveVolumePkcs5; + VolumeTrueCryptMode = EffectiveVolumeTrueCryptMode; + VolumePim = EffectiveVolumePim; + } + else if (!Silent) + { + int GuiPkcs5 = EffectiveVolumePkcs5; + BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode; + int GuiPim = EffectiveVolumePim; + StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume), szFileName); + + if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &GuiTrueCryptMode, NULL, TRUE)) + goto ret; + else + { + VolumePkcs5 = GuiPkcs5; + VolumeTrueCryptMode = GuiTrueCryptMode; + VolumePim = GuiPim; + burn (&GuiPkcs5, sizeof(GuiPkcs5)); + burn (&GuiTrueCryptMode, sizeof(GuiTrueCryptMode)); + burn (&GuiPim, sizeof(GuiPim)); + } + } + + WaitCursor (); + + if (KeyFilesEnable) + KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, szFileName); + + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, !Silent); + NormalCursor (); + + // Check for problematic file extensions (exe, dll, sys) + if (mounted > 0 && CheckFileExtension (szFileName)) + Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING", hwndDlg); + + if (!MultipleMountOperationInProgress) + { + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&VolumePim, sizeof (VolumePim)); + } + + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); + + if (CmdVolumePassword.Length > 0 || Silent) + break; + } + + if (mounted > 0) + { + status = TRUE; + + if (bBeep) + MessageBeep (0xFFFFFFFF); + + RefreshMainDlg(MainDlg); + + if (bExplore) + { + WaitCursor(); + OpenVolumeExplorerWindow (nDosDriveNo); + NormalCursor(); + } + + if (mountOptions.ProtectHiddenVolume) + Info ("HIDVOL_PROT_WARN_AFTER_MOUNT", hwndDlg); + } + +ret: + if (!MultipleMountOperationInProgress) + { + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&VolumePim, sizeof (VolumePim)); + } + + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); + + RestoreDefaultKeyFilesParam (); + + if (UsePreferences) + bCacheInDriver = bCacheInDriverDefault; + + if (status && CloseSecurityTokenSessionsAfterMount && !MultipleMountOperationInProgress) + SecurityToken::CloseAllSessions(); + + return status; +} + + +static BOOL Dismount (HWND hwndDlg, int nDosDriveNo) +{ + BOOL status = FALSE; + WaitCursor (); + + if (nDosDriveNo == -2) + nDosDriveNo = (char) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) - L'A'); + + if (bCloseDismountedWindows) + { + CloseVolumeExplorerWindows (hwndDlg, nDosDriveNo); + } + + if (UnmountVolume (hwndDlg, nDosDriveNo, bForceUnmount)) + { + status = TRUE; + + if (bBeep) + MessageBeep (0xFFFFFFFF); + RefreshMainDlg (hwndDlg); + + if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ()) + LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); + } + + NormalCursor (); + return status; +} + +void __cdecl mountThreadFunction (void *hwndDlgArg) +{ + HWND hwndDlg =(HWND) hwndDlgArg; + BOOL bIsForeground = (GetForegroundWindow () == hwndDlg)? TRUE : FALSE; + // Disable parent dialog during processing to avoid user interaction + EnableWindow(hwndDlg, FALSE); + finally_do_arg2 (HWND, hwndDlg, BOOL, bIsForeground, { EnableWindow(finally_arg, TRUE); if (finally_arg2) BringToForeground (finally_arg); bPrebootPasswordDlgMode = FALSE;}); + + Mount (hwndDlg, -1, 0, -1); +} + +typedef struct +{ + UNMOUNT_STRUCT* punmount; + BOOL interact; + int dismountMaxRetries; + int dismountAutoRetryDelay; + BOOL* pbResult; + DWORD* pdwResult; + DWORD dwLastError; + BOOL bReturn; +} DismountAllThreadParam; + +void CALLBACK DismountAllThreadProc(void* pArg, HWND hwndDlg) +{ + DismountAllThreadParam* pThreadParam = (DismountAllThreadParam*) pArg; + UNMOUNT_STRUCT* punmount = pThreadParam->punmount; + BOOL* pbResult = pThreadParam->pbResult; + DWORD* pdwResult = pThreadParam->pdwResult; + int dismountMaxRetries = pThreadParam->dismountMaxRetries; + int dismountAutoRetryDelay = pThreadParam->dismountAutoRetryDelay; + + do + { + *pbResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, punmount, + sizeof (UNMOUNT_STRUCT), punmount, sizeof (UNMOUNT_STRUCT), pdwResult, NULL); + + if ( punmount->nDosDriveNo < 0 || punmount->nDosDriveNo > 25 + || (punmount->ignoreOpenFiles != TRUE && punmount->ignoreOpenFiles != FALSE) + || (punmount->HiddenVolumeProtectionTriggered != TRUE && punmount->HiddenVolumeProtectionTriggered != FALSE) + || (punmount->nReturnCode < 0) + ) + { + if (*pbResult) + SetLastError (ERROR_INTERNAL_ERROR); + *pbResult = FALSE; + } + + if (*pbResult == FALSE) + { + NormalCursor(); + handleWin32Error (hwndDlg, SRC_POS); + pThreadParam->dwLastError = GetLastError (); + pThreadParam->bReturn = FALSE; + return; + } + + if (punmount->nReturnCode == ERR_SUCCESS + && punmount->HiddenVolumeProtectionTriggered + && !VolumeNotificationsList.bHidVolDamagePrevReported [punmount->nDosDriveNo] + && pThreadParam->interact + && !Silent) + { + wchar_t msg[4096]; + + VolumeNotificationsList.bHidVolDamagePrevReported [punmount->nDosDriveNo] = TRUE; + + StringCbPrintfW (msg, sizeof(msg), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), punmount->nDosDriveNo + L'A'); + SetForegroundWindow (hwndDlg); + MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); + + punmount->HiddenVolumeProtectionTriggered = FALSE; + continue; + } + + if (punmount->nReturnCode == ERR_FILES_OPEN) + Sleep (dismountAutoRetryDelay); + else + break; + + } while (--dismountMaxRetries > 0); + + pThreadParam->dwLastError = GetLastError (); + pThreadParam->bReturn = TRUE; +} + +static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay) +{ + BOOL status = TRUE; + MOUNT_LIST_STRUCT mountList = {0}; + DWORD dwResult; + UNMOUNT_STRUCT unmount = {0}; + BOOL bResult; + MOUNT_LIST_STRUCT prevMountList = {0}; + int i; + DismountAllThreadParam dismountAllThreadParam; + +retry: + WaitCursor(); + + DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); + + if (mountList.ulMountedDrives == 0) + { + NormalCursor(); + return TRUE; + } + + BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, 0, mountList.ulMountedDrives); + + memcpy (&prevMountList, &mountList, sizeof (mountList)); + + for (i = 0; i < 26; i++) + { + if (mountList.ulMountedDrives & (1 << i)) + { + if (bCloseDismountedWindows) + CloseVolumeExplorerWindows (hwndDlg, i); + } + } + + unmount.nDosDriveNo = 0; + unmount.ignoreOpenFiles = forceUnmount; + + dismountAllThreadParam.punmount = &unmount; + dismountAllThreadParam.interact = interact; + dismountAllThreadParam.dismountMaxRetries = dismountMaxRetries; + dismountAllThreadParam.dismountAutoRetryDelay = dismountAutoRetryDelay; + dismountAllThreadParam.pbResult = &bResult; + dismountAllThreadParam.pdwResult = &dwResult; + dismountAllThreadParam.dwLastError = ERROR_SUCCESS; + dismountAllThreadParam.bReturn = TRUE; + + if (interact && !Silent) + { + + ShowWaitDialog (hwndDlg, FALSE, DismountAllThreadProc, &dismountAllThreadParam); + } + else + DismountAllThreadProc (&dismountAllThreadParam, hwndDlg); + + SetLastError (dismountAllThreadParam.dwLastError); + + if (!dismountAllThreadParam.bReturn) + return FALSE; + + memset (&mountList, 0, sizeof (mountList)); + DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); + + // remove any custom label from registry + for (i = 0; i < 26; i++) + { + if ((prevMountList.ulMountedDrives & (1 << i)) && (!(mountList.ulMountedDrives & (1 << i))) && wcslen (prevMountList.wszLabel[i])) + { + UpdateDriveCustomLabel (i, prevMountList.wszLabel[i], FALSE); + } + } + + BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, prevMountList.ulMountedDrives & ~mountList.ulMountedDrives); + + RefreshMainDlg (hwndDlg); + + if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ()) + LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); + + NormalCursor(); + + if (unmount.nReturnCode != 0) + { + if (forceUnmount) + status = FALSE; + + if (unmount.nReturnCode == ERR_FILES_OPEN) + { + if (interact && IDYES == AskWarnYesNoTopmost ("UNMOUNTALL_LOCK_FAILED", hwndDlg)) + { + forceUnmount = TRUE; + goto retry; + } + + if (IsOSAtLeast (WIN_7)) + { + // Undo SHCNE_DRIVEREMOVED + DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, NULL, 0, &mountList, sizeof (mountList), &dwResult, NULL); + + for (i = 0; i < 26; i++) + { + if (mountList.ulMountedDrives & (1 << i)) + { + wchar_t root[] = { (wchar_t) i + L'A', L':', L'\\', 0 }; + SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL); + } + } + } + + return FALSE; + } + + if (interact) + MessageBoxW (hwndDlg, GetString ("UNMOUNT_FAILED"), lpszTitle, MB_ICONERROR); + } + else + { + if (bBeep) + MessageBeep (0xFFFFFFFF); + } + + return status; +} + +static BOOL MountAllDevicesThreadCode (HWND hwndDlg, BOOL bPasswordPrompt) +{ + HWND driveList = GetDlgItem (MainDlg, IDC_DRIVELIST); + int selDrive = ListView_GetSelectionMark (driveList); + BOOL shared = FALSE, status = FALSE, bHeaderBakRetry = FALSE; + int mountedVolCount = 0; + vector devices; + int EffectiveVolumePkcs5 = CmdVolumePkcs5; + BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; + + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (EffectiveVolumePkcs5 == 0) + EffectiveVolumePkcs5 = DefaultVolumePkcs5; + if (!EffectiveVolumeTrueCryptMode) + EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; + + VolumePassword.Length = 0; + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + VolumePim = -1; + + if (selDrive == -1) + selDrive = 0; + + ResetWrongPwdRetryCount (); + + MultipleMountOperationInProgress = TRUE; + + do + { + if (!bHeaderBakRetry) + { + if (!CmdVolumePasswordValid && bPasswordPrompt) + { + int GuiPkcs5 = EffectiveVolumePkcs5; + BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode; + int GuiPim = CmdVolumePim; + PasswordDlgVolume[0] = '\0'; + if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &GuiTrueCryptMode, NULL, TRUE)) + goto ret; + else + { + VolumePkcs5 = GuiPkcs5; + VolumeTrueCryptMode = GuiTrueCryptMode; + VolumePim = GuiPim; + burn (&GuiPkcs5, sizeof(GuiPkcs5)); + burn (&GuiTrueCryptMode, sizeof(GuiTrueCryptMode)); + burn (&GuiPim, sizeof(GuiPim)); + } + } + else if (CmdVolumePasswordValid) + { + bPasswordPrompt = FALSE; + VolumePassword = CmdVolumePassword; + VolumePkcs5 = EffectiveVolumePkcs5; + VolumeTrueCryptMode = EffectiveVolumeTrueCryptMode; + VolumePim = CmdVolumePim; + } + + WaitCursor(); + + if (FirstCmdKeyFile) + KeyFilesApply (hwndDlg, &VolumePassword, FirstCmdKeyFile, NULL); + else if (KeyFilesEnable) + KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, NULL); + + } + + if (devices.empty()) + devices = GetAvailableHostDevices (true, false, true, true); + foreach (const HostDevice &drive, devices) + { + vector partitions = drive.Partitions; + partitions.insert (partitions.begin(), drive); + + foreach (const HostDevice &device, partitions) + { + wchar_t szFileName[TC_MAX_PATH]; + StringCbCopyW (szFileName, sizeof (szFileName), device.Path.c_str()); + BOOL mounted = IsMountedVolume (szFileName); + + // Skip other partitions of the disk if partition0 (whole disk) is mounted + if (!device.IsPartition && mounted) + break; + + if (device.Floppy) + break; + + if (device.HasUnencryptedFilesystem && !mountOptions.UseBackupHeader && !bHeaderBakRetry) + continue; + + if (!mounted) + { + int nDosDriveNo; + int driveAItem = -1, driveBItem = -1; + + while (LOWORD (GetItemLong (driveList, selDrive)) != 0xffff) + { + if(LOWORD (GetItemLong (driveList, selDrive)) != TC_MLIST_ITEM_FREE) + { + selDrive++; + continue; + } + nDosDriveNo = HIWORD(GetItemLong (driveList, selDrive)) - L'A'; + + /* don't use drives A: and B: for now until no other free drive found */ + if (nDosDriveNo == 0) + { + driveAItem = selDrive; + selDrive++; + continue; + } + if (nDosDriveNo == 1) + { + driveBItem = selDrive; + selDrive++; + continue; + } + break; + } + + if (LOWORD (GetItemLong (driveList, selDrive)) == 0xffff) + { + /* use A: or B: if available as a last resort */ + if (driveAItem >= 0) + { + nDosDriveNo = 0; + selDrive = driveAItem; + } + else if (driveBItem >= 0) + { + nDosDriveNo = 1; + selDrive = driveBItem; + } + else + goto ret; + } + + // First try user password then cached passwords + if ((mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, TRUE, FALSE)) > 0 + || ((VolumePassword.Length > 0) && ((mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, TRUE, FALSE)) > 0))) + { + // A volume has been successfully mounted + + ResetWrongPwdRetryCount (); + + if (mounted == 2) + shared = TRUE; + + LoadDriveLetters (hwndDlg, driveList, (HIWORD (GetItemLong (GetDlgItem (MainDlg, IDC_DRIVELIST), selDrive)))); + selDrive++; + + if (bExplore) + { + WaitCursor(); + OpenVolumeExplorerWindow (nDosDriveNo); + NormalCursor(); + } + + if (bBeep) + MessageBeep (0xFFFFFFFF); + + status = TRUE; + + mountedVolCount++; + + // Skip other partitions of the disk if partition0 (whole disk) has been mounted + if (!device.IsPartition) + break; + } + } + } + } + + if (mountedVolCount < 1) + { + // Failed to mount any volume + + IncreaseWrongPwdRetryCount (1); + + if (WrongPwdRetryCountOverLimit () + && !mountOptions.UseBackupHeader + && !bHeaderBakRetry) + { + // Retry using embedded header backup (if any) + mountOptions.UseBackupHeader = TRUE; + bHeaderBakRetry = TRUE; + } + else if (bHeaderBakRetry) + { + mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; + bHeaderBakRetry = FALSE; + } + + if (!Silent && !bHeaderBakRetry) + { + WCHAR szTmp[4096]; + + StringCbPrintfW (szTmp, sizeof(szTmp), GetString (KeyFilesEnable || FirstCmdKeyFile ? "PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT" : "PASSWORD_WRONG_AUTOMOUNT")); + if (CheckCapsLock (hwndDlg, TRUE)) + StringCbCatW (szTmp, sizeof(szTmp), GetString ("PASSWORD_WRONG_CAPSLOCK_ON")); + + MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONWARNING); + } + } + else if (bHeaderBakRetry) + { + // We have successfully mounted a volume using the header backup embedded in the volume (the header is damaged) + mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; + bHeaderBakRetry = FALSE; + + if (!Silent) + Warning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK", hwndDlg); + } + + if (!bHeaderBakRetry) + { + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); + } + + } while (bPasswordPrompt && mountedVolCount < 1); + + /* One or more volumes successfully mounted */ + + ResetWrongPwdRetryCount (); + + if (shared) + Warning ("DEVICE_IN_USE_INFO", hwndDlg); + + if (mountOptions.ProtectHiddenVolume) + { + if (mountedVolCount > 1) + Info ("HIDVOL_PROT_WARN_AFTER_MOUNT_PLURAL", hwndDlg); + else if (mountedVolCount == 1) + Info ("HIDVOL_PROT_WARN_AFTER_MOUNT", hwndDlg); + } + + if (status && CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + +ret: + MultipleMountOperationInProgress = FALSE; + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); + + mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; + + RestoreDefaultKeyFilesParam (); + + if (UsePreferences) + bCacheInDriver = bCacheInDriverDefault; + + EnableDisableButtons (MainDlg); + + NormalCursor(); + + return status; +} + +typedef struct +{ + BOOL bPasswordPrompt; + BOOL bRet; +} MountAllDevicesThreadParam; + +void CALLBACK mountAllDevicesThreadProc(void* pArg, HWND hwndDlg) +{ + MountAllDevicesThreadParam* threadParam =(MountAllDevicesThreadParam*) pArg; + BOOL bPasswordPrompt = threadParam->bPasswordPrompt; + + threadParam->bRet = MountAllDevicesThreadCode (hwndDlg, bPasswordPrompt); +} + +static BOOL MountAllDevices (HWND hwndDlg, BOOL bPasswordPrompt) +{ + MountAllDevicesThreadParam param; + param.bPasswordPrompt = bPasswordPrompt; + param.bRet = FALSE; + + ShowWaitDialog (hwndDlg, FALSE, mountAllDevicesThreadProc, ¶m); + + return param.bRet; +} + +static void ChangePassword (HWND hwndDlg) +{ + INT_PTR result; + int newPimValue = -1; + + GetVolumePath (hwndDlg, szFileName, ARRAYSIZE (szFileName)); + + if (!TranslateVolumeID (hwndDlg, szFileName, ARRAYSIZE (szFileName))) + { + return; + } + + if (IsMountedVolume (szFileName)) + { + Warning (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE", hwndDlg); + return; + } + + if (!VolumePathExists (szFileName)) + { + handleWin32Error (hwndDlg, SRC_POS); + return; + } + + bSysEncPwdChangeDlgMode = FALSE; + + result = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_PASSWORDCHANGE_DLG), hwndDlg, + (DLGPROC) PasswordChangeDlgProc, (LPARAM) &newPimValue); + + if (result == IDOK) + { + switch (pwdChangeDlgMode) + { + case PCDM_CHANGE_PKCS5_PRF: + Info ("PKCS5_PRF_CHANGED", hwndDlg); + break; + + case PCDM_ADD_REMOVE_VOL_KEYFILES: + case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: + Info ("KEYFILE_CHANGED", hwndDlg); + break; + + case PCDM_CHANGE_PASSWORD: + default: + { + Info ("PASSWORD_CHANGED", hwndDlg); + if (newPimValue != -1) + { + // update the encoded volue in favorite XML if found + bool bFavoriteFound = false; + for (vector ::iterator favorite = FavoriteVolumes.begin(); + favorite != FavoriteVolumes.end(); favorite++) + { + if (favorite->Path == szFileName) + { + bFavoriteFound = true; + favorite->Pim = newPimValue; + SaveFavoriteVolumes (hwndDlg, FavoriteVolumes, false); + break; + } + } + + if (!bFavoriteFound) + { + for (vector ::iterator favorite = SystemFavoriteVolumes.begin(); + favorite != SystemFavoriteVolumes.end(); favorite++) + { + if (favorite->Path == szFileName) + { + bFavoriteFound = true; + favorite->Pim = newPimValue; + + if (AskYesNo("FAVORITE_PIM_CHANGED", hwndDlg) == IDYES) + { + SaveFavoriteVolumes (hwndDlg, SystemFavoriteVolumes, true); + } + break; + } + } + } + } + } + } + } +} + +// Change password of the system partition/drive +static void ChangeSysEncPassword (HWND hwndDlg, BOOL bOnlyChangeKDF) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !BootEncStatus.VolumeHeaderPresent + && !SysEncryptionOrDecryptionRequired ()) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); + return; + } + + if (SysEncryptionOrDecryptionRequired () + || BootEncStatus.SetupInProgress) + { + Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED", hwndDlg); + return; + } + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + StringCbPrintfW (OrigKeyboardLayout, sizeof(OrigKeyboardLayout), L"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF); + + bSysEncPwdChangeDlgMode = TRUE; + + if (bOnlyChangeKDF) + pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; + else + pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; + + + INT_PTR result = DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_PASSWORDCHANGE_DLG), hwndDlg, (DLGPROC) PasswordChangeDlgProc); + + bSysEncPwdChangeDlgMode = FALSE; + + if (bKeyboardLayoutChanged) + { + // Restore the original keyboard layout + if (LoadKeyboardLayout (OrigKeyboardLayout, KLF_ACTIVATE | KLF_SUBSTITUTE_OK) == NULL) + Warning ("CANNOT_RESTORE_KEYBOARD_LAYOUT", hwndDlg); + else + bKeyboardLayoutChanged = FALSE; + } + + bKeybLayoutAltKeyWarningShown = FALSE; + + if (result == IDOK) + { + switch (pwdChangeDlgMode) + { + case PCDM_CHANGE_PKCS5_PRF: + Info ("PKCS5_PRF_CHANGED", hwndDlg); + + if (!IsHiddenOSRunning()) + { + if (AskWarnYesNo ("SYS_HKD_ALGO_CHANGED_ASK_RESCUE_DISK", hwndDlg) == IDYES) + CreateRescueDisk (hwndDlg); + } + + break; + + case PCDM_ADD_REMOVE_VOL_KEYFILES: + case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: + // NOP - Keyfiles are not supported for system encryption + break; + + case PCDM_CHANGE_PASSWORD: + default: + Info ("PASSWORD_CHANGED", hwndDlg); + + if (!IsHiddenOSRunning()) + { + if (AskWarnYesNo ("SYS_PASSWORD_CHANGED_ASK_RESCUE_DISK", hwndDlg) == IDYES) + CreateRescueDisk (hwndDlg); + } + } + } + + CloseSysEncMutex (); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); +} + +// Initiates or resumes encryption of the system partition/drive +static void EncryptSystemDevice (HWND hwndDlg) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !SysEncryptionOrDecryptionRequired ()) + { + // System partition/drive is not encrypted (nothing to resume). Initiate the process. + + if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption + { + LaunchVolCreationWizard (hwndDlg, L"/sysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); + + return; + } + else if (SysEncryptionOrDecryptionRequired ()) + { + // System partition/drive encryption already initiated but is incomplete -- attempt to resume the process. + // Note that this also covers the pretest phase and paused decryption (reverses decrypting and starts encrypting) + + if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption + { + LaunchVolCreationWizard (hwndDlg, L"/sysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); + } + else if (SysDriveOrPartitionFullyEncrypted (FALSE)) + { + // System partition/drive appears to be fully encrypted + Info ("SYS_PARTITION_OR_DRIVE_APPEARS_FULLY_ENCRYPTED", hwndDlg); + return; + } +} + +// Initiates decryption of the system partition/drive +static void DecryptSystemDevice (HWND hwndDlg) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !BootEncStatus.DeviceFilterActive + && !BootEncStatus.VolumeHeaderPresent + && !SysEncryptionOrDecryptionRequired ()) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); + return; + } + + if (IsHiddenOSRunning()) + { + Warning ("CANNOT_DECRYPT_HIDDEN_OS", hwndDlg); + return; + } + + if (AskNoYes ("CONFIRM_DECRYPT_SYS_DEVICE", hwndDlg) == IDNO) + return; + + if (AskWarnNoYes ("CONFIRM_DECRYPT_SYS_DEVICE_CAUTION", hwndDlg) == IDNO) + return; + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + try + { + // User-mode app may have crashed and its mutex may have gotten lost, so we need to check the driver status too + if (BootEncStatus.SetupInProgress) + { + int attempts = 20; + + BootEncObj->AbortSetup (); + while (BootEncStatus.SetupInProgress && attempts > 0) + { + Sleep (100); + BootEncStatus = BootEncObj->GetStatus(); + attempts--; + WaitCursor(); + } + } + } + catch (Exception &e) + { + e.Show (MainDlg); + } + NormalCursor (); + + if (BootEncStatus.SetupInProgress) + { + CloseSysEncMutex (); + Error ("SYS_ENCRYPTION_OR_DECRYPTION_IN_PROGRESS", hwndDlg); + return; + } + + CloseSysEncMutex (); + LaunchVolCreationWizard (hwndDlg, L"/dsysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); +} + +// Initiates the process of creation of a hidden operating system +static void CreateHiddenOS (HWND hwndDlg) +{ + + // Display brief information as to what a hidden operating system is and what it's good for. This needs to be + // done, because if the system partition/drive is currently encrypted, the wizard will not display any + // such information, but will exit (displaying only an error meessage). + Info("HIDDEN_OS_PREINFO", hwndDlg); + + LaunchVolCreationWizard (hwndDlg, L"/isysenc"); +} + +static void DecryptNonSysDevice (HWND hwndDlg, BOOL bResolveAmbiguousSelection, BOOL bUseDriveListSel) +{ + wstring scPath; + + if (bResolveAmbiguousSelection) + { + scPath = ResolveAmbiguousSelection (hwndDlg, NULL); + + if (scPath.empty ()) + { + // The user selected Cancel + return; + } + } + else if (bUseDriveListSel) + { + // Decrypt mounted volume selected in the main drive list + + LPARAM lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST)); + + if (LOWORD (lLetter) != 0xffff) + { + VOLUME_PROPERTIES_STRUCT prop; + DWORD bytesReturned; + + memset (&prop, 0, sizeof (prop)); + prop.driveNo = (wchar_t) HIWORD (lLetter) - L'A'; + + if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &bytesReturned, NULL)) + { + handleWin32Error (MainDlg, SRC_POS); + return; + } + + scPath = prop.wszVolume; + } + else + return; + } + else + { + // Decrypt volume specified in the input field below the main drive list + + wchar_t volPath [TC_MAX_PATH]; + + GetVolumePath (MainDlg, volPath, ARRAYSIZE (volPath)); + + scPath = volPath; + } + + if (scPath.empty ()) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + return; + } + + WaitCursor(); + + switch (IsSystemDevicePath (scPath.c_str (), MainDlg, TRUE)) + { + case 1: + case 2: + // The user wants to decrypt the system partition/drive. Divert to the appropriate function. + + NormalCursor (); + + DecryptSystemDevice (hwndDlg); + return; + } + + WaitCursor(); + + // Make sure the user is not attempting to decrypt a partition on an entirely encrypted system drive. + if (IsNonSysPartitionOnSysDrive (scPath.c_str ()) == 1) + { + if (WholeSysDriveEncryption (TRUE)) + { + // The system drive is entirely encrypted and the encrypted OS is running + + NormalCursor (); + + Warning ("CANT_DECRYPT_PARTITION_ON_ENTIRELY_ENCRYPTED_SYS_DRIVE", hwndDlg); + return; + } + } + else if (TCBootLoaderOnInactiveSysEncDrive ((wchar_t *) scPath.c_str ())) + { + // The system drive MAY be entirely encrypted (external access without PBA) and the potentially encrypted OS is not running + + NormalCursor (); + + Warning ("CANT_DECRYPT_PARTITION_ON_ENTIRELY_ENCRYPTED_SYS_DRIVE_UNSURE", hwndDlg); + + // We allow the user to continue as we don't know if the drive is really an encrypted system drive. + // If it is, the user has been warned and he will not be able to start decrypting, because the + // format wizard will not enable (nor will it allow the user to enable) the mount option for + // external without-PBA access (the user will receive the 'Incorrect password' error message). + } + + NormalCursor (); + + + if (AskNoYesString ((wstring (GetString ("CONFIRM_DECRYPT_NON_SYS_DEVICE")) + L"\n\n" + scPath).c_str(), hwndDlg) == IDNO) + return; + + if (AskWarnNoYes ("CONFIRM_DECRYPT_NON_SYS_DEVICE_CAUTION", hwndDlg) == IDNO) + return; + + LaunchVolCreationWizard (hwndDlg, (wstring (L"/inplacedec \"") + scPath + L"\"").c_str ()); +} + +// Blindly attempts (without any checks) to instruct the wizard to resume whatever system encryption process +// had been interrupted or not started but scheduled or exptected to start. +static void ResumeInterruptedSysEncProcess (HWND hwndDlg) +{ + if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption + { + LaunchVolCreationWizard (MainDlg, L"/csysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); +} + +void CreateRescueDisk (HWND hwndDlg) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (IsHiddenOSRunning()) + { + Warning ("CANNOT_CREATE_RESCUE_DISK_ON_HIDDEN_OS", hwndDlg); + return; + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !BootEncStatus.VolumeHeaderPresent + && !SysEncryptionOrDecryptionRequired ()) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); + return; + } + + if (SysEncryptionOrDecryptionRequired () + || BootEncStatus.SetupInProgress) + { + Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED", hwndDlg); + return; + } + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + try + { + wchar_t szTmp [8096]; + wchar_t szRescueDiskISO [TC_MAX_PATH+1]; + + if (AskOkCancel ("RESCUE_DISK_NON_WIZARD_CREATION_SELECT_PATH", hwndDlg) != IDOK) + { + CloseSysEncMutex (); + return; + } + + wchar_t initialDir[MAX_PATH]; + SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, 0, initialDir); + + if (!BrowseFilesInDir (hwndDlg, "OPEN_TITLE", initialDir, szRescueDiskISO, FALSE, TRUE, NULL, L"VeraCrypt Rescue Disk.iso", L"iso")) + { + CloseSysEncMutex (); + return; + } + + WaitCursor(); + BootEncObj->CreateRescueIsoImage (false, szRescueDiskISO); + + StringCbPrintfW (szTmp, sizeof szTmp, + GetString (IsWindowsIsoBurnerAvailable() ? "RESCUE_DISK_NON_WIZARD_CREATION_WIN_ISOBURN" : "RESCUE_DISK_NON_WIZARD_CREATION_BURN"), + szRescueDiskISO); + + if (IsWindowsIsoBurnerAvailable()) + { + if (AskYesNoString (szTmp, hwndDlg) == IDYES) + LaunchWindowsIsoBurner (MainDlg, szRescueDiskISO); + } + else + InfoDirect (szTmp, hwndDlg); + } + catch (Exception &e) + { + e.Show (hwndDlg); + Error ("ERROR_CREATING_RESCUE_DISK", hwndDlg); + } + CloseSysEncMutex (); + + NormalCursor (); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); +} + +static void VerifyRescueDisk (HWND hwndDlg, bool checkIsoFile) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !BootEncStatus.VolumeHeaderPresent + && !SysEncryptionOrDecryptionRequired ()) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); + return; + } + + if (SysEncryptionOrDecryptionRequired () + || BootEncStatus.SetupInProgress) + { + Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED", hwndDlg); + return; + } + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + try + { + if (!checkIsoFile && (AskOkCancel ("RESCUE_DISK_NON_WIZARD_CHECK_INSERT", hwndDlg) != IDOK)) + { + CloseSysEncMutex (); + return; + } + + // Create a temporary up-to-date rescue disk image in RAM (with it the CD/DVD content will be compared) + BootEncObj->CreateRescueIsoImage (false, L""); + + + if (checkIsoFile) + { + wchar_t szRescueDiskISO [TC_MAX_PATH+1]; + wchar_t initialDir[MAX_PATH]; + SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, 0, initialDir); + + if (!BrowseFilesInDir (hwndDlg, "OPEN_TITLE", initialDir, szRescueDiskISO, FALSE, FALSE, NULL, L"VeraCrypt Rescue Disk.iso", L"iso")) + { + CloseSysEncMutex (); + return; + } + + WaitCursor(); + if (!BootEncObj->VerifyRescueDiskIsoImage (szRescueDiskISO)) + Error ("RESCUE_DISK_ISO_IMAGE_CHECK_FAILED", hwndDlg); + else + Info ("RESCUE_DISK_ISO_IMAGE_CHECK_PASSED", hwndDlg); + } + else + { + WaitCursor(); + if (!BootEncObj->VerifyRescueDisk ()) + Error ("RESCUE_DISK_NON_WIZARD_CHECK_FAILED", hwndDlg); + else + Info ("RESCUE_DISK_NON_WIZARD_CHECK_PASSED", hwndDlg); + } + } + catch (Exception &e) + { + e.Show (MainDlg); + Error ("RESCUE_DISK_NON_WIZARD_CHECK_FAILED", hwndDlg); + } + CloseSysEncMutex (); + + NormalCursor (); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", hwndDlg); +} + +static void ShowSystemEncryptionStatus (HWND hwndDlg) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (GetAsyncKeyState (VK_SHIFT) < 0 && GetAsyncKeyState (VK_CONTROL) < 0) + { + // Ctrl+Shift held (for debugging purposes) + + DebugMsgBox ("Debugging information for system encryption:\n\nDeviceFilterActive: %d\nBootLoaderVersion: %x\nSetupInProgress: %d\nSetupMode: %d\nVolumeHeaderPresent: %d\nDriveMounted: %d\nDriveEncrypted: %d\n" + "HiddenSystem: %d\nHiddenSystemPartitionStart: %I64d\n" + "ConfiguredEncryptedAreaStart: %I64d\nConfiguredEncryptedAreaEnd: %I64d\nEncryptedAreaStart: %I64d\nEncryptedAreaEnd: %I64d\nEncrypted: %I64d%%", + BootEncStatus.DeviceFilterActive, + BootEncStatus.BootLoaderVersion, + BootEncStatus.SetupInProgress, + BootEncStatus.SetupMode, + BootEncStatus.VolumeHeaderPresent, + BootEncStatus.DriveMounted, + BootEncStatus.DriveEncrypted, + BootEncStatus.HiddenSystem ? 1 : 0, + BootEncStatus.HiddenSystemPartitionStart, + BootEncStatus.ConfiguredEncryptedAreaStart, + BootEncStatus.ConfiguredEncryptedAreaEnd, + BootEncStatus.EncryptedAreaStart, + BootEncStatus.EncryptedAreaEnd, + !BootEncStatus.DriveEncrypted ? 0 : (BootEncStatus.EncryptedAreaEnd + 1 - BootEncStatus.EncryptedAreaStart) * 100I64 / (BootEncStatus.ConfiguredEncryptedAreaEnd + 1 - BootEncStatus.ConfiguredEncryptedAreaStart)); + } + + if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted) + { + Info ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); + return; + } + + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, + (DLGPROC) VolumePropertiesDlgProc, (LPARAM) TRUE); + +} + +static void ResumeInterruptedNonSysInplaceEncProcess (BOOL bDecrypt) +{ + // IMPORTANT: This function must not check any config files! Otherwise, if a config file was lost or corrupt, + // the user would not be able resume encryption and the data on the volume would be inaccessible. + + LaunchVolCreationWizard (MainDlg, bDecrypt? L"/resumeinplacedec" : L"/zinplace"); +} + +BOOL SelectContainer (HWND hwndDlg) +{ + if (BrowseFiles (hwndDlg, "OPEN_VOL_TITLE", szFileName, bHistory, FALSE, NULL) == FALSE) + return FALSE; + + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + EnableDisableButtons (hwndDlg); + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + return TRUE; +} + +BOOL SelectPartition (HWND hwndDlg) +{ + RawDevicesDlgParam param; + param.pszFileName = szFileName; + INT_PTR nResult = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_RAWDEVICES_DLG), hwndDlg, + (DLGPROC) RawDevicesDlgProc, (LPARAM) & param); + if (nResult == IDOK) + { + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + EnableDisableButtons (hwndDlg); + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + return TRUE; + } + + return FALSE; +} + +static void WipeCache (HWND hwndDlg, BOOL silent) +{ + DWORD dwResult; + BOOL bResult; + + bResult = DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + if (hwndDlg == NULL) + return; + + if (bResult == FALSE) + handleWin32Error (hwndDlg, SRC_POS); + else + { + EnableDisableButtons (hwndDlg); + + if (!silent) + InfoBalloon ("PASSWORD_CACHE_WIPED_SHORT", "PASSWORD_CACHE_WIPED", hwndDlg); + } +} + +static void Benchmark (HWND hwndDlg) +{ + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_BENCHMARK_DLG), hwndDlg, + (DLGPROC) BenchmarkDlgProc, (LPARAM) NULL); +} + + +static BOOL CheckMountList (HWND hwndDlg, BOOL bForceTaskBarUpdate) +{ + MOUNT_LIST_STRUCT current; + static BootEncryptionStatus newBootEncStatus; + static BOOL lastbUseDifferentTrayIconIfVolMounted = bUseDifferentTrayIconIfVolMounted; + static uint32 lastUlMountedDrives = 0; + + GetMountList (¤t); + + if ((bForceTaskBarUpdate || current.ulMountedDrives != lastUlMountedDrives || bUseDifferentTrayIconIfVolMounted != lastbUseDifferentTrayIconIfVolMounted) + && TaskBarIconMutex != NULL) + { + lastUlMountedDrives = current.ulMountedDrives; + lastbUseDifferentTrayIconIfVolMounted = bUseDifferentTrayIconIfVolMounted; + + TaskBarIconChange (MainDlg, current.ulMountedDrives != 0 && bUseDifferentTrayIconIfVolMounted ? IDI_TRUECRYPT_MOUNTED_ICON : IDI_TRUECRYPT_ICON); + } + + if (bForceTaskBarUpdate) + { + return TRUE; + } + + if (LastKnownLogicalDrives != GetUsedLogicalDrives() + || memcmp (&LastKnownMountList, ¤t, sizeof (current)) != 0) + { + wchar_t selDrive; + + WaitCursor (); + LastKnownMountList = current; + + selDrive = (wchar_t) HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))); + LoadDriveLetters (hwndDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0); + NormalCursor (); + + if (selDrive != ((wchar_t) 0xFFFF) && (current.ulMountedDrives & (1 << (selDrive - L'A'))) == 0 && !IsDriveAvailable (selDrive - L'A')) + { + nSelectedDriveIndex = -1; + return FALSE; + } + + if (selDrive != ((wchar_t) 0xFFFF)) + SelectItem (GetDlgItem (MainDlg, IDC_DRIVELIST),selDrive); + } + + try + { + newBootEncStatus = BootEncObj->GetStatus(); + + if (newBootEncStatus.SetupInProgress != RecentBootEncStatus.SetupInProgress + || newBootEncStatus.EncryptedAreaEnd != RecentBootEncStatus.EncryptedAreaEnd + || newBootEncStatus.DriveEncrypted != RecentBootEncStatus.DriveEncrypted + || newBootEncStatus.DriveMounted != RecentBootEncStatus.DriveMounted + || newBootEncStatus.SetupMode != RecentBootEncStatus.SetupMode + || newBootEncStatus.EncryptedAreaStart != RecentBootEncStatus.EncryptedAreaStart) + { + /* System encryption status change */ + + wchar_t selDrive; + int driveLetterToRefresh; + + if (RecentBootEncStatus.DriveMounted == newBootEncStatus.DriveMounted) // If an icon (and whole new line) for a system device isn't to be added/removed + { + // Partial refresh + if (WholeSysDriveEncryption (TRUE)) + { + // System drive (not just partition) + driveLetterToRefresh = ENC_SYSDRIVE_PSEUDO_DRIVE_LETTER; + } + else + { + // System partition + driveLetterToRefresh = GetSystemDriveLetter (); + } + } + else + { + // Full rebuild of the mount list + driveLetterToRefresh = 0; + } + + selDrive = (wchar_t) HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))); + LoadDriveLetters (hwndDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), driveLetterToRefresh); + + RecentBootEncStatus = newBootEncStatus; + + if (selDrive != ((wchar_t) 0xFFFF) && (current.ulMountedDrives & (1 << (selDrive - L'A'))) == 0 && !IsDriveAvailable (selDrive - L'A')) + { + nSelectedDriveIndex = -1; + } + + if (selDrive != ((wchar_t) 0xFFFF)) + { + SelectItem (GetDlgItem (MainDlg, IDC_DRIVELIST),selDrive); + } + } + + /* Miscellaneous notifications */ + + // Hibernation prevention notifications + if (newBootEncStatus.HibernationPreventionCount != RecentBootEncStatus.HibernationPreventionCount + && !bHibernationPreventionNotified) + { + bHibernationPreventionNotified = TRUE; + RecentBootEncStatus.HibernationPreventionCount = newBootEncStatus.HibernationPreventionCount; + + if (IsHiddenOSRunning() && BootEncObj->GetSystemDriveConfiguration().ExtraBootPartitionPresent) + WarningTopMost ("HIDDEN_OS_HIBERNATION_PREVENTED", hwndDlg); + else + WarningTopMost ("SYS_ENC_HIBERNATION_PREVENTED", hwndDlg); + } + + // Write mode prevention (hidden OS leak protection) + if (IsHiddenOSRunning()) + { + if (newBootEncStatus.HiddenSysLeakProtectionCount != RecentBootEncStatus.HiddenSysLeakProtectionCount + && !bHiddenSysLeakProtNotifiedDuringSession) + { + bHiddenSysLeakProtNotifiedDuringSession = TRUE; + + switch (HiddenSysLeakProtectionNotificationStatus) + { + case TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT: + { + char *tmp[] = {0, "HIDDEN_OS_WRITE_PROTECTION_BRIEF_INFO", "SHOW_MORE_INFORMATION", "DO_NOT_SHOW_THIS_AGAIN", "CONTINUE", 0}; + switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg)) + { + case 1: + InfoDirect ((wstring (GetString ("HIDDEN_OS_WRITE_PROTECTION_BRIEF_INFO")) + + L"\n\n" + + GetString ("HIDDEN_OS_WRITE_PROTECTION_EXPLANATION") + + L"\n\n\n" + + GetString ("DECOY_TO_HIDDEN_OS_DATA_TRANSFER_HOWTO")).c_str(), hwndDlg); + break; + + case 2: + // No more warnings will be shown + if (ConfigBuffer == NULL) + { + // We need to load the config file because it is not done automatically when + // launched from the sys startup sequence (and SaveSettings would start by _loading_ + // the settings to cache). + LoadSettings (MainDlg); + } + HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED; + SaveSettings (MainDlg); + break; + + default: + // NOP + break; + } + } + break; + + case TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED: + // NOP + break; + + case TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE: + default: + { + // First time warning -- include technical explanation + InfoDirect ((wstring (GetString ("HIDDEN_OS_WRITE_PROTECTION_BRIEF_INFO")) + + L"\n\n" + + GetString ("HIDDEN_OS_WRITE_PROTECTION_EXPLANATION") + + L"\n\n\n" + + GetString ("DECOY_TO_HIDDEN_OS_DATA_TRANSFER_HOWTO")).c_str(), hwndDlg); + + // Further warnings will not include the explanation (and will allow disabling) + + if (ConfigBuffer == NULL) + { + // We need to load the config file because it is not done automatically when + // launched from the sys startup sequence (and SaveSettings would start by _loading_ + // the settings to cache). + LoadSettings (MainDlg); + } + HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT; + SaveSettings (MainDlg); + } + break; + } + } + } + } + catch (...) + { + // NOP + } + + return TRUE; +} + + +void DisplayDriveListContextMenu (HWND hwndDlg, LPARAM lParam) +{ + /* Drive list context menu */ + DWORD mPos; + int menuItem; + HMENU popup = CreatePopupMenu (); + HWND hList = GetDlgItem (hwndDlg, IDC_DRIVELIST); + + SetFocus (hList); + + switch (LOWORD (GetSelectedLong (hList))) + { + case TC_MLIST_ITEM_FREE: + + // No mounted volume at this drive letter + + AppendMenuW (popup, MF_STRING, IDM_MOUNT_VOLUME, GetString ("IDM_MOUNT_VOLUME")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDPM_SELECT_FILE_AND_MOUNT, GetString ("SELECT_FILE_AND_MOUNT")); + AppendMenuW (popup, MF_STRING, IDPM_SELECT_DEVICE_AND_MOUNT, GetString ("SELECT_DEVICE_AND_MOUNT")); + break; + + case TC_MLIST_ITEM_NONSYS_VOL: + + // There's a mounted non-system volume at this drive letter + + AppendMenuW (popup, MF_STRING, IDM_UNMOUNT_VOLUME, GetString ("DISMOUNT")); + AppendMenuW (popup, MF_STRING, IDPM_OPEN_VOLUME, GetString ("OPEN")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDPM_CHECK_FILESYS, GetString ("IDPM_CHECK_FILESYS")); + AppendMenuW (popup, MF_STRING, IDPM_REPAIR_FILESYS, GetString ("IDPM_REPAIR_FILESYS")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDPM_ADD_TO_FAVORITES, GetString ("IDPM_ADD_TO_FAVORITES")); + AppendMenuW (popup, MF_STRING, IDPM_ADD_TO_SYSTEM_FAVORITES, GetString ("IDPM_ADD_TO_SYSTEM_FAVORITES")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_DECRYPT_NONSYS_VOL, GetString ("IDM_DECRYPT_NONSYS_VOL")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_VOLUME_PROPERTIES, GetString ("IDPM_PROPERTIES")); + break; + + case TC_MLIST_ITEM_SYS_PARTITION: + case TC_MLIST_ITEM_SYS_DRIVE: + + // System partition/drive + + PopulateSysEncContextMenu (popup, FALSE); + break; + } + + if (lParam) + { + mPos=GetMessagePos(); + } + else + { + POINT pt = {0}; + if (ListView_GetItemPosition (hList, nSelectedDriveIndex, &pt)) + { + pt.x += 2 + ::GetSystemMetrics(SM_CXICON); + pt.y += 2; + } + ClientToScreen (hList, &pt); + mPos = MAKELONG (pt.x, pt.y); + } + + menuItem = TrackPopupMenu (popup, + TPM_RETURNCMD | TPM_LEFTBUTTON, + GET_X_LPARAM(mPos), + GET_Y_LPARAM(mPos), + 0, + hwndDlg, + NULL); + + DestroyMenu (popup); + + switch (menuItem) + { + case IDPM_SELECT_FILE_AND_MOUNT: + if (SelectContainer (hwndDlg)) + MountSelectedVolume (hwndDlg, FALSE); + break; + + case IDPM_SELECT_DEVICE_AND_MOUNT: + if (SelectPartition (hwndDlg)) + MountSelectedVolume (hwndDlg, FALSE); + break; + + case IDPM_CHECK_FILESYS: + case IDPM_REPAIR_FILESYS: + { + LPARAM lLetter = GetSelectedLong (hList); + + if (LOWORD (lLetter) != 0xffff) + CheckFilesystem (hwndDlg, (wchar_t) HIWORD (lLetter) - L'A', menuItem == IDPM_REPAIR_FILESYS); + } + break; + + case IDM_UNMOUNT_VOLUME: + if (CheckMountList (hwndDlg, FALSE)) + Dismount (hwndDlg, -2); + break; + + case IDM_DECRYPT_NONSYS_VOL: + if (CheckMountList (hwndDlg, FALSE)) + DecryptNonSysDevice (hwndDlg, FALSE, TRUE); + break; + + case IDPM_OPEN_VOLUME: + { + LPARAM state; + if (lParam) + nSelectedDriveIndex = ((LPNMITEMACTIVATE)lParam)->iItem; + else + nSelectedDriveIndex = ListView_GetSelectionMark (hList); + state = GetItemLong (hList, nSelectedDriveIndex ); + + WaitCursor (); + OpenVolumeExplorerWindow (HIWORD(state) - L'A'); + NormalCursor (); + } + break; + + case IDM_VOLUME_PROPERTIES: + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, + (DLGPROC) VolumePropertiesDlgProc, (LPARAM) FALSE); + break; + + case IDM_MOUNT_VOLUME: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (CheckMountList (hwndDlg, FALSE)) + _beginthread(mountThreadFunction, 0, hwndDlg); + } + break; + + case IDPM_ADD_TO_FAVORITES: + case IDPM_ADD_TO_SYSTEM_FAVORITES: + { + LPARAM selectedDrive = GetSelectedLong (hList); + + if (LOWORD (selectedDrive) == TC_MLIST_ITEM_NONSYS_VOL) + AddMountedVolumeToFavorites (hwndDlg, HIWORD (selectedDrive) - L'A', menuItem == IDPM_ADD_TO_SYSTEM_FAVORITES); + } + break; + + default: + SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); + break; + } +} + + +/* Except in response to the WM_INITDIALOG and WM_ENDSESSION messages, the dialog box procedure + should return nonzero if it processes a message, and zero if it does not. */ +BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static UINT taskBarCreatedMsg; + WORD lw = LOWORD (wParam); + WORD hw = HIWORD (wParam); + + switch (uMsg) + { + case WM_HOTKEY: + + HandleHotKey (hwndDlg, wParam); + return 1; + + case WM_INITDIALOG: + { + int exitCode = 0; + + MainDlg = hwndDlg; + + if (IsTrueCryptInstallerRunning()) + AbortProcess ("TC_INSTALLER_IS_RUNNING"); + + // Set critical default options in case UsePreferences is false + bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = TRUE; + bShowDisconnectedNetworkDrives = FALSE; + bHideWaitingDialog = FALSE; + + ResetWrongPwdRetryCount (); + + ExtractCommandLine (hwndDlg, (wchar_t *) lParam); + + try + { + BootEncObj->SetParentWindow (hwndDlg); + BootEncStatus = BootEncObj->GetStatus(); + RecentBootEncStatus = BootEncStatus; + } + catch (...) + { + // NOP + } + + if (UsePreferences) + { + // General preferences + LoadSettings (hwndDlg); + + // Keyfiles + LoadDefaultKeyFilesParam (); + RestoreDefaultKeyFilesParam (); + } + + if (ComServerMode) + { + InitDialog (hwndDlg); + + if (!ComServerMain ()) + { + handleWin32Error (hwndDlg, SRC_POS); + exit (1); + } + exit (0); + } + + if (CmdMountOptionsValid) + mountOptions = CmdMountOptions; + + InitMainDialog (hwndDlg); + + try + { + if (IsHiddenOSRunning()) + { + uint32 driverConfig = ReadDriverConfigurationFlags(); + if (BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM) + Warning ("UPDATE_TC_IN_HIDDEN_OS_TOO", hwndDlg); + if ( !(driverConfig & TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION) + && !BootEncObj->CheckBootloaderFingerprint ()) + Warning ("BOOT_LOADER_FINGERPRINT_CHECK_FAILED", hwndDlg); + } + else if (SysDriveOrPartitionFullyEncrypted (TRUE)) + { + uint32 driverConfig = ReadDriverConfigurationFlags(); + if (BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM) + { + Warning ("BOOT_LOADER_VERSION_DIFFERENT_FROM_DRIVER_VERSION", hwndDlg); + } + if ( !(driverConfig & TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION) + && !BootEncObj->CheckBootloaderFingerprint ()) + Warning ("BOOT_LOADER_FINGERPRINT_CHECK_FAILED", hwndDlg); + } + } + catch (...) { } + + // Automount + if (bAuto || (Quit && szFileName[0] != 0)) + { + // No drive letter specified on command line + if (commandLineDrive == 0) + szDriveLetter[0] = (wchar_t) GetFirstAvailableDrive () + L'A'; + + if (bAutoMountDevices) + { + defaultMountOptions = mountOptions; + if (FirstCmdKeyFile) + { + KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles = TRUE; + KeyFileCloneAll (FirstCmdKeyFile, &FirstKeyFile); + KeyFileCloneAll (FirstCmdKeyFile, &defaultKeyFilesParam.FirstKeyFile); + } + + if (!MountAllDevices (hwndDlg, !Silent && !CmdVolumePasswordValid && IsPasswordCacheEmpty())) + exitCode = 1; + } + + if (bAutoMountFavorites) + { + defaultMountOptions = mountOptions; + if (FirstCmdKeyFile) + { + KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles = TRUE; + KeyFileCloneAll (FirstCmdKeyFile, &FirstKeyFile); + KeyFileCloneAll (FirstCmdKeyFile, &defaultKeyFilesParam.FirstKeyFile); + } + + if (!MountFavoriteVolumes (hwndDlg, FALSE, LogOn)) + exitCode = 1; + } + + if (szFileName[0] != 0 && !TranslateVolumeID (hwndDlg, szFileName, ARRAYSIZE (szFileName))) + { + exitCode = 1; + } + else if (szFileName[0] != 0 && !IsMountedVolume (szFileName)) + { + BOOL mounted = FALSE; + int EffectiveVolumePkcs5 = CmdVolumePkcs5; + BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode; + BOOL bEffectiveTryEmptyPasswordWhenKeyfileUsed = bCmdTryEmptyPasswordWhenKeyfileUsedValid? bCmdTryEmptyPasswordWhenKeyfileUsed : bTryEmptyPasswordWhenKeyfileUsed; + + if (!VolumePathExists (szFileName)) + { + handleWin32Error (hwndDlg, SRC_POS); + } + else + { + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (EffectiveVolumePkcs5 == 0) + EffectiveVolumePkcs5 = DefaultVolumePkcs5; + if (!EffectiveVolumeTrueCryptMode) + EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode; + + // Command line password or keyfiles + if (CmdVolumePassword.Length != 0 || (FirstCmdKeyFile && (CmdVolumePasswordValid || bEffectiveTryEmptyPasswordWhenKeyfileUsed))) + { + BOOL reportBadPasswd = CmdVolumePassword.Length > 0; + + if (FirstCmdKeyFile) + KeyFilesApplyWithPin (hwndDlg, &CmdVolumePassword, CmdTokenPin, FirstCmdKeyFile, szFileName); + + mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', + szFileName, &CmdVolumePassword, EffectiveVolumePkcs5, CmdVolumePim, EffectiveVolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, + &mountOptions, Silent, reportBadPasswd); + + burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); + } + else + { + // Cached password + mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, NULL, EffectiveVolumePkcs5, CmdVolumePim, EffectiveVolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, Silent, FALSE); + } + + if (FirstCmdKeyFile) + { + KeyFileRemoveAll (&FirstKeyFile); + FirstKeyFile = FirstCmdKeyFile; + KeyFilesEnable = TRUE; + } + + // Ask user for password + while (!mounted && !Silent) + { + int GuiPkcs5 = EffectiveVolumePkcs5; + int GuiPim = CmdVolumePim; + BOOL GuiTrueCryptMode = EffectiveVolumeTrueCryptMode; + VolumePassword.Length = 0; + + StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume),szFileName); + if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &GuiTrueCryptMode, NULL, TRUE)) + break; + else + { + VolumePkcs5 = GuiPkcs5; + VolumePim = GuiPim; + VolumeTrueCryptMode = GuiTrueCryptMode; + burn (&GuiPkcs5, sizeof(GuiPkcs5)); + burn (&GuiPim, sizeof(GuiPim)); + burn (&GuiTrueCryptMode, sizeof(GuiTrueCryptMode)); + } + + WaitCursor (); + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApplyWithPin (hwndDlg, &VolumePassword, CmdTokenPin, FirstKeyFile, szFileName); + + mounted = MountVolume (hwndDlg, szDriveLetter[0] - L'A', szFileName, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, bCacheInDriver, bIncludePimInCache, bForceMount, &mountOptions, FALSE, TRUE); + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf)); + + NormalCursor (); + } + } + + if (UsePreferences) + { + RestoreDefaultKeyFilesParam (); + bCacheInDriver = bCacheInDriverDefault; + } + + if (mounted > 0) + { + if (bBeep) + MessageBeep (0xFFFFFFFF); + + if (bExplore) + OpenVolumeExplorerWindow (szDriveLetter[0] - L'A'); + + RefreshMainDlg(hwndDlg); + + if(!Silent) + { + // Check for problematic file extensions (exe, dll, sys) + if (CheckFileExtension (szFileName)) + Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING", hwndDlg); + } + } + else + exitCode = 1; + } + else if (bExplore && GetMountedVolumeDriveNo (szFileName) != -1) + OpenVolumeExplorerWindow (GetMountedVolumeDriveNo (szFileName)); + else if (szFileName[0] != 0 && IsMountedVolume (szFileName)) + Warning ("VOL_ALREADY_MOUNTED", hwndDlg); + + if (!Quit) + RefreshMainDlg(hwndDlg); + } + + // Wipe cache + if (bWipe) + WipeCache (hwndDlg, Silent); + + // Wipe command line password + if (CmdVolumePassword.Length != 0) + { + burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); + CmdVolumePassword.Length = 0; + } + + // Wipe command line keyfiles + if (FirstCmdKeyFile) + { + if (defaultKeyFilesParam.FirstKeyFile) + KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); + + defaultKeyFilesParam.EnableKeyFiles = FALSE; + + if (!Quit) + { + LoadSettings (hwndDlg); + LoadDefaultKeyFilesParam (); + RestoreDefaultKeyFilesParam (); + } + } + + // Dismount + if (cmdUnmountDrive >= 0) + { + MOUNT_LIST_STRUCT mountList; + DWORD bytesReturned; + + if (DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, NULL, 0, &mountList, sizeof (mountList), &bytesReturned, NULL) + && (mountList.ulMountedDrives & (1 << cmdUnmountDrive)) == 0) + { + Error ("NO_VOLUME_MOUNTED_TO_DRIVE", hwndDlg); + exitCode = 1; + } + else if (!Dismount (hwndDlg, cmdUnmountDrive)) + exitCode = 1; + } + else if (cmdUnmountDrive == -1) + { + if (!DismountAll (hwndDlg, bForceUnmount, !Silent, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY)) + exitCode = 1; + } + + // TaskBar icon + if (bEnableBkgTask) + TaskBarIconAdd (hwndDlg); + + // Quit + if (Quit) + { + if (TaskBarIconMutex == NULL) + exit (exitCode); + + MainWindowHidden = TRUE; + + LoadSettings (hwndDlg); + LoadDefaultKeyFilesParam (); + RestoreDefaultKeyFilesParam (); + + if (!bEnableBkgTask) + { + if (TaskBarIconMutex) + TaskBarIconRemove (hwndDlg); + exit (exitCode); + } + } + + // No command line arguments or only /volume => bring active instance + // to foreground if available + if (NoCmdLineArgs == 0 || (CmdLineVolumeSpecified && NoCmdLineArgs <= 2)) + { + HWND h = hwndDlg; + EnumWindows (FindTCWindowEnum, (LPARAM) &h); + + if (h != hwndDlg + && (!IsAdmin() || (GetWindowLongPtrW (h, DWLP_USER) & TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES) != 0)) + { + if (CmdLineVolumeSpecified) + { + COPYDATASTRUCT cd; + memcpy (&cd.dwData, WM_COPY_SET_VOLUME_NAME, 4); + cd.lpData = szFileName; + cd.cbData = (DWORD) ((wcslen (szFileName) + 1) * sizeof (wchar_t)); + + SendMessage (h, WM_COPYDATA, (WPARAM)hwndDlg, (LPARAM)&cd); + } + + SendMessage (h, TC_APPMSG_MOUNT_SHOW_WINDOW, 0, 0); + + ShowWindow (h, SW_SHOW); + SetForegroundWindow (h); + + if (TaskBarIconMutex == NULL) + exit (0); + } + } + + HookMouseWheel (hwndDlg, IDC_VOLUME); + + // Register hot keys + if (!RegisterAllHotkeys (hwndDlg, Hotkeys) + && TaskBarIconMutex != NULL) // Warn only if we are the first instance of TrueCrypt + Warning("HOTKEY_REGISTRATION_ERROR", hwndDlg); + + Silent = FALSE; + + GetMountList (&LastKnownMountList); + SetTimer (hwndDlg, TIMER_ID_MAIN, TIMER_INTERVAL_MAIN, NULL); + + taskBarCreatedMsg = RegisterWindowMessage (L"TaskbarCreated"); + + AllowMessageInUIPI (taskBarCreatedMsg); + + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + /* Check system encryption status */ + + if (!Quit) // Do not care about system encryption or in-place encryption if we were launched from the system startup sequence (the wizard was added to it too). + { + if (SysEncryptionOrDecryptionRequired ()) + { + if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption + { + // We shouldn't block the mutex at this point + + if (SystemEncryptionStatus == SYSENC_STATUS_PRETEST + || AskWarnYesNo ("SYSTEM_ENCRYPTION_RESUME_PROMPT", hwndDlg) == IDYES) + { + // The wizard was not launched during the system startup seq, or the user may have forgotten + // to resume the encryption/decryption process. + + + LaunchVolCreationWizard (hwndDlg, L"/csysenc"); + } + } + } + + if (bInPlaceEncNonSysPending && !NonSysInplaceEncInProgressElsewhere()) + { + BOOL bDecrypt = FALSE; + if (AskNonSysInPlaceEncryptionResume(hwndDlg, &bDecrypt) == IDYES) + ResumeInterruptedNonSysInplaceEncProcess (bDecrypt); + } + } + + if (TaskBarIconMutex != NULL) + RegisterWtsNotification(hwndDlg); + DoPostInstallTasks (hwndDlg); + ResetCurrentDirectory (); + } + return 0; + + case WM_MOUSEWHEEL: + return HandleDriveListMouseWheelEvent (uMsg, wParam, lParam, FALSE); + + case WM_CONTEXTMENU: + { + HWND hList = GetDlgItem (hwndDlg, IDC_DRIVELIST); + // only handle if it is coming from keyboard and if the drive + // list has focus. The other cases are handled elsewhere + if ( (-1 == GET_X_LPARAM(lParam)) + && (-1 == GET_Y_LPARAM(lParam)) + && (GetFocus () == hList) + ) + { + INT item = ListView_GetSelectionMark (hList); + if (item >= 0) + { + nSelectedDriveIndex = item; + DisplayDriveListContextMenu (hwndDlg, NULL); + } + } + } + break; + + case WM_WINDOWPOSCHANGING: + if (MainWindowHidden) + { + // Prevent window from being shown + PWINDOWPOS wp = (PWINDOWPOS)lParam; + wp->flags &= ~SWP_SHOWWINDOW; + return 0; + } + return 1; + + case WM_SYSCOMMAND: + if (lw == IDC_ABOUT) + { + DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc); + return 1; + } + return 0; + + case WM_HELP: + OpenPageHelp (hwndDlg, 0); + return 1; + + case WM_WTSSESSION_CHANGE: + if (TaskBarIconMutex != NULL) + { + if (bDismountOnSessionLocked && ((WTS_SESSION_LOCK == wParam) || (WTS_CONSOLE_DISCONNECT == wParam) || (WTS_REMOTE_DISCONNECT == wParam))) + { + // Auto-dismount when session is locked + DWORD dwResult; + + if (bWipeCacheOnAutoDismount) + { + DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + SecurityToken::CloseAllSessions(); + } + + DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); + } + } + return 0; + + case WM_ENDSESSION: + if (TaskBarIconMutex != NULL) + { + if (bDismountOnLogOff) + { + // Auto-dismount when user logs off + DWORD dwResult; + + if (bWipeCacheOnAutoDismount) + DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + + DismountAll (hwndDlg, bForceAutoDismount, FALSE, 1, 0); + } + + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + } + EndMainDlg (hwndDlg); + localcleanup (); + return 0; + + case WM_POWERBROADCAST: + if (wParam == PBT_APMSUSPEND + && TaskBarIconMutex != NULL && bDismountOnPowerSaving) + { + // Auto-dismount when entering power-saving mode + DWORD dwResult; + + if (bWipeCacheOnAutoDismount) + { + DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + SecurityToken::CloseAllSessions(); + } + + DismountAll (hwndDlg, bForceAutoDismount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); + } + return 0; + + case WM_TIMER: + { + // Check mount list and update GUI if needed + CheckMountList (hwndDlg, FALSE); + + // Cache status + if (IsPasswordCacheEmpty() == IsWindowEnabled (GetDlgItem (hwndDlg, IDC_WIPE_CACHE))) + EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty()); + + // Check driver warning flags + DWORD bytesOut; + GetWarningFlagsRequest warnings; + if (DeviceIoControl (hDriver, TC_IOCTL_GET_WARNING_FLAGS, NULL, 0, &warnings, sizeof (warnings), &bytesOut, NULL)) + { + if (warnings.SystemFavoriteVolumeDirty) + WarningTopMost ("SYS_FAVORITE_VOLUME_DIRTY", hwndDlg); + + if (warnings.PagingFileCreationPrevented) + WarningTopMost ("PAGING_FILE_CREATION_PREVENTED", hwndDlg); + } + + if (TaskBarIconMutex != NULL) + { + + // Idle auto-dismount + if (MaxVolumeIdleTime > 0) + DismountIdleVolumes (); + + // Screen saver auto-dismount + if (bDismountOnScreenSaver) + { + static BOOL previousState = FALSE; + BOOL running = FALSE; + SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0); + + if (running && !previousState) + { + DWORD dwResult; + previousState = TRUE; + + if (bWipeCacheOnAutoDismount) + { + DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + SecurityToken::CloseAllSessions(); + } + + DismountAll (hwndDlg, bForceAutoDismount, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); + } + else + { + previousState = running; + } + } + + // Auto-mount favorite volumes on arrival +#if TIMER_INTERVAL_MAIN != 500 +#error TIMER_INTERVAL_MAIN != 500 +#endif + static int favoritesAutoMountTimerDivisor = 0; + if ((++favoritesAutoMountTimerDivisor & 1) && !FavoritesOnArrivalMountRequired.empty()) + { + static bool reentry = false; + if (reentry) + break; + + reentry = true; + + foreach (FavoriteVolume favorite, FavoritesOnArrivalMountRequired) + { + if (favorite.UseVolumeID) + { + if (IsMountedVolumeID (favorite.VolumeID)) + continue; + + std::wstring volDevPath = FindDeviceByVolumeID (favorite.VolumeID); + if (volDevPath.length() > 0) + { + favorite.Path = volDevPath; + favorite.DisconnectedDevice = false; + } + else + continue; + } + else if (!favorite.VolumePathId.empty()) + { + if (IsMountedVolume (favorite.Path.c_str())) + continue; + + wchar_t volDevPath[TC_MAX_PATH]; + if (QueryDosDevice (favorite.VolumePathId.substr (4, favorite.VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) == 0) + continue; + + favorite.DisconnectedDevice = false; + } + else if (favorite.Path.find (L"\\\\?\\Volume{") == 0) + { + wstring resolvedPath = VolumeGuidPathToDevicePath (favorite.Path); + if (resolvedPath.empty()) + continue; + + favorite.DisconnectedDevice = false; + favorite.VolumePathId = favorite.Path; + favorite.Path = resolvedPath; + } + + if (IsMountedVolume (favorite.Path.c_str())) + continue; + + if (!IsVolumeDeviceHosted (favorite.Path.c_str())) + { + if (!FileExists (favorite.Path.c_str())) + continue; + } + else if (favorite.VolumePathId.empty()) + continue; + + bool mountedAndNotDisconnected = false; + foreach (FavoriteVolume mountedFavorite, FavoritesMountedOnArrivalStillConnected) + { + if (favorite.Path == mountedFavorite.Path) + { + mountedAndNotDisconnected = true; + break; + } + } + + if (!mountedAndNotDisconnected) + { + FavoriteMountOnArrivalInProgress = TRUE; + MountFavoriteVolumes (hwndDlg, FALSE, FALSE, FALSE, favorite); + FavoriteMountOnArrivalInProgress = FALSE; + + FavoritesMountedOnArrivalStillConnected.push_back (favorite); + } + } + + bool deleted; + for (list ::iterator favorite = FavoritesMountedOnArrivalStillConnected.begin(); + favorite != FavoritesMountedOnArrivalStillConnected.end(); + deleted ? favorite : ++favorite) + { + deleted = false; + + if (IsMountedVolume (favorite->Path.c_str())) + continue; + + if (!IsVolumeDeviceHosted (favorite->Path.c_str())) + { + if (FileExists (favorite->Path.c_str())) + continue; + } + + wchar_t volDevPath[TC_MAX_PATH]; + if (favorite->VolumePathId.size() > 5 + && QueryDosDevice (favorite->VolumePathId.substr (4, favorite->VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) != 0) + { + continue; + } + + // set DisconnectedDevice field on FavoritesOnArrivalMountRequired element + foreach (FavoriteVolume onArrivalFavorite, FavoritesOnArrivalMountRequired) + { + if (onArrivalFavorite.Path == favorite->Path) + { + onArrivalFavorite.DisconnectedDevice = true; + break; + } + } + + favorite = FavoritesMountedOnArrivalStillConnected.erase (favorite); + deleted = true; + } + + reentry = false; + } + } + + // Exit background process in non-install mode or if no volume mounted + // and no other instance active + if (LastKnownMountList.ulMountedDrives == 0 + && MainWindowHidden +#ifndef _DEBUG + && (bCloseBkgTaskWhenNoVolumes || IsNonInstallMode ()) + && !SysEncDeviceActive (TRUE) +#endif + && GetDriverRefCount () < 2) + { + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + EndMainDlg (hwndDlg); + } + } + return 1; + + case TC_APPMSG_TASKBAR_ICON: + { + switch (lParam) + { + case WM_LBUTTONDOWN: + SetForegroundWindow (hwndDlg); + MainWindowHidden = FALSE; + ShowWindow (hwndDlg, SW_SHOW); + ShowWindow (hwndDlg, SW_RESTORE); + return 1; + + case WM_RBUTTONUP: + { + POINT pos; + HMENU popup = CreatePopupMenu (); + int sel, i, n; + + if (MainWindowHidden) + { + AppendMenuW (popup, MF_STRING, IDM_SHOW_HIDE, GetString ("SHOW_TC")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + } + else if (bEnableBkgTask + && (!(LastKnownMountList.ulMountedDrives == 0 + && (bCloseBkgTaskWhenNoVolumes || IsNonInstallMode ()) + && !SysEncDeviceActive (TRUE) + && GetDriverRefCount () < 2))) + { + AppendMenuW (popup, MF_STRING, IDM_SHOW_HIDE, GetString ("HIDE_TC")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + } + AppendMenuW (popup, MF_STRING, IDM_MOUNTALL, GetString ("IDC_MOUNTALL")); + AppendMenuW (popup, MF_STRING, IDM_MOUNT_FAVORITE_VOLUMES, GetString ("IDM_MOUNT_FAVORITE_VOLUMES")); + AppendMenuW (popup, MF_STRING, IDM_UNMOUNTALL, GetString ("IDC_UNMOUNTALL")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + + for (n = 0; n < 2; n++) + { + for (i = 0; i < 26; i++) + { + if (LastKnownMountList.ulMountedDrives & (1 << i)) + { + wchar_t s[1024]; + wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[i]; + + if (wcsstr (vol, L"\\??\\")) vol += 4; + + // first check label used for mounting. If empty, look for it in favorites. + bool useInExplorer = false; + wstring label = (wchar_t *) LastKnownMountList.wszLabel[i]; + if (label.empty()) + label = GetFavoriteVolumeLabel (vol, useInExplorer); + + StringCbPrintfW (s, sizeof(s), L"%s %c: (%s)", + GetString (n==0 ? "OPEN" : "DISMOUNT"), + i + L'A', + label.empty() ? vol : label.c_str()); + AppendMenuW (popup, MF_STRING, n*26 + TRAYICON_MENU_DRIVE_OFFSET + i, s); + } + } + if (LastKnownMountList.ulMountedDrives != 0) + AppendMenu (popup, MF_SEPARATOR, 0, L""); + } + + AppendMenuW (popup, MF_STRING, IDM_HELP, GetString ("MENU_HELP")); + AppendMenuW (popup, MF_STRING, IDM_HOMEPAGE_SYSTRAY, GetString ("HOMEPAGE")); + AppendMenuW (popup, MF_STRING, IDM_PREFERENCES, GetString ("IDM_PREFERENCES")); + AppendMenuW (popup, MF_STRING, IDM_ABOUT, GetString ("IDM_ABOUT")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDCANCEL, GetString ("EXIT")); + + GetCursorPos (&pos); + + SetForegroundWindow(hwndDlg); + + sel = TrackPopupMenu (popup, + TPM_RETURNCMD | TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, + pos.x, + pos.y, + 0, + hwndDlg, + NULL); + + if (sel >= TRAYICON_MENU_DRIVE_OFFSET && sel < TRAYICON_MENU_DRIVE_OFFSET + 26) + { + OpenVolumeExplorerWindow (sel - TRAYICON_MENU_DRIVE_OFFSET); + } + else if (sel >= TRAYICON_MENU_DRIVE_OFFSET + 26 && sel < TRAYICON_MENU_DRIVE_OFFSET + 26*2) + { + if (CheckMountList (hwndDlg, FALSE)) + { + if (Dismount (hwndDlg, sel - TRAYICON_MENU_DRIVE_OFFSET - 26)) + { + wchar_t txt [2048]; + StringCbPrintfW (txt, sizeof(txt), GetString ("VOLUME_MOUNTED_AS_DRIVE_LETTER_X_DISMOUNTED"), sel - TRAYICON_MENU_DRIVE_OFFSET - 26 + L'A'); + + InfoBalloonDirect (GetString ("SUCCESSFULLY_DISMOUNTED"), txt, hwndDlg); + } + } + } + else if (sel == IDM_SHOW_HIDE) + { + ChangeMainWindowVisibility (); + } + else if (sel == IDM_HOMEPAGE_SYSTRAY) + { + Applink ("home", TRUE, ""); + } + else if (sel == IDCANCEL) + { + if ((LastKnownMountList.ulMountedDrives == 0 + && !SysEncDeviceActive (TRUE)) + || AskWarnNoYes ("CONFIRM_EXIT", hwndDlg) == IDYES) + { + // Close all other TC windows + EnumWindows (CloseTCWindowsEnum, 0); + + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + SendMessage (hwndDlg, WM_COMMAND, sel, 0); + } + } + else + { + SendMessage (hwndDlg, WM_COMMAND, sel, 0); + } + + PostMessage(hwndDlg, WM_NULL, 0, 0); + DestroyMenu (popup); + } + return 1; + } + } + + return 0; + + case TC_APPMSG_CLOSE_BKG_TASK: + if (TaskBarIconMutex != NULL) + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + + return 1; + + case TC_APPMSG_SYSENC_CONFIG_UPDATE: + LoadSysEncSettings (); + + // The wizard added VeraCrypt.exe to the system startup sequence or performed other operations that + // require us to update our cached settings. + LoadSettings (hwndDlg); + + return 1; + + case WM_DEVICECHANGE: + if (!IgnoreWmDeviceChange && wParam != DBT_DEVICEARRIVAL) + { + // Check if any host device has been removed and force dismount of volumes accordingly + PDEV_BROADCAST_HDR hdr = (PDEV_BROADCAST_HDR) lParam; + int m; + + GetMountList (&LastKnownMountList); + + if (wParam == DBT_DEVICEREMOVECOMPLETE && hdr->dbch_devicetype == DBT_DEVTYP_VOLUME) + { + // File-hosted volumes + PDEV_BROADCAST_VOLUME vol = (PDEV_BROADCAST_VOLUME) lParam; + int i; + + for (i = 0; i < 26; i++) + { + if ((vol->dbcv_unitmask & (1 << i)) && !(GetUsedLogicalDrives() & (1 << i))) + { + for (m = 0; m < 26; m++) + { + if (LastKnownMountList.ulMountedDrives & (1 << m)) + { + wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[m]; + + if (wcsstr (vol, L"\\??\\") == vol) + vol += 4; + + if (vol[1] == L':' && i == (vol[0] - (vol[0] <= L'Z' ? L'A' : L'a'))) + { + UnmountVolume (hwndDlg, m, TRUE); + WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN", hwndDlg); + } + } + } + } + } + } + + // Device-hosted volumes + for (m = 0; m < 26; m++) + { + if (LastKnownMountList.ulMountedDrives & (1 << m)) + { + wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[m]; + + if (wcsstr (vol, L"\\??\\") == vol) + vol += 4; + + if (IsVolumeDeviceHosted (vol)) + { + OPEN_TEST_STRUCT ots = {0}; + + if (!OpenDevice (vol, &ots, FALSE, FALSE, NULL)) + { + UnmountVolume (hwndDlg, m, TRUE); + WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN", hwndDlg); + } + } + } + } + + // Favorite volumes + UpdateDeviceHostedFavoriteVolumes(); + + return 1; + } + return 0; + + case WM_NOTIFY: + + if(wParam == IDC_DRIVELIST) + { + if (((LPNMHDR) lParam)->code == NM_CUSTOMDRAW) + { + int width = ListView_GetColumnWidth (GetDlgItem (hwndDlg, IDC_DRIVELIST), 1); + if (width != LastDriveListVolumeColumnWidth) + { + LastDriveListVolumeColumnWidth = width; + LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); + } + return 0; + } + + /* Single click within drive list */ + if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED )) + { + nSelectedDriveIndex = ((LPNMLISTVIEW) lParam)->iItem; + EnableDisableButtons (hwndDlg); + return 1; + } + + /* Double click within drive list */ + if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE) + { + LPARAM state = GetItemLong (GetDlgItem (hwndDlg, IDC_DRIVELIST), ((LPNMITEMACTIVATE)lParam)->iItem ); + nSelectedDriveIndex = ((LPNMITEMACTIVATE)lParam)->iItem; + if (LOWORD(state) == TC_MLIST_ITEM_NONSYS_VOL || LOWORD(state) == TC_MLIST_ITEM_SYS_PARTITION) + { + // Open explorer window for mounted volume + WaitCursor (); + OpenVolumeExplorerWindow (HIWORD(state) - L'A'); + NormalCursor (); + } + else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) + { + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (GetAsyncKeyState (VK_CONTROL) < 0) + { + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (CmdVolumePkcs5 == 0) + mountOptions.ProtectedHidVolPkcs5Prf = DefaultVolumePkcs5; + else + mountOptions.ProtectedHidVolPkcs5Prf = CmdVolumePkcs5; + mountOptions.ProtectedHidVolPim = CmdVolumePim; + + if (IDCANCEL == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, + (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions)) + return 1; + + if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) + { + wchar_t selectedVolume [TC_MAX_PATH + 1]; + GetVolumePath (hwndDlg, selectedVolume, ARRAYSIZE (selectedVolume)); + KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, selectedVolume); + } + } + + if (CheckMountList (hwndDlg, FALSE)) + _beginthread(mountThreadFunction, 0, hwndDlg); + } + return 1; + } + + /* Right click and drag&drop operations */ + + switch (((NM_LISTVIEW *) lParam)->hdr.code) + { + case NM_RCLICK: + case LVN_BEGINRDRAG: + /* If the mouse was moving while the right mouse button is pressed, popup menu would + not open, because drag&drop operation would be initiated. Therefore, we're handling + RMB drag-and-drop operations as well. */ + { + + DisplayDriveListContextMenu (hwndDlg, lParam); + + return 1; + } + } + } + return 0; + + case WM_ERASEBKGND: + return 0; + + case WM_COMMAND: + + if (lw == IDCANCEL || lw == IDC_EXIT) + { + EndMainDlg (hwndDlg); + return 1; + } + + if (lw == IDHELP || lw == IDM_HELP) + { + OpenPageHelp (hwndDlg, 0); + return 1; + } + + if (lw == IDM_ABOUT || lw == IDC_LOGO) + { + DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc); + return 1; + } + + if (lw == IDOK && LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_NONSYS_VOL + || lw == IDM_UNMOUNT_VOLUME) + { + if (lw == IDM_UNMOUNT_VOLUME && LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) != TC_MLIST_ITEM_NONSYS_VOL) + { + Warning ("SELECT_A_MOUNTED_VOLUME", hwndDlg); + return 1; + } + + if (CheckMountList (hwndDlg, FALSE)) + Dismount (hwndDlg, -2); + return 1; + } + + if ((lw == IDOK || lw == IDM_MOUNT_VOLUME || lw == IDM_MOUNT_VOLUME_OPTIONS || lw == IDC_MOUNTALL || lw == IDM_MOUNTALL) + && LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == 0xffff) + { + MessageBoxW (hwndDlg, GetString ("SELECT_FREE_DRIVE"), L"VeraCrypt", MB_ICONEXCLAMATION); + return 1; + } + + if ((lw == IDOK || lw == IDM_MOUNT_VOLUME || lw == IDM_MOUNT_VOLUME_OPTIONS)) + { + MountSelectedVolume (hwndDlg, lw == IDM_MOUNT_VOLUME_OPTIONS); + return 1; + } + + if (lw == IDC_UNMOUNTALL || lw == IDM_UNMOUNTALL) + { + if (DismountAll (hwndDlg, bForceUnmount, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY) + && lw == IDM_UNMOUNTALL) // If initiated via the systray menu + { + InfoBalloon ("SUCCESSFULLY_DISMOUNTED", "MOUNTED_VOLUMES_DISMOUNTED", hwndDlg); + } + + return 1; + } + + if (lw == IDC_MOUNTALL || lw == IDM_MOUNTALL) + { + // If Shift key is down and the password cache isn't empty, bypass password prompt + MountAllDevices (hwndDlg, !(GetAsyncKeyState (VK_SHIFT) < 0 && !IsPasswordCacheEmpty())); + return 1; + } + + if (lw == IDC_SELECT_FILE || lw == IDM_SELECT_FILE) + { + SelectContainer (hwndDlg); + return 1; + } + + if (lw == IDC_SELECT_DEVICE || lw == IDM_SELECT_DEVICE) + { + SelectPartition (hwndDlg); + return 1; + } + + // System Encryption menu + switch (lw) + { + case IDM_ENCRYPT_SYSTEM_DEVICE: + EncryptSystemDevice (hwndDlg); + break; + case IDM_PERMANENTLY_DECRYPT_SYS: + DecryptSystemDevice (hwndDlg); + break; + case IDM_CREATE_HIDDEN_OS: + CreateHiddenOS (hwndDlg); + break; + case IDM_SYSENC_RESUME: + ResumeInterruptedSysEncProcess (hwndDlg); + break; + case IDM_SYSTEM_ENCRYPTION_STATUS: + ShowSystemEncryptionStatus (hwndDlg); + break; + case IDM_CHANGE_SYS_PASSWORD: + ChangeSysEncPassword (hwndDlg, FALSE); + break; + case IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO: + ChangeSysEncPassword (hwndDlg, TRUE); + break; + case IDM_CREATE_RESCUE_DISK: + CreateRescueDisk (hwndDlg); + break; + case IDM_VERIFY_RESCUE_DISK: + VerifyRescueDisk (hwndDlg, false); + break; + case IDM_VERIFY_RESCUE_DISK_ISO: + VerifyRescueDisk (hwndDlg, true); + break; + case IDM_MOUNT_SYSENC_PART_WITHOUT_PBA: + + if (CheckSysEncMountWithoutPBA (hwndDlg, L"", FALSE)) + { + mountOptions = defaultMountOptions; + mountOptions.PartitionInInactiveSysEncScope = TRUE; + bPrebootPasswordDlgMode = TRUE; + + if (CheckMountList (hwndDlg, FALSE)) + _beginthread(mountThreadFunction, 0, hwndDlg); + } + break; + } + + if (lw == IDC_VOLUME_TOOLS) + { + /* Volume Tools popup menu */ + + int menuItem; + wchar_t volPath[TC_MAX_PATH]; /* Volume to mount */ + HMENU popup = CreatePopupMenu (); + RECT rect; + + if (ActiveSysEncDeviceSelected ()) + { + PopulateSysEncContextMenu (popup, TRUE); + } + else + { + AppendMenuW (popup, MF_STRING, IDM_CHANGE_PASSWORD, GetString ("IDM_CHANGE_PASSWORD")); + AppendMenuW (popup, MF_STRING, IDM_CHANGE_HEADER_KEY_DERIV_ALGO, GetString ("IDM_CHANGE_HEADER_KEY_DERIV_ALGO")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_ADD_REMOVE_VOL_KEYFILES, GetString ("IDM_ADD_REMOVE_VOL_KEYFILES")); + AppendMenuW (popup, MF_STRING, IDM_REMOVE_ALL_KEYFILES_FROM_VOL, GetString ("IDM_REMOVE_ALL_KEYFILES_FROM_VOL")); + AppendMenu (popup, MF_SEPARATOR, 0, L""); + AppendMenuW (popup, MF_STRING, IDM_DECRYPT_NONSYS_VOL, GetString ("IDM_DECRYPT_NONSYS_VOL")); + AppendMenu (popup, MF_SEPARATOR, 0, NULL); + AppendMenuW (popup, MF_STRING, IDM_BACKUP_VOL_HEADER, GetString ("IDM_BACKUP_VOL_HEADER")); + AppendMenuW (popup, MF_STRING, IDM_RESTORE_VOL_HEADER, GetString ("IDM_RESTORE_VOL_HEADER")); + } + + GetWindowRect (GetDlgItem (hwndDlg, IDC_VOLUME_TOOLS), &rect); + + menuItem = TrackPopupMenu (popup, + TPM_RETURNCMD | TPM_LEFTBUTTON, + rect.left + 2, + rect.top + 2, + 0, + hwndDlg, + NULL); + + DestroyMenu (popup); + + switch (menuItem) + { + case IDM_DECRYPT_NONSYS_VOL: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + DecryptNonSysDevice (hwndDlg, TRUE, FALSE); + } + break; + + case IDM_CHANGE_PASSWORD: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; + ChangePassword (hwndDlg); + } + break; + + case IDM_CHANGE_HEADER_KEY_DERIV_ALGO: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; + ChangePassword (hwndDlg); + } + break; + + case IDM_ADD_REMOVE_VOL_KEYFILES: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + pwdChangeDlgMode = PCDM_ADD_REMOVE_VOL_KEYFILES; + ChangePassword (hwndDlg); + } + break; + + case IDM_REMOVE_ALL_KEYFILES_FROM_VOL: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + pwdChangeDlgMode = PCDM_REMOVE_ALL_KEYFILES_FROM_VOL; + ChangePassword (hwndDlg); + } + break; + + case IDM_BACKUP_VOL_HEADER: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); + + WaitCursor (); + + int iStatus = 0; + BackupHeaderThreadParam threadParam; + threadParam.bRequireConfirmation = TRUE; + threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); + threadParam.iResult = &iStatus; + + ShowWaitDialog (hwndDlg, TRUE, BackupHeaderWaitThreadProc, &threadParam); + + NormalCursor (); + } + break; + + case IDM_RESTORE_VOL_HEADER: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); + + WaitCursor (); + + int iStatus = 0; + RestoreHeaderThreadParam threadParam; + threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); + threadParam.iResult = &iStatus; + + ShowWaitDialog(hwndDlg, TRUE, RestoreHeaderWaitThreadProc, &threadParam); + + NormalCursor (); + } + break; + + default: + SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); + break; + } + return 1; + } + + if (lw == IDM_DECRYPT_NONSYS_VOL) + { + LPARAM selectedDrive = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + if (LOWORD (selectedDrive) == TC_MLIST_ITEM_FREE && !VolumeSelected (MainDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + DecryptNonSysDevice (hwndDlg, TRUE, FALSE); + } + + return 1; + } + + if (lw == IDM_CHANGE_PASSWORD) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + if (ActiveSysEncDeviceSelected ()) + { + ChangeSysEncPassword (hwndDlg, FALSE); + } + else + { + pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; + ChangePassword (hwndDlg); + } + } + return 1; + } + + if (lw == IDM_CHANGE_HEADER_KEY_DERIV_ALGO) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + if (ActiveSysEncDeviceSelected ()) + { + ChangeSysEncPassword (hwndDlg, TRUE); + } + else + { + pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; + ChangePassword (hwndDlg); + } + } + return 1; + } + + if (lw == IDC_WIPE_CACHE || lw == IDM_WIPE_CACHE) + { + WipeCache (hwndDlg, FALSE); + return 1; + } + + if (lw == IDM_CLEAR_HISTORY) + { + ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); + EnableDisableButtons (hwndDlg); + return 1; + } + + if (lw == IDC_CREATE_VOLUME || lw == IDM_CREATE_VOLUME || lw == IDM_VOLUME_WIZARD) + { + LaunchVolCreationWizard (hwndDlg, L""); + return 1; + } + + if (lw == IDM_VOLUME_EXPANDER) + { + LaunchVolExpander (hwndDlg); + return 1; + } + + if (lw == IDM_ADD_REMOVE_VOL_KEYFILES) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + pwdChangeDlgMode = PCDM_ADD_REMOVE_VOL_KEYFILES; + ChangePassword (hwndDlg); + } + return 1; + } + + if (lw == IDM_REMOVE_ALL_KEYFILES_FROM_VOL) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + pwdChangeDlgMode = PCDM_REMOVE_ALL_KEYFILES_FROM_VOL; + ChangePassword (hwndDlg); + } + return 1; + } + + if (lw == IDM_MANAGE_TOKEN_KEYFILES) + { + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, NULL); + return 1; + } + + if (lw == IDM_CLOSE_ALL_TOKEN_SESSIONS) + { + { + WaitCursor(); + finally_do ({ NormalCursor(); }); + + SecurityToken::CloseAllSessions(); + } + + InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg); + + return 1; + } + + if (lw == IDM_KEYFILE_GENERATOR) + { + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILE_GENERATOR), hwndDlg, + (DLGPROC) KeyfileGeneratorDlgProc, (LPARAM) 0); + + return 1; + } + + if (lw == IDM_DONATE) + { + Applink ("donate", TRUE, ""); + return 1; + } + + if (lw == IDM_LICENSE) + { + TextInfoDialogBox (TC_TBXID_LEGAL_NOTICES); + return 1; + } + + if (lw == IDM_WEBSITE) + { + Applink ("website", TRUE, ""); + return 1; + } + else if (lw == IDM_HOMEPAGE) + { + Applink ("homepage", TRUE, ""); + return 1; + } + else if (lw == IDM_ONLINE_TUTORIAL) + { + Applink ("tutorial", TRUE, ""); + return 1; + } + else if (lw == IDM_ONLINE_HELP) + { + OpenOnlineHelp (); + return 1; + } + else if (lw == IDM_FAQ) + { + Applink ("faq", TRUE, ""); + return 1; + } + else if (lw == IDM_TC_DOWNLOADS) + { + Applink ("downloads", TRUE, ""); + return 1; + } + else if (lw == IDM_NEWS) + { + Applink ("news", TRUE, ""); + return 1; + } + else if (lw == IDM_VERSION_HISTORY) + { + Applink ("history", TRUE, ""); + return 1; + } + else if (lw == IDM_CONTACT) + { + Applink ("contact", FALSE, ""); + return 1; + } + + if (lw == IDM_PREFERENCES) + { + if (IDOK == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_PREFERENCES_DLG), hwndDlg, + (DLGPROC) PreferencesDlgProc, (LPARAM) 0)) + { + if (bEnableBkgTask) + { + TaskBarIconAdd (hwndDlg); + RegisterWtsNotification(hwndDlg); + } + else + { + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + if (MainWindowHidden) + EndMainDlg (hwndDlg); + } + } + return 1; + } + + if (lw == IDM_HOTKEY_SETTINGS) + { + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_HOTKEYS_DLG), hwndDlg, + (DLGPROC) HotkeysDlgProc, (LPARAM) 0); + return 1; + } + + if (lw == IDM_PERFORMANCE_SETTINGS) + { + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_PERFORMANCE_SETTINGS), hwndDlg, (DLGPROC) PerformanceSettingsDlgProc, 0); + return 1; + } + + if (lw == IDM_DEFAULT_KEYFILES) + { + KeyfileDefaultsDlg (hwndDlg); + return 1; + } + + if (lw == IDM_DEFAULT_MOUNT_PARAMETERS) + { + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_DEFAULT_MOUNT_PARAMETERS), hwndDlg, (DLGPROC) DefaultMountParametersDlgProc, 0); + return 1; + } + + if (lw == IDM_ADD_VOLUME_TO_FAVORITES || lw == IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES) + { + LPARAM selectedDrive = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + wchar_t volPathLower[TC_MAX_PATH]; + + // volPathLower will contain the volume path (if any) from the input field below the drive list + GetVolumePath (hwndDlg, volPathLower, ARRAYSIZE (volPathLower)); + + if (LOWORD (selectedDrive) != TC_MLIST_ITEM_NONSYS_VOL + && !(VolumeSelected (hwndDlg) && IsMountedVolume (volPathLower))) + { + Warning ("SELECT_A_MOUNTED_VOLUME", hwndDlg); + + return 1; + } + + int driveNo; + + if (VolumeSelected (hwndDlg) + && IsMountedVolume (volPathLower)) + { + TranslateVolumeID (hwndDlg, volPathLower, ARRAYSIZE (volPathLower)); + + if (LOWORD (selectedDrive) != TC_MLIST_ITEM_NONSYS_VOL) + { + driveNo = GetMountedVolumeDriveNo (volPathLower); + } + else + { + /* We need to resolve selection ambiguity. Two different mounted volumes are currently + selected (one in the drive letter list and the other in the input field below the list). */ + + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + + memset (&prop, 0, sizeof(prop)); + prop.driveNo = HIWORD (selectedDrive) - L'A'; + + if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) + { + Warning ("SELECT_A_MOUNTED_VOLUME", hwndDlg); + return 1; + } + + // volPathHigher will contain the volume path selected in the main drive list + wstring volPathHigher (prop.wszVolume); + + if (wcscmp (((wmemcmp (prop.wszVolume, L"\\??\\", 4) == 0) ? (wchar_t *) prop.wszVolume + 4 : prop.wszVolume), volPathLower) != 0) + { + // The path selected in the input field is different from the path to the volume selected + // in the drive lettter list. We have to resolve possible ambiguity. + + wchar_t *tmp[] = {L"", L"", L"", L"", L"", 0}; + const int maxVolPathLen = 80; + + if (volPathHigher.length () > maxVolPathLen) + { + volPathHigher = wstring (L"...") + volPathHigher.substr (volPathHigher.length () - maxVolPathLen, maxVolPathLen); + } + + wstring volPathLowerWStr (volPathLower); + + if (volPathLowerWStr.length () > maxVolPathLen) + { + volPathLowerWStr = wstring (L"...") + volPathLowerWStr.substr (volPathLowerWStr.length () - maxVolPathLen, maxVolPathLen); + } + + tmp[1] = GetString ("AMBIGUOUS_VOL_SELECTION"); + tmp[2] = (wchar_t *) volPathHigher.c_str(); + tmp[3] = (wchar_t *) volPathLowerWStr.c_str(); + tmp[4] = GetString ("IDCANCEL"); + + switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg)) + { + case 1: + driveNo = HIWORD (selectedDrive) - L'A'; + break; + + case 2: + driveNo = GetMountedVolumeDriveNo (volPathLower); + break; + + default: + return 1; + } + } + else + { + driveNo = HIWORD (selectedDrive) - L'A'; + } + } + } + else + { + driveNo = HIWORD (selectedDrive) - L'A'; + } + + AddMountedVolumeToFavorites (hwndDlg, driveNo, lw == IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES); + + return 1; + } + + if (lw == IDM_ORGANIZE_FAVORITES || lw == IDM_ORGANIZE_SYSTEM_FAVORITES) + { + OrganizeFavoriteVolumes (hwndDlg, lw == IDM_ORGANIZE_SYSTEM_FAVORITES); + return 1; + } + + if (lw == IDM_TOKEN_PREFERENCES) + { + SecurityTokenPreferencesDialog (hwndDlg); + return 1; + } + + if (lw == IDM_SYSENC_SETTINGS || lw == IDM_SYS_ENC_SETTINGS) + { + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_SETTINGS), hwndDlg, (DLGPROC) BootLoaderPreferencesDlgProc, 0); + return 1; + } + + if (lw == IDM_SYS_FAVORITES_SETTINGS) + { + OrganizeFavoriteVolumes (hwndDlg, true); + return 1; + } + + if (lw == IDM_BENCHMARK) + { + Benchmark (hwndDlg); + return 1; + } + + if (lw == IDM_TRAVELER) + { + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_TRAVELER_DLG), hwndDlg, + (DLGPROC) TravelerDlgProc, (LPARAM) 0); + return 1; + } + + if (lw == IDM_BACKUP_VOL_HEADER) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + wchar_t volPath[TC_MAX_PATH]; /* Volume to mount */ + + GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); + + WaitCursor (); + + int iStatus = 0; + BackupHeaderThreadParam threadParam; + threadParam.bRequireConfirmation = TRUE; + threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); + threadParam.iResult = &iStatus; + + ShowWaitDialog (hwndDlg, TRUE, BackupHeaderWaitThreadProc, &threadParam); + + NormalCursor (); + } + return 1; + } + + if (lw == IDM_RESTORE_VOL_HEADER) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else + { + wchar_t volPath[TC_MAX_PATH]; /* Volume to mount */ + + GetVolumePath (hwndDlg, volPath, ARRAYSIZE (volPath)); + + WaitCursor (); + + int iStatus = 0; + RestoreHeaderThreadParam threadParam; + threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); + threadParam.iResult = &iStatus; + + ShowWaitDialog(hwndDlg, TRUE, RestoreHeaderWaitThreadProc, &threadParam); + + NormalCursor (); + } + return 1; + } + + if (lw == IDM_LANGUAGE) + { + BOOL p; + if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_LANGUAGE), hwndDlg, + (DLGPROC) LanguageDlgProc, (LPARAM) 0) == IDOK) + { + LoadLanguageFile (); + SaveSettings (hwndDlg); + + p = LocalizationActive; + LocalizationActive = TRUE; + InitMainDialog (hwndDlg); + InvalidateRect (hwndDlg, NULL, FALSE); + LocalizationActive = p; + DrawMenuBar (hwndDlg); + } + return 1; + } + + if (lw == IDM_TEST_VECTORS) + { + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_CIPHER_TEST_DLG), hwndDlg, (DLGPROC) CipherTestDialogProc, (LPARAM) 1); + return 1; + } + + if (lw == IDM_REFRESH_DRIVE_LETTERS) + { + DWORD driveMap = GetUsedLogicalDrives (); + + WaitCursor (); + + if (!(nCurrentOS == WIN_2000 && RemoteSession)) + { + BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, ~driveMap); + Sleep (100); + BroadcastDeviceChange (DBT_DEVICEARRIVAL, 0, driveMap); + } + + LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); + + if (nSelectedDriveIndex >= 0) + { + SelectItem (GetDlgItem (hwndDlg, IDC_DRIVELIST), + (wchar_t) HIWORD (GetItemLong (GetDlgItem (hwndDlg, IDC_DRIVELIST), nSelectedDriveIndex))); + } + + NormalCursor (); + return 1; + } + + if (lw == IDM_MOUNT_FAVORITE_VOLUMES) + { + _beginthread(mountFavoriteVolumeThreadFunction, 0, NULL); + return 1; + } + + if (lw == IDM_RESUME_INTERRUPTED_PROC) + { + // Ask the user to select encryption, decryption, or cancel + BOOL bDecrypt = FALSE; + char *tmpStr[] = {0, + "CHOOSE_ENCRYPT_OR_DECRYPT", + "ENCRYPT", + "DECRYPT", + "IDCANCEL", + 0}; + + switch (AskMultiChoice ((void **) tmpStr, FALSE, hwndDlg)) + { + case 1: + bDecrypt = FALSE; + break; + case 2: + bDecrypt = TRUE; + break; + default: + return 1; + } + ResumeInterruptedNonSysInplaceEncProcess (bDecrypt); + return 1; + } + + if (lw == IDC_VOLUME_PROPERTIES || lw == IDM_VOLUME_PROPERTIES) + { + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), hwndDlg, + (DLGPROC) VolumePropertiesDlgProc, (LPARAM) 0); + return 1; + } + + if (lw == IDC_VOLUME && hw == CBN_EDITCHANGE) + { + EnableDisableButtons (hwndDlg); + return 1; + } + + if (lw == IDC_VOLUME && hw == CBN_SELCHANGE) + { + UpdateComboOrder (GetDlgItem (hwndDlg, IDC_VOLUME)); + MoveEditToCombo ((HWND) lParam, bHistory); + PostMessage (hwndDlg, TC_APPMSG_MOUNT_ENABLE_DISABLE_CONTROLS, 0, 0); + return 1; + } + + if (lw == IDC_NO_HISTORY) + { + if (!(bHistory = !IsButtonChecked (GetDlgItem (hwndDlg, IDC_NO_HISTORY)))) + ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); + + return 1; + } + + if (lw >= TC_FAVORITE_MENU_CMD_ID_OFFSET && lw < TC_FAVORITE_MENU_CMD_ID_OFFSET_END) + { + size_t favoriteIndex = lw - TC_FAVORITE_MENU_CMD_ID_OFFSET; + + if (favoriteIndex < FavoriteVolumes.size()) + { + if ((FavoriteVolumes[favoriteIndex].UseVolumeID && IsMountedVolumeID (FavoriteVolumes[favoriteIndex].VolumeID)) + || (!FavoriteVolumes[favoriteIndex].UseVolumeID && IsMountedVolume (FavoriteVolumes[favoriteIndex].Path.c_str())) + ) + { + std::wstring volName; + WaitCursor(); + if (FavoriteVolumes[favoriteIndex].UseVolumeID) + volName = FindDeviceByVolumeID (FavoriteVolumes[favoriteIndex].VolumeID); + else + volName = FavoriteVolumes[favoriteIndex].Path; + OpenVolumeExplorerWindow (GetMountedVolumeDriveNo ((wchar_t*) FavoriteVolumes[favoriteIndex].Path.c_str())); + NormalCursor(); + } + else + { + mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) calloc(1, sizeof(mountFavoriteVolumeThreadParam)); + pParam->systemFavorites = FALSE; + pParam->logOnMount = FALSE; + pParam->hotKeyMount = FALSE; + pParam->favoriteVolumeToMount = &FavoriteVolumes[favoriteIndex]; + + _beginthread(mountFavoriteVolumeThreadFunction, 0, pParam); + } + } + + return 1; + } + + return 0; + + case WM_DROPFILES: + { + HDROP hdrop = (HDROP) wParam; + DragQueryFile (hdrop, 0, szFileName, ARRAYSIZE (szFileName)); + DragFinish (hdrop); + + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + EnableDisableButtons (hwndDlg); + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + } + return 1; + + case TC_APPMSG_MOUNT_ENABLE_DISABLE_CONTROLS: + EnableDisableButtons (hwndDlg); + return 1; + + case TC_APPMSG_MOUNT_SHOW_WINDOW: + MainWindowHidden = FALSE; + ShowWindow (hwndDlg, SW_SHOW); + ShowWindow (hwndDlg, SW_RESTORE); + return 1; + + case WM_COPYDATA: + { + PCOPYDATASTRUCT cd = (PCOPYDATASTRUCT)lParam; + if (memcmp (&cd->dwData, WM_COPY_SET_VOLUME_NAME, 4) == 0) + { + if (cd->cbData > 0) + { + ((wchar_t *) cd->lpData)[(cd->cbData / sizeof (wchar_t)) - 1] = 0; + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), (wchar_t *)cd->lpData, bHistory); + } + + EnableDisableButtons (hwndDlg); + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + } + } + return 1; + + case WM_CLOSE: + EndMainDlg (hwndDlg); + return 1; + + case WM_INITMENUPOPUP: + { + // disable "Set Header Key Derivation Algorithm" entry in "Volumes" menu + // "Volumes" menu is the first (index 0) submenu of the main menu + if ((HMENU) wParam == GetSubMenu (GetMenu (hwndDlg), 0)) + { + if (ActiveSysEncDeviceSelected ()) + EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_HEADER_KEY_DERIV_ALGO, MF_GRAYED); + else + EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_HEADER_KEY_DERIV_ALGO, MF_ENABLED); + } + } + return 1; + + default: + // Recreate tray icon if Explorer restarted + if (taskBarCreatedMsg != 0 && uMsg == taskBarCreatedMsg && TaskBarIconMutex != NULL) + { + TaskBarIconRemove (hwndDlg); + TaskBarIconAdd (hwndDlg); + CheckMountList(hwndDlg, TRUE); + return 1; + } + } + + return 0; +} + +void ExtractCommandLine (HWND hwndDlg, wchar_t *lpszCommandLine) +{ + wchar_t **lpszCommandLineArgs = NULL; /* Array of command line arguments */ + int nNoCommandLineArgs; /* The number of arguments in the array */ + wchar_t tmpPath[MAX_PATH * 2]; + + /* Defaults */ + mountOptions.PreserveTimestamp = TRUE; + + if (_wcsicmp (lpszCommandLine, L"-Embedding") == 0) + { + ComServerMode = TRUE; + return; + } + + /* Extract command line arguments */ + NoCmdLineArgs = nNoCommandLineArgs = Win32CommandLine (&lpszCommandLineArgs); + + if (nNoCommandLineArgs > 0) + { + int i; + + for (i = 0; i < nNoCommandLineArgs; i++) + { + enum + { + OptionAuto, + OptionBeep, + OptionCache, + CommandDismount, + OptionExplore, + OptionForce, + CommandHelp, + OptionHistory, + OptionKeyfile, + OptionLetter, + OptionMountOption, + OptionPassword, + OptionQuit, + OptionSilent, + OptionTokenLib, + OptionTokenPin, + OptionVolume, + CommandWipeCache, + OptionPkcs5, + OptionTrueCryptMode, + OptionPim, + OptionTryEmptyPassword, + OptionNoWaitDlg, + }; + + argument args[]= + { + { OptionAuto, L"/auto", L"/a", FALSE }, + { OptionBeep, L"/beep", L"/b", FALSE }, + { OptionCache, L"/cache", L"/c", FALSE }, + { CommandDismount, L"/dismount", L"/d", FALSE }, + { OptionExplore, L"/explore", L"/e", FALSE }, + { OptionForce, L"/force", L"/f", FALSE }, + { OptionPkcs5, L"/hash", NULL , FALSE }, + { CommandHelp, L"/help", L"/?", FALSE }, + { OptionHistory, L"/history", L"/h", FALSE }, + { OptionKeyfile, L"/keyfile", L"/k", FALSE }, + { OptionLetter, L"/letter", L"/l", FALSE }, + { OptionMountOption, L"/mountoption", L"/m", FALSE }, + { OptionPassword, L"/password", L"/p", FALSE }, + { OptionPim, L"/pim", NULL, FALSE }, + { OptionQuit, L"/quit", L"/q", FALSE }, + { OptionSilent, L"/silent", L"/s", FALSE }, + { OptionTokenLib, L"/tokenlib", NULL, FALSE }, + { OptionTokenPin, L"/tokenpin", NULL, FALSE }, + { OptionTrueCryptMode, L"/truecrypt", L"/tc", FALSE }, + { OptionVolume, L"/volume", L"/v", FALSE }, + { CommandWipeCache, L"/wipecache", L"/w", FALSE }, + { OptionTryEmptyPassword, L"/tryemptypass", NULL, FALSE }, + { OptionNoWaitDlg, L"/nowaitdlg", NULL, FALSE }, + }; + + argumentspec as; + + as.args = args; + as.arg_cnt = sizeof(args)/ sizeof(args[0]); + + switch (GetArgumentID (&as, lpszCommandLineArgs[i])) + { + case OptionAuto: + { + wchar_t szTmp[32] = {0}; + bAuto = TRUE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp (szTmp, L"devices")) + bAutoMountDevices = TRUE; + else if (!_wcsicmp (szTmp, L"favorites")) + bAutoMountFavorites = TRUE; + else if (!_wcsicmp (szTmp, L"logon")) + LogOn = TRUE; + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + break; + + case OptionBeep: + bBeep = TRUE; + break; + + case OptionTryEmptyPassword: + { + wchar_t szTmp[16] = {0}; + bCmdTryEmptyPasswordWhenKeyfileUsed = TRUE; + bCmdTryEmptyPasswordWhenKeyfileUsedValid = TRUE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) + bCmdTryEmptyPasswordWhenKeyfileUsed = FALSE; + else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) + bCmdTryEmptyPasswordWhenKeyfileUsed = TRUE; + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + break; + + case OptionNoWaitDlg: + { + wchar_t szTmp[16] = {0}; + bCmdHideWaitingDialog = TRUE; + bCmdHideWaitingDialogValid = TRUE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) + bCmdHideWaitingDialog = FALSE; + else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) + bCmdHideWaitingDialog = TRUE; + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + break; + + case OptionCache: + { + wchar_t szTmp[16] = {0}; + bCacheInDriver = TRUE; + bIncludePimInCache = FALSE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) + bCacheInDriver = FALSE; + else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) + bCacheInDriver = TRUE; + else if (!_wcsicmp(szTmp,L"p") || !_wcsicmp(szTmp,L"pim")) + { + bCacheInDriver = TRUE; + bIncludePimInCache = TRUE; + } + else if (!_wcsicmp(szTmp,L"f") || !_wcsicmp(szTmp,L"favorites")) + { + bCacheInDriver = FALSE; + bCmdCacheDuringMultipleMount = TRUE; + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + break; + + case CommandDismount: + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szDriveLetter, ARRAYSIZE (szDriveLetter))) + { + if ( (wcslen(szDriveLetter) == 1) + || (wcslen(szDriveLetter) == 2 && szDriveLetter[1] == L':') + ) + { + cmdUnmountDrive = towupper(szDriveLetter[0]) - L'A'; + if ((cmdUnmountDrive < 0) || (cmdUnmountDrive > (L'Z' - L'A'))) + AbortProcess ("BAD_DRIVE_LETTER"); + } + else + AbortProcess ("BAD_DRIVE_LETTER"); + + } + else + cmdUnmountDrive = -1; + + break; + + case OptionExplore: + bExplore = TRUE; + break; + + case OptionForce: + bForceMount = TRUE; + bForceUnmount = TRUE; + break; + + case OptionKeyfile: + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, + nNoCommandLineArgs, tmpPath, ARRAYSIZE (tmpPath))) + { + KeyFile *kf; + RelativePath2Absolute (tmpPath); + kf = (KeyFile *) malloc (sizeof (KeyFile)); + if (kf) + { + StringCchCopyW (kf->FileName, ARRAYSIZE(kf->FileName), tmpPath); + FirstCmdKeyFile = KeyFileAdd (FirstCmdKeyFile, kf); + } + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + + break; + + case OptionLetter: + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szDriveLetter, ARRAYSIZE (szDriveLetter))) + { + if ( (wcslen(szDriveLetter) == 1) + || (wcslen(szDriveLetter) == 2 && szDriveLetter[1] == L':') + ) + { + commandLineDrive = *szDriveLetter = (wchar_t) towupper (*szDriveLetter); + + if (commandLineDrive < L'A' || commandLineDrive > L'Z') + AbortProcess ("BAD_DRIVE_LETTER"); + } + else + AbortProcess ("BAD_DRIVE_LETTER"); + } + else + AbortProcess ("BAD_DRIVE_LETTER"); + + break; + + case OptionHistory: + { + wchar_t szTmp[8] = {0}; + bHistory = bHistoryCmdLine = TRUE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp(szTmp,L"n") || !_wcsicmp(szTmp,L"no")) + bHistory = FALSE; + else if (!_wcsicmp(szTmp,L"y") || !_wcsicmp(szTmp,L"yes")) + bHistory = TRUE; + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + break; + + case OptionMountOption: + { + wchar_t szTmp[64] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp (szTmp, L"ro") || !_wcsicmp (szTmp, L"readonly")) + mountOptions.ReadOnly = TRUE; + + else if (!_wcsicmp (szTmp, L"rm") || !_wcsicmp (szTmp, L"removable")) + mountOptions.Removable = TRUE; + + else if (!_wcsicmp (szTmp, L"ts") || !_wcsicmp (szTmp, L"timestamp")) + mountOptions.PreserveTimestamp = FALSE; + + else if (!_wcsicmp (szTmp, L"sm") || !_wcsicmp (szTmp, L"system")) + mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode = TRUE; + + else if (!_wcsicmp (szTmp, L"bk") || !_wcsicmp (szTmp, L"headerbak")) + mountOptions.UseBackupHeader = TRUE; + + else if (!_wcsicmp (szTmp, L"recovery")) + mountOptions.RecoveryMode = TRUE; + else if ((wcslen(szTmp) > 6) && (wcslen(szTmp) <= 38) && !_wcsnicmp (szTmp, L"label=", 6)) + { + // get the label + StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), &szTmp[6]); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + + CmdMountOptions = mountOptions; + CmdMountOptionsValid = TRUE; + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + + case OptionPassword: + { + wchar_t szTmp[MAX_PASSWORD + 1]; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szTmp, ARRAYSIZE (szTmp))) + { + int iLen = WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, (char*) CmdVolumePassword.Text, MAX_PASSWORD + 1, NULL, NULL); + burn (szTmp, sizeof (szTmp)); + if (iLen > 0) + { + CmdVolumePassword.Length = (unsigned __int32) (iLen - 1); + CmdVolumePasswordValid = TRUE; + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + + case OptionVolume: + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, + nNoCommandLineArgs, szFileName, ARRAYSIZE (szFileName))) + { + RelativePath2Absolute (szFileName); + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + CmdLineVolumeSpecified = TRUE; + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + break; + + case OptionQuit: + { + wchar_t szTmp[32] = {0}; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) + { + if (!_wcsicmp (szTmp, L"UAC")) // Used to indicate non-install elevation + break; + + else if (!_wcsicmp (szTmp, L"preferences")) + { + Quit = TRUE; + UsePreferences = TRUE; + break; + } + + else if (!_wcsicmp (szTmp, L"background")) + bEnableBkgTask = TRUE; + + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + + Quit = TRUE; + UsePreferences = FALSE; + } + break; + + case OptionSilent: + Silent = TRUE; + break; + + case OptionTokenLib: + if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, SecurityTokenLibraryPath, ARRAYSIZE (SecurityTokenLibraryPath)) == HAS_ARGUMENT) + InitSecurityTokenLibrary(hwndDlg); + else + AbortProcess ("COMMAND_LINE_ERROR"); + + break; + + case OptionTokenPin: + { + wchar_t szTmp[SecurityToken::MaxPasswordLength + 1] = {0}; + if (GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp)) == HAS_ARGUMENT) + { + if (0 == WideCharToMultiByte (CP_UTF8, 0, szTmp, -1, CmdTokenPin, array_capacity (CmdTokenPin), nullptr, nullptr)) + AbortProcess ("COMMAND_LINE_ERROR"); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + + break; + + case CommandWipeCache: + bWipe = TRUE; + break; + + case CommandHelp: + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_COMMANDHELP_DLG), hwndDlg, (DLGPROC) + CommandHelpDlgProc, (LPARAM) &as); + exit(0); + break; + + case OptionPkcs5: + { + wchar_t szTmp[32] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) + { + if (_wcsicmp(szTmp, L"sha512") == 0 || _wcsicmp(szTmp, L"sha-512") == 0) + CmdVolumePkcs5 = SHA512; + else if (_wcsicmp(szTmp, L"whirlpool") == 0) + CmdVolumePkcs5 = WHIRLPOOL; + else if (_wcsicmp(szTmp, L"sha256") == 0 || _wcsicmp(szTmp, L"sha-256") == 0) + CmdVolumePkcs5 = SHA256; + else if (_wcsicmp(szTmp, L"ripemd160") == 0 || _wcsicmp(szTmp, L"ripemd-160") == 0) + CmdVolumePkcs5 = RIPEMD160; + else + { + CmdVolumePkcs5 = 0; + AbortProcess ("COMMAND_LINE_ERROR"); + } + + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + + case OptionPim: + { + wchar_t szTmp[32] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, ARRAYSIZE (szTmp))) + { + wchar_t* endPtr = NULL; + CmdVolumePim = (int) wcstol(szTmp, &endPtr, 0); + if (CmdVolumePim < 0 || CmdVolumePim > MAX_PIM_VALUE || endPtr == szTmp || *endPtr != L'\0') + { + CmdVolumePim = 0; + AbortProcess ("COMMAND_LINE_ERROR"); + } + + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + + case OptionTrueCryptMode: + CmdVolumeTrueCryptMode = TRUE; + break; + + // no option = file name if there is only one argument + default: + { + if (nNoCommandLineArgs == 1) + { + StringCbCopyW (szFileName, array_capacity (szFileName), lpszCommandLineArgs[i]); + RelativePath2Absolute (szFileName); + + CmdLineVolumeSpecified = TRUE; + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + } + } + + /* Free up the command line arguments */ + while (--nNoCommandLineArgs >= 0) + { + free (lpszCommandLineArgs[nNoCommandLineArgs]); + } + + if (lpszCommandLineArgs) + free (lpszCommandLineArgs); +} + + +static SERVICE_STATUS SystemFavoritesServiceStatus; +static SERVICE_STATUS_HANDLE SystemFavoritesServiceStatusHandle; + +static void SystemFavoritesServiceLogMessage (const wstring &errorMessage, WORD wType) +{ + HANDLE eventSource = RegisterEventSource (NULL, TC_SYSTEM_FAVORITES_SERVICE_NAME); + + if (eventSource) + { + LPCTSTR strings[] = { TC_SYSTEM_FAVORITES_SERVICE_NAME, errorMessage.c_str() }; + ReportEvent (eventSource, wType, 0, 0xC0000000 + wType, NULL, array_capacity (strings), 0, strings, NULL); + + DeregisterEventSource (eventSource); + } +} + +static void SystemFavoritesServiceLogError (const wstring &errorMessage) +{ + SystemFavoritesServiceLogMessage (errorMessage, EVENTLOG_ERROR_TYPE); +} + +static void SystemFavoritesServiceLogWarning (const wstring &warningMessage) +{ + SystemFavoritesServiceLogMessage (warningMessage, EVENTLOG_WARNING_TYPE); +} + +static void SystemFavoritesServiceLogInfo (const wstring &infoMessage) +{ + SystemFavoritesServiceLogMessage (infoMessage, EVENTLOG_INFORMATION_TYPE); +} + + +static void SystemFavoritesServiceSetStatus (DWORD status, DWORD waitHint = 0) +{ + SystemFavoritesServiceStatus.dwCurrentState = status; + SystemFavoritesServiceStatus.dwWaitHint = waitHint; + SystemFavoritesServiceStatus.dwWin32ExitCode = NO_ERROR; + + SetServiceStatus (SystemFavoritesServiceStatusHandle, &SystemFavoritesServiceStatus); +} + + +static VOID WINAPI SystemFavoritesServiceCtrlHandler (DWORD control) +{ + if (control == SERVICE_CONTROL_STOP) + SystemFavoritesServiceSetStatus (SERVICE_STOP_PENDING); + else + SystemFavoritesServiceSetStatus (SystemFavoritesServiceStatus.dwCurrentState); +} + + +static VOID WINAPI SystemFavoritesServiceMain (DWORD argc, LPTSTR *argv) +{ + BOOL status = FALSE; + memset (&SystemFavoritesServiceStatus, 0, sizeof (SystemFavoritesServiceStatus)); + SystemFavoritesServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + + SystemFavoritesServiceStatusHandle = RegisterServiceCtrlHandler (TC_SYSTEM_FAVORITES_SERVICE_NAME, SystemFavoritesServiceCtrlHandler); + if (!SystemFavoritesServiceStatusHandle) + return; + + SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000); + + SystemFavoritesServiceLogInfo (wstring (L"Starting System Favorites mounting process")); + + try + { + status = MountFavoriteVolumes (NULL, TRUE); + } + catch (...) { } + + if (status) + { + SystemFavoritesServiceLogInfo (wstring (L"System Favorites mounting process finished")); + } + else + { + SystemFavoritesServiceLogError (wstring (L"System Favorites mounting process failed.")); + } + + SystemFavoritesServiceSetStatus (SERVICE_RUNNING); + SystemFavoritesServiceSetStatus (SERVICE_STOPPED); +} + + +static BOOL StartSystemFavoritesService () +{ + ServiceMode = TRUE; + Silent = TRUE; + DeviceChangeBroadcastDisabled = TRUE; + bShowDisconnectedNetworkDrives = TRUE; + bHideWaitingDialog = TRUE; + + InitOSVersionInfo(); + + if (DriverAttach() != ERR_SUCCESS) + return FALSE; + + SERVICE_TABLE_ENTRY serviceTable[2]; + serviceTable[0].lpServiceName = TC_SYSTEM_FAVORITES_SERVICE_NAME; + serviceTable[0].lpServiceProc = SystemFavoritesServiceMain; + + serviceTable[1].lpServiceName = NULL; + serviceTable[1].lpServiceProc = NULL; + + BOOL result = StartServiceCtrlDispatcher (serviceTable); + + if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD)) + WipeCache (NULL, TRUE); + + return result; +} + +#ifndef VCEXPANDER +int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpszCommandLine, int nCmdShow) +{ + int argc; + LPWSTR *argv = CommandLineToArgvW (GetCommandLineW(), &argc); + + if (argv && argc == 2 && wstring (TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION) == argv[1]) + return StartSystemFavoritesService() ? 0 : 1; + + int status; + atexit (localcleanup); + SetProcessShutdownParameters (0x100, 0); + + VirtualLock (&VolumePassword, sizeof (VolumePassword)); + VirtualLock (&CmdVolumePassword, sizeof (CmdVolumePassword)); + VirtualLock (&mountOptions, sizeof (mountOptions)); + VirtualLock (&defaultMountOptions, sizeof (defaultMountOptions)); + VirtualLock (&szFileName, sizeof(szFileName)); + VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin)); + + DetectX86Features (); + + try + { + BootEncObj = new BootEncryption (NULL); + } + catch (Exception &e) + { + e.Show (NULL); + } + + if (BootEncObj == NULL) + AbortProcess ("INIT_SYS_ENC"); + + InitApp (hInstance, lpszCommandLine); + + RegisterRedTick(hInstance); + + /* Allocate, dup, then store away the application title */ + lpszTitle = L"VeraCrypt"; + + status = DriverAttach (); + if (status != 0) + { + if (status == ERR_OS_ERROR) + handleWin32Error (NULL, SRC_POS); + else + handleError (NULL, status, SRC_POS); + + AbortProcess ("NODRIVER"); + } + + /* Create the main dialog box */ + DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_MOUNT_DLG), NULL, (DLGPROC) MainDialogProc, + (LPARAM) lpszCommandLine); + + FinalizeApp (); + /* Terminate */ + return 0; +} +#endif + + +BOOL TaskBarIconAdd (HWND hwnd) +{ + NOTIFYICONDATAW tnid; + + ZeroMemory (&tnid, sizeof (tnid)); + + // Only one icon may be created + if (TaskBarIconMutex != NULL) return TRUE; + + TaskBarIconMutex = CreateMutex (NULL, TRUE, L"VeraCryptTaskBarIcon"); + if (TaskBarIconMutex == NULL || GetLastError () == ERROR_ALREADY_EXISTS) + { + if (TaskBarIconMutex != NULL) + { + CloseHandle(TaskBarIconMutex); + TaskBarIconMutex = NULL; + } + return FALSE; + } + + tnid.cbSize = sizeof (NOTIFYICONDATAW); + tnid.hWnd = hwnd; + tnid.uID = IDI_TRUECRYPT_ICON; + tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + tnid.uCallbackMessage = TC_APPMSG_TASKBAR_ICON; + tnid.hIcon = (HICON) LoadImage (hInst, MAKEINTRESOURCE (IDI_TRUECRYPT_ICON), + IMAGE_ICON, + ScreenDPI >= 120 ? 0 : 16, + ScreenDPI >= 120 ? 0 : 16, + (ScreenDPI >= 120 ? LR_DEFAULTSIZE : 0) + | LR_SHARED + | (nCurrentOS != WIN_2000 ? LR_DEFAULTCOLOR : LR_VGACOLOR)); // Windows 2000 cannot display more than 16 fixed colors in notification tray + + StringCbCopyW (tnid.szTip, sizeof(tnid.szTip), L"VeraCrypt"); + + return Shell_NotifyIconW (NIM_ADD, &tnid); +} + + +BOOL TaskBarIconRemove (HWND hwnd) +{ + if (TaskBarIconMutex != NULL) + { + NOTIFYICONDATA tnid; + BOOL res; + + ZeroMemory (&tnid, sizeof (tnid)); + tnid.cbSize = sizeof(NOTIFYICONDATA); + tnid.hWnd = hwnd; + tnid.uID = IDI_TRUECRYPT_ICON; + + res = Shell_NotifyIcon (NIM_DELETE, &tnid); + if (TaskBarIconMutex) + { + CloseHandle (TaskBarIconMutex); + TaskBarIconMutex = NULL; + } + return res; + } + else + return FALSE; +} + + +BOOL TaskBarIconChange (HWND hwnd, int iconId) +{ + if (TaskBarIconMutex == NULL) + return FALSE; + + NOTIFYICONDATA tnid; + + ZeroMemory (&tnid, sizeof (tnid)); + + tnid.cbSize = sizeof (tnid); + tnid.hWnd = hwnd; + tnid.uID = IDI_TRUECRYPT_ICON; + tnid.uFlags = NIF_ICON; + tnid.hIcon = (HICON) LoadImage (hInst, MAKEINTRESOURCE (iconId), + IMAGE_ICON, + ScreenDPI >= 120 ? 0 : 16, + ScreenDPI >= 120 ? 0 : 16, + (ScreenDPI >= 120 ? LR_DEFAULTSIZE : 0) + | LR_SHARED + | (nCurrentOS != WIN_2000 ? LR_DEFAULTCOLOR : LR_VGACOLOR)); // Windows 2000 cannot display more than 16 fixed colors in notification tray + + return Shell_NotifyIcon (NIM_MODIFY, &tnid); +} + + +void DismountIdleVolumes () +{ + static DWORD lastMinTickCount; + static int InactivityTime[26]; + static unsigned __int64 LastRead[26], LastWritten[26]; + static int LastId[26]; + + VOLUME_PROPERTIES_STRUCT prop; + DWORD dwResult; + BOOL bResult; + int i; + + if (GetTickCount() > lastMinTickCount && GetTickCount() - lastMinTickCount < 60 * 1000) + return; + + lastMinTickCount = GetTickCount(); + + for (i = 0; i < 26; i++) + { + if (LastKnownMountList.ulMountedDrives & (1 << i)) + { + memset (&prop, 0, sizeof(prop)); + prop.driveNo = i; + + bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, + sizeof (prop), &prop, sizeof (prop), &dwResult, NULL); + + if ( bResult + && ( (prop.driveNo == i) && prop.uniqueId >= 0 + && prop.ea >= EAGetFirst() && prop.ea <= EAGetCount() + && prop.mode >= FIRST_MODE_OF_OPERATION_ID && prop.mode <= LAST_MODE_OF_OPERATION + && prop.pkcs5 >= FIRST_PRF_ID && prop.pkcs5 <= LAST_PRF_ID + && prop.pkcs5Iterations > 0 + && prop.hiddenVolProtection >= 0 && prop.volFormatVersion >= 0 + && prop.volumePim >= 0 + ) + ) + { + if (LastRead[i] == prop.totalBytesRead + && LastWritten[i] == prop.totalBytesWritten + && LastId[i] == prop.uniqueId) + { + if (++InactivityTime[i] >= MaxVolumeIdleTime) + { + BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, i, 0); + + if (bCloseDismountedWindows && CloseVolumeExplorerWindows (MainDlg, i)) + Sleep (250); + + if (DriverUnmountVolume (MainDlg, i, bForceAutoDismount) == 0) + { + InactivityTime[i] = 0; + BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, i, 0); + + if (bWipeCacheOnAutoDismount) + { + DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + SecurityToken::CloseAllSessions(); + } + } + } + } + else + { + InactivityTime[i] = 0; + LastRead[i] = prop.totalBytesRead; + LastWritten[i] = prop.totalBytesWritten; + LastId[i] = prop.uniqueId; + } + } + } + } +} + +static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, BOOL& lastbExplore, BOOL& userForcedReadOnly, BOOL systemFavorites, BOOL logOnMount, BOOL hotKeyMount, const FavoriteVolume &favoriteVolumeToMount) +{ + BOOL status = TRUE; + int drive; + std::wstring effectiveVolumePath; + drive = towupper (favorite.MountPoint[0]) - L'A'; + + if ((drive < MIN_MOUNTED_VOLUME_DRIVE_NUMBER) || (drive > MAX_MOUNTED_VOLUME_DRIVE_NUMBER)) + { + if (!systemFavorites) + Error ("DRIVE_LETTER_UNAVAILABLE", MainDlg); + else if (ServiceMode && systemFavorites) + { + SystemFavoritesServiceLogError (wstring (L"The drive letter ") + (wchar_t) (drive + L'A') + wstring (L" used by favorite \"") + favorite.Path + L"\" is invalid.\nThis system favorite will not be mounted"); + } + return FALSE; + } + + mountOptions.ReadOnly = favorite.ReadOnly || userForcedReadOnly; + mountOptions.Removable = favorite.Removable; + if (favorite.UseLabelInExplorer && !favorite.Label.empty()) + StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), favorite.Label.c_str()); + else + ZeroMemory (mountOptions.Label, sizeof (mountOptions.Label)); + + if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID))) + { + effectiveVolumePath = FindDeviceByVolumeID (favorite.VolumeID); + } + else + effectiveVolumePath = favorite.Path; + + if (favorite.SystemEncryption) + { + mountOptions.PartitionInInactiveSysEncScope = TRUE; + bPrebootPasswordDlgMode = TRUE; + } + else + { + mountOptions.PartitionInInactiveSysEncScope = FALSE; + bPrebootPasswordDlgMode = FALSE; + } + + if ((LastKnownMountList.ulMountedDrives & (1 << drive)) == 0) + { + MountVolumesAsSystemFavorite = systemFavorites; + + wstring mountPoint = (wchar_t) (drive + L'A') + wstring (L":\\"); + wchar_t prevVolumeAtMountPoint[MAX_PATH] = { 0 }; + + if (systemFavorites) + { + // Partitions of new drives are assigned free drive letters by Windows on boot. Make sure this does not prevent system favorite volumes + // from being mounted. Each partition (using the same drive letter as a system favorite volume) is assigned another free drive letter. + + if (GetVolumeNameForVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint, ARRAYSIZE (prevVolumeAtMountPoint))) + DeleteVolumeMountPoint (mountPoint.c_str()); + else + prevVolumeAtMountPoint[0] = 0; + } + + lastbExplore = bExplore; + + bExplore = (BOOL) favorite.OpenExplorerWindow; + + if (!systemFavorites + && !logOnMount + && !hotKeyMount + && !favoriteVolumeToMount.Path.empty() + && GetAsyncKeyState (VK_CONTROL) < 0) + { + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (CmdVolumePkcs5 == 0) + mountOptions.ProtectedHidVolPkcs5Prf = DefaultVolumePkcs5; + else + mountOptions.ProtectedHidVolPkcs5Prf = CmdVolumePkcs5; + mountOptions.ProtectedHidVolPim = CmdVolumePim; + if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwnd, (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions) == IDCANCEL) + { + status = FALSE; + goto skipMount; + } + } + + BOOL prevReadOnly = mountOptions.ReadOnly; + + if (ServiceMode) + SystemFavoritesServiceLogInfo (wstring (L"Mounting system favorite \"") + effectiveVolumePath + L"\""); + + status = Mount (hwnd, drive, (wchar_t *) effectiveVolumePath.c_str(), favorite.Pim); + + if (ServiceMode) + { + // Update the service status to avoid being killed + SystemFavoritesServiceStatus.dwCheckPoint++; + SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000); + + if (status) + { + SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + effectiveVolumePath + wstring (L"\" mounted successfully as ") + (wchar_t) (drive + L'A') + L":"); + } + else + { + SystemFavoritesServiceLogError (wstring (L"Favorite \"") + effectiveVolumePath + L"\" failed to mount"); + } + } + + if (status && mountOptions.ReadOnly != prevReadOnly) + userForcedReadOnly = mountOptions.ReadOnly; + +skipMount: + bExplore = lastbExplore; + + if (systemFavorites && prevVolumeAtMountPoint[0]) + { + if (status) + { + int freeDrive = GetFirstAvailableDrive(); + if (freeDrive != -1) + { + mountPoint[0] = (wchar_t) (freeDrive + L'A'); + SetVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint); + } + } + else + SetVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint); + } + + LoadDriveLetters (MainDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0); + + MountVolumesAsSystemFavorite = FALSE; + + if (ServiceMode && LastMountedVolumeDirty) + { + DWORD bytesOut; + DeviceIoControl (hDriver, TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY, NULL, 0, NULL, 0, &bytesOut, NULL); + + SystemFavoritesServiceLogError (wstring (L"The filesystem of the volume mounted as ") + (wchar_t) (drive + L'A') + L": was not cleanly dismounted and needs to be checked for errors."); + } + } + else if (!systemFavorites && !favoriteVolumeToMount.Path.empty()) + Error ("DRIVE_LETTER_UNAVAILABLE", MainDlg); + else if (ServiceMode && systemFavorites) + { + SystemFavoritesServiceLogError (wstring (L"The drive letter ") + (wchar_t) (drive + L'A') + wstring (L" used by favorite \"") + effectiveVolumePath + L"\" is already taken.\nThis system favorite will not be mounted"); + } + + return status; +} + + +BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOOL hotKeyMount, const FavoriteVolume &favoriteVolumeToMount) +{ + BOOL bRet = TRUE, status = TRUE; + BOOL lastbExplore; + BOOL userForcedReadOnly = FALSE; + + if (ServiceMode) + { + // in service case, intialize some global variable here. + LastKnownMountList.ulMountedDrives = 0; + LoadDriveLetters (MainDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0); + } + + mountOptions = defaultMountOptions; + + VolumePassword.Length = 0; + MultipleMountOperationInProgress = (favoriteVolumeToMount.Path.empty() || FavoriteMountOnArrivalInProgress); + + vector favorites, skippedSystemFavorites; + + if (systemFavorites) + { + try + { + if (ServiceMode) + SystemFavoritesServiceLogInfo (wstring (L"Reading System Favorites XML file")); + LoadFavoriteVolumes (favorites, true); + + if (ServiceMode) + { + wchar_t szTmp[32]; + StringCbPrintf (szTmp, sizeof(szTmp), L"%d", (int) favorites.size()); + SystemFavoritesServiceLogInfo (wstring (L"Loaded ") + szTmp + wstring (L" favorites from the file")); + + /* correct set the connected state of the system favorites */ + for (vector ::iterator favorite = favorites.begin(); + favorite != favorites.end(); favorite++) + { + if (favorite->UseVolumeID) + { + std::wstring path = FindDeviceByVolumeID (favorite->VolumeID); + if (path.empty ()) + { + favorite->DisconnectedDevice = true; + } + else + { + favorite->DisconnectedDevice = false; + favorite->Path = path; + favorite->UseVolumeID = false; /* force the use of real path to avoid calling FindDeviceByVolumeID again */ + } + } + } + } + } + catch (...) + { + if (ServiceMode) + SystemFavoritesServiceLogError (wstring (L"An error occured while reading System Favorites XML file")); + return false; + } + } + else if (!favoriteVolumeToMount.Path.empty()) + favorites.push_back (favoriteVolumeToMount); + else + favorites = FavoriteVolumes; + + foreach (const FavoriteVolume &favorite, favorites) + { + if (ServiceMode && systemFavorites && favorite.DisconnectedDevice) + { + skippedSystemFavorites.push_back (favorite); + if (favorite.UseVolumeID) + SystemFavoritesServiceLogWarning (wstring (L"Favorite \"ID:") + ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)) + L"\" is disconnected. It will be ignored."); + else + SystemFavoritesServiceLogWarning (wstring (L"Favorite \"") + favorite.Path + L"\" is disconnected. It will be ignored."); + } + + if (favorite.DisconnectedDevice + || (logOnMount && !favorite.MountOnLogOn) + || (hotKeyMount && favorite.DisableHotkeyMount)) + { + continue; + } + + status = MountFavoriteVolumeBase (hwnd, favorite, lastbExplore, userForcedReadOnly, systemFavorites, logOnMount, hotKeyMount, favoriteVolumeToMount); + if (!status) + bRet = FALSE; + } + + if (systemFavorites && ServiceMode && !skippedSystemFavorites.empty()) + { + // Some drives need more time to initialize correctly. + // We retry 4 times after sleeping 5 seconds + int retryCounter = 0; + size_t remainingFavorites = skippedSystemFavorites.size(); + while ((remainingFavorites > 0) && (retryCounter++ < 4)) + { + Sleep (5000); + + SystemFavoritesServiceLogInfo (wstring (L"Trying to mount skipped system favorites")); + + // Update the service status to avoid being killed + SystemFavoritesServiceStatus.dwCheckPoint++; + SystemFavoritesServiceSetStatus (SERVICE_START_PENDING, 120000); + + for (vector ::iterator favorite = skippedSystemFavorites.begin(); + favorite != skippedSystemFavorites.end(); favorite++) + { + if (favorite->DisconnectedDevice) + { + // check if the favorite is here and get its path + wstring resolvedPath; + if (favorite->UseVolumeID) + { + resolvedPath = FindDeviceByVolumeID (favorite->VolumeID); + } + else + resolvedPath = VolumeGuidPathToDevicePath (favorite->Path); + if (!resolvedPath.empty()) + { + favorite->DisconnectedDevice = false; + favorite->VolumePathId = favorite->Path; + favorite->Path = resolvedPath; + + remainingFavorites--; + + // favorite OK. + if (favorite->UseVolumeID) + SystemFavoritesServiceLogInfo (wstring (L"Favorite \"ID:") + ArrayToHexWideString (favorite->VolumeID, sizeof (favorite->VolumeID)) + L"\" is connected. Performing mount."); + else + SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + favorite->VolumePathId + L"\" is connected. Performing mount."); + + status = MountFavoriteVolumeBase (hwnd, *favorite, lastbExplore, userForcedReadOnly, systemFavorites, logOnMount, hotKeyMount, favoriteVolumeToMount); + if (!status) + bRet = FALSE; + } + } + } + + if (remainingFavorites == 0) + SystemFavoritesServiceLogInfo (wstring (L"All skipped system favorites have been processed")); + else + { + wchar_t szTmp[32]; + StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", (int) remainingFavorites); + SystemFavoritesServiceLogWarning (wstring (L"Number of unprocessed system favorites is ") + szTmp); + } + } + } + + MultipleMountOperationInProgress = FALSE; + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + + if (bRet && CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + + return bRet; +} + +void CALLBACK mountFavoriteVolumeCallbackFunction (void *pArg, HWND hwnd) +{ + mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) pArg; + + if (pParam) + { + if (pParam->favoriteVolumeToMount) + MountFavoriteVolumes (hwnd, pParam->systemFavorites, pParam->logOnMount, pParam->hotKeyMount, *(pParam->favoriteVolumeToMount)); + else + MountFavoriteVolumes (hwnd, pParam->systemFavorites, pParam->logOnMount, pParam->hotKeyMount); + + free (pParam); + } + else + MountFavoriteVolumes (hwnd); +} + +void __cdecl mountFavoriteVolumeThreadFunction (void *pArg) +{ + ShowWaitDialog (MainDlg, FALSE, mountFavoriteVolumeCallbackFunction, pArg); +} + +static void SaveDefaultKeyFilesParam (HWND hwnd) +{ + if (defaultKeyFilesParam.FirstKeyFile == NULL) + { + /* No keyfiles selected */ + _wremove (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES)); + } + else + { + FILE *f; + KeyFile *kf = FirstKeyFile; + + f = _wfopen (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES), L"w,ccs=UTF-8"); + if (f == NULL) + { + handleWin32Error (MainDlg, SRC_POS); + return; + } + + XmlWriteHeader (f); + + fputws (L"\n\t", f); + + while (kf != NULL) + { + wchar_t q[TC_MAX_PATH * 2]; + + XmlQuoteTextW (kf->FileName, q, ARRAYSIZE (q)); + fwprintf (f, L"\n\t\t%s", q); + + kf = kf->Next; + } + + fputws (L"\n\t", f); + + XmlWriteFooter (f); + + CheckFileStreamWriteErrors (hwnd, f, TC_APPD_FILENAME_DEFAULT_KEYFILES); + fclose (f); + return; + } +} + + +static void KeyfileDefaultsDlg (HWND hwndDlg) +{ + KeyFilesDlgParam param; + + param.EnableKeyFiles = defaultKeyFilesParam.EnableKeyFiles; + param.FirstKeyFile = defaultKeyFilesParam.FirstKeyFile; + + if (DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg, + (DLGPROC) KeyFilesDlgProc, (LPARAM) ¶m) == IDOK) + { + if (!param.EnableKeyFiles || AskWarnYesNo ("CONFIRM_SAVE_DEFAULT_KEYFILES", hwndDlg) == IDYES) + { + KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); + defaultKeyFilesParam.EnableKeyFiles = param.EnableKeyFiles; + defaultKeyFilesParam.FirstKeyFile = param.FirstKeyFile; + + RestoreDefaultKeyFilesParam (); + SaveDefaultKeyFilesParam (hwndDlg); + } + } +} + + +static void HandleHotKey (HWND hwndDlg, WPARAM wParam) +{ + DWORD dwResult; + BOOL success = TRUE; + + switch (wParam) + { + case HK_AUTOMOUNT_DEVICES: + MountAllDevices (hwndDlg, TRUE); + break; + + case HK_DISMOUNT_ALL: + case HK_DISMOUNT_ALL_AND_WIPE: + + if (wParam == HK_DISMOUNT_ALL_AND_WIPE) + WipeCache (hwndDlg, TRUE); + + if (DismountAll (hwndDlg, FALSE, TRUE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY)) + { + if (bDisplayBalloonOnSuccessfulHkDismount) + InfoBalloon ("SUCCESSFULLY_DISMOUNTED", (wParam == HK_DISMOUNT_ALL_AND_WIPE ? "VOLUMES_DISMOUNTED_CACHE_WIPED" : "MOUNTED_VOLUMES_DISMOUNTED"), hwndDlg); + + if (bPlaySoundOnSuccessfulHkDismount) + MessageBeep (0xFFFFFFFF); + } + + break; + + case HK_WIPE_CACHE: + WipeCache (hwndDlg, FALSE); + + break; + + case HK_FORCE_DISMOUNT_ALL_AND_WIPE: + success = DismountAll (hwndDlg, TRUE, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); + success &= DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + if (success) + { + if (bDisplayBalloonOnSuccessfulHkDismount) + InfoBalloon ("SUCCESSFULLY_DISMOUNTED", "VOLUMES_DISMOUNTED_CACHE_WIPED", hwndDlg); + + if (bPlaySoundOnSuccessfulHkDismount) + MessageBeep (0xFFFFFFFF); + } + break; + + case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT: + success = DismountAll (hwndDlg, TRUE, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY); + success &= DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + if (success) + { + if (bDisplayBalloonOnSuccessfulHkDismount) + InfoBalloon ("SUCCESSFULLY_DISMOUNTED", "VOLUMES_DISMOUNTED_CACHE_WIPED", hwndDlg); + + if (bPlaySoundOnSuccessfulHkDismount) + MessageBeep (0xFFFFFFFF); + } + TaskBarIconRemove (hwndDlg); + UnregisterWtsNotification(hwndDlg); + EndMainDlg (hwndDlg); + break; + + case HK_MOUNT_FAVORITE_VOLUMES: + { + mountFavoriteVolumeThreadParam* pParam = (mountFavoriteVolumeThreadParam*) calloc(1, sizeof(mountFavoriteVolumeThreadParam)); + pParam->systemFavorites = FALSE; + pParam->logOnMount = FALSE; + pParam->hotKeyMount = TRUE; + pParam->favoriteVolumeToMount = NULL; + + _beginthread(mountFavoriteVolumeThreadFunction, 0, pParam); + } + break; + + case HK_SHOW_HIDE_MAIN_WINDOW: + ChangeMainWindowVisibility (); + break; + + case HK_CLOSE_SECURITY_TOKEN_SESSIONS: + SecurityToken::CloseAllSessions(); + + InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED", hwndDlg); + + break; + } +} + + +void ChangeMainWindowVisibility () +{ + MainWindowHidden = !MainWindowHidden; + + if (!MainWindowHidden) + SetForegroundWindow (MainDlg); + + ShowWindow (MainDlg, !MainWindowHidden ? SW_SHOW : SW_HIDE); + + if (!MainWindowHidden) + ShowWindow (MainDlg, SW_RESTORE); +} + + +int BackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, const wchar_t *lpszVolume) +{ + int nStatus = ERR_OS_ERROR; + wchar_t szTmp[4096]; + int fBackup = -1; + OpenVolumeContext volume; + OpenVolumeContext hiddenVolume; + Password hiddenVolPassword; + int hiddenVolPkcs5 = 0, hiddenVolPim = 0; + byte temporaryKey[MASTER_KEYDATA_SIZE]; + byte originalK2[MASTER_KEYDATA_SIZE]; + int EffectiveVolumePkcs5 = CmdVolumePkcs5; + int EffectiveVolumePim = CmdVolumePim; + + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (EffectiveVolumePkcs5 == 0) + EffectiveVolumePkcs5 = DefaultVolumePkcs5; + + if (!lpszVolume) + { + nStatus = ERR_OUTOFMEMORY; + handleError (hwndDlg, nStatus, SRC_POS); + return nStatus; + } + + volume.VolumeIsOpen = FALSE; + hiddenVolume.VolumeIsOpen = FALSE; + + switch (IsSystemDevicePath (lpszVolume, hwndDlg, TRUE)) + { + case 1: + case 2: + if (AskErrNoYes ("BACKUP_HEADER_NOT_FOR_SYS_DEVICE", hwndDlg) == IDYES) + CreateRescueDisk (hwndDlg); + + return 0; + } + + if (IsMountedVolume (lpszVolume)) + { + Warning ("DISMOUNT_FIRST", hwndDlg); + goto ret; + } + + if (!VolumePathExists (lpszVolume)) + { + handleWin32Error (hwndDlg, SRC_POS); + goto ret; + } + + Info ("EXTERNAL_VOL_HEADER_BAK_FIRST_INFO", hwndDlg); + + + WaitCursor(); + + // Open both types of volumes + for (int type = TC_VOLUME_TYPE_NORMAL; type <= TC_VOLUME_TYPE_HIDDEN; ++type) + { + OpenVolumeContext *askVol = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolume : &volume); + Password *askPassword = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolPassword : &VolumePassword); + int* askPkcs5 = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolPkcs5 : &VolumePkcs5); + int* askPim = (type == TC_VOLUME_TYPE_HIDDEN ? &hiddenVolPim : &VolumePim); + + while (TRUE) + { + int GuiPkcs5 = ((EffectiveVolumePkcs5 > 0) && (*askPkcs5 == 0))? EffectiveVolumePkcs5 : *askPkcs5; + int GuiPim = ((EffectiveVolumePim > 0) && (*askPim <= 0))? EffectiveVolumePim : *askPim; + if (!AskVolumePassword (hwndDlg, askPassword, &GuiPkcs5, &GuiPim, &VolumeTrueCryptMode, type == TC_VOLUME_TYPE_HIDDEN ? "ENTER_HIDDEN_VOL_PASSWORD" : "ENTER_NORMAL_VOL_PASSWORD", FALSE)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + else + { + *askPkcs5 = GuiPkcs5; + *askPim = GuiPim; + burn (&GuiPkcs5, sizeof (GuiPkcs5)); + burn (&GuiPim, sizeof (GuiPim)); + } + + WaitCursor(); + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (hwndDlg, askPassword, FirstKeyFile, lpszVolume); + + nStatus = OpenVolume (askVol, lpszVolume, askPassword, *askPkcs5, *askPim, VolumeTrueCryptMode, FALSE, bPreserveTimestamp, FALSE); + + NormalCursor(); + + if (nStatus == ERR_SUCCESS) + { + if ((type == TC_VOLUME_TYPE_NORMAL && askVol->CryptoInfo->hiddenVolume) + || (type == TC_VOLUME_TYPE_HIDDEN && !askVol->CryptoInfo->hiddenVolume)) + { + CloseVolume (askVol); + handleError (hwndDlg, ERR_PASSWORD_WRONG, SRC_POS); + continue; + } + + RandSetHashFunction (askVol->CryptoInfo->pkcs5); + + if (type == TC_VOLUME_TYPE_NORMAL) + { + // Ask the user if there is a hidden volume + char *volTypeChoices[] = {0, "DOES_VOLUME_CONTAIN_HIDDEN", "VOLUME_CONTAINS_HIDDEN", "VOLUME_DOES_NOT_CONTAIN_HIDDEN", "IDCANCEL", 0}; + switch (AskMultiChoice ((void **) volTypeChoices, FALSE, hwndDlg)) + { + case 1: + break; + case 2: + goto noHidden; + + default: + nStatus = ERR_SUCCESS; + goto ret; + } + } + + break; + } + + if (nStatus != ERR_PASSWORD_WRONG) + goto error; + + handleError (hwndDlg, nStatus, SRC_POS); + } + } +noHidden: + + if (hiddenVolume.VolumeIsOpen && volume.CryptoInfo->LegacyVolume != hiddenVolume.CryptoInfo->LegacyVolume) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CONFIRM_VOL_HEADER_BAK"), lpszVolume); + + if (bRequireConfirmation + && (MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONQUESTION|MB_DEFBUTTON1) == IDNO)) + goto ret; + + /* Select backup file */ + if (!BrowseFiles (hwndDlg, "OPEN_TITLE", szFileName, bHistory, TRUE, NULL)) + goto ret; + + /* Conceive the backup file */ + if ((fBackup = _wopen(szFileName, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) == -1) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + // Backup headers + + byte backup[TC_VOLUME_HEADER_GROUP_SIZE]; + + bool legacyVolume = volume.CryptoInfo->LegacyVolume ? true : false; + int backupFileSize = legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY * 2 : TC_VOLUME_HEADER_GROUP_SIZE; + + // Fill backup buffer with random data + memcpy (originalK2, volume.CryptoInfo->k2, sizeof (volume.CryptoInfo->k2)); + + if (Randinit() != ERR_SUCCESS) + { + if (CryptoAPILastError == ERROR_SUCCESS) + nStatus = ERR_RAND_INIT_FAILED; + else + nStatus = ERR_CAPI_INIT_FAILED; + goto error; + } + + /* force the display of the random enriching dialog */ + SetRandomPoolEnrichedByUserStatus (FALSE); + + NormalCursor(); + UserEnrichRandomPool (hwndDlg); + WaitCursor(); + + // Temporary keys + if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (volume.CryptoInfo->ea), TRUE) + || !RandgetBytes (hwndDlg, volume.CryptoInfo->k2, sizeof (volume.CryptoInfo->k2), FALSE)) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + if (EAInit (volume.CryptoInfo->ea, temporaryKey, volume.CryptoInfo->ks) != ERR_SUCCESS || !EAInitMode (volume.CryptoInfo)) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + EncryptBuffer (backup, backupFileSize, volume.CryptoInfo); + + memcpy (volume.CryptoInfo->k2, originalK2, sizeof (volume.CryptoInfo->k2)); + if (EAInit (volume.CryptoInfo->ea, volume.CryptoInfo->master_keydata, volume.CryptoInfo->ks) != ERR_SUCCESS || !EAInitMode (volume.CryptoInfo)) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + // Store header encrypted with a new key + nStatus = ReEncryptVolumeHeader (hwndDlg, (char *) backup, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); + if (nStatus != ERR_SUCCESS) + goto error; + + if (hiddenVolume.VolumeIsOpen) + { + nStatus = ReEncryptVolumeHeader (hwndDlg, (char *) backup + (legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE), + FALSE, hiddenVolume.CryptoInfo, &hiddenVolPassword, hiddenVolPim, FALSE); + + if (nStatus != ERR_SUCCESS) + goto error; + } + + if (_write (fBackup, backup, backupFileSize) == -1) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + /* Backup has been successfully created */ + Warning("VOL_HEADER_BACKED_UP", hwndDlg); + +ret: + nStatus = ERR_SUCCESS; + +error: + DWORD dwError = GetLastError (); + + CloseVolume (&volume); + CloseVolume (&hiddenVolume); + + if (fBackup != -1) + _close (fBackup); + + SetLastError (dwError); + if (nStatus != 0) + handleError (hwndDlg, nStatus, SRC_POS); + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + burn (&hiddenVolPassword, sizeof (hiddenVolPassword)); + burn (temporaryKey, sizeof (temporaryKey)); + burn (originalK2, sizeof (originalK2)); + + RestoreDefaultKeyFilesParam(); + RandStop (FALSE); + NormalCursor(); + + return nStatus; +} + + +int RestoreVolumeHeader (HWND hwndDlg, const wchar_t *lpszVolume) +{ + int nDosLinkCreated = -1, nStatus = ERR_OS_ERROR; + wchar_t szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; + wchar_t szFileName[TC_MAX_PATH]; + wchar_t szDosDevice[TC_MAX_PATH]; + void *dev = INVALID_HANDLE_VALUE; + DWORD dwError; + BOOL bDevice; + unsigned __int64 hostSize = 0; + FILETIME ftCreationTime; + FILETIME ftLastWriteTime; + FILETIME ftLastAccessTime; + wchar_t szTmp[4096]; + BOOL bTimeStampValid = FALSE; + HANDLE fBackup = INVALID_HANDLE_VALUE; + LARGE_INTEGER headerOffset; + CRYPTO_INFO *restoredCryptoInfo = NULL; + int EffectiveVolumePkcs5 = CmdVolumePkcs5; + int EffectiveVolumePim = CmdVolumePim; + + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (EffectiveVolumePkcs5 == 0) + EffectiveVolumePkcs5 = DefaultVolumePkcs5; + + if (!lpszVolume) + { + nStatus = ERR_OUTOFMEMORY; + handleError (hwndDlg, nStatus, SRC_POS); + return nStatus; + } + + switch (IsSystemDevicePath (lpszVolume, hwndDlg, TRUE)) + { + case 1: + case 2: + if (AskErrNoYes ("RESTORE_HEADER_NOT_FOR_SYS_DEVICE", hwndDlg) == IDYES) + CreateRescueDisk (hwndDlg); + + return 0; + + case -1: + // In some environments (such as PE), the system volume is not located on a hard drive. + // Therefore, we must interpret this return code as "Not a system device path" (otherwise, + // it would not be possible to restore headers on non-system devices in such environments). + // Note that this is rather safe, because bReliableRequired is set to TRUE. + + // NOP + break; + } + + if (IsMountedVolume (lpszVolume)) + { + Warning ("DISMOUNT_FIRST", hwndDlg); + return 0; + } + + if (!VolumePathExists (lpszVolume)) + { + handleWin32Error (hwndDlg, SRC_POS); + return 0; + } + + BOOL restoreInternalBackup; + + // Ask the user to select the type of backup (internal/external) + char *volTypeChoices[] = {0, "HEADER_RESTORE_EXTERNAL_INTERNAL", "HEADER_RESTORE_INTERNAL", "HEADER_RESTORE_EXTERNAL", "IDCANCEL", 0}; + switch (AskMultiChoice ((void **) volTypeChoices, FALSE, hwndDlg)) + { + case 1: + restoreInternalBackup = TRUE; + break; + case 2: + restoreInternalBackup = FALSE; + break; + default: + return 0; + } + + OpenVolumeContext volume; + volume.VolumeIsOpen = FALSE; + + /* force the display of the random enriching dialog */ + SetRandomPoolEnrichedByUserStatus (FALSE); + + WaitCursor(); + + if (restoreInternalBackup) + { + // Restore header from the internal backup + + // Open the volume using backup header + while (TRUE) + { + int GuiPkcs5 = ((EffectiveVolumePkcs5 > 0) && (VolumePkcs5 == 0))? EffectiveVolumePkcs5 : VolumePkcs5; + int GuiPim = ((EffectiveVolumePim > 0) && (VolumePim <= 0))? EffectiveVolumePim : VolumePim; + StringCbCopyW (PasswordDlgVolume, sizeof(PasswordDlgVolume), lpszVolume); + if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &VolumeTrueCryptMode, NULL, FALSE)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + else + { + VolumePkcs5 = GuiPkcs5; + VolumePim = GuiPim; + burn (&GuiPkcs5, sizeof (GuiPkcs5)); + burn (&GuiPim, sizeof (GuiPim)); + } + + WaitCursor(); + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, lpszVolume); + + nStatus = OpenVolume (&volume, lpszVolume, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode,TRUE, bPreserveTimestamp, TRUE); + + NormalCursor(); + + if (nStatus == ERR_SUCCESS) + break; + + if (nStatus != ERR_PASSWORD_WRONG) + goto error; + + handleError (hwndDlg, nStatus, SRC_POS); + } + + if (volume.CryptoInfo->LegacyVolume) + { + Error ("VOLUME_HAS_NO_BACKUP_HEADER", hwndDlg); + nStatus = ERROR_SUCCESS; + goto error; + } + + // Create a new header with a new salt + char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + + nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); + if (nStatus != 0) + goto error; + + headerOffset.QuadPart = volume.CryptoInfo->hiddenVolume ? TC_HIDDEN_VOLUME_HEADER_OFFSET : TC_VOLUME_HEADER_OFFSET; + if (!SetFilePointerEx (volume.HostFileHandle, headerOffset, NULL, FILE_BEGIN)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + if (!WriteEffectiveVolumeHeader (volume.IsDevice, volume.HostFileHandle, (byte *) buffer)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + } + else + { + // Restore header from an external backup + + StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CONFIRM_VOL_HEADER_RESTORE"), lpszVolume); + + if (MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2) == IDNO) + { + nStatus = ERR_SUCCESS; + goto ret; + } + + /* Select backup file */ + if (!BrowseFiles (hwndDlg, "OPEN_TITLE", szFileName, bHistory, FALSE, NULL)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + + /* Open the backup file */ + fBackup = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (fBackup == INVALID_HANDLE_VALUE) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + // Determine size of the backup file + LARGE_INTEGER backupSize; + if (!GetFileSizeEx (fBackup, &backupSize)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), lpszVolume, &bDevice); + + if (bDevice == FALSE) + StringCbCopyW (szCFDevice, sizeof(szCFDevice), szDiskFile); + else + { + nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, sizeof(szDosDevice),szCFDevice, sizeof(szCFDevice),FALSE); + if (nDosLinkCreated != 0) + goto error; + } + + // Open the volume + dev = CreateFile (szCFDevice, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + + if (dev == INVALID_HANDLE_VALUE) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + // Determine volume host size + if (bDevice) + { + PARTITION_INFORMATION diskInfo; + DWORD dwResult; + BOOL bResult; + + bResult = GetPartitionInfo (lpszVolume, &diskInfo); + + if (bResult) + { + hostSize = diskInfo.PartitionLength.QuadPart; + } + else + { + DISK_GEOMETRY driveInfo; + + bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, + &driveInfo, sizeof (driveInfo), &dwResult, NULL); + + if (!bResult) + goto error; + + hostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector * + driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder; + } + + if (hostSize == 0) + { + nStatus = ERR_VOL_SIZE_WRONG; + goto error; + } + } + else + { + LARGE_INTEGER fileSize; + if (!GetFileSizeEx (dev, &fileSize)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + hostSize = fileSize.QuadPart; + } + + if (!bDevice && bPreserveTimestamp) + { + /* Remember the container modification/creation date and time. */ + + if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0) + bTimeStampValid = FALSE; + else + bTimeStampValid = TRUE; + } + + /* Read the volume header from the backup file */ + char buffer[TC_VOLUME_HEADER_GROUP_SIZE]; + + DWORD bytesRead; + if (!ReadFile (fBackup, buffer, sizeof (buffer), &bytesRead, NULL)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + if (bytesRead != backupSize.QuadPart) + { + nStatus = ERR_VOL_SIZE_WRONG; + goto error; + } + + LARGE_INTEGER headerOffset; + LARGE_INTEGER headerBackupOffset; + bool legacyBackup; + int headerOffsetBackupFile; + + // Determine the format of the backup file + switch (backupSize.QuadPart) + { + case TC_VOLUME_HEADER_GROUP_SIZE: + legacyBackup = false; + break; + + case TC_VOLUME_HEADER_SIZE_LEGACY * 2: + legacyBackup = true; + break; + + default: + Error ("HEADER_BACKUP_SIZE_INCORRECT", hwndDlg); + nStatus = ERR_SUCCESS; + goto error; + } + + // Open the header + while (TRUE) + { + int GuiPkcs5 = ((EffectiveVolumePkcs5 > 0) && (VolumePkcs5 == 0))? EffectiveVolumePkcs5 : VolumePkcs5; + int GuiPim = ((EffectiveVolumePim > 0) && (VolumePim <= 0))? EffectiveVolumePim : VolumePim; + if (!AskVolumePassword (hwndDlg, &VolumePassword, &GuiPkcs5, &GuiPim, &VolumeTrueCryptMode, "ENTER_HEADER_BACKUP_PASSWORD", FALSE)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + else + { + VolumePkcs5 = GuiPkcs5; + VolumePim = GuiPim; + burn (&GuiPkcs5, sizeof (GuiPkcs5)); + burn (&GuiPim, sizeof (GuiPim)); + } + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, bDevice? NULL : lpszVolume); + + // Decrypt volume header + headerOffsetBackupFile = 0; + for (int type = TC_VOLUME_TYPE_NORMAL; type <= TC_VOLUME_TYPE_HIDDEN; ++type) + { + if (type == TC_VOLUME_TYPE_HIDDEN) + headerOffsetBackupFile += (legacyBackup ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE); + + nStatus = ReadVolumeHeader (FALSE, buffer + headerOffsetBackupFile, &VolumePassword, VolumePkcs5, VolumePim, VolumeTrueCryptMode, &restoredCryptoInfo, NULL); + if (nStatus == ERR_SUCCESS) + break; + } + + if (nStatus == ERR_SUCCESS) + break; + + if (nStatus != ERR_PASSWORD_WRONG) + goto error; + + handleError (hwndDlg, nStatus, SRC_POS); + } + + BOOL hiddenVol = restoredCryptoInfo->hiddenVolume; + + if (legacyBackup) + { + headerOffset.QuadPart = hiddenVol ? hostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY : TC_VOLUME_HEADER_OFFSET; + } + else + { + headerOffset.QuadPart = hiddenVol ? TC_HIDDEN_VOLUME_HEADER_OFFSET : TC_VOLUME_HEADER_OFFSET; + headerBackupOffset.QuadPart = hiddenVol ? hostSize - TC_VOLUME_HEADER_SIZE : hostSize - TC_VOLUME_HEADER_GROUP_SIZE; + } + + WaitCursor(); + + // Restore header encrypted with a new key + nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, restoredCryptoInfo, &VolumePassword, VolumePim, FALSE); + if (nStatus != ERR_SUCCESS) + goto error; + + if (!SetFilePointerEx (dev, headerOffset, NULL, FILE_BEGIN)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + if (!WriteEffectiveVolumeHeader (bDevice, dev, (byte *) buffer)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + if (!restoredCryptoInfo->LegacyVolume) + { + // Restore backup header encrypted with a new key + nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, restoredCryptoInfo, &VolumePassword, VolumePim, FALSE); + if (nStatus != ERR_SUCCESS) + goto error; + + if (!SetFilePointerEx (dev, headerBackupOffset, NULL, FILE_BEGIN)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + + if (!WriteEffectiveVolumeHeader (bDevice, dev, (byte *) buffer)) + { + nStatus = ERR_OS_ERROR; + goto error; + } + } + } + + + /* Volume header has been successfully restored */ + + Info("VOL_HEADER_RESTORED", hwndDlg); +ret: + nStatus = ERR_SUCCESS; + +error: + dwError = GetLastError (); + NormalCursor(); + + if (restoreInternalBackup) + { + CloseVolume (&volume); + } + else + { + if (restoredCryptoInfo) + crypto_close (restoredCryptoInfo); + + if (bTimeStampValid) + SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime); + + if (dev != INVALID_HANDLE_VALUE) + CloseHandle (dev); + + if (fBackup != INVALID_HANDLE_VALUE) + CloseHandle (fBackup); + + if (nDosLinkCreated == 0) + RemoveFakeDosName (szDiskFile, szDosDevice); + } + + SetLastError (dwError); + if (nStatus != 0) + handleError (hwndDlg, nStatus, SRC_POS); + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&VolumePkcs5, sizeof (VolumePkcs5)); + burn (&VolumePim, sizeof (VolumePim)); + burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode)); + RestoreDefaultKeyFilesParam(); + RandStop (FALSE); + NormalCursor(); + + return nStatus; +} + + +void SetDriverConfigurationFlag (uint32 flag, BOOL state) +{ + BootEncObj->SetDriverConfigurationFlag (flag, state ? true : false); +} + + +static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + LocalizeDialog (hwndDlg, "IDD_PERFORMANCE_SETTINGS"); + + uint32 driverConfig = ReadDriverConfigurationFlags(); + CheckDlgButton (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION, (driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? BST_UNCHECKED : BST_CHECKED); + CheckDlgButton (hwndDlg, IDC_ENABLE_EXTENDED_IOCTL_SUPPORT, (driverConfig & TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL) ? BST_CHECKED : BST_UNCHECKED); + + SYSTEM_INFO sysInfo; + GetSystemInfo (&sysInfo); + + HWND freeCpuCombo = GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT); + uint32 encryptionFreeCpuCount = ReadEncryptionThreadPoolFreeCpuCountLimit(); + + if (encryptionFreeCpuCount > sysInfo.dwNumberOfProcessors - 1) + encryptionFreeCpuCount = sysInfo.dwNumberOfProcessors - 1; + + for (uint32 i = 1; i < sysInfo.dwNumberOfProcessors; ++i) + { + wstringstream s; + s << i; + AddComboPair (freeCpuCombo, s.str().c_str(), i); + } + + if (sysInfo.dwNumberOfProcessors < 2 || encryptionFreeCpuCount == 0) + EnableWindow (freeCpuCombo, FALSE); + + if (sysInfo.dwNumberOfProcessors < 2) + EnableWindow (GetDlgItem (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL), FALSE); + + if (encryptionFreeCpuCount != 0) + { + CheckDlgButton (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL, BST_CHECKED); + SendMessage (freeCpuCombo, CB_SETCURSEL, encryptionFreeCpuCount - 1, 0); + } + + SetWindowTextW (GetDlgItem (hwndDlg, IDT_LIMIT_ENC_THREAD_POOL_NOTE), GetString("LIMIT_ENC_THREAD_POOL_NOTE")); + + SetDlgItemTextW (hwndDlg, IDC_HW_AES_SUPPORTED_BY_CPU, (wstring (L" ") + (GetString (is_aes_hw_cpu_supported() ? "UISTR_YES" : "UISTR_NO"))).c_str()); + + ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_HW_ACCELERATION); + ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION); + } + return 0; + + case WM_COMMAND: + + switch (lw) + { + case IDCANCEL: + EndDialog (hwndDlg, lw); + return 1; + + case IDOK: + { + if (IsNonInstallMode()) + { + Error ("FEATURE_REQUIRES_INSTALLATION", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + BOOL disableHW = !IsDlgButtonChecked (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION); + BOOL enableExtendedIOCTL = IsDlgButtonChecked (hwndDlg, IDC_ENABLE_EXTENDED_IOCTL_SUPPORT); + + try + { + VOLUME_PROPERTIES_STRUCT prop; + try + { + BootEncStatus = BootEncObj->GetStatus(); + BootEncObj->GetVolumeProperties (&prop); + } + catch (...) + { + BootEncStatus.DriveMounted = false; + } + + if (BootEncStatus.DriveMounted) + { + byte userConfig; + string customUserMessage; + uint16 bootLoaderVersion; + + BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig, &customUserMessage, &bootLoaderVersion); + + if (bootLoaderVersion != VERSION_NUM) + Warning ("BOOT_LOADER_VERSION_INCORRECT_PREFERENCES", hwndDlg); + + if (disableHW) + userConfig |= TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION; + else + userConfig &= ~TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION; + + BootEncObj->WriteBootSectorUserConfig (userConfig, customUserMessage, prop.volumePim); + } + + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION, disableHW); + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL, enableExtendedIOCTL); + + DWORD bytesReturned; + if (!DeviceIoControl (hDriver, TC_IOCTL_REREAD_DRIVER_CONFIG, NULL, 0, NULL, 0, &bytesReturned, NULL)) + handleWin32Error (hwndDlg, SRC_POS); + + EnableHwEncryption (!disableHW); + + uint32 cpuFreeCount = 0; + if (IsDlgButtonChecked (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL)) + { + LRESULT cpuFreeItem = SendMessage (GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT), CB_GETCURSEL, 0, 0); + if (cpuFreeItem != CB_ERR) + cpuFreeCount = (uint32) (cpuFreeItem + 1); + } + + if (ReadEncryptionThreadPoolFreeCpuCountLimit() != cpuFreeCount) + { + BootEncObj->WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME, cpuFreeCount); + Warning ("SETTING_REQUIRES_REBOOT", hwndDlg); + } + + EndDialog (hwndDlg, lw); + return 1; + } + catch (Exception &e) + { + e.Show (hwndDlg); + } + } + return 1; + + case IDC_ENABLE_HARDWARE_ENCRYPTION: + if (!IsDlgButtonChecked (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION) + && AskWarnYesNo ("CONFIRM_SETTING_DEGRADES_PERFORMANCE", hwndDlg) == IDNO) + { + CheckDlgButton (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION, BST_CHECKED); + } + return 1; + + case IDC_LIMIT_ENC_THREAD_POOL: + if (IsDlgButtonChecked (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL) + && AskWarnYesNo ("CONFIRM_SETTING_DEGRADES_PERFORMANCE", hwndDlg) == IDNO) + { + CheckDlgButton (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL, BST_UNCHECKED); + } + else + { + SendMessage (GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT), CB_SETCURSEL, 0, 0); + Warning ("SETTING_REQUIRES_REBOOT", hwndDlg); // Warn the user before he thinks about benchmarking + } + + EnableWindow (GetDlgItem (hwndDlg, IDC_ENCRYPTION_FREE_CPU_COUNT), IsDlgButtonChecked (hwndDlg, IDC_LIMIT_ENC_THREAD_POOL)); + return 1; + + case IDC_BENCHMARK: + Benchmark (hwndDlg); + return 1; + + case IDC_MORE_INFO_ON_HW_ACCELERATION: + Applink ("hwacceleration", TRUE, ""); + return 1; + + case IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION: + Applink ("parallelization", TRUE, ""); + return 1; + } + + return 0; + } + + return 0; +} + + +static BOOL CALLBACK SecurityTokenPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + LocalizeDialog (hwndDlg, "IDD_TOKEN_PREFERENCES"); + SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, SecurityTokenLibraryPath); + CheckDlgButton (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT, CloseSecurityTokenSessionsAfterMount ? BST_CHECKED : BST_UNCHECKED); + + SetWindowTextW (GetDlgItem (hwndDlg, IDT_PKCS11_LIB_HELP), GetString("PKCS11_LIB_LOCATION_HELP")); + + return 0; + + case WM_COMMAND: + + switch (lw) + { + case IDCANCEL: + EndDialog (hwndDlg, lw); + return 1; + + case IDOK: + { + wchar_t securityTokenLibraryPath[MAX_PATH]; + GetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, securityTokenLibraryPath, ARRAYSIZE (securityTokenLibraryPath)); + + if (securityTokenLibraryPath[0] == 0) + { + try + { + SecurityToken::CloseLibrary(); + } + catch (...) { } + + SecurityTokenLibraryPath[0] = 0; + } + else + { + wchar_t prevSecurityTokenLibraryPath[MAX_PATH]; + StringCbCopyW (prevSecurityTokenLibraryPath, sizeof(prevSecurityTokenLibraryPath), SecurityTokenLibraryPath); + StringCbCopyW (SecurityTokenLibraryPath, sizeof(SecurityTokenLibraryPath), securityTokenLibraryPath); + + if (!InitSecurityTokenLibrary(hwndDlg)) + { + StringCbCopyW (SecurityTokenLibraryPath, sizeof(SecurityTokenLibraryPath), prevSecurityTokenLibraryPath); + return 1; + } + } + + CloseSecurityTokenSessionsAfterMount = (IsDlgButtonChecked (hwndDlg, IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT) == BST_CHECKED); + + WaitCursor (); + SaveSettings (hwndDlg); + NormalCursor (); + + EndDialog (hwndDlg, lw); + return 1; + } + + case IDC_AUTO_DETECT_PKCS11_MODULE: + { + wchar_t systemDir[MAX_PATH]; + GetSystemDirectory (systemDir, ARRAYSIZE (systemDir)); + WIN32_FIND_DATA findData; + bool found = false; + + WaitCursor(); + + HANDLE find = FindFirstFile ((wstring (systemDir) + L"\\*.dll").c_str(), &findData); + while (!found && find != INVALID_HANDLE_VALUE) + { + wstring dllPathname = wstring (systemDir) + L"\\" + findData.cFileName; + DWORD fileSize; + + char *file = LoadFile (dllPathname.c_str(), &fileSize); + if (file) + { + const char *functionName = "C_GetFunctionList"; + size_t strLen = strlen (functionName); + + if (fileSize > strLen) + { + for (size_t i = 0; i < fileSize - strLen; ++i) + { + if (memcmp (file + i, functionName, strLen) == 0) + { + HMODULE module = LoadLibrary (dllPathname.c_str()); + if (module) + { + if (GetProcAddress (module, functionName)) + { + SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, dllPathname.c_str()); + found = true; + + FreeLibrary (module); + break; + } + + FreeLibrary (module); + } + } + } + } + + free (file); + } + + if (!FindNextFile (find, &findData)) + break; + } + + if (find != INVALID_HANDLE_VALUE) + FindClose (find); + + NormalCursor(); + + if (!found) + Warning ("PKCS11_MODULE_AUTO_DETECTION_FAILED", hwndDlg); + + return 1; + } + + case IDC_SELECT_PKCS11_MODULE: + { + wchar_t securityTokenLibraryPath[MAX_PATH]; + wchar_t systemDir[MAX_PATH]; + wchar_t browseFilter[1024]; + + Info ("SELECT_PKCS11_MODULE_HELP", hwndDlg); + + StringCbPrintfW (browseFilter, sizeof(browseFilter), L"%ls (*.dll)%c*.dll%c%c", GetString ("DLL_FILES"), 0, 0, 0); + GetSystemDirectory (systemDir, ARRAYSIZE (systemDir)); + + if (BrowseFilesInDir (hwndDlg, "SELECT_PKCS11_MODULE", systemDir, securityTokenLibraryPath, TRUE, FALSE, browseFilter)) + SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, securityTokenLibraryPath); + return 1; + } + } + return 0; + } + + return 0; +} + +static BOOL CALLBACK DefaultMountParametersDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + LocalizeDialog (hwndDlg, "IDD_DEFAULT_MOUNT_PARAMETERS"); + + SendMessage (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), BM_SETCHECK, + DefaultVolumeTrueCryptMode ? BST_CHECKED:BST_UNCHECKED, 0); + + /* Populate the PRF algorithms list */ + int i, nIndex, defaultPrfIndex = 0; + HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); + SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); + + nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION")); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0); + + for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++) + { + nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i)); + SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i); + if (DefaultVolumePkcs5 && (DefaultVolumePkcs5 == i)) + defaultPrfIndex = nIndex; + } + + /* make autodetection the default unless a specific PRF was specified in the command line */ + SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0); + + return 0; + } + + case WM_COMMAND: + + switch (lw) + { + case IDCANCEL: + EndDialog (hwndDlg, lw); + return 1; + + case IDOK: + { + int pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); + BOOL truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE); + /* SHA-256 is not supported by TrueCrypt */ + if ( (truecryptMode) + && (pkcs5 == SHA256) + ) + { + Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg); + } + else + { + WaitCursor (); + DefaultVolumeTrueCryptMode = truecryptMode; + DefaultVolumePkcs5 = pkcs5; + + SaveSettings (hwndDlg); + + NormalCursor (); + EndDialog (hwndDlg, lw); + } + return 1; + } + + } + return 0; + } + + return 0; +} + +void SecurityTokenPreferencesDialog (HWND hwndDlg) +{ + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PREFERENCES), hwndDlg, (DLGPROC) SecurityTokenPreferencesDlgProc, 0); +} + + +static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + if (!BootEncObj->GetStatus().DriveMounted) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED", hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + try + { + LocalizeDialog (hwndDlg, "IDD_SYSENC_SETTINGS"); + + uint32 driverConfig = ReadDriverConfigurationFlags(); + byte userConfig; + string customUserMessage; + uint16 bootLoaderVersion; + BOOL bPasswordCacheEnabled = (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD)? TRUE : FALSE; + BOOL bPimCacheEnabled = (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PIM)? TRUE : FALSE; + + BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig, &customUserMessage, &bootLoaderVersion); + + if (bootLoaderVersion != VERSION_NUM) + Warning ("BOOT_LOADER_VERSION_INCORRECT_PREFERENCES", hwndDlg); + + SendMessage (GetDlgItem (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE), EM_LIMITTEXT, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, 0); + SetDlgItemTextA (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE, customUserMessage.c_str()); + + CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT, (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT, (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton (hwndDlg, IDC_ALLOW_ESC_PBA_BYPASS, (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC) ? BST_UNCHECKED : BST_CHECKED); + CheckDlgButton (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD, bPasswordCacheEnabled ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton (hwndDlg, IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION, (driverConfig & TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION) ? BST_CHECKED : BST_UNCHECKED); + EnableWindow (GetDlgItem (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM), bPasswordCacheEnabled); + CheckDlgButton (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM, (bPasswordCacheEnabled && bPimCacheEnabled)? BST_CHECKED : BST_UNCHECKED); + + SetWindowTextW (GetDlgItem (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE_HELP), GetString("CUSTOM_BOOT_LOADER_MESSAGE_HELP")); + } + catch (Exception &e) + { + e.Show (hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + } + return 0; + + case WM_COMMAND: + + switch (lw) + { + case IDCANCEL: + EndDialog (hwndDlg, lw); + return 1; + + case IDOK: + { + VOLUME_PROPERTIES_STRUCT prop; + + if (!BootEncObj->GetStatus().DriveMounted) + { + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + try + { + BootEncObj->GetVolumeProperties (&prop); + } + catch (Exception &e) + { + e.Show (hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + char customUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; + GetDlgItemTextA (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE, customUserMessage, sizeof (customUserMessage)); + + byte userConfig; + try + { + BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig); + } + catch (Exception &e) + { + e.Show (hwndDlg); + return 1; + } + + if (IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT)) + userConfig |= TC_BOOT_USER_CFG_FLAG_DISABLE_PIM; + else + userConfig &= ~TC_BOOT_USER_CFG_FLAG_DISABLE_PIM; + + if (IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT)) + userConfig |= TC_BOOT_USER_CFG_FLAG_SILENT_MODE; + else + userConfig &= ~TC_BOOT_USER_CFG_FLAG_SILENT_MODE; + + if (!IsDlgButtonChecked (hwndDlg, IDC_ALLOW_ESC_PBA_BYPASS)) + userConfig |= TC_BOOT_USER_CFG_FLAG_DISABLE_ESC; + else + userConfig &= ~TC_BOOT_USER_CFG_FLAG_DISABLE_ESC; + + try + { + BOOL bPasswordCacheEnabled = IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD); + BOOL bPimCacheEnabled = IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM); + BootEncObj->WriteBootSectorUserConfig (userConfig, customUserMessage, prop.volumePim); + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD, bPasswordCacheEnabled); + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PIM, (bPasswordCacheEnabled && bPimCacheEnabled)? TRUE : FALSE); + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION, IsDlgButtonChecked (hwndDlg, IDC_DISABLE_EVIL_MAID_ATTACK_DETECTION)); + } + catch (Exception &e) + { + e.Show (hwndDlg); + return 1; + } + + EndDialog (hwndDlg, lw); + return 1; + } + + case IDC_DISABLE_BOOT_LOADER_PIM_PROMPT: + if ((IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT)) + && AskWarnYesNo ("DISABLE_BOOT_LOADER_PIM_PROMPT", hwndDlg) == IDNO) + { + CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_PIM_PROMPT, BST_UNCHECKED); + } + + case IDC_DISABLE_BOOT_LOADER_OUTPUT: + if ((IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT)) + && AskWarnYesNo ("CUSTOM_BOOT_LOADER_MESSAGE_PROMPT", hwndDlg) == IDNO) + { + CheckDlgButton (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT, BST_UNCHECKED); + } + + break; + + case IDC_BOOT_LOADER_CACHE_PASSWORD: + if (IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD)) + { + Warning ("BOOT_PASSWORD_CACHE_KEYBOARD_WARNING", hwndDlg); + EnableWindow (GetDlgItem (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM), TRUE); + } + else + { + EnableWindow (GetDlgItem (hwndDlg, IDC_BOOT_LOADER_CACHE_PIM), FALSE); + } + + break; + } + return 0; + } + + return 0; +} + + +void MountSelectedVolume (HWND hwndDlg, BOOL mountWithOptions) +{ + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED", hwndDlg); + } + else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) + { + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (mountWithOptions || GetAsyncKeyState (VK_CONTROL) < 0) + { + /* Priority is given to command line parameters + * Default values used only when nothing specified in command line + */ + if (CmdVolumePkcs5 == 0) + mountOptions.ProtectedHidVolPkcs5Prf = DefaultVolumePkcs5; + else + mountOptions.ProtectedHidVolPkcs5Prf = CmdVolumePkcs5; + mountOptions.ProtectedHidVolPim = CmdVolumePim; + if (IDCANCEL == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, + (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions)) + return; + + if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) + { + wchar_t selectedVolume [TC_MAX_PATH + 1]; + GetVolumePath (hwndDlg, selectedVolume, ARRAYSIZE (selectedVolume)); + KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, selectedVolume); + } + } + + if (CheckMountList (hwndDlg, FALSE)) + _beginthread (mountThreadFunction, 0, hwndDlg); + } + else + Warning ("SELECT_FREE_DRIVE", hwndDlg); +} + +static BOOL HandleDriveListMouseWheelEvent (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bListMustBePointed) +{ + static BOOL eventHandlerActive = FALSE; + if (eventHandlerActive) + return 0; + + RECT listRect; + int mouseX = GET_X_LPARAM (lParam); + int mouseY = GET_Y_LPARAM (lParam); + + GetWindowRect (GetDlgItem (MainDlg, IDC_DRIVELIST), &listRect); + + // Determine if the mouse pointer is within the main drive list + bool bListPointed = (mouseX >= listRect.left && mouseX <= listRect.right + && mouseY >= listRect.top && mouseY <= listRect.bottom); + + if (bListMustBePointed && bListPointed + || !bListMustBePointed) + { + eventHandlerActive = TRUE; + + if (!bListMustBePointed && bListPointed) + SetFocus (GetDlgItem (MainDlg, IDC_DRIVELIST)); + + SendMessage (GetDlgItem (MainDlg, IDC_DRIVELIST), uMsg, wParam, lParam); + + eventHandlerActive = FALSE; + return 0; // Do not process this event any further e.g. to prevent two lists from being scrolled at once + } + + return 1; +} + + +static LRESULT CALLBACK MouseWheelProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC wp = (WNDPROC) GetWindowLongPtrW (hwnd, GWLP_USERDATA); + + switch (message) + { + case WM_MOUSEWHEEL: + + if (HandleDriveListMouseWheelEvent (message, wParam, lParam, TRUE) == 0) + return 0; // Do not process this event any further e.g. to prevent two lists from being scrolled at once + } + + return CallWindowProcW (wp, hwnd, message, wParam, lParam); +} + + +void HookMouseWheel (HWND hwndDlg, UINT ctrlId) +{ + HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); + + SetWindowLongPtrW (hwndCtrl, GWLP_USERDATA, (LONG_PTR) GetWindowLongPtrW (hwndCtrl, GWLP_WNDPROC)); + SetWindowLongPtrW (hwndCtrl, GWLP_WNDPROC, (LONG_PTR) MouseWheelProc); +} -- cgit v1.2.3