From c606f0866c3a2a5db3ef9bc41738ef33eb9612a9 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 22 Jun 2013 16:16:13 +0200 Subject: Add original TrueCrypt 7.1a sources --- src/Mount/Drive_icon_96dpi.bmp | Bin 0 -> 1206 bytes src/Mount/Drive_icon_mask_96dpi.bmp | Bin 0 -> 110 bytes src/Mount/Favorites.cpp | 867 +++ src/Mount/Favorites.h | 74 + src/Mount/Hotkeys.c | 525 ++ src/Mount/Hotkeys.h | 48 + src/Mount/Logo_288dpi.bmp | Bin 0 -> 50166 bytes src/Mount/Logo_96dpi.bmp | Bin 0 -> 5622 bytes src/Mount/MainCom.cpp | 267 + src/Mount/MainCom.h | 32 + src/Mount/MainCom.idl | 50 + src/Mount/Mount.c | 8999 ++++++++++++++++++++++++++++ src/Mount/Mount.h | 115 + src/Mount/Mount.manifest | 21 + src/Mount/Mount.rc | 635 ++ src/Mount/Mount.vcproj | 689 +++ src/Mount/Resource.h | 234 + src/Mount/System_drive_icon_96dpi.bmp | Bin 0 -> 1206 bytes src/Mount/System_drive_icon_mask_96dpi.bmp | Bin 0 -> 110 bytes 19 files changed, 12556 insertions(+) create mode 100644 src/Mount/Drive_icon_96dpi.bmp create mode 100644 src/Mount/Drive_icon_mask_96dpi.bmp create mode 100644 src/Mount/Favorites.cpp create mode 100644 src/Mount/Favorites.h create mode 100644 src/Mount/Hotkeys.c create mode 100644 src/Mount/Hotkeys.h create mode 100644 src/Mount/Logo_288dpi.bmp create mode 100644 src/Mount/Logo_96dpi.bmp create mode 100644 src/Mount/MainCom.cpp create mode 100644 src/Mount/MainCom.h create mode 100644 src/Mount/MainCom.idl create mode 100644 src/Mount/Mount.c create mode 100644 src/Mount/Mount.h create mode 100644 src/Mount/Mount.manifest create mode 100644 src/Mount/Mount.rc create mode 100644 src/Mount/Mount.vcproj create mode 100644 src/Mount/Resource.h create mode 100644 src/Mount/System_drive_icon_96dpi.bmp create mode 100644 src/Mount/System_drive_icon_mask_96dpi.bmp (limited to 'src/Mount') diff --git a/src/Mount/Drive_icon_96dpi.bmp b/src/Mount/Drive_icon_96dpi.bmp new file mode 100644 index 00000000..8c97b566 Binary files /dev/null and b/src/Mount/Drive_icon_96dpi.bmp differ diff --git a/src/Mount/Drive_icon_mask_96dpi.bmp b/src/Mount/Drive_icon_mask_96dpi.bmp new file mode 100644 index 00000000..38a48ccf Binary files /dev/null and b/src/Mount/Drive_icon_mask_96dpi.bmp differ diff --git a/src/Mount/Favorites.cpp b/src/Mount/Favorites.cpp new file mode 100644 index 00000000..d608d5ad --- /dev/null +++ b/src/Mount/Favorites.cpp @@ -0,0 +1,867 @@ +/* + Copyright (c) 2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "Tcdefs.h" +#include "Platform/Finally.h" +#include "Platform/ForEach.h" +#include "BootEncryption.h" +#include "Dlgcode.h" +#include "Language.h" +#include "Mount.h" +#include "Resource.h" +#include "Xml.h" +#include "Favorites.h" + +using namespace std; + +namespace TrueCrypt +{ + vector FavoriteVolumes; + vector SystemFavoriteVolumes; + list FavoritesOnArrivalMountRequired; + list FavoritesMountedOnArrivalStillConnected; + HMENU FavoriteVolumesMenu; + + + BOOL AddMountedVolumeToFavorites (HWND hwndDlg, int driveNo, bool systemFavorites) + { + VOLUME_PROPERTIES_STRUCT prop; + DWORD bytesReturned; + + memset (&prop, 0, sizeof (prop)); + prop.driveNo = driveNo; + + if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &bytesReturned, NULL)) + { + handleWin32Error (hwndDlg); + return FALSE; + } + + FavoriteVolume favorite; + favorite.MountPoint = "X:\\"; + favorite.MountPoint[0] = (char) (prop.driveNo + 'A'); + + favorite.Path = WideToSingleString ((wchar_t *) prop.wszVolume); + if (favorite.Path.find ("\\??\\") == 0) + favorite.Path = favorite.Path.substr (4); + + if (IsVolumeDeviceHosted (favorite.Path.c_str())) + { + // Get GUID path + string volumeDevPath = favorite.Path; + + wchar_t resolvedVolumeDevPath[TC_MAX_PATH]; + if (ResolveSymbolicLink (SingleStringToWide (volumeDevPath).c_str(), resolvedVolumeDevPath)) + volumeDevPath = WideToSingleString (resolvedVolumeDevPath); + + char volumeName[TC_MAX_PATH]; + HANDLE find = FindFirstVolume (volumeName, sizeof (volumeName)); + + if (find != INVALID_HANDLE_VALUE) + { + do + { + char findVolumeDevPath[TC_MAX_PATH]; + string vn = volumeName; + + if (QueryDosDevice (vn.substr (4, vn.size() - 5).c_str(), findVolumeDevPath, sizeof (findVolumeDevPath)) != 0 + && volumeDevPath == findVolumeDevPath) + { + favorite.VolumePathId = volumeName; + break; + } + + } while (FindNextVolume (find, volumeName, sizeof (volumeName))); + + FindVolumeClose (find); + } + } + + favorite.ReadOnly = prop.readOnly ? true : false; + favorite.Removable = prop.removable ? true : false; + favorite.SystemEncryption = prop.partitionInInactiveSysEncScope ? true : false; + favorite.OpenExplorerWindow = (bExplore == TRUE); + + if (favorite.VolumePathId.empty() + && IsVolumeDeviceHosted (favorite.Path.c_str()) + && favorite.Path.find ("\\\\?\\Volume{") != 0) + { + Warning (favorite.Path.find ("\\Partition0") == string::npos ? "FAVORITE_ADD_PARTITION_TYPE_WARNING" : "FAVORITE_ADD_DRIVE_DEV_WARNING"); + } + + return OrganizeFavoriteVolumes (hwndDlg, systemFavorites, favorite); + } + + + static BOOL CALLBACK FavoriteVolumesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) + { + /* This dialog is used both for System Favorites and non-system Favorites. + + The following options have different meaning in System Favorites mode: + + IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT => MOUNT_SYSTEM_FAVORITES_ON_BOOT + IDC_FAVORITE_DISABLE_HOTKEY => DISABLE_NONADMIN_SYS_FAVORITES_ACCESS + + */ + + WORD lw = LOWORD (wParam); + static bool SystemFavoritesMode; + static vector Favorites; + static int SelectedItem; + static HWND FavoriteListControl; + + switch (msg) + { + case WM_INITDIALOG: + { + try + { + FavoriteListControl = GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST); + + FavoriteVolumesDlgProcArguments *args = (FavoriteVolumesDlgProcArguments *) lParam; + SystemFavoritesMode = args->SystemFavorites; + + LocalizeDialog (hwndDlg, SystemFavoritesMode ? "SYSTEM_FAVORITES_DLG_TITLE" : "IDD_FAVORITE_VOLUMES"); + + if (SystemFavoritesMode) + { + RECT rec; + + BootEncryptionStatus bootEncStatus = BootEncryption (hwndDlg).GetStatus(); + + if (!bootEncStatus.DriveMounted) + throw ErrorException ("SYS_FAVORITES_REQUIRE_PBA"); + + ShowWindow (GetDlgItem(hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON), SW_HIDE); + ShowWindow (GetDlgItem(hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL), SW_HIDE); + + // MOUNT_SYSTEM_FAVORITES_ON_BOOT + + SetWindowTextW (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), GetString ("MOUNT_SYSTEM_FAVORITES_ON_BOOT")); + + // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS + + SetWindowTextW (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), GetString ("DISABLE_NONADMIN_SYS_FAVORITES_ACCESS")); + + // Group box + + GetClientRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &rec); + + SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, 0, 0, + rec.right, + rec.bottom - CompensateYDPI (90), + SWP_NOMOVE | SWP_NOZORDER); + + InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE); + } + else + { + ShowWindow (GetDlgItem(hwndDlg, IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX), SW_HIDE); + } + + Favorites.clear(); + + LVCOLUMNW column; + SendMessageW (FavoriteListControl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); + + memset (&column, 0, sizeof (column)); + column.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; + column.pszText = GetString ("DRIVE"); + column.cx = CompensateXDPI (38); + column.fmt = LVCFMT_CENTER; + SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column); + + ++column.iSubItem; + column.fmt = LVCFMT_LEFT; + column.pszText = GetString ("LABEL"); + column.cx = CompensateXDPI (160); + SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 2, (LPARAM) &column); + + ++column.iSubItem; + column.fmt = LVCFMT_LEFT; + column.pszText = GetString ("VOLUME"); + column.cx = CompensateXDPI (330); + SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 3, (LPARAM) &column); + + SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false); + + if (SystemFavoritesMode) + LoadFavoriteVolumes (Favorites, true); + else + Favorites = FavoriteVolumes; + + if (args->AddFavoriteVolume) + Favorites.push_back (args->NewFavoriteVolume); + + FillListControl (FavoriteListControl, Favorites); + + SelectedItem = -1; + + if (args->AddFavoriteVolume) + { + ListView_SetItemState (FavoriteListControl, Favorites.size() - 1, LVIS_SELECTED, LVIS_SELECTED); + ListView_EnsureVisible (FavoriteListControl, Favorites.size() - 1, FALSE); + } + + if (SystemFavoritesMode) + SetDlgItemTextW (hwndDlg, IDC_FAVORITES_HELP_LINK, GetString ("SYS_FAVORITES_HELP_LINK")); + + ToHyperlink (hwndDlg, IDC_FAVORITES_HELP_LINK); + } + catch (Exception &e) + { + e.Show (hwndDlg); + EndDialog (hwndDlg, IDCLOSE); + } + } + return 1; + + case WM_COMMAND: + + switch (lw) + { + case IDOK: + + /* Global System Favorites settings */ + + if (SystemFavoritesMode) + { + BootEncryption BootEncObj (NULL); + + if (BootEncObj.GetStatus().DriveMounted) + { + try + { + uint32 reqConfig = IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT) ? TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES : 0; + if (reqConfig != (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES)) + BootEncObj.RegisterSystemFavoritesService (reqConfig ? TRUE : FALSE); + + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS, IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY)); + } + catch (Exception &e) + { + e.Show (hwndDlg); + } + } + } + + /* (System) Favorites list */ + + if (SelectedItem != -1 && !Favorites.empty()) + SetFavoriteVolume (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode); + + if (SaveFavoriteVolumes (Favorites, SystemFavoritesMode)) + { + if (!SystemFavoritesMode) + { + bMountFavoritesOnLogon = FALSE; + + foreach (const FavoriteVolume &favorite, Favorites) + { + if (favorite.MountOnLogOn) + { + bMountFavoritesOnLogon = TRUE; + break; + } + } + + if (!bEnableBkgTask || bCloseBkgTaskWhenNoVolumes || IsNonInstallMode()) + { + foreach (const FavoriteVolume favorite, Favorites) + { + if (favorite.MountOnArrival) + { + Warning ("FAVORITE_ARRIVAL_MOUNT_BACKGROUND_TASK_ERR"); + break; + } + } + } + + FavoriteVolumes = Favorites; + + ManageStartupSeq(); + SaveSettings (hwndDlg); + } + else + SystemFavoriteVolumes = Favorites; + + OnFavoriteVolumesUpdated(); + LoadDriveLetters (GetDlgItem (MainDlg, IDC_DRIVELIST), 0); + + EndDialog (hwndDlg, IDOK); + } + + return 1; + + case IDCANCEL: + EndDialog (hwndDlg, IDCLOSE); + return 1; + + case IDC_FAVORITE_MOVE_DOWN: + if (SelectedItem != -1 && Favorites.size() > (size_t) SelectedItem + 1) + { + swap (Favorites[SelectedItem], Favorites[SelectedItem + 1]); + + FillListControl (FavoriteListControl, Favorites); + ++SelectedItem; + ListView_SetItemState (FavoriteListControl, SelectedItem, LVIS_SELECTED, LVIS_SELECTED); + ListView_EnsureVisible (FavoriteListControl, SelectedItem, FALSE); + } + return 1; + + case IDC_FAVORITE_MOVE_UP: + if (SelectedItem > 0) + { + swap (Favorites[SelectedItem], Favorites[SelectedItem - 1]); + + FillListControl (FavoriteListControl, Favorites); + --SelectedItem; + ListView_SetItemState (FavoriteListControl, SelectedItem, LVIS_SELECTED, LVIS_SELECTED); + ListView_EnsureVisible (FavoriteListControl, SelectedItem, FALSE); + } + return 1; + + case IDC_FAVORITE_REMOVE: + if (SelectedItem != -1) + { + Favorites.erase (Favorites.begin() + SelectedItem); + FillListControl (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST), Favorites); + SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false); + SelectedItem = -1; + } + return 1; + + + case IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT: // Note that this option means "MOUNT_SYSTEM_FAVORITES_ON_BOOT" when SystemFavoritesMode is true + if (SystemFavoritesMode) + { + // MOUNT_SYSTEM_FAVORITES_ON_BOOT + + if (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT)) + { + WarningDirect ((wstring (GetString ("SYS_FAVORITES_KEYBOARD_WARNING")) + L"\n\n" + GetString ("BOOT_PASSWORD_CACHE_KEYBOARD_WARNING")).c_str()); + + if (!IsServerOS() && !IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY)) + Info ("SYS_FAVORITES_ADMIN_ONLY_INFO"); + } + } + return 1; + + case IDC_FAVORITE_DISABLE_HOTKEY: // Note that this option means "DISABLE_NONADMIN_SYS_FAVORITES_ACCESS" when SystemFavoritesMode is true + if (SystemFavoritesMode) + { + // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS + + if (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY)) + WarningDirect ((wstring (GetString ("SYS_FAVORITES_ADMIN_ONLY_WARNING")) + L"\n\n" + GetString ("SETTING_REQUIRES_REBOOT")).c_str()); + else + Warning ("SETTING_REQUIRES_REBOOT"); + } + return 1; + + case IDC_FAVORITES_HELP_LINK: + Applink (SystemFavoritesMode ? "sysfavorites" : "favorites", TRUE, ""); + return 1; + } + + return 0; + + case WM_NOTIFY: + if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) + { + static bool reentry = false; + if (reentry) + break; + + reentry = true; + + if (SelectedItem != -1) + { + SetFavoriteVolume (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode); + FillListControlSubItems (FavoriteListControl, SelectedItem, Favorites[SelectedItem]); + } + + SelectedItem = ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST), -1, LVIS_SELECTED); + + if (SelectedItem != -1) + SetControls (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode); + else + SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false); + + reentry = false; + return 1; + } + break; + + case WM_CLOSE: + EndDialog (hwndDlg, IDCLOSE); + return 1; + } + + return 0; + } + + + static void FillFavoriteVolumesMenu () + { + while (DeleteMenu (FavoriteVolumesMenu, 7, MF_BYPOSITION)) { } + + if (FavoriteVolumes.empty()) + return; + + AppendMenu (FavoriteVolumesMenu, MF_SEPARATOR, 0, NULL); + + int i = 0; + foreach (const FavoriteVolume &favorite, FavoriteVolumes) + { + UINT flags = MF_STRING; + + if (favorite.DisconnectedDevice) + flags |= MF_GRAYED; + + wstring menuText = SingleStringToWide (favorite.Path); + if (favorite.DisconnectedDevice) + menuText = favorite.Label.empty() ? wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")" : L""; + + if (!favorite.Label.empty()) + { + if (favorite.DisconnectedDevice) + menuText = favorite.Label + L" " + menuText; + else + menuText = favorite.Label; + } + + AppendMenuW (FavoriteVolumesMenu, flags, TC_FAVORITE_MENU_CMD_ID_OFFSET + i++, + (menuText + L"\t" + SingleStringToWide (favorite.MountPoint).substr (0, 2)).c_str()); + } + } + + + static void FillListControl (HWND favoriteListControl, vector &favorites) + { + SendMessage (favoriteListControl, LVM_DELETEALLITEMS, 0, 0); + + int line = 0; + foreach (const FavoriteVolume favorite, favorites) + { + ListItemAdd (favoriteListControl, line, (char *) favorite.MountPoint.substr (0, 2).c_str()); + FillListControlSubItems (favoriteListControl, line++, favorite); + } + } + + + static void FillListControlSubItems (HWND FavoriteListControl, int line, const FavoriteVolume &favorite) + { + ListSubItemSetW (FavoriteListControl, line, 1, (wchar_t *) favorite.Label.c_str()); + + if (favorite.DisconnectedDevice) + ListSubItemSetW (FavoriteListControl, line, 2, (wchar_t *) (wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")").c_str()); + else + ListSubItemSet (FavoriteListControl, line, 2, (char *) favorite.Path.c_str()); + } + + + wstring GetFavoriteVolumeLabel (const string &volumePath) + { + foreach (const FavoriteVolume &favorite, FavoriteVolumes) + { + if (favorite.Path == volumePath) + return favorite.Label; + } + + foreach (const FavoriteVolume &favorite, SystemFavoriteVolumes) + { + if (favorite.Path == volumePath) + return favorite.Label; + } + + return wstring(); + } + + + void LoadFavoriteVolumes () + { + LoadFavoriteVolumes (FavoriteVolumes, false); + + try + { + LoadFavoriteVolumes (SystemFavoriteVolumes, true, true); + } + catch (...) { } // Ignore errors as SystemFavoriteVolumes list is used only for resolving volume paths to labels + + OnFavoriteVolumesUpdated(); + } + + + void LoadFavoriteVolumes (vector &favorites, bool systemFavorites, bool noUacElevation) + { + favorites.clear(); + string favoritesFilePath = systemFavorites ? GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES) : GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES); + + if (systemFavorites && !IsAdmin() && !noUacElevation) + { + favoritesFilePath = GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES); + + try + { + BootEncryption bootEnc (MainDlg); + bootEnc.CopyFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str(), favoritesFilePath.c_str()); + } + catch (SystemException &e) + { + if (e.ErrorCode == ERROR_FILE_NOT_FOUND) + return; + + throw; + } + } + + DWORD size; + char *favoritesXml = LoadFile (favoritesFilePath.c_str(), &size); + + if (systemFavorites && !IsAdmin() && !noUacElevation) + DeleteFile (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES)); + + char *xml = favoritesXml; + char mountPoint[MAX_PATH], volume[MAX_PATH]; + + if (xml == NULL) + return; + + while (xml = XmlFindElement (xml, "volume")) + { + FavoriteVolume favorite; + + XmlGetAttributeText (xml, "mountpoint", mountPoint, sizeof (mountPoint)); + favorite.MountPoint = mountPoint; + + XmlGetNodeText (xml, volume, sizeof (volume)); + favorite.Path = WideToSingleString (Utf8StringToWide (volume)); + + char label[1024]; + XmlGetAttributeText (xml, "label", label, sizeof (label)); + favorite.Label = Utf8StringToWide (label); + + char boolVal[2]; + XmlGetAttributeText (xml, "readonly", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.ReadOnly = (boolVal[0] == '1'); + + XmlGetAttributeText (xml, "removable", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.Removable = (boolVal[0] == '1'); + + XmlGetAttributeText (xml, "system", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.SystemEncryption = (boolVal[0] == '1'); + + XmlGetAttributeText (xml, "noHotKeyMount", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.DisableHotkeyMount = (boolVal[0] == '1'); + + XmlGetAttributeText (xml, "openExplorerWindow", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.OpenExplorerWindow = (boolVal[0] == '1'); + + XmlGetAttributeText (xml, "mountOnArrival", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.MountOnArrival = (boolVal[0] == '1'); + + XmlGetAttributeText (xml, "mountOnLogOn", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.MountOnLogOn = (boolVal[0] == '1'); + + if (favorite.Path.find ("\\\\?\\Volume{") == 0 && favorite.Path.rfind ("}\\") == favorite.Path.size() - 2) + { + string resolvedPath = VolumeGuidPathToDevicePath (favorite.Path); + if (!resolvedPath.empty()) + { + favorite.DisconnectedDevice = false; + favorite.VolumePathId = favorite.Path; + favorite.Path = resolvedPath; + } + else + favorite.DisconnectedDevice = true; + } + + favorites.push_back (favorite); + xml++; + } + + free (favoritesXml); + } + + + static void OnFavoriteVolumesUpdated () + { + FillFavoriteVolumesMenu(); + + FavoritesOnArrivalMountRequired.clear(); + + foreach (const FavoriteVolume favorite, FavoriteVolumes) + { + if (favorite.MountOnArrival) + { + FavoritesOnArrivalMountRequired.push_back (favorite); + + if (IsMountedVolume (favorite.Path.c_str())) + { + bool present = false; + + foreach (const FavoriteVolume favoriteConnected, FavoritesMountedOnArrivalStillConnected) + { + if (favorite.Path == favoriteConnected.Path) + { + present = true; + break; + } + } + + if (!present) + FavoritesMountedOnArrivalStillConnected.push_back (favorite); + } + } + } + } + + + BOOL OrganizeFavoriteVolumes (HWND hwndDlg, bool systemFavorites, const FavoriteVolume &newFavorite) + { + FavoriteVolumesDlgProcArguments args; + args.SystemFavorites = systemFavorites; + + if (!newFavorite.Path.empty()) + { + args.AddFavoriteVolume = true; + args.NewFavoriteVolume = newFavorite; + } + else + args.AddFavoriteVolume = false; + + return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_FAVORITE_VOLUMES), hwndDlg, (DLGPROC) FavoriteVolumesDlgProc, (LPARAM) &args) == IDOK; + } + + + static bool SaveFavoriteVolumes (const vector &favorites, bool systemFavorites) + { + FILE *f; + int cnt = 0; + + f = fopen (GetConfigPath (systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES), "w,ccs=UTF-8"); + if (f == NULL) + { + handleWin32Error (MainDlg); + return false; + } + + XmlWriteHeaderW (f); + fputws (L"\n\t", f); + + foreach (const FavoriteVolume &favorite, favorites) + { + char tq[2048]; + + if (systemFavorites && favorite.Path.find ("\\\\") == 0 && favorite.Path.find ("Volume{") == string::npos) + Warning ("SYSTEM_FAVORITE_NETWORK_PATH_ERR"); + + XmlQuoteText (!favorite.VolumePathId.empty() ? favorite.VolumePathId.c_str() : favorite.Path.c_str(), tq, sizeof (tq)); + + wstring s = L"\n\t\t" + SingleStringToWide (tq) + L""; + + fwprintf (f, L"%ws", s.c_str()); + cnt++; + } + + fputws (L"\n\t", f); + XmlWriteFooterW (f); + + if (!CheckFileStreamWriteErrors (f, systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES)) + { + fclose (f); + return false; + } + + fclose (f); + + BootEncryption bootEnc (MainDlg); + + if (systemFavorites) + { + finally_do ({ remove (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES)); }); + + try + { + bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str()); + } + catch (UserAbort&) { return false; } + catch (...) { } + + try + { + if (cnt != 0) + { + bootEnc.CopyFileAdmin (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES), GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str()); + + if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES)) + Info ("SYS_FAVORITE_VOLUMES_SAVED"); + } + } + catch (Exception &e) + { + e.Show (NULL); + } + } + + if (cnt == 0) + { + if (systemFavorites) + { + try + { + bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str()); + } + catch (...) { } + } + else + remove (GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES)); + } + + return true; + } + + + static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable) + { + SetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, favorite.Label.c_str()); + SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON, favorite.MountOnLogOn); + SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL, favorite.MountOnArrival); + SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_READONLY, favorite.ReadOnly); + SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE, favorite.Removable); + + if (systemFavoritesMode) + { + uint32 driverConfig = ReadDriverConfigurationFlags(); + + // MOUNT_SYSTEM_FAVORITES_ON_BOOT + CheckDlgButton (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES) ? BST_CHECKED : BST_UNCHECKED); + + // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS + CheckDlgButton (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY, (driverConfig & TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS) ? BST_CHECKED : BST_UNCHECKED); + } + else + { + SetCheckBox (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, favorite.OpenExplorerWindow); + SetCheckBox (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY, favorite.DisableHotkeyMount); + } + + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOVE_UP), enable); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOVE_DOWN), enable); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_REMOVE), enable); + EnableWindow (GetDlgItem (hwndDlg, IDT_FAVORITE_LABEL), enable); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_LABEL), enable); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON), enable && !systemFavoritesMode); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL), enable && !systemFavoritesMode); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_READONLY), enable); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE), enable); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), enable || systemFavoritesMode); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), enable || systemFavoritesMode); + } + + + static void SetFavoriteVolume (HWND hwndDlg, FavoriteVolume &favorite, bool systemFavoritesMode) + { + wchar_t label[1024]; + if (GetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, label, ARRAYSIZE (label)) != 0) + { + favorite.Label = label; + + for (size_t i = 0; i < favorite.Label.size(); ++i) + { + if (favorite.Label[i] == L'"') + favorite.Label.at (i) = L'\''; + } + } + else + favorite.Label.clear(); + + favorite.ReadOnly = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_READONLY) != 0); + favorite.Removable = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE) != 0); + + if (!systemFavoritesMode) + { + favorite.MountOnLogOn = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON) != 0); + favorite.MountOnArrival = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL) != 0); + favorite.DisableHotkeyMount = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY) != 0); + favorite.OpenExplorerWindow = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT) != 0); + } + + if (favorite.VolumePathId.empty() + && IsVolumeDeviceHosted (favorite.Path.c_str()) + && favorite.Path.find ("\\\\?\\Volume{") != 0) + { + bool partition = (favorite.Path.find ("\\Partition0") == string::npos); + + if (!favorite.Label.empty()) + { + ErrorDirect ((GetString (partition ? "FAVORITE_LABEL_PARTITION_TYPE_ERR" : "FAVORITE_LABEL_DEVICE_PATH_ERR") + wstring (L"\n\n") + SingleStringToWide (favorite.Path)).c_str()); + favorite.Label.clear(); + } + + if (favorite.MountOnArrival) + { + ErrorDirect ((GetString (partition ? "FAVORITE_ARRIVAL_MOUNT_PARTITION_TYPE_ERR" : "FAVORITE_ARRIVAL_MOUNT_DEVICE_PATH_ERR") + wstring (L"\n\n") + SingleStringToWide (favorite.Path)).c_str()); + favorite.MountOnArrival = false; + } + } + + if (favorite.MountOnArrival && favorite.Path.find ("\\\\") == 0 && favorite.Path.find ("Volume{") == string::npos) + { + Error ("FAVORITE_ARRIVAL_MOUNT_NETWORK_PATH_ERR"); + favorite.MountOnArrival = false; + } + } + + + void UpdateDeviceHostedFavoriteVolumes () + { + try + { + LoadFavoriteVolumes(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + } +} diff --git a/src/Mount/Favorites.h b/src/Mount/Favorites.h new file mode 100644 index 00000000..31179fb7 --- /dev/null +++ b/src/Mount/Favorites.h @@ -0,0 +1,74 @@ +/* + Copyright (c) 2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_Mount_FavoriteVolumes +#define TC_HEADER_Mount_FavoriteVolumes + +#include + +namespace TrueCrypt +{ + struct FavoriteVolume + { + FavoriteVolume() + : + DisableHotkeyMount (false), + DisconnectedDevice (false), + MountOnLogOn (false), + MountOnArrival (false), + OpenExplorerWindow (false), + ReadOnly (false), + Removable (false), + SystemEncryption (false) + { + } + + string Path; + string MountPoint; + string VolumePathId; + wstring Label; + + bool DisableHotkeyMount; + bool DisconnectedDevice; + bool MountOnLogOn; + bool MountOnArrival; + bool OpenExplorerWindow; + bool ReadOnly; + bool Removable; + bool SystemEncryption; + }; + + struct FavoriteVolumesDlgProcArguments + { + bool SystemFavorites; + bool AddFavoriteVolume; + FavoriteVolume NewFavoriteVolume; + }; + + extern vector FavoriteVolumes; + extern list FavoritesOnArrivalMountRequired; + extern list FavoritesMountedOnArrivalStillConnected; + extern HMENU FavoriteVolumesMenu; + + BOOL AddMountedVolumeToFavorites (HWND hwndDlg, int driveNo, bool systemFavorites); + static BOOL CALLBACK FavoriteVolumesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static void FillFavoriteVolumesMenu (); + static void FillListControl (HWND favoriteListControl, vector &favorites); + static void FillListControlSubItems (HWND favoriteListControl, int line, const FavoriteVolume &favorite); + wstring GetFavoriteVolumeLabel (const string &volumePath); + void LoadFavoriteVolumes (); + void LoadFavoriteVolumes (vector &favorites, bool systemFavorites, bool noUacElevation = false); + static void OnFavoriteVolumesUpdated (); + BOOL OrganizeFavoriteVolumes (HWND hwndDlg, bool systemFavorites, const FavoriteVolume &newFavorite = FavoriteVolume()); + static bool SaveFavoriteVolumes (const vector &favorites, bool systemFavorites); + static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable = true); + static void SetFavoriteVolume (HWND hwndDlg, FavoriteVolume &favorite, bool systemFavoritesMode); + void UpdateDeviceHostedFavoriteVolumes (); +} + +#endif // TC_HEADER_Mount_FavoriteVolumes diff --git a/src/Mount/Hotkeys.c b/src/Mount/Hotkeys.c new file mode 100644 index 00000000..96f9abcd --- /dev/null +++ b/src/Mount/Hotkeys.c @@ -0,0 +1,525 @@ +/* + Copyright (c) 2005 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include "Dlgcode.h" +#include "Hotkeys.h" +#include "Language.h" +#include "Mount.h" +#include "Resource.h" + +#define MAX_KEY_COMB_NAME_LEN 260 + +TCHOTKEY Hotkeys [NBR_HOTKEYS]; +static TCHOTKEY tmpHotkeys [NBR_HOTKEYS]; + +static int nSelectedHotkeyId; +static UINT currentVKeyCode; + + +static void ScanAndProcessKey (UINT *vKeyCode, wchar_t *keyName) +{ + UINT vKey; + *vKeyCode = 0; + + for (vKey = 0; vKey <= 0xFF; vKey++) + { + if (GetAsyncKeyState (vKey) < 0) + { + if (GetKeyName (vKey, keyName)) // If the key is allowed and its name has been resolved + *vKeyCode = vKey; + } + } +} + + +/* Returns TRUE if the key is allowed and its name is resolved. */ +BOOL GetKeyName (UINT vKey, wchar_t *keyName) +{ + BOOL result = TRUE; + + if (vKey >= 0x30 && vKey <= 0x5a) + { + // ASCII characters + wsprintfW (keyName, L"%hc", (char) vKey); + } + else if (vKey >= 0xE9 && vKey <= 0xF5) + { + // OEM-specific + wsprintfW (keyName, L"OEM-%d", vKey); + } + else if (vKey >= VK_F1 && vKey <= VK_F24) + { + // F1-F24 + wsprintfW (keyName, L"F%d", vKey - VK_F1 + 1); + } + else if (vKey >= VK_NUMPAD0 && vKey <= VK_NUMPAD9) + { + // Numpad numbers + wsprintfW (keyName, L"%s %d", GetString ("VK_NUMPAD"), vKey - VK_NUMPAD0); + } + else + { + switch (vKey) + { + case VK_MULTIPLY: wsprintfW (keyName, L"%s *", GetString ("VK_NUMPAD")); break; + case VK_ADD: wsprintfW (keyName, L"%s +", GetString ("VK_NUMPAD")); break; + case VK_SEPARATOR: wsprintfW (keyName, L"%s Separator", GetString ("VK_NUMPAD")); break; + case VK_SUBTRACT: wsprintfW (keyName, L"%s -", GetString ("VK_NUMPAD")); break; + case VK_DECIMAL: wsprintfW (keyName, L"%s .", GetString ("VK_NUMPAD")); break; + case VK_DIVIDE: wsprintfW (keyName, L"%s /", GetString ("VK_NUMPAD")); break; + case VK_OEM_1: wcscpy (keyName, L"OEM 1 (';')"); break; + case VK_OEM_PLUS: wcscpy (keyName, L"+"); break; + case VK_OEM_COMMA: wcscpy (keyName, L","); break; + case VK_OEM_MINUS: wcscpy (keyName, L"-"); break; + case VK_OEM_PERIOD: wcscpy (keyName, L"."); break; + case VK_OEM_2: wcscpy (keyName, L"OEM 2 ('/')"); break; + case VK_OEM_3: wcscpy (keyName, L"OEM 3 (`)"); break; + case VK_OEM_4: wcscpy (keyName, L"OEM 4 ('[')"); break; + case VK_OEM_5: wcscpy (keyName, L"OEM 5 ('\\')"); break; + case VK_OEM_6: wcscpy (keyName, L"OEM 6 (']')"); break; + case VK_OEM_7: wcscpy (keyName, L"OEM 7 (')"); break; + case VK_OEM_8: wcscpy (keyName, L"OEM 8"); break; + case VK_OEM_AX: wcscpy (keyName, L"OEM AX"); break; + case VK_OEM_102: wcscpy (keyName, L"OEM 102"); break; + case VK_ICO_HELP: wcscpy (keyName, L"ICO_HELP"); break; + case VK_ICO_00: wcscpy (keyName, L"ICO_00"); break; + case VK_ICO_CLEAR: wcscpy (keyName, L"ICO_CLEAR"); break; + case VK_ATTN: wcscpy (keyName, L"Attn"); break; + case VK_CRSEL: wcscpy (keyName, L"CrSel"); break; + case VK_EXSEL: wcscpy (keyName, L"ExSel"); break; + case VK_EREOF: wcscpy (keyName, L"Erase EOF"); break; + case VK_PA1: wcscpy (keyName, L"PA1"); break; + case VK_OEM_CLEAR: wcscpy (keyName, L"OEM Clear"); break; + + case 0: + case 1: + case 0xFF: + result = FALSE; + break; + + default: + { + char key[16]; + wchar_t *desc; + sprintf (key, "VKEY_%02X", vKey); + desc = GetString (key); + if (desc == UnknownString) + result = FALSE; + else + wcsncpy (keyName, desc, MAX_KEY_COMB_NAME_LEN); + } + } + } + return result; +} + + +static BOOL ShortcutInUse (UINT vKeyCode, UINT modifiers, TCHOTKEY hotkeys[]) +{ + int i; + + for (i = 0; i < NBR_HOTKEYS; i++) + { + if (hotkeys[i].vKeyCode == vKeyCode && hotkeys[i].vKeyModifiers == modifiers) + return TRUE; + } + return FALSE; +} + + +void UnregisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[]) +{ + int i; + + for (i = 0; i < NBR_HOTKEYS; i++) + { + if (hotkeys[i].vKeyCode != 0) + UnregisterHotKey (hwndDlg, i); + + } +} + + +BOOL RegisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[]) +{ + BOOL result = TRUE; + int i; + + for (i = 0; i < NBR_HOTKEYS; i++) + { + if (hotkeys[i].vKeyCode != 0 + && !RegisterHotKey (hwndDlg, i, hotkeys[i].vKeyModifiers, hotkeys[i].vKeyCode)) + result = FALSE; + } + + return result; +} + + +static void DisplayHotkeyList (HWND hwndDlg) +{ + LVITEMW item; + HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST); + int i; + wchar_t ShortcutMod [MAX_KEY_COMB_NAME_LEN]; + wchar_t ShortcutFinal [MAX_KEY_COMB_NAME_LEN*2]; + wchar_t Shortcut [MAX_KEY_COMB_NAME_LEN]; + + SendMessage (hList, LVM_DELETEALLITEMS,0, (LPARAM)&item); + + for (i = 0; i < NBR_HOTKEYS; i++) + { + memset (&item,0,sizeof(item)); + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + + switch (i) + { + + case HK_AUTOMOUNT_DEVICES: + item.pszText = GetString ("HK_AUTOMOUNT_DEVICES"); + break; + + case HK_DISMOUNT_ALL: + item.pszText = GetString ("HK_DISMOUNT_ALL"); + break; + + case HK_WIPE_CACHE: + item.pszText = GetString ("HK_WIPE_CACHE"); + break; + + case HK_DISMOUNT_ALL_AND_WIPE: + item.pszText = GetString ("HK_DISMOUNT_ALL_AND_WIPE"); + break; + + case HK_FORCE_DISMOUNT_ALL_AND_WIPE: + item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE"); + break; + + case HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT: + item.pszText = GetString ("HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT"); + break; + + case HK_MOUNT_FAVORITE_VOLUMES: + item.pszText = GetString ("HK_MOUNT_FAVORITE_VOLUMES"); + break; + + case HK_SHOW_HIDE_MAIN_WINDOW: + item.pszText = GetString ("HK_SHOW_HIDE_MAIN_WINDOW"); + break; + + case HK_CLOSE_SECURITY_TOKEN_SESSIONS: + item.pszText = GetString ("IDM_CLOSE_ALL_TOKEN_SESSIONS"); + break; + + default: + item.pszText = L"[?]"; + } + + SendMessageW (hList,LVM_INSERTITEMW,0,(LPARAM)&item); + + item.iSubItem = 1; + wcscpy (Shortcut, L""); + wcscpy (ShortcutMod, L""); + + if (GetKeyName (tmpHotkeys[i].vKeyCode, Shortcut)) + { + if (tmpHotkeys[i].vKeyModifiers & MOD_CONTROL) + { + wcscat (ShortcutMod, GetString ("VK_CONTROL")); + wcscat (ShortcutMod, L"+"); + } + + if (tmpHotkeys[i].vKeyModifiers & MOD_SHIFT) + { + wcscat (ShortcutMod, GetString ("VK_SHIFT")); + wcscat (ShortcutMod, L"+"); + } + + if (tmpHotkeys[i].vKeyModifiers & MOD_ALT) + { + wcscat (ShortcutMod, GetString ("VK_ALT")); + wcscat (ShortcutMod, L"+"); + } + + if (tmpHotkeys[i].vKeyModifiers & MOD_WIN) + { + wcscat (ShortcutMod, GetString ("VK_WIN")); + wcscat (ShortcutMod, L"+"); + } + + wsprintfW (ShortcutFinal, L"%s%s", ShortcutMod, Shortcut); + item.pszText = ShortcutFinal; + } + else + item.pszText = L""; + + SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&item); + } +} + + + +BOOL CALLBACK HotkeysDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hList = GetDlgItem (hwndDlg, IDC_HOTKEY_LIST); + HWND hwndMainDlg = hwndDlg; + WORD lw = LOWORD (wParam); + WORD hw = HIWORD (wParam); + static BOOL bKeyScanOn; + static BOOL bTPlaySoundOnSuccessfulHkDismount; + static BOOL bTDisplayBalloonOnSuccessfulHkDismount; + + while (GetParent (hwndMainDlg) != NULL) + { + hwndMainDlg = GetParent (hwndMainDlg); + } + + switch (msg) + { + case WM_INITDIALOG: + { + LVCOLUMNW col; + + bKeyScanOn = FALSE; + nSelectedHotkeyId = -1; + currentVKeyCode = 0; + memcpy (tmpHotkeys, Hotkeys, sizeof(tmpHotkeys)); + + SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0, + LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP + ); + + memset (&col,0,sizeof(col)); + col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; + col.pszText = GetString ("ACTION"); + col.cx = CompensateXDPI (341); + col.fmt = LVCFMT_LEFT; + SendMessageW (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&col); + + col.pszText = GetString ("SHORTCUT"); + col.cx = CompensateXDPI (190); + col.fmt = LVCFMT_LEFT; + SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&col); + + LocalizeDialog (hwndDlg, "IDD_HOTKEYS_DLG"); + + SetCheckBox (hwndDlg, IDC_HK_MOD_CTRL, TRUE); + SetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT, FALSE); + SetCheckBox (hwndDlg, IDC_HK_MOD_ALT, TRUE); + SetCheckBox (hwndDlg, IDC_HK_MOD_WIN, FALSE); + + SetCheckBox (hwndDlg, IDC_HK_DISMOUNT_PLAY_SOUND, bPlaySoundOnSuccessfulHkDismount); + SetCheckBox (hwndDlg, IDC_HK_DISMOUNT_BALLOON_TOOLTIP, bDisplayBalloonOnSuccessfulHkDismount); + + bTPlaySoundOnSuccessfulHkDismount = bPlaySoundOnSuccessfulHkDismount; + bTDisplayBalloonOnSuccessfulHkDismount = bDisplayBalloonOnSuccessfulHkDismount; + + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); + + DisplayHotkeyList(hwndDlg); + + SetTimer (hwndDlg, 0xfe, 10, NULL); + return 1; + } + + case WM_TIMER: + { + if (nSelectedHotkeyId > -1) + { + wchar_t keyName [MAX_KEY_COMB_NAME_LEN]; + UINT tmpVKeyCode; + + keyName[0] = 0; + + ScanAndProcessKey (&tmpVKeyCode, &keyName[0]); + + if (keyName[0] != 0) + { + currentVKeyCode = tmpVKeyCode; + SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), keyName); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), TRUE); + } + } + return 1; + } + + case WM_COMMAND: + case WM_NOTIFY: + + if (lw == IDC_HOTKEY_KEY && hw == EN_CHANGE) + { + if (!bKeyScanOn && nSelectedHotkeyId < 0 && GetWindowTextLengthW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY))) + SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); + } + + if (msg == WM_NOTIFY && wParam == IDC_HOTKEY_LIST) + { + if (((LPNMHDR) lParam)->code == LVN_ITEMACTIVATE + || ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED)) + { + LVITEM item; + memset(&item,0,sizeof(item)); + nSelectedHotkeyId = ((LPNMLISTVIEW) lParam)->iItem; + SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), GetString ("PRESS_A_KEY_TO_ASSIGN")); + + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), (tmpHotkeys[nSelectedHotkeyId].vKeyCode > 0)); + + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); + bKeyScanOn = TRUE; + return 1; + } + } + + if (lw == IDC_HOTKEY_ASSIGN) + { + BOOL bOwnActiveShortcut = FALSE; + + if (nSelectedHotkeyId >= 0 && currentVKeyCode != 0) + { + UINT modifiers = 0; + if (GetCheckBox (hwndDlg, IDC_HK_MOD_CTRL)) + modifiers = MOD_CONTROL; + + if (GetCheckBox (hwndDlg, IDC_HK_MOD_ALT)) + modifiers |= MOD_ALT; + + if (GetCheckBox (hwndDlg, IDC_HK_MOD_SHIFT)) + modifiers |= MOD_SHIFT; + + if (GetCheckBox (hwndDlg, IDC_HK_MOD_WIN)) + modifiers |= MOD_WIN; + + // Check if it's not already assigned + if (ShortcutInUse (currentVKeyCode, modifiers, tmpHotkeys)) + { + Error ("SHORTCUT_ALREADY_IN_USE"); + return 1; + } + + // Check for reserved system keys + switch (currentVKeyCode) + { + case VK_F1: + case VK_F12: + /* F1 is help and F12 is reserved for use by the debugger at all times */ + if (modifiers == 0) + { + Error ("CANNOT_USE_RESERVED_KEY"); + return 1; + } + break; + } + + bOwnActiveShortcut = ShortcutInUse (currentVKeyCode, modifiers, Hotkeys); + + // Test if the shortcut can be assigned without errors + if (!bOwnActiveShortcut + && !RegisterHotKey (hwndDlg, nSelectedHotkeyId, modifiers, currentVKeyCode)) + { + handleWin32Error(hwndDlg); + return 1; + } + else + { + if (!bOwnActiveShortcut && !UnregisterHotKey (hwndDlg, nSelectedHotkeyId)) + handleWin32Error(hwndDlg); + + tmpHotkeys[nSelectedHotkeyId].vKeyCode = currentVKeyCode; + tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = modifiers; + + SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); + nSelectedHotkeyId = -1; + bKeyScanOn = FALSE; + } + } + DisplayHotkeyList(hwndDlg); + return 1; + } + + if (lw == IDC_HOTKEY_REMOVE) + { + if (nSelectedHotkeyId >= 0) + { + tmpHotkeys[nSelectedHotkeyId].vKeyCode = 0; + tmpHotkeys[nSelectedHotkeyId].vKeyModifiers = 0; + SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); + nSelectedHotkeyId = -1; + bKeyScanOn = FALSE; + DisplayHotkeyList(hwndDlg); + } + return 1; + } + + if (lw == IDC_RESET_HOTKEYS) + { + int i; + + for (i = 0; i < NBR_HOTKEYS; i++) + { + tmpHotkeys[i].vKeyCode = 0; + tmpHotkeys[i].vKeyModifiers = 0; + } + SetWindowTextW (GetDlgItem (hwndDlg, IDC_HOTKEY_KEY), L""); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_ASSIGN), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_HOTKEY_REMOVE), FALSE); + nSelectedHotkeyId = -1; + bKeyScanOn = FALSE; + DisplayHotkeyList(hwndDlg); + return 1; + } + + if (lw == IDC_HK_DISMOUNT_PLAY_SOUND) + { + bTPlaySoundOnSuccessfulHkDismount = GetCheckBox (hwndDlg, IDC_HK_DISMOUNT_PLAY_SOUND); + } + + if (lw == IDC_HK_DISMOUNT_BALLOON_TOOLTIP) + { + bTDisplayBalloonOnSuccessfulHkDismount = GetCheckBox (hwndDlg, IDC_HK_DISMOUNT_BALLOON_TOOLTIP); + } + + if (lw == IDCANCEL || lw == IDCLOSE) + { + KillTimer (hwndDlg, 0xfe); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + if (lw == IDOK) + { + UnregisterAllHotkeys (hwndMainDlg, Hotkeys); + memcpy (Hotkeys, tmpHotkeys, sizeof(Hotkeys)); + RegisterAllHotkeys (hwndMainDlg, Hotkeys); + KillTimer (hwndDlg, 0xfe); + bPlaySoundOnSuccessfulHkDismount = bTPlaySoundOnSuccessfulHkDismount; + bDisplayBalloonOnSuccessfulHkDismount = bTDisplayBalloonOnSuccessfulHkDismount; + + SaveSettings (hwndDlg); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + return 0; + + case WM_CLOSE: + + KillTimer (hwndDlg, 0xfe); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + return 0; +} + + diff --git a/src/Mount/Hotkeys.h b/src/Mount/Hotkeys.h new file mode 100644 index 00000000..f01f4d62 --- /dev/null +++ b/src/Mount/Hotkeys.h @@ -0,0 +1,48 @@ +/* + Copyright (c) 2005 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +enum +{ + /* When adding/removing hot keys, update the following functions in Mount.c: + DisplayHotkeyList() + SaveSettings() + LoadSettings() + HandleHotKey() */ + + HK_AUTOMOUNT_DEVICES = 0, + HK_CLOSE_SECURITY_TOKEN_SESSIONS, + HK_DISMOUNT_ALL, + HK_DISMOUNT_ALL_AND_WIPE, + HK_FORCE_DISMOUNT_ALL_AND_WIPE, + HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT, + HK_MOUNT_FAVORITE_VOLUMES, + HK_SHOW_HIDE_MAIN_WINDOW, + HK_WIPE_CACHE, + NBR_HOTKEYS +}; + +typedef struct +{ + UINT vKeyCode; + UINT vKeyModifiers; +} TCHOTKEY; + +extern TCHOTKEY Hotkeys [NBR_HOTKEYS]; + +BOOL CALLBACK HotkeysDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +BOOL GetKeyName (UINT vKey, wchar_t *keyName); +void UnregisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[]); +BOOL RegisterAllHotkeys (HWND hwndDlg, TCHOTKEY hotkeys[]); + +#ifdef __cplusplus +} +#endif diff --git a/src/Mount/Logo_288dpi.bmp b/src/Mount/Logo_288dpi.bmp new file mode 100644 index 00000000..5de59a76 Binary files /dev/null and b/src/Mount/Logo_288dpi.bmp differ diff --git a/src/Mount/Logo_96dpi.bmp b/src/Mount/Logo_96dpi.bmp new file mode 100644 index 00000000..b76984f9 Binary files /dev/null and b/src/Mount/Logo_96dpi.bmp differ diff --git a/src/Mount/MainCom.cpp b/src/Mount/MainCom.cpp new file mode 100644 index 00000000..ca3b5ef6 --- /dev/null +++ b/src/Mount/MainCom.cpp @@ -0,0 +1,267 @@ +/* + Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include +#include +#include +#include "BaseCom.h" +#include "BootEncryption.h" +#include "Dlgcode.h" +#include "MainCom.h" +#include "MainCom_h.h" +#include "MainCom_i.c" +#include "Mount.h" +#include "Password.h" + +using namespace TrueCrypt; + +static volatile LONG ObjectCount = 0; + +class TrueCryptMainCom : public ITrueCryptMainCom +{ + +public: + TrueCryptMainCom (DWORD messageThreadId) : RefCount (0), MessageThreadId (messageThreadId) + { + InterlockedIncrement (&ObjectCount); + } + + ~TrueCryptMainCom () + { + if (InterlockedDecrement (&ObjectCount) == 0) + PostThreadMessage (MessageThreadId, WM_APP, 0, 0); + } + + virtual ULONG STDMETHODCALLTYPE AddRef () + { + return InterlockedIncrement (&RefCount); + } + + virtual ULONG STDMETHODCALLTYPE Release () + { + if (!InterlockedDecrement (&RefCount)) + { + delete this; + return 0; + } + + return RefCount; + } + + virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **ppvObject) + { + if (riid == IID_IUnknown || riid == IID_ITrueCryptMainCom) + *ppvObject = this; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + AddRef (); + return S_OK; + } + + virtual void STDMETHODCALLTYPE AnalyzeKernelMiniDump (LONG_PTR hwndDlg) + { + MainDlg = (HWND) hwndDlg; + ::AnalyzeKernelMiniDump ((HWND) hwndDlg); + } + + virtual int STDMETHODCALLTYPE BackupVolumeHeader (LONG_PTR hwndDlg, BOOL bRequireConfirmation, BSTR lpszVolume) + { + USES_CONVERSION; + MainDlg = (HWND) hwndDlg; + return ::BackupVolumeHeader ((HWND) hwndDlg, bRequireConfirmation, CW2A (lpszVolume)); + } + + virtual int STDMETHODCALLTYPE RestoreVolumeHeader (LONG_PTR hwndDlg, BSTR lpszVolume) + { + USES_CONVERSION; + MainDlg = (HWND) hwndDlg; + return ::RestoreVolumeHeader ((HWND) hwndDlg, CW2A (lpszVolume)); + } + + virtual DWORD STDMETHODCALLTYPE CallDriver (DWORD ioctl, BSTR input, BSTR *output) + { + return BaseCom::CallDriver (ioctl, input, output); + } + + virtual int STDMETHODCALLTYPE ChangePassword (BSTR volumePath, Password *oldPassword, Password *newPassword, int pkcs5, LONG_PTR hWnd) + { + USES_CONVERSION; + MainDlg = (HWND) hWnd; + return ::ChangePwd (CW2A (volumePath), oldPassword, newPassword, pkcs5, (HWND) hWnd); + } + + virtual DWORD STDMETHODCALLTYPE CopyFile (BSTR sourceFile, BSTR destinationFile) + { + return BaseCom::CopyFile (sourceFile, destinationFile); + } + + virtual DWORD STDMETHODCALLTYPE DeleteFile (BSTR file) + { + return BaseCom::DeleteFile (file); + } + + virtual BOOL STDMETHODCALLTYPE IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) + { + return BaseCom::IsPagingFileActive (checkNonWindowsPartitionsOnly); + } + + virtual DWORD STDMETHODCALLTYPE ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone) + { + return BaseCom::ReadWriteFile (write, device, filePath, bufferBstr, offset, size, sizeDone); + } + + virtual DWORD STDMETHODCALLTYPE RegisterFilterDriver (BOOL registerDriver, int filterType) + { + return BaseCom::RegisterFilterDriver (registerDriver, filterType); + } + + virtual DWORD STDMETHODCALLTYPE RegisterSystemFavoritesService (BOOL registerService) + { + return BaseCom::RegisterSystemFavoritesService (registerService); + } + + virtual DWORD STDMETHODCALLTYPE SetDriverServiceStartType (DWORD startType) + { + return BaseCom::SetDriverServiceStartType (startType); + } + + virtual DWORD STDMETHODCALLTYPE WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value) + { + return BaseCom::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value); + } + +protected: + DWORD MessageThreadId; + LONG RefCount; +}; + + +extern "C" BOOL ComServerMain () +{ + SetProcessShutdownParameters (0x100, 0); + + TrueCryptFactory factory (GetCurrentThreadId ()); + DWORD cookie; + + if (IsUacSupported ()) + UacElevated = TRUE; + + if (CoRegisterClassObject (CLSID_TrueCryptMainCom, (LPUNKNOWN) &factory, + CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie) != S_OK) + return FALSE; + + MSG msg; + while (int r = GetMessage (&msg, NULL, 0, 0)) + { + if (r == -1) + return FALSE; + + TranslateMessage (&msg); + DispatchMessage (&msg); + + if (msg.message == WM_APP + && ObjectCount < 1 + && !factory.IsServerLocked ()) + break; + } + CoRevokeClassObject (cookie); + + return TRUE; +} + + +static BOOL ComGetInstance (HWND hWnd, ITrueCryptMainCom **tcServer) +{ + return ComGetInstanceBase (hWnd, CLSID_TrueCryptMainCom, IID_ITrueCryptMainCom, (void **) tcServer); +} + + +ITrueCryptMainCom *GetElevatedInstance (HWND parent) +{ + ITrueCryptMainCom *instance; + + if (!ComGetInstance (parent, &instance)) + throw UserAbort (SRC_POS); + + return instance; +} + + +extern "C" void UacAnalyzeKernelMiniDump (HWND hwndDlg) +{ + CComPtr tc; + + CoInitialize (NULL); + + if (ComGetInstance (hwndDlg, &tc)) + { + WaitCursor(); + tc->AnalyzeKernelMiniDump ((LONG_PTR) hwndDlg); + NormalCursor(); + } + + CoUninitialize (); +} + + +extern "C" int UacBackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, char *lpszVolume) +{ + CComPtr tc; + int r; + + CoInitialize (NULL); + + if (ComGetInstance (hwndDlg, &tc)) + r = tc->BackupVolumeHeader ((LONG_PTR) hwndDlg, bRequireConfirmation, CComBSTR (lpszVolume)); + else + r = -1; + + CoUninitialize (); + + return r; +} + + +extern "C" int UacRestoreVolumeHeader (HWND hwndDlg, char *lpszVolume) +{ + CComPtr tc; + int r; + + CoInitialize (NULL); + + if (ComGetInstance (hwndDlg, &tc)) + r = tc->RestoreVolumeHeader ((LONG_PTR) hwndDlg, CComBSTR (lpszVolume)); + else + r = -1; + + CoUninitialize (); + + return r; +} + + +extern "C" int UacChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg) +{ + CComPtr tc; + int r; + + if (ComGetInstance (hwndDlg, &tc)) + { + WaitCursor (); + r = tc->ChangePassword (CComBSTR (lpszVolume), oldPassword, newPassword, pkcs5, (LONG_PTR) hwndDlg); + NormalCursor (); + } + else + r = -1; + + return r; +} diff --git a/src/Mount/MainCom.h b/src/Mount/MainCom.h new file mode 100644 index 00000000..44d9db45 --- /dev/null +++ b/src/Mount/MainCom.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#ifndef TC_HEADER_MAIN_COM +#define TC_HEADER_MAIN_COM + +#include + +#ifdef __cplusplus + +#include "MainCom_h.h" +ITrueCryptMainCom *GetElevatedInstance (HWND parent); + +extern "C" { +#endif + +BOOL ComServerMain (); +void UacAnalyzeKernelMiniDump (HWND hwndDlg); +int UacBackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, char *lpszVolume); +int UacRestoreVolumeHeader (HWND hwndDlg, char *lpszVolume); +int UacChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg); + +#ifdef __cplusplus +} +#endif + +#endif // TC_HEADER_MAIN_COM diff --git a/src/Mount/MainCom.idl b/src/Mount/MainCom.idl new file mode 100644 index 00000000..7d8f60dc --- /dev/null +++ b/src/Mount/MainCom.idl @@ -0,0 +1,50 @@ +/* + Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +import "wtypes.idl"; +import "..\Common\Password.h"; + +[ + uuid(1770F56C-7881-4591-A179-79B8001C7D42), + helpstring("TrueCrypt Main UAC Support Library"), + version(2.4) // Update ComSetup.cpp when changing version number +] +library TrueCryptMainCom +{ + [ + uuid(252C9DE6-D4B9-4A59-8A10-9CA73217B3D0), + object, + oleautomation, + helpstring("TrueCrypt Main UAC Support Interface") + ] + interface ITrueCryptMainCom : IUnknown + { + void AnalyzeKernelMiniDump (LONG_PTR hwndDlg); + int BackupVolumeHeader (LONG_PTR hwndDlg, BOOL bRequireConfirmation, BSTR lpszVolume); + DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output); + int ChangePassword (BSTR volumePath, Password *oldPassword, Password *newPassword, int pkcs5, LONG_PTR hWnd); + DWORD CopyFile (BSTR sourceFile, BSTR destinationFile); + DWORD DeleteFile (BSTR file); + BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly); + DWORD ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone); + DWORD RegisterFilterDriver (BOOL registerDriver, int filterType); + DWORD RegisterSystemFavoritesService (BOOL registerService); + int RestoreVolumeHeader (LONG_PTR hwndDlg, BSTR lpszVolume); + DWORD SetDriverServiceStartType (DWORD startType); + DWORD WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value); + }; + + [ + uuid(CECBC0EE-78D9-41E6-BCF1-BC222BB224BA), + helpstring("TrueCrypt Main UAC Support Coclass") + ] + coclass TrueCryptMainCom + { + [default] interface ITrueCryptMainCom; + } +} diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c new file mode 100644 index 00000000..47d16500 --- /dev/null +++ b/src/Mount/Mount.c @@ -0,0 +1,8999 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of Encryption for the Masses 2.02a, which is + Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License + Agreement for Encryption for the Masses'. Modifications and additions to + the original source code (contained in this file) and all other portions + of this file are Copyright (c) 2003-2012 TrueCrypt Developers Association + and are governed by the TrueCrypt License 3.0 the full text of which is + contained in the file License.txt included in TrueCrypt binary and source + code distribution packages. */ + +#include "Tcdefs.h" + +#include +#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" + +using namespace TrueCrypt; + +enum timer_ids +{ + TIMER_ID_MAIN = 0xff, + TIMER_ID_KEYB_LAYOUT_GUARD +}; + +enum hidden_os_read_only_notif_mode +{ + TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE = 0, + TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT, + TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED +}; + +#define TIMER_INTERVAL_MAIN 500 +#define TIMER_INTERVAL_KEYB_LAYOUT_GUARD 10 + +BootEncryption *BootEncObj = NULL; +BootEncryptionStatus BootEncStatus; +BootEncryptionStatus RecentBootEncStatus; + +BOOL bExplore = FALSE; /* Display explorer window after mount */ +BOOL bBeep = FALSE; /* Donot beep after mount */ +char szFileName[TC_MAX_PATH+1]; /* Volume to mount */ +char szDriveLetter[3]; /* Drive Letter to mount */ +char commandLineDrive = 0; +BOOL bCacheInDriver = FALSE; /* Cache any passwords we see */ +BOOL bCacheInDriverDefault = FALSE; +BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */ +BOOL 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 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 DisableSystemCrashDetection = FALSE; +BOOL SystemCrashDetected = 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 = 0; /* Volume drive letter to unmount (-1 = all) */ +Password VolumePassword; /* Password used for mounting volumes */ +Password CmdVolumePassword; /* Password passed from command line */ +BOOL CmdVolumePasswordValid = FALSE; +MountOptions CmdMountOptions; +BOOL CmdMountOptionsValid = FALSE; +MountOptions mountOptions; +MountOptions defaultMountOptions; +KeyFile *FirstCmdKeyFile; + +HBITMAP hbmLogoBitmapRescaled = NULL; +char OrigKeyboardLayout [8+1] = "00000409"; +BOOL bKeyboardLayoutChanged = FALSE; /* TRUE if the keyboard layout was changed to the standard US keyboard layout (from any other layout). */ +BOOL bKeybLayoutAltKeyWarningShown = FALSE; /* TRUE if the user has been informed that it is not possible to type characters by pressing keys while the right Alt key is held down. */ + +static KeyFilesDlgParam hidVolProtKeyFilesParam; + +static MOUNT_LIST_STRUCT LastKnownMountList; +VOLUME_NOTIFICATIONS_LIST VolumeNotificationsList; +static DWORD LastKnownLogicalDrives; + +static HANDLE TaskBarIconMutex = NULL; +static BOOL MainWindowHidden = FALSE; +static int pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; +static int bSysEncPwdChangeDlgMode = FALSE; +static int bPrebootPasswordDlgMode = FALSE; +static int NoCmdLineArgs; +static BOOL CmdLineVolumeSpecified; +static int LastDriveListVolumeColumnWidth; + +static void localcleanup (void) +{ + // Wipe command line + char *c = GetCommandLineA (); + wchar_t *wc = GetCommandLineW (); + burn(c, strlen (c)); + burn(wc, wcslen (wc) * sizeof (wchar_t)); + + /* Delete buffered bitmaps (if any) */ + if (hbmLogoBitmapRescaled != NULL) + { + DeleteObject ((HGDIOBJ) hbmLogoBitmapRescaled); + hbmLogoBitmapRescaled = NULL; + } + + /* These items should have already been cleared by the functions that used them, but we're going to + clear them for extra security. */ + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); + burn (&mountOptions, sizeof (mountOptions)); + burn (&defaultMountOptions, sizeof (defaultMountOptions)); + burn (&szFileName, sizeof(szFileName)); + + /* Cleanup common code resources */ + cleanup (); + + if (BootEncObj != NULL) + { + delete BootEncObj; + BootEncObj = NULL; + } + + RandStop (TRUE); +} + +void RefreshMainDlg (HWND hwndDlg) +{ + int drive = (char) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)))); + + MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory); + LoadDriveLetters (GetDlgItem (hwndDlg, IDC_DRIVELIST), drive); + EnableDisableButtons (hwndDlg); +} + +void EndMainDlg (HWND hwndDlg) +{ + MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory); + + if (UsePreferences) + SaveSettings (hwndDlg); + + if (bWipeCacheOnExit) + { + DWORD dwResult; + DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL); + } + + if (!bHistory) + { + SetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), ""); + ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME)); + } + + if (TaskBarIconMutex != NULL) + { + MainWindowHidden = TRUE; + ShowWindow (hwndDlg, SW_HIDE); + } + else + { + KillTimer (hwndDlg, TIMER_ID_MAIN); + TaskBarIconRemove (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); + + SetWindowLongPtr (hwndDlg, DWLP_USER, (LONG_PTR) (IsAdmin() ? TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES : 0)); + + DragAcceptFiles (hwndDlg, TRUE); + + SendMessage (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 = 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 = wcslen (str); + + SetMenuItemInfoW (GetMenu (hwndDlg), i, TRUE, &info); + } + + 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 (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); + } + + SendMessage (GetDlgItem (hwndDlg, IDC_NO_HISTORY), BM_SETCHECK, bHistory ? BST_UNCHECKED : BST_CHECKED, 0); + EnableDisableButtons (hwndDlg); +} + +void EnableDisableButtons (HWND hwndDlg) +{ + HWND hOKButton = GetDlgItem (hwndDlg, IDOK); + WORD x; + + x = LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))); + + EnableMenuItem (GetMenu (hwndDlg), IDM_MOUNT_VOLUME, MF_ENABLED); + EnableMenuItem (GetMenu (hwndDlg), IDM_MOUNT_VOLUME_OPTIONS, MF_ENABLED); + EnableMenuItem (GetMenu (hwndDlg), IDM_BACKUP_VOL_HEADER, MF_ENABLED); + EnableMenuItem (GetMenu (hwndDlg), IDM_RESTORE_VOL_HEADER, MF_ENABLED); + EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_PASSWORD, MF_ENABLED); + EnableWindow (hOKButton, TRUE); + + switch (x) + { + case TC_MLIST_ITEM_NONSYS_VOL: + { + SetWindowTextW (hOKButton, GetString ("UNMOUNT_BUTTON")); + EnableWindow (hOKButton, TRUE); + EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_ENABLED); + + EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), TRUE); + EnableMenuItem (GetMenu (hwndDlg), IDM_VOLUME_PROPERTIES, MF_ENABLED); + } + break; + + case TC_MLIST_ITEM_SYS_PARTITION: + case TC_MLIST_ITEM_SYS_DRIVE: + EnableWindow (hOKButton, FALSE); + SetWindowTextW (hOKButton, GetString ("MOUNT_BUTTON")); + EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), TRUE); + EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_GRAYED); + break; + + case TC_MLIST_ITEM_FREE: + default: + SetWindowTextW (hOKButton, GetString ("MOUNT_BUTTON")); + EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), FALSE); + EnableMenuItem (GetMenu (hwndDlg), IDM_VOLUME_PROPERTIES, MF_GRAYED); + EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_GRAYED); + } + + EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty()); + EnableMenuItem (GetMenu (hwndDlg), IDM_WIPE_CACHE, IsPasswordCacheEmpty() ? MF_GRAYED:MF_ENABLED); + EnableMenuItem (GetMenu (hwndDlg), IDM_CLEAR_HISTORY, IsComboEmpty (GetDlgItem (hwndDlg, IDC_VOLUME)) ? MF_GRAYED:MF_ENABLED); +} + +BOOL VolumeSelected (HWND hwndDlg) +{ + return (GetWindowTextLength (GetDlgItem (hwndDlg, IDC_VOLUME)) > 0); +} + +/* Returns TRUE if the last partition/drive selected via the Select Device dialog box was the system +partition/drive and if it is encrypted. + WARNING: This function is very fast but not always reliable (for example, if the user manually types + a device path before Select Device is invoked during the session; after the Select Device dialog + has been invoked at least once, the correct system device paths are cached). Therefore, it must NOT + be used before performing any dangerous operations (such as header backup restore or formatting a + supposedly non-system device) -- instead use IsSystemDevicePath(path, hwndDlg, TRUE) for such + purposes. This function can be used only for preliminary GUI checks requiring very fast responses. */ +BOOL ActiveSysEncDeviceSelected (void) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + + if (BootEncStatus.DriveEncrypted) + { + int retCode = 0; + + GetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szFileName, sizeof (szFileName)); + + retCode = IsSystemDevicePath (szFileName, MainDlg, FALSE); + + return (WholeSysDriveEncryption(FALSE) ? (retCode == 2 || retCode == 1) : (retCode == 1)); + } + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + return FALSE; +} + +void LoadSettings (HWND hwndDlg) +{ + EnableHwEncryption ((ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE); + + WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE; + + LoadSysEncSettings (hwndDlg); + + if (LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0) + bInPlaceEncNonSysPending = TRUE; + + // If the config file has already been loaded during this session + if (ConfigBuffer != NULL) + { + free (ConfigBuffer); + ConfigBuffer = NULL; + } + + // Options + bExplore = ConfigReadInt ("OpenExplorerWindowAfterMount", FALSE); + bUseDifferentTrayIconIfVolMounted = ConfigReadInt ("UseDifferentTrayIconIfVolumesMounted", TRUE); + + bHistory = ConfigReadInt ("SaveVolumeHistory", FALSE); + + bCacheInDriverDefault = bCacheInDriver = ConfigReadInt ("CachePasswords", FALSE); + bWipeCacheOnExit = ConfigReadInt ("WipePasswordCacheOnExit", FALSE); + bWipeCacheOnAutoDismount = ConfigReadInt ("WipeCacheOnAutoDismount", TRUE); + + bStartOnLogon = ConfigReadInt ("StartOnLogon", FALSE); + bMountDevicesOnLogon = ConfigReadInt ("MountDevicesOnLogon", FALSE); + bMountFavoritesOnLogon = ConfigReadInt ("MountFavoritesOnLogon", FALSE); + + bEnableBkgTask = ConfigReadInt ("EnableBackgroundTask", TRUE); + bCloseBkgTaskWhenNoVolumes = ConfigReadInt ("CloseBackgroundTaskOnNoVolumes", FALSE); + + bDismountOnLogOff = ConfigReadInt ("DismountOnLogOff", !(IsServerOS() && IsAdmin())); + bDismountOnPowerSaving = ConfigReadInt ("DismountOnPowerSaving", FALSE); + bDismountOnScreenSaver = ConfigReadInt ("DismountOnScreenSaver", FALSE); + bForceAutoDismount = ConfigReadInt ("ForceAutoDismount", TRUE); + MaxVolumeIdleTime = ConfigReadInt ("MaxVolumeIdleTime", -60); + + HiddenSectorDetectionStatus = ConfigReadInt ("HiddenSectorDetectionStatus", 0); + + defaultKeyFilesParam.EnableKeyFiles = ConfigReadInt ("UseKeyfiles", FALSE); + + bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = ConfigReadInt ("PreserveTimestamps", TRUE); + defaultMountOptions.Removable = ConfigReadInt ("MountVolumesRemovable", FALSE); + defaultMountOptions.ReadOnly = ConfigReadInt ("MountVolumesReadOnly", FALSE); + defaultMountOptions.ProtectHiddenVolume = FALSE; + defaultMountOptions.PartitionInInactiveSysEncScope = FALSE; + defaultMountOptions.RecoveryMode = FALSE; + defaultMountOptions.UseBackupHeader = FALSE; + + mountOptions = defaultMountOptions; + + CloseSecurityTokenSessionsAfterMount = ConfigReadInt ("CloseSecurityTokenSessionsAfterMount", 0); + DisableSystemCrashDetection = ConfigReadInt ("DisableSystemCrashDetection", FALSE); + + if (IsHiddenOSRunning()) + HiddenSysLeakProtectionNotificationStatus = ConfigReadInt ("HiddenSystemLeakProtNotifStatus", TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE); + + // Drive letter - command line arg overrides registry + if (szDriveLetter[0] == 0) + ConfigReadString ("LastSelectedDrive", "", szDriveLetter, sizeof (szDriveLetter)); + + ConfigReadString ("SecurityTokenLibrary", "", SecurityTokenLibraryPath, sizeof (SecurityTokenLibraryPath) - 1); + if (SecurityTokenLibraryPath[0]) + InitSecurityTokenLibrary(); + + // Hotkeys + bPlaySoundOnSuccessfulHkDismount = ConfigReadInt ("PlaySoundOnHotkeyMountDismount", TRUE); + bDisplayBalloonOnSuccessfulHkDismount = ConfigReadInt ("DisplayMsgBoxOnHotkeyDismount", TRUE); + Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyModifiers = ConfigReadInt ("HotkeyModAutoMountDevices", 0); + Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyCode = ConfigReadInt ("HotkeyCodeAutoMountDevices", 0); + Hotkeys [HK_DISMOUNT_ALL].vKeyModifiers = ConfigReadInt ("HotkeyModDismountAll", 0); + Hotkeys [HK_DISMOUNT_ALL].vKeyCode = ConfigReadInt ("HotkeyCodeDismountAll", 0); + Hotkeys [HK_WIPE_CACHE].vKeyModifiers = ConfigReadInt ("HotkeyModWipeCache", 0); + Hotkeys [HK_WIPE_CACHE].vKeyCode = ConfigReadInt ("HotkeyCodeWipeCache", 0); + Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers = ConfigReadInt ("HotkeyModDismountAllWipe", 0); + Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyCode = ConfigReadInt ("HotkeyCodeDismountAllWipe", 0); + Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers = ConfigReadInt ("HotkeyModForceDismountAllWipe", 0); + Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode = ConfigReadInt ("HotkeyCodeForceDismountAllWipe", 0); + Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers = ConfigReadInt ("HotkeyModForceDismountAllWipeExit", 0); + Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode = ConfigReadInt ("HotkeyCodeForceDismountAllWipeExit", 0); + Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers = ConfigReadInt ("HotkeyModMountFavoriteVolumes", 0); + Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyCode = ConfigReadInt ("HotkeyCodeMountFavoriteVolumes", 0); + Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers = ConfigReadInt ("HotkeyModShowHideMainWindow", 0); + Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode = ConfigReadInt ("HotkeyCodeShowHideMainWindow", 0); + Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers = ConfigReadInt ("HotkeyModCloseSecurityTokenSessions", 0); + Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode = ConfigReadInt ("HotkeyCodeCloseSecurityTokenSessions", 0); + + // History + if (bHistoryCmdLine != TRUE) + { + LoadCombo (GetDlgItem (hwndDlg, IDC_VOLUME)); + if (CmdLineVolumeSpecified) + SetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName); + } +} + +void SaveSettings (HWND hwndDlg) +{ + WaitCursor (); + + char szTmp[32] = {0}; + LPARAM lLetter; + + // Options + ConfigWriteBegin (); + + ConfigWriteInt ("OpenExplorerWindowAfterMount", bExplore); + ConfigWriteInt ("UseDifferentTrayIconIfVolumesMounted", bUseDifferentTrayIconIfVolMounted); + ConfigWriteInt ("SaveVolumeHistory", !IsButtonChecked (GetDlgItem (hwndDlg, IDC_NO_HISTORY))); + + ConfigWriteInt ("CachePasswords", bCacheInDriverDefault); + ConfigWriteInt ("WipePasswordCacheOnExit", bWipeCacheOnExit); + ConfigWriteInt ("WipeCacheOnAutoDismount", bWipeCacheOnAutoDismount); + + ConfigWriteInt ("StartOnLogon", bStartOnLogon); + ConfigWriteInt ("MountDevicesOnLogon", bMountDevicesOnLogon); + ConfigWriteInt ("MountFavoritesOnLogon", bMountFavoritesOnLogon); + + ConfigWriteInt ("MountVolumesReadOnly", defaultMountOptions.ReadOnly); + ConfigWriteInt ("MountVolumesRemovable", defaultMountOptions.Removable); + ConfigWriteInt ("PreserveTimestamps", defaultMountOptions.PreserveTimestamp); + + ConfigWriteInt ("EnableBackgroundTask", bEnableBkgTask); + ConfigWriteInt ("CloseBackgroundTaskOnNoVolumes", bCloseBkgTaskWhenNoVolumes); + + ConfigWriteInt ("DismountOnLogOff", bDismountOnLogOff); + ConfigWriteInt ("DismountOnPowerSaving", bDismountOnPowerSaving); + ConfigWriteInt ("DismountOnScreenSaver", bDismountOnScreenSaver); + ConfigWriteInt ("ForceAutoDismount", bForceAutoDismount); + ConfigWriteInt ("MaxVolumeIdleTime", MaxVolumeIdleTime); + + ConfigWriteInt ("HiddenSectorDetectionStatus", HiddenSectorDetectionStatus); + + ConfigWriteInt ("UseKeyfiles", defaultKeyFilesParam.EnableKeyFiles); + + if (IsHiddenOSRunning()) + ConfigWriteInt ("HiddenSystemLeakProtNotifStatus", HiddenSysLeakProtectionNotificationStatus); + + // Drive Letter + lLetter = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + if (LOWORD (lLetter) != 0xffff) + sprintf (szTmp, "%c:", (char) HIWORD (lLetter)); + ConfigWriteString ("LastSelectedDrive", szTmp); + + ConfigWriteInt ("CloseSecurityTokenSessionsAfterMount", CloseSecurityTokenSessionsAfterMount); + ConfigWriteInt ("DisableSystemCrashDetection", DisableSystemCrashDetection); + + // 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 + if (GetPreferredLangId () != NULL) + ConfigWriteString ("Language", GetPreferredLangId ()); + + // PKCS#11 Library Path + ConfigWriteString ("SecurityTokenLibrary", SecurityTokenLibraryPath[0] ? SecurityTokenLibraryPath : ""); + + ConfigWriteEnd (); + + // History + DumpCombo (GetDlgItem (hwndDlg, IDC_VOLUME), IsButtonChecked (GetDlgItem (hwndDlg, 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) is (or is to be) encrypted +BOOL WholeSysDriveEncryption (BOOL bSilent) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + + 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 (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 (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, NULL); + } + } + + 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, NULL); + AppendMenuW (popup, MF_STRING, IDM_SYS_ENC_SETTINGS, GetString ("IDM_SYS_ENC_SETTINGS")); + + if (!IsHiddenOSRunning()) + { + AppendMenu (popup, MF_SEPARATOR, 0, NULL); + 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")); + } + + if (!bToolsOnly) + { + if (SysDriveOrPartitionFullyEncrypted (FALSE) && !IsHiddenOSRunning()) + { + AppendMenu (popup, MF_SEPARATOR, 0, NULL); + AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT")); + } + AppendMenu (popup, MF_SEPARATOR, 0, NULL); + 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 (const char *devicePath, BOOL quiet) +{ + BOOL tmpbDevice; + char szDevicePath [TC_MAX_PATH+1]; + char szDiskFile [TC_MAX_PATH+1]; + + if (strlen (devicePath) < 2) + { + GetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szDevicePath, sizeof (szDevicePath)); + CreateFullVolumePath (szDiskFile, szDevicePath, &tmpbDevice); + + if (!tmpbDevice) + { + if (!quiet) + Warning ("NO_SYSENC_PARTITION_SELECTED"); + + return FALSE; + } + + if (LOWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))) != TC_MLIST_ITEM_FREE) + { + if (!quiet) + Warning ("SELECT_FREE_DRIVE"); + + return FALSE; + } + } + else + strncpy (szDevicePath, devicePath, sizeof (szDevicePath)); + + char *partionPortion = strrchr (szDevicePath, '\\'); + + if (!partionPortion + || !_stricmp (partionPortion, "\\Partition0")) + { + // Only partitions are supported (not whole drives) + if (!quiet) + Warning ("NO_SYSENC_PARTITION_SELECTED"); + + return FALSE; + } + + try + { + BootEncStatus = BootEncObj->GetStatus(); + + if (BootEncStatus.DriveMounted) + { + int retCode = 0; + int driveNo; + char parentDrivePath [TC_MAX_PATH+1]; + + if (sscanf (szDevicePath, "\\Device\\Harddisk%d\\Partition", &driveNo) != 1) + { + if (!quiet) + Error ("INVALID_PATH"); + + return FALSE; + } + + _snprintf (parentDrivePath, + sizeof (parentDrivePath), + "\\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"); + + return FALSE; + } + } + else + return TRUE; + } + catch (Exception &e) + { + NormalCursor(); + e.Show (MainDlg); + } + + 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 (void) +{ + try + { + int driveNo; + char szDevicePath [TC_MAX_PATH+1]; + char parentDrivePath [TC_MAX_PATH+1]; + + if (bPrebootPasswordDlgMode) + return FALSE; + + GetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szDevicePath, sizeof (szDevicePath)); + + if (sscanf (szDevicePath, "\\Device\\Harddisk%d\\Partition", &driveNo) != 1) + return FALSE; + + _snprintf (parentDrivePath, + sizeof (parentDrivePath), + "\\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, char 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 = (char) (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 char *arg) +{ + char t[TC_MAX_PATH] = {'"',0}; + char *tmp; + + GetModuleFileName (NULL, t+1, sizeof(t)-1); + + tmp = strrchr (t, '\\'); + if (tmp) + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory (&si, sizeof (si)); + + strcpy (++tmp, "TrueCrypt Format.exe\""); + + if (!FileExists(t)) + Error ("VOL_CREATION_WIZARD_NOT_FOUND"); // Display a user-friendly error message and advise what to do + + if (strlen (arg) > 0) + { + strcat (t, " "); + strcat (t, arg); + } + + if (!CreateProcess (NULL, (LPSTR) t, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) + { + handleWin32Error (hwndDlg); + } + else + { + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + } + } +} + + +// Fills drive list +// drive>0 = update only the corresponding drive subitems +void LoadDriveLetters (HWND hTree, int drive) +{ + // Remember the top-most visible item + int lastTopMostVisibleItem = ListView_GetTopIndex (hTree); + + char *szDriveLetters[]= + {"A:", "B:", "C:", "D:", + "E:", "F:", "G:", "H:", "I:", "J:", "K:", + "L:", "M:", "N:", "O:", "P:", "Q:", "R:", + "S:", "T:", "U:", "V:", "W:", "X:", "Y:", + "Z:"}; + + DWORD dwResult; + BOOL bResult; + DWORD dwUsedDrives; + MOUNT_LIST_STRUCT driver; + VOLUME_PROPERTIES_STRUCT propSysEnc; + char 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); + AbortProcessSilent(); + } + + LastKnownLogicalDrives = dwUsedDrives = GetLogicalDrives (); + if (dwUsedDrives == 0) + Warning ("DRIVELETTERS"); + + 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); + } + + { + char 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; + strcpy (szTmp, " "); + + 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)) + { + wcscpy (szTmpW, GetString ("SYSTEM_DRIVE")); + } + else + { + // Partially encrypted + + if (BootEncStatus.SetupInProgress) + { + // Currently encrypting/decrypting + + if (BootEncStatus.SetupMode != SetupDecryption) + { + _snwprintf (szTmpW, + sizeof szTmpW/2, + GetString ("SYSTEM_DRIVE_ENCRYPTING"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + else + { + _snwprintf (szTmpW, + sizeof szTmpW/2, + GetString ("SYSTEM_DRIVE_DECRYPTING"), + 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0)); + } + } + else + { + _snwprintf (szTmpW, + sizeof szTmpW/2, + GetString ("SYSTEM_DRIVE_PARTIALLY_ENCRYPTED"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + } + + ListSubItemSetW (hTree, listItem.iItem, 1, szTmpW); + + GetSizeString (GetSysEncDeviceSize(TRUE), szTmpW); + ListSubItemSetW (hTree, listItem.iItem, 2, szTmpW); + + EAGetName (szTmp, propSysEnc.ea); + listItem.iSubItem = 3; + ListView_SetItem (hTree, &listItem); + + ListSubItemSetW (hTree, listItem.iItem, 4, GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE")); + } + } + + /* Drive letters */ + + for (i = 2; i < 26; i++) + { + int curDrive = 0; + + BOOL bSysEncPartition = (bSysEnc && !bWholeSysDriveEncryption && sysDriveLetter == *((char *) 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) + { + char 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 + '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)) + { + wcscpy (szTmpW, GetString (IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION")); + } + else + { + // Partially encrypted + + if (BootEncStatus.SetupInProgress) + { + // Currently encrypting/decrypting + + if (BootEncStatus.SetupMode != SetupDecryption) + { + _snwprintf (szTmpW, + sizeof szTmpW/2, + GetString ("SYSTEM_PARTITION_ENCRYPTING"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + else + { + _snwprintf (szTmpW, + sizeof szTmpW/2, + GetString ("SYSTEM_PARTITION_DECRYPTING"), + 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0)); + } + } + else + { + _snwprintf (szTmpW, + sizeof szTmpW/2, + GetString ("SYSTEM_PARTITION_PARTIALLY_ENCRYPTED"), + (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0); + } + } + + ListSubItemSetW (hTree, listItem.iItem, 1, szTmpW); + } + else + { + ToSBCS (driver.wszVolume[i]); + char *path = (char *) driver.wszVolume[i]; + + if (memcmp (path, "\\??\\", 4) == 0) + path += 4; + + listItem.iSubItem = 1; + + wstring label = GetFavoriteVolumeLabel (path); + if (!label.empty()) + ListSubItemSetW (hTree, listItem.iItem, 1, (wchar_t *) label.c_str()); + else + ListSubItemSet (hTree, listItem.iItem, 1, (char *) FitPathInGfxWidth (hTree, hUserFont, ListView_GetColumnWidth (hTree, 1) - GetTextGfxWidth (hTree, L"___", hUserFont), path).c_str()); + } + + GetSizeString (bSysEncPartition ? GetSysEncDeviceSize(TRUE) : driver.diskLength[i], szTmpW); + ListSubItemSetW (hTree, listItem.iItem, 2, szTmpW); + + EAGetName (szTmp, bSysEncPartition ? propSysEnc.ea : driver.ea[i]); + listItem.iSubItem = 3; + ListView_SetItem (hTree, &listItem); + + if (bSysEncPartition) + { + ws = GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE"); + VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE; + ListSubItemSetW (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"?"; + } + ListSubItemSetW (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; + swprintf (szTmp, GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), i+'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 = ""; + 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]; + BOOL bEnable = TRUE; + + GetWindowText (GetDlgItem (hwndDlg, passwordId), password, sizeof (password)); + + 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)); + break; + + default: + GetWindowText (GetDlgItem (hwndDlg, newPasswordId), newPassword, sizeof (newPassword)); + GetWindowText (GetDlgItem (hwndDlg, newVerifyId), newVerify, sizeof (newVerify)); + } + + if (!keyFilesEnabled && strlen (password) < MIN_PASSWORD) + bEnable = FALSE; + else if (strcmp (newPassword, newVerify) != 0) + bEnable = FALSE; + else if (!newKeyFilesEnabled && strlen (newPassword) < MIN_PASSWORD) + bEnable = FALSE; + + burn (password, sizeof (password)); + burn (newPassword, sizeof (newPassword)); + burn (newVerify, sizeof (newVerify)); + + EnableWindow (GetDlgItem (hwndDlg, button), bEnable); +} + + +/* 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; + + WORD lw = LOWORD (wParam); + WORD hw = HIWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + LPARAM nIndex; + HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID); + int i; + + ZeroMemory (&newKeyFilesParam, sizeof (newKeyFilesParam)); + + 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); + EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE); + + SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable); + EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE); + EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), TRUE); + + 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); + + 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, 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, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), 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, 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_PKCS5_PRF), FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE); + break; + + case PCDM_CHANGE_PASSWORD: + default: + // NOP + break; + }; + + if (bSysEncPwdChangeDlgMode) + { + 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 ("00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION"); + EndDialog (hwndDlg, IDCANCEL); + return 0; + } + + bKeyboardLayoutChanged = TRUE; + } + + ShowWindow(GetDlgItem(hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_SHOW_PASSWORD_CHPWD_ORI), SW_HIDE); + + if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0) + { + Error ("CANNOT_SET_TIMER"); + 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 + char tmp[MAX_PASSWORD+1]; + memset (tmp, '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), ""); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), ""); + SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), ""); + + keybLayout = (DWORD) LoadKeyboardLayout ("00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION"); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + bKeyboardLayoutChanged = TRUE; + + wchar_t szTmp [4096]; + wcscpy (szTmp, GetString ("KEYB_LAYOUT_CHANGE_PREVENTED")); + wcscat (szTmp, L"\n\n"); + wcscat (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]; + wcscpy (szTmp, GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION")); + wcscat (szTmp, L"\n\n"); + wcscat (szTmp, GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION")); + MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST); + } + } + } + return 1; + } + return 0; + + case WM_COMMAND: + if (lw == IDCANCEL) + { + // Attempt to wipe passwords stored in the input field buffers + char tmp[MAX_PASSWORD+1]; + memset (tmp, '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); + + return 1; + } + + if (lw == IDC_KEYFILES) + { + if (bSysEncPwdChangeDlgMode) + { + Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION"); + 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"); + 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 = 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 && new_hash_algo_id != DEFAULT_HASH_ALGORITHM_BOOT) + { + int new_hash_algo_id = DEFAULT_HASH_ALGORITHM_BOOT; + Info ("ALGO_NOT_SUPPORTED_FOR_SYS_ENCRYPTION"); + SelectAlgo (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), &new_hash_algo_id); + } + } + break; + } + return 1; + + } + + if (lw == IDC_SHOW_PASSWORD_CHPWD_ORI) + { + SendMessage (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), + EM_SETPASSWORDCHAR, + GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_ORI) ? 0 : '*', + 0); + InvalidateRect (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), NULL, TRUE); + return 1; + } + + if (lw == IDC_SHOW_PASSWORD_CHPWD_NEW) + { + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), + EM_SETPASSWORDCHAR, + GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW) ? 0 : '*', + 0); + SendMessage (GetDlgItem (hwndDlg, IDC_VERIFY), + EM_SETPASSWORDCHAR, + GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW) ? 0 : '*', + 0); + InvalidateRect (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL, TRUE); + InvalidateRect (GetDlgItem (hwndDlg, IDC_VERIFY), NULL, TRUE); + return 1; + } + + if (lw == IDOK) + { + HWND hParent = GetParent (hwndDlg); + Password oldPassword; + Password newPassword; + int nStatus; + int pkcs5 = SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, + SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0); + + if (!CheckPasswordCharEncoding (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL)) + { + Error ("UNSUPPORTED_CHARS_IN_PWD"); + 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, GetDlgItem (hwndDlg, IDC_PASSWORD))) + return 1; + } + + GetWindowText (GetDlgItem (hParent, IDC_VOLUME), szFileName, sizeof (szFileName)); + + GetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), (LPSTR) oldPassword.Text, sizeof (oldPassword.Text)); + oldPassword.Length = strlen ((char *) oldPassword.Text); + + 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 = strlen ((char *) oldPassword.Text); + break; + + default: + GetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), (LPSTR) newPassword.Text, sizeof (newPassword.Text)); + newPassword.Length = strlen ((char *) newPassword.Text); + } + + WaitCursor (); + + if (KeyFilesEnable) + KeyFilesApply (&oldPassword, FirstKeyFile); + + if (newKeyFilesParam.EnableKeyFiles) + { + if (!KeyFilesApply (&newPassword, pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? FirstKeyFile : newKeyFilesParam.FirstKeyFile)) + { + nStatus = ERR_DONT_REPORT; + goto err; + } + } + + if (bSysEncPwdChangeDlgMode) + { + // System + + pkcs5 = 0; // PKCS-5 PRF unchanged (currently system encryption supports only RIPEMD-160) + + try + { + nStatus = BootEncObj->ChangePassword (&oldPassword, &newPassword, pkcs5); + } + catch (Exception &e) + { + e.Show (MainDlg); + nStatus = ERR_OS_ERROR; + } + } + else + { + // Non-system + + nStatus = ChangePwd (szFileName, &oldPassword, &newPassword, pkcs5, hwndDlg); + + if (nStatus == ERR_OS_ERROR + && GetLastError () == ERROR_ACCESS_DENIED + && IsUacSupported () + && IsVolumeDeviceHosted (szFileName)) + { + nStatus = UacChangePwd (szFileName, &oldPassword, &newPassword, pkcs5, hwndDlg); + } + } + +err: + burn (&oldPassword, sizeof (oldPassword)); + burn (&newPassword, sizeof (newPassword)); + + NormalCursor (); + + if (nStatus == 0) + { + // Attempt to wipe passwords stored in the input field buffers + char tmp[MAX_PASSWORD+1]; + memset (tmp, '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 char PasswordDlgVolume[MAX_PATH]; +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; + + switch (msg) + { + case WM_INITDIALOG: + { + szXPwd = (Password *) lParam; + LocalizeDialog (hwndDlg, "IDD_PASSWORD_DLG"); + DragAcceptFiles (hwndDlg, TRUE); + + if (PasswordDialogTitleStringId) + { + SetWindowTextW (hwndDlg, GetString (PasswordDialogTitleStringId)); + } + else if (strlen (PasswordDlgVolume) > 0) + { + wchar_t s[1024]; + RECT rect; + GetWindowRect (hwndDlg, &rect); + + wstring label = GetFavoriteVolumeLabel (PasswordDlgVolume); + if (!label.empty()) + { + wsprintfW (s, GetString ("ENTER_PASSWORD_FOR_LABEL"), label.c_str()); + } + else + { + wsprintfW (s, GetString ("ENTER_PASSWORD_FOR"), "___"); + wsprintfW (s, GetString ("ENTER_PASSWORD_FOR"), FitPathInGfxWidth (hwndDlg, WindowTitleBarFont, rect.right - rect.left - GetTextGfxWidth (hwndDlg, s, WindowTitleBarFont), PasswordDlgVolume).c_str()); + } + + SetWindowTextW (hwndDlg, s); + } + + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0); + SendMessage (GetDlgItem (hwndDlg, IDC_CACHE), BM_SETCHECK, bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0); + + 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); + } + + 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: + { + ToBootPwdField (hwndDlg, IDC_PASSWORD); + + // Attempt to wipe the password stored in the input field buffer + char tmp[MAX_PASSWORD+1]; + memset (tmp, 'X', MAX_PASSWORD); + tmp [MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), ""); + + sprintf (OrigKeyboardLayout, "%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF); + + DWORD keybLayout = (DWORD) LoadKeyboardLayout ("00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION"); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0) + { + Error ("CANNOT_SET_TIMER"); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + SetCheckBox (hwndDlg, IDC_SHOW_PASSWORD, FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD), FALSE); + + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_SETPASSWORDCHAR, '*', 0); + InvalidateRect (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL, TRUE); + + 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 + char tmp[MAX_PASSWORD+1]; + memset (tmp, 'X', MAX_PASSWORD); + tmp [MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp); + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), ""); + + keybLayout = (DWORD) LoadKeyboardLayout ("00000409", KLF_ACTIVATE); + + if (keybLayout != 0x00000409 && keybLayout != 0x04090409) + { + KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD); + Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION"); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + wchar_t szTmp [4096]; + wcscpy (szTmp, GetString ("KEYB_LAYOUT_CHANGE_PREVENTED")); + wcscat (szTmp, L"\n\n"); + wcscat (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) + { + 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_SHOW_PASSWORD) + { + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), + EM_SETPASSWORDCHAR, + GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD) ? 0 : '*', + 0); + InvalidateRect (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL, TRUE); + return 1; + } + + 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) + { + char tmp[MAX_PASSWORD+1]; + + if (lw == IDOK) + { + if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) + KeyFilesApply (&mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile); + + GetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), (LPSTR) szXPwd->Text, MAX_PASSWORD + 1); + szXPwd->Length = strlen ((char *) szXPwd->Text); + + bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_CACHE)); + } + + // Attempt to wipe password stored in the input field buffer + memset (tmp, '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"); + } + + 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)); + DragQueryFile (hdrop, i++, kf->FileName, sizeof (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(); + + 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_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_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_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_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") == 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_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 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 || p || s)) + { + if (AskWarnNoYes ("CONFIRM_NO_FORCED_AUTODISMOUNT") == 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_POWERSAVING && p + || lw == IDC_PREF_DISMOUNT_SCREENSAVER && s)) + Warning ("WARN_PREF_AUTO_DISMOUNT"); + } + + if (p && lw == IDC_PREF_DISMOUNT_POWERSAVING) + Warning ("WARN_PREF_AUTO_DISMOUNT_ON_POWER"); + } + + 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)); + 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)); + 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)); + 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 (); + + 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_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; + } + + 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); + + 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); + + SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles); + + SendDlgItemMessage (hwndDlg, IDC_PASSWORD_PROT_HIDVOL, EM_LIMITTEXT, MAX_PASSWORD, 0); + + if (mountOptions->ProtectedHidVolPassword.Length > 0) + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), (LPSTR) mountOptions->ProtectedHidVolPassword.Text); + + 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) + { + SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), + EM_SETPASSWORDCHAR, + GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD_MO) ? 0 : '*', + 0); + InvalidateRect (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), NULL, TRUE); + return 1; + } + + if (lw == IDC_LINK_HIDVOL_PROTECTION_INFO) + { + Applink ("hiddenvolprotection", TRUE, ""); + } + + if (lw == IDCANCEL) + { + char tmp[MAX_PASSWORD+1]; + + // Cleanup + memset (tmp, 'X', MAX_PASSWORD); + tmp[MAX_PASSWORD] = 0; + SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp); + + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDOK) + { + char 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)); + + if (mountOptions->ProtectHiddenVolume) + { + GetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), + (LPSTR) mountOptions->ProtectedHidVolPassword.Text, + sizeof (mountOptions->ProtectedHidVolPassword.Text)); + + mountOptions->ProtectedHidVolPassword.Length = strlen ((char *) mountOptions->ProtectedHidVolPassword.Text); + } + + // Cleanup + memset (tmp, '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") == 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); + + 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)) + { + 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)) + { + return prop.mode; + } + + return 0; +} + + +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); + char 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))) - '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 + ListItemAddW (list, i, GetString ("LOCATION")); + if (bSysEnc) + ListSubItemSetW (list, i++, 1, GetString (bSysEncWholeDrive ? "SYSTEM_DRIVE" : IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION")); + else + ListSubItemSetW (list, i++, 1, (wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4)); + + // Size + ListItemAddW (list, i, GetString ("SIZE")); + swprintf (sw, L"%I64u %s", prop.diskLength, GetString ("BYTES")); + ListSubItemSetW (list, i++, 1, sw); + + // Type + ListItemAddW (list, i, GetString ("TYPE")); + if (bSysEnc) + ListSubItemSetW (list, i++, 1, GetString (IsHiddenOSRunning() ? "TYPE_HIDDEN_SYSTEM_ADJECTIVE" : "SYSTEM_VOLUME_TYPE_ADJECTIVE")); + else + { + ListSubItemSetW (list, i++, 1, + prop.hiddenVolume ? GetString ("HIDDEN") : + (prop.hiddenVolProtection != HIDVOL_PROT_STATUS_NONE ? GetString ("OUTER") : GetString ("NORMAL"))); + } + + if (!bSysEnc) + { + // Write protection + ListItemAddW (list, i, GetString ("READ_ONLY")); + + if (prop.readOnly || prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN) + s = GetString ("UISTR_YES"); + else + s = GetString ("UISTR_NO"); + + ListSubItemSetW (list, i++, 1, s); + + // Hidden Volume Protection + ListItemAddW (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"); + + ListSubItemSetW (list, i++, 1, s); + } + + // Encryption algorithm + ListItemAddW (list, i, GetString ("ENCRYPTION_ALGORITHM")); + + if (prop.ea == 0 || prop.ea > EAGetCount ()) + { + ListSubItemSet (list, i, 1, "?"); + return 1; + } + + EAGetName (szTmp, prop.ea); + ListSubItemSet (list, i++, 1, szTmp); + + // Key size(s) + { + char name[128]; + int size = EAGetKeySize (prop.ea); + EAGetName (name, prop.ea); + + if (strcmp (name, "Triple DES") == 0) /* Deprecated/legacy */ + size -= 3; // Compensate for parity bytes + + // Primary key + ListItemAddW (list, i, GetString ("KEY_SIZE")); + wsprintfW (sw, L"%d %s", size * 8, GetString ("BITS")); + ListSubItemSetW (list, i++, 1, sw); + + if (strcmp (EAGetModeName (prop.ea, prop.mode, TRUE), "XTS") == 0) + { + // Secondary key (XTS) + + ListItemAddW (list, i, GetString ("SECONDARY_KEY_SIZE_XTS")); + ListSubItemSetW (list, i++, 1, sw); + } + else if (strcmp (EAGetModeName (prop.ea, prop.mode, TRUE), "LRW") == 0) + { + // Tweak key (LRW) + + ListItemAddW (list, i, GetString ("SECONDARY_KEY_SIZE_LRW")); + swprintf (sw, L"%d %s", CipherGetBlockSize (EAGetFirstCipher(prop.ea))*8, GetString ("BITS")); + ListSubItemSetW (list, i++, 1, sw); + } + } + + // Block size + ListItemAddW (list, i, GetString ("BLOCK_SIZE")); + if (EAGetFirstMode (prop.ea) == INNER_CBC) + { + // Cascaded ciphers with non-equal block sizes (deprecated/legacy) + wchar_t tmpstr[64]; + int i = EAGetLastCipher(prop.ea); + + swprintf (sw, L"%d", CipherGetBlockSize(i)*8); + + while (i = EAGetPreviousCipher(prop.ea, i)) + { + swprintf (tmpstr, L"/%d", CipherGetBlockSize(i)*8); + wcscat (sw, tmpstr); + } + wcscat (sw, L" "); + } + else + { + swprintf (sw, L"%d ", CipherGetBlockSize (EAGetFirstCipher(prop.ea))*8); + } + wcscat (sw, GetString ("BITS")); + ListSubItemSetW (list, i++, 1, sw); + + // Mode + ListItemAddW (list, i, GetString ("MODE_OF_OPERATION")); + ListSubItemSet (list, i++, 1, EAGetModeName (prop.ea, prop.mode, TRUE)); + + // PKCS 5 PRF + ListItemAddW (list, i, GetString ("PKCS5_PRF")); + ListSubItemSet (list, i++, 1, get_pkcs5_prf_name (prop.pkcs5)); + +#if 0 + // PCKS 5 iterations + ListItemAddW (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 + ListItemAddW (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); + ListSubItemSetW (list, i++, 1, date); + + // Header date + ListItemAddW (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)); + ListSubItemSetW (list, i++, 1, date); + } +#endif // 0 + + if (!bSysEnc || IsHiddenOSRunning()) + { + // Volume format version + ListItemAddW (list, i, GetString ("VOLUME_FORMAT_VERSION")); + sprintf (szTmp, "%d", prop.volFormatVersion); + ListSubItemSet (list, i++, 1, szTmp); + + // Backup header + ListItemAddW (list, i, GetString ("BACKUP_HEADER")); + ListSubItemSetW (list, i++, 1, GetString (prop.volFormatVersion > 1 ? "UISTR_YES" : "UISTR_NO")); + } + + // Total data read + ListItemAddW (list, i, GetString ("TOTAL_DATA_READ")); + GetSizeString (prop.totalBytesRead, sw); + ListSubItemSetW (list, i++, 1, sw); + + // Total data written + ListItemAddW (list, i, GetString ("TOTAL_DATA_WRITTEN")); + GetSizeString (prop.totalBytesWritten, sw); + ListSubItemSetW (list, i++, 1, sw); + + if (bSysEnc) + { + // TrueCrypt Boot Loader version + ListItemAddW (list, i, GetString ("TC_BOOT_LOADER_VERSION")); + ListSubItemSet (list, i++, 1, (char *) GetUserFriendlyVersionString (BootEncStatus.BootLoaderVersion).c_str()); + + // Encrypted portion + ListItemAddW (list, i, GetString ("ENCRYPTED_PORTION")); + if (GetSysEncDeviceEncryptedPartSize (FALSE) == GetSysEncDeviceSize (FALSE)) + ListSubItemSetW (list, i++, 1, GetString ("ENCRYPTED_PORTION_FULLY_ENCRYPTED")); + else if (GetSysEncDeviceEncryptedPartSize (FALSE) <= 1) + ListSubItemSetW (list, i++, 1, GetString ("ENCRYPTED_PORTION_NOT_ENCRYPTED")); + else + { + + _snwprintf (sw, + sizeof sw/2, + GetString ("PROCESSED_PORTION_X_PERCENT"), + (double) GetSysEncDeviceEncryptedPartSize (FALSE) / (double) GetSysEncDeviceSize (FALSE) * 100.0); + + ListSubItemSetW (list, i++, 1, sw); + } + } + + 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: + { + char i; + int index; + char drive[] = { 0, ':', 0 }; + + LocalizeDialog (hwndDlg, "IDD_TRAVELER_DLG"); + + SendDlgItemMessage (hwndDlg, IDC_COPY_WIZARD, 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 = SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) GetString ("FIRST_AVAILABLE")); + SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) 0); + + for (i = 'D'; i <= 'Z'; i++) + { + drive[0] = i; + index = SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) drive); + SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) i); + } + + SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_SETCURSEL, 0, 0); + + 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_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"); + } + + return 1; + } + + if (lw == IDC_BROWSE_FILES) + { + char dstDir[MAX_PATH]; + char volName[MAX_PATH] = { 0 }; + + GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstDir, sizeof dstDir); + + if (BrowseFilesInDir (hwndDlg, "OPEN_TITLE", dstDir, volName, bHistory, FALSE, NULL)) + SetDlgItemText (hwndDlg, IDC_VOLUME_NAME, strchr (volName, '\\') + 1); + + return 1; + } + + if (lw == IDC_BROWSE_DIRS) + { + char dstPath[MAX_PATH * 2]; + GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath, sizeof 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, bExplore, bCacheInDriver, bAutoRun, bAutoMount, bMountReadOnly; + char dstDir[MAX_PATH]; + char srcPath[MAX_PATH * 2]; + char dstPath[MAX_PATH * 2]; + char appDir[MAX_PATH]; + char sysDir[MAX_PATH]; + char volName[MAX_PATH]; + int drive; + + GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstDir, sizeof dstDir); + volName[0] = 0; + GetDlgItemText (hwndDlg, IDC_VOLUME_NAME, volName + 1, sizeof volName); + + drive = SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETCURSEL, 0, 0); + drive = SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETITEMDATA, drive, 0); + + copyWizard = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_WIZARD)); + bExplore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER)); + bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS)); + 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] = '"'; + strcat (volName, "\""); + } + + GetModuleFileName (NULL, appDir, sizeof (appDir)); + strrchr (appDir, '\\')[0] = 0; + + WaitCursor (); + GetSystemDirectory (sysDir, sizeof (sysDir)); + + sprintf (dstPath, "%s\\TrueCrypt", dstDir); + CreateDirectory (dstPath, NULL); + + // Main app + sprintf (srcPath, "%s\\TrueCrypt.exe", appDir); + sprintf (dstPath, "%s\\TrueCrypt\\TrueCrypt.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg); + goto stop; + } + + // Wizard + if (copyWizard) + { + sprintf (srcPath, "%s\\TrueCrypt Format.exe", appDir); + sprintf (dstPath, "%s\\TrueCrypt\\TrueCrypt Format.exe", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg); + goto stop; + } + } + + // Driver + sprintf (srcPath, "%s\\truecrypt.sys", appDir); + sprintf (dstPath, "%s\\TrueCrypt\\truecrypt.sys", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg); + goto stop; + } + + // Driver x64 + sprintf (srcPath, "%s\\truecrypt-x64.sys", appDir); + sprintf (dstPath, "%s\\TrueCrypt\\truecrypt-x64.sys", dstDir); + if (!TCCopyFile (srcPath, dstPath)) + { + handleWin32Error (hwndDlg); + goto stop; + } + + if (GetPreferredLangId () && strcmp (GetPreferredLangId (), "en") != 0) + { + // Language pack + sprintf (srcPath, "%s\\Language.%s.xml", appDir, GetPreferredLangId ()); + sprintf (dstPath, "%s\\TrueCrypt\\Language.%s.xml", dstDir, GetPreferredLangId ()); + TCCopyFile (srcPath, dstPath); + } + + // AutoRun + sprintf (dstPath, "%s\\autorun.inf", dstDir); + DeleteFile (dstPath); + if (bAutoRun) + { + FILE *af; + char autoMount[100]; + char driveLetter[] = { ' ', '/', 'l', (char) drive, 0 }; + + af = fopen (dstPath, "w,ccs=UNICODE"); + + if (af == NULL) + { + MessageBoxW (hwndDlg, GetString ("CANT_CREATE_AUTORUN"), lpszTitle, MB_ICONERROR); + goto stop; + } + + sprintf (autoMount, "TrueCrypt\\TrueCrypt.exe /q background%s%s%s%s /m rm /v %s", + drive > 0 ? driveLetter : "", + bExplore ? " /e" : "", + bCacheInDriver ? " /c y" : "", + bMountReadOnly ? " /m ro" : "", + volName); + + fwprintf (af, L"[autorun]\nlabel=%s\nicon=TrueCrypt\\TrueCrypt.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=%hs\n", bAutoMount ? autoMount : "TrueCrypt\\TrueCrypt.exe"); + fwprintf (af, L"shell\\start=%s\nshell\\start\\command=TrueCrypt\\TrueCrypt.exe\n", GetString ("IDC_PREF_LOGON_START")); + fwprintf (af, L"shell\\dismount=%s\nshell\\dismount\\command=TrueCrypt\\TrueCrypt.exe /q /d\n", GetString ("DISMOUNT_ALL_TC_VOLUMES")); + + CheckFileStreamWriteErrors (af, dstPath); + fclose (af); + } + MessageBoxW (hwndDlg, GetString ("TRAVELER_DISK_CREATED"), lpszTitle, MB_ICONINFORMATION); + +stop: + NormalCursor (); + return 1; + } + return 0; + } + + return 0; +} + +void BuildTree (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 (253); + 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 (121); + lvCol.fmt = LVCFMT_LEFT; + SendMessage (hTree,LVM_INSERTCOLUMNW,3,(LPARAM)&lvCol); + + lvCol.pszText = GetString ("TYPE"); + lvCol.cx = CompensateXDPI (52); + 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 = ImageList_Create (16, 12, ILC_COLOR8|ILC_MASK, 2, 2); + if (ImageList_Add (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 (ImageList_Add (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 (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_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, char *titleStringId, BOOL enableMountOptions) +{ + int result; + + PasswordDialogTitleStringId = titleStringId; + PasswordDialogDisableMountOptions = !enableMountOptions; + + result = DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_PASSWORD_DLG), hwndDlg, + (DLGPROC) PasswordDlgProc, (LPARAM) password); + + if (result != IDOK) + { + password->Length = 0; + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + } + + return result == IDOK; +} + +// GUI actions + +static BOOL Mount (HWND hwndDlg, int nDosDriveNo, char *szFileName) +{ + BOOL status = FALSE; + char fileName[MAX_PATH]; + int mounted = 0, modeOfOperation; + + bPrebootPasswordDlgMode = mountOptions.PartitionInInactiveSysEncScope; + + if (nDosDriveNo == 0) + nDosDriveNo = HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) - 'A'; + + if (!MultipleMountOperationInProgress) + VolumePassword.Length = 0; + + if (szFileName == NULL) + { + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), fileName, sizeof (fileName)); + szFileName = fileName; + } + + if (strlen(szFileName) == 0) + { + status = FALSE; + goto ret; + } + + if (IsMountedVolume (szFileName)) + { + Warning ("VOL_ALREADY_MOUNTED"); + status = FALSE; + goto ret; + } + + if (!VolumePathExists (szFileName)) + { + if (!MultipleMountOperationInProgress) + handleWin32Error (hwndDlg); + + status = FALSE; + goto ret; + } + + ResetWrongPwdRetryCount (); + + // First try cached passwords and if they fail ask user for a new one + WaitCursor (); + + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, bCacheInDriver, bForceMount, &mountOptions, Silent, FALSE); + + // If keyfiles are enabled, test empty password first + if (!mounted && KeyFilesEnable && FirstKeyFile) + { + Password emptyPassword; + emptyPassword.Length = 0; + + KeyFilesApply (&emptyPassword, FirstKeyFile); + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &emptyPassword, bCacheInDriver, bForceMount, &mountOptions, Silent, FALSE); + + burn (&emptyPassword, sizeof (emptyPassword)); + } + + // Test password and/or keyfiles used for the previous volume + if (!mounted && MultipleMountOperationInProgress && VolumePassword.Length != 0) + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, bCacheInDriver, bForceMount, &mountOptions, Silent, FALSE); + + NormalCursor (); + + if (mounted) + { + // Check for deprecated CBC mode + modeOfOperation = GetModeOfOperationByDriveNo (nDosDriveNo); + if (modeOfOperation == CBC || modeOfOperation == OUTER_CBC) + Warning("WARN_CBC_MODE"); + + // Check for deprecated 64-bit-block ciphers + if (GetCipherBlockSizeByDriveNo (nDosDriveNo) == 64) + Warning("WARN_64_BIT_BLOCK_CIPHER"); + + // Check for problematic file extensions (exe, dll, sys) + if (CheckFileExtension(szFileName)) + Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING"); + } + + while (mounted == 0) + { + if (CmdVolumePassword.Length > 0) + { + VolumePassword = CmdVolumePassword; + } + else if (!Silent) + { + strcpy (PasswordDlgVolume, szFileName); + + if (!AskVolumePassword (hwndDlg, &VolumePassword, NULL, TRUE)) + goto ret; + } + + WaitCursor (); + + if (KeyFilesEnable) + KeyFilesApply (&VolumePassword, FirstKeyFile); + + mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, bCacheInDriver, bForceMount, &mountOptions, Silent, !Silent); + NormalCursor (); + + // Check for deprecated CBC mode + modeOfOperation = GetModeOfOperationByDriveNo (nDosDriveNo); + if (modeOfOperation == CBC || modeOfOperation == OUTER_CBC) + Warning("WARN_CBC_MODE"); + + // Check for deprecated 64-bit-block ciphers + if (GetCipherBlockSizeByDriveNo (nDosDriveNo) == 64) + Warning("WARN_64_BIT_BLOCK_CIPHER"); + + // Check for legacy non-ASCII passwords + if (mounted > 0 && !KeyFilesEnable && !CheckPasswordCharEncoding (NULL, &VolumePassword)) + Warning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); + + // Check for problematic file extensions (exe, dll, sys) + if (mounted > 0 && CheckFileExtension (szFileName)) + Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING"); + + if (!MultipleMountOperationInProgress) + burn (&VolumePassword, sizeof (VolumePassword)); + + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + + if (CmdVolumePassword.Length > 0 || Silent) + break; + } + + if (mounted > 0) + { + status = TRUE; + + if (bBeep) + MessageBeep (0xFFFFFFFF); + + RefreshMainDlg(hwndDlg); + + if (bExplore) + { + WaitCursor(); + OpenVolumeExplorerWindow (nDosDriveNo); + NormalCursor(); + } + + if (mountOptions.ProtectHiddenVolume) + Info ("HIDVOL_PROT_WARN_AFTER_MOUNT"); + } + +ret: + if (!MultipleMountOperationInProgress) + burn (&VolumePassword, sizeof (VolumePassword)); + + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + + 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 == 0) + nDosDriveNo = (char) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) - '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 (GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); + } + + NormalCursor (); + return status; +} + +static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay) +{ + BOOL status = TRUE; + MOUNT_LIST_STRUCT mountList; + DWORD dwResult; + UNMOUNT_STRUCT unmount; + BOOL bResult; + unsigned __int32 prevMountedDrives = 0; + int i; + +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); + + prevMountedDrives = mountList.ulMountedDrives; + + for (i = 0; i < 26; i++) + { + if (mountList.ulMountedDrives & (1 << i)) + { + if (bCloseDismountedWindows) + CloseVolumeExplorerWindows (hwndDlg, i); + } + } + + unmount.nDosDriveNo = 0; + unmount.ignoreOpenFiles = forceUnmount; + + do + { + bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_ALL_VOLUMES, &unmount, + sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL); + + if (bResult == FALSE) + { + NormalCursor(); + handleWin32Error (hwndDlg); + return FALSE; + } + + if (unmount.nReturnCode == ERR_SUCCESS + && unmount.HiddenVolumeProtectionTriggered + && !VolumeNotificationsList.bHidVolDamagePrevReported [unmount.nDosDriveNo]) + { + wchar_t msg[4096]; + + VolumeNotificationsList.bHidVolDamagePrevReported [unmount.nDosDriveNo] = TRUE; + swprintf (msg, GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), unmount.nDosDriveNo + 'A'); + SetForegroundWindow (hwndDlg); + MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); + + unmount.HiddenVolumeProtectionTriggered = FALSE; + continue; + } + + if (unmount.nReturnCode == ERR_FILES_OPEN) + Sleep (dismountAutoRetryDelay); + else + break; + + } while (--dismountMaxRetries > 0); + + memset (&mountList, 0, sizeof (mountList)); + DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL); + BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, prevMountedDrives & ~mountList.ulMountedDrives); + + RefreshMainDlg (hwndDlg); + + if (nCurrentOS == WIN_2000 && RemoteSession && !IsAdmin ()) + LoadDriveLetters (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")) + { + 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)) + { + char root[] = { (char) i + 'A', ':', '\\', 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 MountAllDevices (HWND hwndDlg, BOOL bPasswordPrompt) +{ + HWND driveList = GetDlgItem (hwndDlg, IDC_DRIVELIST); + int selDrive = ListView_GetSelectionMark (driveList); + BOOL shared = FALSE, status = FALSE, b64BitBlockCipher = FALSE, bCBCMode = FALSE, bHeaderBakRetry = FALSE; + int mountedVolCount = 0, modeOfOperation; + vector devices; + + VolumePassword.Length = 0; + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (selDrive == -1) + selDrive = 0; + + ResetWrongPwdRetryCount (); + + MultipleMountOperationInProgress = TRUE; + + do + { + if (!bHeaderBakRetry) + { + if (!CmdVolumePasswordValid && bPasswordPrompt) + { + PasswordDlgVolume[0] = '\0'; + if (!AskVolumePassword (hwndDlg, &VolumePassword, NULL, TRUE)) + goto ret; + } + else if (CmdVolumePasswordValid) + { + bPasswordPrompt = FALSE; + VolumePassword = CmdVolumePassword; + } + + WaitCursor(); + + if (FirstCmdKeyFile) + KeyFilesApply (&VolumePassword, FirstCmdKeyFile); + else if (KeyFilesEnable) + KeyFilesApply (&VolumePassword, FirstKeyFile); + + } + + 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) + { + char szFileName[TC_MAX_PATH]; + strcpy_s (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; + + while (LOWORD (GetItemLong (driveList, selDrive)) != 0xffff) + { + if(LOWORD (GetItemLong (driveList, selDrive)) != TC_MLIST_ITEM_FREE) + { + selDrive++; + continue; + } + nDosDriveNo = HIWORD(GetItemLong (driveList, selDrive)) - 'A'; + break; + } + + if (LOWORD (GetItemLong (driveList, selDrive)) == 0xffff) + goto ret; + + // First try user password then cached passwords + if ((mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, &VolumePassword, bCacheInDriver, bForceMount, &mountOptions, TRUE, FALSE)) > 0 + || (mounted = MountVolume (hwndDlg, nDosDriveNo, szFileName, NULL, bCacheInDriver, bForceMount, &mountOptions, TRUE, FALSE)) > 0) + { + // A volume has been successfully mounted + + ResetWrongPwdRetryCount (); + + if (mounted == 2) + shared = TRUE; + + LoadDriveLetters (driveList, (HIWORD (GetItemLong (GetDlgItem (hwndDlg, IDC_DRIVELIST), selDrive)))); + selDrive++; + + if (bExplore) + { + WaitCursor(); + OpenVolumeExplorerWindow (nDosDriveNo); + NormalCursor(); + } + + if (bBeep) + MessageBeep (0xFFFFFFFF); + + status = TRUE; + + // Check for deprecated CBC mode + modeOfOperation = GetModeOfOperationByDriveNo (nDosDriveNo); + bCBCMode = (modeOfOperation == CBC || modeOfOperation == OUTER_CBC); + + if (GetCipherBlockSizeByDriveNo(nDosDriveNo) == 64) + b64BitBlockCipher = 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]; + + swprintf (szTmp, GetString (KeyFilesEnable || FirstCmdKeyFile ? "PASSWORD_OR_KEYFILE_WRONG_AUTOMOUNT" : "PASSWORD_WRONG_AUTOMOUNT")); + if (CheckCapsLock (hwndDlg, TRUE)) + wcscat (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"); + } + + if (!bHeaderBakRetry) + { + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + } + + } while (bPasswordPrompt && mountedVolCount < 1); + + /* One or more volumes successfully mounted */ + + ResetWrongPwdRetryCount (); + + if (shared) + Warning ("DEVICE_IN_USE_INFO"); + + if (mountOptions.ProtectHiddenVolume) + { + if (mountedVolCount > 1) + Info ("HIDVOL_PROT_WARN_AFTER_MOUNT_PLURAL"); + else if (mountedVolCount == 1) + Info ("HIDVOL_PROT_WARN_AFTER_MOUNT"); + } + + // Check for deprecated CBC mode + if (bCBCMode) + Warning("WARN_CBC_MODE"); + + // Check for deprecated 64-bit-block ciphers + if (b64BitBlockCipher) + Warning("WARN_64_BIT_BLOCK_CIPHER"); + + // Check for legacy non-ASCII passwords + if (!KeyFilesEnable + && !FirstCmdKeyFile + && mountedVolCount > 0 + && !CheckPasswordCharEncoding (NULL, &VolumePassword)) + Warning ("UNSUPPORTED_CHARS_IN_PWD_RECOM"); + + if (status && CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + +ret: + MultipleMountOperationInProgress = FALSE; + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + + mountOptions.UseBackupHeader = defaultMountOptions.UseBackupHeader; + + RestoreDefaultKeyFilesParam (); + + if (UsePreferences) + bCacheInDriver = bCacheInDriverDefault; + + EnableDisableButtons (hwndDlg); + + NormalCursor(); + + return status; +} + +static void ChangePassword (HWND hwndDlg) +{ + int result; + + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, sizeof (szFileName)); + if (IsMountedVolume (szFileName)) + { + Warning (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE"); + return; + } + + if (!VolumePathExists (szFileName)) + { + handleWin32Error (hwndDlg); + return; + } + + bSysEncPwdChangeDlgMode = FALSE; + + result = DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_PASSWORDCHANGE_DLG), hwndDlg, + (DLGPROC) PasswordChangeDlgProc); + + if (result == IDOK) + { + switch (pwdChangeDlgMode) + { + case PCDM_CHANGE_PKCS5_PRF: + Info ("PKCS5_PRF_CHANGED"); + break; + + case PCDM_ADD_REMOVE_VOL_KEYFILES: + case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL: + Info ("KEYFILE_CHANGED"); + break; + + case PCDM_CHANGE_PASSWORD: + default: + Info ("PASSWORD_CHANGED"); + } + } +} + +// 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"); + return; + } + + if (SysEncryptionOrDecryptionRequired () + || BootEncStatus.SetupInProgress) + { + Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED"); + return; + } + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + sprintf (OrigKeyboardLayout, "%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"); + else + bKeyboardLayoutChanged = FALSE; + } + + bKeybLayoutAltKeyWarningShown = FALSE; + + if (result == IDOK) + { + switch (pwdChangeDlgMode) + { + case PCDM_CHANGE_PKCS5_PRF: + Info ("PKCS5_PRF_CHANGED"); + + if (!IsHiddenOSRunning()) + { + if (AskWarnYesNo ("SYS_HKD_ALGO_CHANGED_ASK_RESCUE_DISK") == IDYES) + CreateRescueDisk (); + } + + 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"); + + if (!IsHiddenOSRunning()) + { + if (AskWarnYesNo ("SYS_PASSWORD_CHANGED_ASK_RESCUE_DISK") == IDYES) + CreateRescueDisk (); + } + } + } + + CloseSysEncMutex (); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); +} + +// Initiates or resumes encryption of the system partition/drive +static void EncryptSystemDevice (void) +{ + 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 (MainDlg, "/sysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); + + 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 (MainDlg, "/sysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); + } + else if (SysDriveOrPartitionFullyEncrypted (FALSE)) + { + // System partition/drive appears to be fully encrypted + Info ("SYS_PARTITION_OR_DRIVE_APPEARS_FULLY_ENCRYPTED"); + return; + } +} + +// Initiates decryption of the system partition/drive +static void DecryptSystemDevice (void) +{ + 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"); + return; + } + + if (IsHiddenOSRunning()) + { + Warning ("CANNOT_DECRYPT_HIDDEN_OS"); + return; + } + + if (AskNoYes ("CONFIRM_DECRYPT_SYS_DEVICE") == IDNO) + return; + + if (AskWarnNoYes ("CONFIRM_DECRYPT_SYS_DEVICE_CAUTION") == 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"); + return; + } + + CloseSysEncMutex (); + LaunchVolCreationWizard (MainDlg, "/dsysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); +} + +// Initiates the process of creation of a hidden operating system +static void CreateHiddenOS (void) +{ + + // 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"); + + LaunchVolCreationWizard (MainDlg, "/isysenc"); +} + +// 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 (void) +{ + if (!MutexExistsOnSystem (TC_MUTEX_NAME_SYSENC)) // If no instance of the wizard is currently taking care of system encryption + { + LaunchVolCreationWizard (MainDlg, "/csysenc"); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); +} + +void CreateRescueDisk (void) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (IsHiddenOSRunning()) + { + Warning ("CANNOT_CREATE_RESCUE_DISK_ON_HIDDEN_OS"); + return; + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !BootEncStatus.VolumeHeaderPresent + && !SysEncryptionOrDecryptionRequired ()) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED"); + return; + } + + if (SysEncryptionOrDecryptionRequired () + || BootEncStatus.SetupInProgress) + { + Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED"); + return; + } + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + try + { + wchar_t szTmp [8096]; + char szRescueDiskISO [TC_MAX_PATH+1]; + + if (AskOkCancel ("RESCUE_DISK_NON_WIZARD_CREATION_SELECT_PATH") != IDOK) + { + CloseSysEncMutex (); + return; + } + + char initialDir[MAX_PATH]; + SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, 0, initialDir); + + if (!BrowseFilesInDir (MainDlg, "OPEN_TITLE", initialDir, szRescueDiskISO, FALSE, TRUE, NULL, L"TrueCrypt Rescue Disk.iso", L"iso")) + { + CloseSysEncMutex (); + return; + } + + WaitCursor(); + BootEncObj->CreateRescueIsoImage (false, szRescueDiskISO); + + _snwprintf (szTmp, sizeof szTmp / 2, + GetString (IsWindowsIsoBurnerAvailable() ? "RESCUE_DISK_NON_WIZARD_CREATION_WIN_ISOBURN" : "RESCUE_DISK_NON_WIZARD_CREATION_BURN"), + szRescueDiskISO); + + if (IsWindowsIsoBurnerAvailable()) + { + if (AskYesNoString (szTmp) == IDYES) + LaunchWindowsIsoBurner (MainDlg, szRescueDiskISO); + } + else + InfoDirect (szTmp); + } + catch (Exception &e) + { + e.Show (MainDlg); + Error ("ERROR_CREATING_RESCUE_DISK"); + } + CloseSysEncMutex (); + + NormalCursor (); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); +} + +static void VerifyRescueDisk (void) +{ + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + catch (Exception &e) + { + e.Show (MainDlg); + } + + if (!BootEncStatus.DriveEncrypted + && !BootEncStatus.DriveMounted + && !BootEncStatus.VolumeHeaderPresent + && !SysEncryptionOrDecryptionRequired ()) + { + Warning ("SYS_DRIVE_NOT_ENCRYPTED"); + return; + } + + if (SysEncryptionOrDecryptionRequired () + || BootEncStatus.SetupInProgress) + { + Warning ("SYSTEM_ENCRYPTION_NOT_COMPLETED"); + return; + } + + if (CreateSysEncMutex ()) // If no instance of the wizard is currently taking care of system encryption + { + try + { + if (AskOkCancel ("RESCUE_DISK_NON_WIZARD_CHECK_INSERT") != 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, ""); + + WaitCursor(); + if (!BootEncObj->VerifyRescueDisk ()) + Error ("RESCUE_DISK_NON_WIZARD_CHECK_FAILED"); + else + Info ("RESCUE_DISK_NON_WIZARD_CHECK_PASSED"); + } + catch (Exception &e) + { + e.Show (MainDlg); + Error ("RESCUE_DISK_NON_WIZARD_CHECK_FAILED"); + } + CloseSysEncMutex (); + + NormalCursor (); + } + else + Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE"); +} + +static void ShowSystemEncryptionStatus (void) +{ + 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"); + return; + } + + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_VOLUME_PROPERTIES), MainDlg, + (DLGPROC) VolumePropertiesDlgProc, (LPARAM) TRUE); + +} + +static void ResumeInterruptedNonSysInplaceEncProcess (void) +{ + // 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, "/zinplace"); +} + +static 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; +} + +static BOOL SelectPartition (HWND hwndDlg) +{ + int nResult = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_RAWDEVICES_DLG), hwndDlg, + (DLGPROC) RawDevicesDlgProc, (LPARAM) & szFileName[0]); + 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); + else + { + EnableDisableButtons (hwndDlg); + + if (!silent) + InfoBalloon ("PASSWORD_CACHE_WIPED_SHORT", "PASSWORD_CACHE_WIPED"); + } +} + +static void Benchmark (HWND hwndDlg) +{ + DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_BENCHMARK_DLG), hwndDlg, + (DLGPROC) BenchmarkDlgProc, (LPARAM) NULL); +} + + +static BOOL CheckMountList () +{ + MOUNT_LIST_STRUCT current; + static BootEncryptionStatus newBootEncStatus; + static BOOL lastbUseDifferentTrayIconIfVolMounted = bUseDifferentTrayIconIfVolMounted; + static uint32 lastUlMountedDrives = 0; + + GetMountList (¤t); + + if ((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 (LastKnownLogicalDrives != GetLogicalDrives() + || memcmp (&LastKnownMountList, ¤t, sizeof (current)) != 0) + { + char selDrive; + + WaitCursor (); + LastKnownMountList = current; + + selDrive = (char) HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))); + LoadDriveLetters (GetDlgItem (MainDlg, IDC_DRIVELIST), 0); + NormalCursor (); + + if (selDrive != -1 && (current.ulMountedDrives & (1 << (selDrive - 'A'))) == 0 && !IsDriveAvailable (selDrive - 'A')) + { + nSelectedDriveIndex = -1; + return FALSE; + } + + if (selDrive != -1) + 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 */ + + char 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 = (char) HIWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))); + LoadDriveLetters (GetDlgItem (MainDlg, IDC_DRIVELIST), driveLetterToRefresh); + + RecentBootEncStatus = newBootEncStatus; + + if (selDrive != -1 && (current.ulMountedDrives & (1 << (selDrive - 'A'))) == 0 && !IsDriveAvailable (selDrive - 'A')) + { + nSelectedDriveIndex = -1; + } + + if (selDrive != -1) + { + 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"); + else + WarningTopMost ("SYS_ENC_HIBERNATION_PREVENTED"); + } + + // 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)) + { + 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()); + 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()); + + // 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; +} + + +/* 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); + DWORD mPos; + + switch (uMsg) + { + case WM_HOTKEY: + + HandleHotKey (hwndDlg, wParam); + return 1; + + case WM_INITDIALOG: + { + int exitCode = 0; + int modeOfOperation; + + MainDlg = hwndDlg; + + if (IsTrueCryptInstallerRunning()) + AbortProcess ("TC_INSTALLER_IS_RUNNING"); + + // Set critical default options in case UsePreferences is false + bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = TRUE; + + ResetWrongPwdRetryCount (); + + ExtractCommandLine (hwndDlg, (char *) lParam); + + try + { + BootEncStatus = BootEncObj->GetStatus(); + RecentBootEncStatus = BootEncStatus; + } + catch (...) + { + // NOP + } + + if (UsePreferences) + { + // General preferences + LoadSettings (hwndDlg); + + // Keyfiles + LoadDefaultKeyFilesParam (); + RestoreDefaultKeyFilesParam (); + } + + if (ComServerMode) + { + InitDialog (hwndDlg); + + if (!ComServerMain ()) + { + handleWin32Error (hwndDlg); + exit (1); + } + exit (0); + } + + if (CmdMountOptionsValid) + mountOptions = CmdMountOptions; + + InitMainDialog (hwndDlg); + + try + { + if (IsHiddenOSRunning()) + { + if (BootEncObj->GetInstalledBootLoaderVersion() > VERSION_NUM) + Warning ("UPDATE_TC_IN_HIDDEN_OS_TOO"); + } + else if (SysDriveOrPartitionFullyEncrypted (TRUE) + && BootEncObj->GetInstalledBootLoaderVersion() != VERSION_NUM) + { + Warning ("BOOT_LOADER_VERSION_DIFFERENT_FROM_DRIVER_VERSION"); + } + } + catch (...) { } + + // Automount + if (bAuto || (Quit && szFileName[0] != 0)) + { + // No drive letter specified on command line + if (commandLineDrive == 0) + szDriveLetter[0] = (char) GetFirstAvailableDrive () + 'A'; + + if (bAutoMountDevices) + { + defaultMountOptions = mountOptions; + if (FirstCmdKeyFile) + { + KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles = TRUE; + FirstKeyFile = KeyFileCloneAll (FirstCmdKeyFile); + defaultKeyFilesParam.FirstKeyFile = KeyFileCloneAll (FirstCmdKeyFile); + } + + if (!MountAllDevices (hwndDlg, !Silent && !CmdVolumePasswordValid && IsPasswordCacheEmpty())) + exitCode = 1; + } + + if (bAutoMountFavorites) + { + defaultMountOptions = mountOptions; + if (FirstCmdKeyFile) + { + KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles = TRUE; + FirstKeyFile = KeyFileCloneAll (FirstCmdKeyFile); + defaultKeyFilesParam.FirstKeyFile = KeyFileCloneAll (FirstCmdKeyFile); + } + + if (!MountFavoriteVolumes (FALSE, LogOn)) + exitCode = 1; + } + + if (szFileName[0] != 0 && !IsMountedVolume (szFileName)) + { + BOOL mounted; + + // Cached password + mounted = MountVolume (hwndDlg, szDriveLetter[0] - 'A', szFileName, NULL, bCacheInDriver, bForceMount, &mountOptions, Silent, FALSE); + + // Command line password or keyfiles + if (!mounted && (CmdVolumePassword.Length != 0 || FirstCmdKeyFile)) + { + BOOL reportBadPasswd = CmdVolumePassword.Length > 0; + + if (FirstCmdKeyFile) + KeyFilesApply (&CmdVolumePassword, FirstCmdKeyFile); + + mounted = MountVolume (hwndDlg, szDriveLetter[0] - 'A', + szFileName, &CmdVolumePassword, bCacheInDriver, bForceMount, + &mountOptions, Silent, reportBadPasswd); + + burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); + } + + if (FirstCmdKeyFile) + { + FirstKeyFile = FirstCmdKeyFile; + KeyFilesEnable = TRUE; + } + + // Ask user for password + while (!mounted && !Silent) + { + VolumePassword.Length = 0; + + strcpy (PasswordDlgVolume, szFileName); + if (!AskVolumePassword (hwndDlg, &VolumePassword, NULL, TRUE)) + break; + + WaitCursor (); + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (&VolumePassword, FirstKeyFile); + + mounted = MountVolume (hwndDlg, szDriveLetter[0] - 'A', szFileName, &VolumePassword, bCacheInDriver, bForceMount, &mountOptions, FALSE, TRUE); + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword)); + + NormalCursor (); + } + + if (UsePreferences) + { + RestoreDefaultKeyFilesParam (); + bCacheInDriver = bCacheInDriverDefault; + } + + if (mounted > 0) + { + if (bBeep) + MessageBeep (0xFFFFFFFF); + + if (bExplore) + OpenVolumeExplorerWindow (szDriveLetter[0] - 'A'); + + RefreshMainDlg(hwndDlg); + + if(!Silent) + { + // Check for deprecated CBC mode + modeOfOperation = GetModeOfOperationByDriveNo (szDriveLetter[0] - 'A'); + if (modeOfOperation == CBC || modeOfOperation == OUTER_CBC) + Warning("WARN_CBC_MODE"); + + // Check for deprecated 64-bit-block ciphers + if (GetCipherBlockSizeByDriveNo (szDriveLetter[0] - 'A') == 64) + Warning("WARN_64_BIT_BLOCK_CIPHER"); + + // Check for problematic file extensions (exe, dll, sys) + if (CheckFileExtension (szFileName)) + Warning ("EXE_FILE_EXTENSION_MOUNT_WARNING"); + } + } + else + exitCode = 1; + } + else if (bExplore && GetMountedVolumeDriveNo (szFileName) != -1) + OpenVolumeExplorerWindow (GetMountedVolumeDriveNo (szFileName)); + else if (szFileName[0] != 0 && IsMountedVolume (szFileName)) + Warning ("VOL_ALREADY_MOUNTED"); + + 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"); + 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() || (GetWindowLongPtr (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 = strlen (szFileName) + 1; + + 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"); + + Silent = FALSE; + + GetMountList (&LastKnownMountList); + SetTimer (hwndDlg, TIMER_ID_MAIN, TIMER_INTERVAL_MAIN, NULL); + + taskBarCreatedMsg = RegisterWindowMessage ("TaskbarCreated"); + + 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") == 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, "/csysenc"); + } + } + } + + if (bInPlaceEncNonSysPending && !NonSysInplaceEncInProgressElsewhere()) + { + if (AskNonSysInPlaceEncryptionResume() == IDYES) + ResumeInterruptedNonSysInplaceEncProcess (); + } + } + + if (!DisableSystemCrashDetection + && IsOSAtLeast (WIN_7)) + { + // Auto-detect a system crash + + const int detectionPeriodInMonthsSinceReleaseDate = 2; + int maxYear = TC_RELEASE_DATE_YEAR; + int maxMonth = TC_RELEASE_DATE_MONTH + detectionPeriodInMonthsSinceReleaseDate; + if (maxMonth > 12) + { + ++maxYear; + maxMonth -= 12; + } + + SYSTEMTIME systemTime; + GetSystemTime (&systemTime); + + if (systemTime.wYear >= TC_RELEASE_DATE_YEAR + && !(systemTime.wYear == TC_RELEASE_DATE_YEAR && systemTime.wMonth < TC_RELEASE_DATE_MONTH) + && systemTime.wYear <= maxYear + && !(systemTime.wYear == maxYear && systemTime.wMonth > maxMonth)) + { + char winDir[MAX_PATH] = { 0 }; + GetWindowsDirectory (winDir, sizeof (winDir)); + + WIN32_FIND_DATA findData; + HANDLE find = FindFirstFile ((string (winDir) + "\\MEMORY.DMP").c_str(), &findData); + + if (find != INVALID_HANDLE_VALUE) + { + SYSTEMTIME systemTime; + FILETIME ft; + GetSystemTime (&systemTime); + SystemTimeToFileTime (&systemTime, &ft); + + ULARGE_INTEGER sysTime, fileTime; + sysTime.HighPart = ft.dwHighDateTime; + sysTime.LowPart = ft.dwLowDateTime; + fileTime.HighPart = findData.ftLastWriteTime.dwHighDateTime; + fileTime.LowPart = findData.ftLastWriteTime.dwLowDateTime; + + // Memory dump must not be older than 10 minutes + if (sysTime.QuadPart - fileTime.QuadPart < 10I64 * 1000 * 1000 * 60 * 10) + SystemCrashDetected = TRUE; + + FindClose (find); + } + } + } + + DoPostInstallTasks (); + ResetCurrentDirectory (); + } + return 0; + + case WM_MOUSEWHEEL: + return HandleDriveListMouseWheelEvent (uMsg, wParam, lParam, FALSE); + + 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_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); + } + 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 (); + + // 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"); + + if (warnings.PagingFileCreationPrevented) + WarningTopMost ("PAGING_FILE_CREATION_PREVENTED"); + } + + if (TaskBarIconMutex != NULL) + { + // Handle system crash + static BOOL systemCrashHandlerLocked = FALSE; + if (SystemCrashDetected && !systemCrashHandlerLocked) + { + systemCrashHandlerLocked = TRUE; + + SetForegroundWindow (hwndDlg); + MainWindowHidden = FALSE; + ShowWindow (hwndDlg, SW_SHOW); + ShowWindow (hwndDlg, SW_RESTORE); + + if (AskYesNoTopmost ("SYSTEM_CRASHED_ASK_REPORT") == IDYES) + { + if (!IsAdmin() && IsUacSupported()) + UacAnalyzeKernelMiniDump (hwndDlg); + else + AnalyzeKernelMiniDump (hwndDlg); + } + else if (AskYesNoTopmost ("ASK_KEEP_DETECTING_SYSTEM_CRASH") == IDNO) + { + DisableSystemCrashDetection = TRUE; + SaveSettings (hwndDlg); + } + } + + // 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.VolumePathId.empty()) + { + if (IsMountedVolume (favorite.Path.c_str())) + continue; + + char 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 ("\\\\?\\Volume{") == 0) + { + string 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 (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; + } + + char 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; + } + + 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); + 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, NULL); + } + 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, NULL); + } + 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, NULL); + + 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; + + wstring label = GetFavoriteVolumeLabel (WideToSingleString (vol)); + + wsprintfW (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, NULL); + } + + 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, NULL); + 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 ()) + { + if (Dismount (hwndDlg, sel - TRAYICON_MENU_DRIVE_OFFSET - 26)) + { + wchar_t txt [2048]; + wsprintfW (txt, GetString ("VOLUME_MOUNTED_AS_DRIVE_LETTER_X_DISMOUNTED"), sel - TRAYICON_MENU_DRIVE_OFFSET - 26 + L'A'); + + InfoBalloonDirect (GetString ("SUCCESSFULLY_DISMOUNTED"), txt); + } + } + } + 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") == IDYES) + { + // Close all other TC windows + EnumWindows (CloseTCWindowsEnum, 0); + + TaskBarIconRemove (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); + + return 1; + + case TC_APPMSG_SYSENC_CONFIG_UPDATE: + LoadSysEncSettings (hwndDlg); + + // The wizard added TrueCrypt.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)) && !(GetLogicalDrives() & (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"); + } + } + } + } + } + } + + // Device-hosted volumes + for (m = 0; m < 26; m++) + { + if (LastKnownMountList.ulMountedDrives & (1 << m)) + { + wchar_t *vol = (wchar_t *) LastKnownMountList.wszVolume[m]; + char volp[MAX_PATH]; + + if (wcsstr (vol, L"\\??\\") == vol) + vol += 4; + + _snprintf (volp, sizeof(volp), "%ls", vol); + + if (IsVolumeDeviceHosted (volp)) + { + OPEN_TEST_STRUCT ots; + + if (!OpenDevice (volp, &ots, FALSE)) + { + UnmountVolume (hwndDlg, m, TRUE); + WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN"); + } + } + } + } + + // 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 (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) + { + int 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) - 'A'); + NormalCursor (); + } + else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) + { + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (GetAsyncKeyState (VK_CONTROL) < 0) + { + if (IDCANCEL == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, + (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions)) + return 1; + + if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) + KeyFilesApply (&mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile); + } + + if (CheckMountList ()) + Mount (hwndDlg, 0, 0); + } + 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. */ + { + + /* Drive list context menu */ + + int menuItem; + HMENU popup = CreatePopupMenu (); + + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + switch (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)))) + { + 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, NULL); + 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, NULL); + 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, NULL); + 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, NULL); + 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; + } + + mPos=GetMessagePos(); + + 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 (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + if (LOWORD (lLetter) != 0xffff) + CheckFilesystem ((char) HIWORD (lLetter) - 'A', menuItem == IDPM_REPAIR_FILESYS); + } + break; + + case IDM_UNMOUNT_VOLUME: + if (CheckMountList ()) + Dismount (hwndDlg, 0); + break; + + case IDPM_OPEN_VOLUME: + { + int state = GetItemLong(GetDlgItem (hwndDlg, IDC_DRIVELIST), ((LPNMITEMACTIVATE)lParam)->iItem ); + nSelectedDriveIndex = ((LPNMITEMACTIVATE)lParam)->iItem; + + WaitCursor (); + OpenVolumeExplorerWindow (HIWORD(state) - '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"); + } + else + { + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (CheckMountList ()) + Mount (hwndDlg, 0, 0); + } + break; + + case IDPM_ADD_TO_FAVORITES: + case IDPM_ADD_TO_SYSTEM_FAVORITES: + { + LPARAM selectedDrive = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + if (LOWORD (selectedDrive) == TC_MLIST_ITEM_NONSYS_VOL) + AddMountedVolumeToFavorites (hwndDlg, HIWORD (selectedDrive) - 'A', menuItem == IDPM_ADD_TO_SYSTEM_FAVORITES); + } + break; + + default: + SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); + break; + } + 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"); + return 1; + } + + if (CheckMountList ()) + Dismount (hwndDlg, 0); + 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"TrueCrypt", 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"); + } + + 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 (); + break; + case IDM_PERMANENTLY_DECRYPT_SYS: + DecryptSystemDevice (); + break; + case IDM_CREATE_HIDDEN_OS: + CreateHiddenOS (); + break; + case IDM_SYSENC_RESUME: + ResumeInterruptedSysEncProcess (); + break; + case IDM_SYSTEM_ENCRYPTION_STATUS: + ShowSystemEncryptionStatus (); + 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 (); + break; + case IDM_VERIFY_RESCUE_DISK: + VerifyRescueDisk (); + break; + case IDM_MOUNT_SYSENC_PART_WITHOUT_PBA: + + if (CheckSysEncMountWithoutPBA ("", FALSE)) + { + mountOptions = defaultMountOptions; + mountOptions.PartitionInInactiveSysEncScope = TRUE; + bPrebootPasswordDlgMode = TRUE; + + if (CheckMountList ()) + Mount (hwndDlg, 0, 0); + + bPrebootPasswordDlgMode = FALSE; + } + break; + } + + if (lw == IDC_VOLUME_TOOLS) + { + /* Volume Tools popup menu */ + + int menuItem; + char 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, NULL); + 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, 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_CHANGE_PASSWORD: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + pwdChangeDlgMode = PCDM_CHANGE_PASSWORD; + ChangePassword (hwndDlg); + } + break; + + case IDM_CHANGE_HEADER_KEY_DERIV_ALGO: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + pwdChangeDlgMode = PCDM_CHANGE_PKCS5_PRF; + ChangePassword (hwndDlg); + } + break; + + case IDM_ADD_REMOVE_VOL_KEYFILES: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + pwdChangeDlgMode = PCDM_ADD_REMOVE_VOL_KEYFILES; + ChangePassword (hwndDlg); + } + break; + + case IDM_REMOVE_ALL_KEYFILES_FROM_VOL: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + pwdChangeDlgMode = PCDM_REMOVE_ALL_KEYFILES_FROM_VOL; + ChangePassword (hwndDlg); + } + break; + + case IDM_BACKUP_VOL_HEADER: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), volPath, sizeof (volPath)); + + WaitCursor (); + + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (volPath)) + UacBackupVolumeHeader (hwndDlg, TRUE, volPath); + else + BackupVolumeHeader (hwndDlg, TRUE, volPath); + + NormalCursor (); + } + break; + + case IDM_RESTORE_VOL_HEADER: + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), volPath, sizeof (volPath)); + + WaitCursor (); + + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (volPath)) + UacRestoreVolumeHeader (hwndDlg, volPath); + else + RestoreVolumeHeader (hwndDlg, volPath); + + NormalCursor (); + } + break; + + default: + SendMessage (MainDlg, WM_COMMAND, menuItem, NULL); + break; + } + return 1; + } + + if (lw == IDM_CHANGE_PASSWORD) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + 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"); + } + 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, ""); + return 1; + } + + if (lw == IDM_ADD_REMOVE_VOL_KEYFILES) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + 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"); + } + 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"); + + return 1; + } + + if (lw == IDM_KEYFILE_GENERATOR) + { + DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_KEYFILE_GENERATOR), hwndDlg, + (DLGPROC) KeyfileGeneratorDlgProc, (LPARAM) 0); + + 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_ANALYZE_SYSTEM_CRASH) + { + if (!IsAdmin() && IsUacSupported()) + UacAnalyzeKernelMiniDump (hwndDlg); + else + AnalyzeKernelMiniDump (hwndDlg); + + 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); + } + else + { + TaskBarIconRemove (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_ADD_VOLUME_TO_FAVORITES || lw == IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES) + { + LPARAM selectedDrive = GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + + char volPathLower[TC_MAX_PATH]; + wchar_t volPathLowerW[TC_MAX_PATH]; + + // volPathLower will contain the volume path (if any) from the input field below the drive list + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), volPathLower, sizeof (volPathLower)); + + if (LOWORD (selectedDrive) != TC_MLIST_ITEM_NONSYS_VOL + && !(VolumeSelected (hwndDlg) && IsMountedVolume (volPathLower))) + { + Warning ("SELECT_A_MOUNTED_VOLUME"); + + return 1; + } + + int driveNo; + + if (VolumeSelected (hwndDlg) + && IsMountedVolume (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) - 'A'; + + if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0) + { + Warning ("SELECT_A_MOUNTED_VOLUME"); + return 1; + } + + // volPathHigher will contain the volume path selected in the main drive list + wstring volPathHigher (prop.wszVolume); + + ToSBCS (prop.wszVolume); + strcpy ((char *) volPathLowerW, volPathLower); + ToUNICODE ((char *) volPathLowerW); + + if (strcmp (((memcmp ((char *) prop.wszVolume, "\\??\\", 4) == 0) ? (char *) prop.wszVolume + 4 : (char *) 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 (volPathLowerW); + + 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)) + { + case 1: + driveNo = HIWORD (selectedDrive) - 'A'; + break; + + case 2: + driveNo = GetMountedVolumeDriveNo (volPathLower); + break; + + default: + return 1; + } + } + else + { + driveNo = HIWORD (selectedDrive) - 'A'; + } + } + } + else + { + driveNo = HIWORD (selectedDrive) - '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"); + } + else + { + char volPath[TC_MAX_PATH]; /* Volume to mount */ + + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), volPath, sizeof (volPath)); + + WaitCursor (); + + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (volPath)) + UacBackupVolumeHeader (hwndDlg, TRUE, volPath); + else + BackupVolumeHeader (hwndDlg, TRUE, volPath); + + NormalCursor (); + } + return 1; + } + + if (lw == IDM_RESTORE_VOL_HEADER) + { + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else + { + char volPath[TC_MAX_PATH]; /* Volume to mount */ + + GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), volPath, sizeof (volPath)); + + WaitCursor (); + + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (volPath)) + UacRestoreVolumeHeader (hwndDlg, volPath); + else + RestoreVolumeHeader (hwndDlg, volPath); + + 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 = GetLogicalDrives (); + + WaitCursor (); + + if (!(nCurrentOS == WIN_2000 && RemoteSession)) + { + BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, 0, ~driveMap); + Sleep (100); + BroadcastDeviceChange (DBT_DEVICEARRIVAL, 0, driveMap); + } + + LoadDriveLetters (GetDlgItem (hwndDlg, IDC_DRIVELIST), 0); + + if (nSelectedDriveIndex >= 0) + { + SelectItem (GetDlgItem (hwndDlg, IDC_DRIVELIST), + (char) HIWORD (GetItemLong (GetDlgItem (hwndDlg, IDC_DRIVELIST), nSelectedDriveIndex))); + } + + NormalCursor (); + return 1; + } + + if (lw == IDM_MOUNT_FAVORITE_VOLUMES) + { + MountFavoriteVolumes(); + return 1; + } + + if (lw == IDM_RESUME_INTERRUPTED_PROC) + { + ResumeInterruptedNonSysInplaceEncProcess (); + 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 (IsMountedVolume (FavoriteVolumes[favoriteIndex].Path.c_str())) + { + WaitCursor(); + OpenVolumeExplorerWindow (GetMountedVolumeDriveNo ((char *) FavoriteVolumes[favoriteIndex].Path.c_str())); + NormalCursor(); + } + else + MountFavoriteVolumes (FALSE, FALSE, FALSE, FavoriteVolumes[favoriteIndex]); + } + + return 1; + } + + return 0; + + case WM_DROPFILES: + { + HDROP hdrop = (HDROP) wParam; + DragQueryFile (hdrop, 0, szFileName, sizeof 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) + { + ((char *) cd->lpData)[cd->cbData - 1] = 0; + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), (char *)cd->lpData, bHistory); + } + + EnableDisableButtons (hwndDlg); + SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST)); + } + } + return 1; + + case WM_CLOSE: + EndMainDlg (hwndDlg); + return 1; + + default: + // Recreate tray icon if Explorer restarted + if (taskBarCreatedMsg != 0 && uMsg == taskBarCreatedMsg && TaskBarIconMutex != NULL) + { + TaskBarIconRemove (hwndDlg); + TaskBarIconAdd (hwndDlg); + return 1; + } + } + + return 0; +} + +void ExtractCommandLine (HWND hwndDlg, char *lpszCommandLine) +{ + char **lpszCommandLineArgs; /* Array of command line arguments */ + int nNoCommandLineArgs; /* The number of arguments in the array */ + char tmpPath[MAX_PATH * 2]; + + /* Defaults */ + mountOptions.PreserveTimestamp = TRUE; + + if (_stricmp (lpszCommandLine, "-Embedding") == 0) + { + ComServerMode = TRUE; + return; + } + + /* Extract command line arguments */ + NoCmdLineArgs = nNoCommandLineArgs = Win32CommandLine (lpszCommandLine, &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, + OptionVolume, + CommandWipeCache + }; + + argument args[]= + { + { OptionAuto, "/auto", "/a", FALSE }, + { OptionBeep, "/beep", "/b", FALSE }, + { OptionCache, "/cache", "/c", FALSE }, + { CommandDismount, "/dismount", "/d", FALSE }, + { OptionExplore, "/explore", "/e", FALSE }, + { OptionForce, "/force", "/f", FALSE }, + { CommandHelp, "/help", "/?", FALSE }, + { OptionHistory, "/history", "/h", FALSE }, + { OptionKeyfile, "/keyfile", "/k", FALSE }, + { OptionLetter, "/letter", "/l", FALSE }, + { OptionMountOption, "/mountoption", "/m", FALSE }, + { OptionPassword, "/password", "/p", FALSE }, + { OptionQuit, "/quit", "/q", FALSE }, + { OptionSilent, "/silent", "/s", FALSE }, + { OptionTokenLib, "/tokenlib", NULL, FALSE }, + { OptionVolume, "/volume", "/v", FALSE }, + { CommandWipeCache, "/wipecache", "/w", FALSE } + }; + + argumentspec as; + + int nArgPos; + + as.args = args; + as.arg_cnt = sizeof(args)/ sizeof(args[0]); + + switch (GetArgumentID (&as, lpszCommandLineArgs[i], &nArgPos)) + { + case OptionAuto: + { + char szTmp[32]; + bAuto = TRUE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + nArgPos, &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + if (!_stricmp (szTmp, "devices")) + bAutoMountDevices = TRUE; + else if (!_stricmp (szTmp, "favorites")) + bAutoMountFavorites = TRUE; + else if (!_stricmp (szTmp, "logon")) + LogOn = TRUE; + } + } + break; + + case OptionBeep: + bBeep = TRUE; + break; + + case OptionCache: + { + char szTmp[8]; + bCacheInDriver = TRUE; + + GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, nNoCommandLineArgs, + szTmp, sizeof (szTmp)); + + if (!_stricmp(szTmp,"n") || !_stricmp(szTmp,"no")) + bCacheInDriver = FALSE; + } + break; + + case CommandDismount: + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, nNoCommandLineArgs, + szDriveLetter, sizeof (szDriveLetter))) + cmdUnmountDrive = toupper(szDriveLetter[0]) - 'A'; + else + cmdUnmountDrive = -1; + + break; + + case OptionExplore: + bExplore = TRUE; + break; + + case OptionForce: + bForceMount = TRUE; + bForceUnmount = TRUE; + break; + + case OptionKeyfile: + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, + nNoCommandLineArgs, tmpPath, sizeof (tmpPath))) + { + KeyFile *kf; + RelativePath2Absolute (tmpPath); + kf = (KeyFile *) malloc (sizeof (KeyFile)); + strncpy (kf->FileName, tmpPath, sizeof (kf->FileName)); + FirstCmdKeyFile = KeyFileAdd (FirstCmdKeyFile, kf); + } + break; + + case OptionLetter: + GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, nNoCommandLineArgs, + szDriveLetter, sizeof (szDriveLetter)); + commandLineDrive = *szDriveLetter = (char) toupper (*szDriveLetter); + + if (commandLineDrive < 'C' || commandLineDrive > 'Z') + AbortProcess ("BAD_DRIVE_LETTER"); + + break; + + case OptionHistory: + { + char szTmp[8]; + bHistory = bHistoryCmdLine = TRUE; + + GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, nNoCommandLineArgs, + szTmp, sizeof (szTmp)); + + if (!_stricmp(szTmp,"n") || !_stricmp(szTmp,"no")) + bHistory = FALSE; + } + break; + + case OptionMountOption: + { + char szTmp[16]; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + nArgPos, &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + if (!_stricmp (szTmp, "ro") || !_stricmp (szTmp, "readonly")) + mountOptions.ReadOnly = TRUE; + + if (!_stricmp (szTmp, "rm") || !_stricmp (szTmp, "removable")) + mountOptions.Removable = TRUE; + + if (!_stricmp (szTmp, "ts") || !_stricmp (szTmp, "timestamp")) + mountOptions.PreserveTimestamp = FALSE; + + if (!_stricmp (szTmp, "sm") || !_stricmp (szTmp, "system")) + mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode = TRUE; + + if (!_stricmp (szTmp, "bk") || !_stricmp (szTmp, "headerbak")) + mountOptions.UseBackupHeader = TRUE; + + if (!_stricmp (szTmp, "recovery")) + mountOptions.RecoveryMode = TRUE; + + CmdMountOptions = mountOptions; + CmdMountOptionsValid = TRUE; + } + } + break; + + case OptionPassword: + GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, nNoCommandLineArgs, + (char *) CmdVolumePassword.Text, sizeof (CmdVolumePassword.Text)); + CmdVolumePassword.Length = strlen ((char *) CmdVolumePassword.Text); + CmdVolumePasswordValid = TRUE; + break; + + case OptionVolume: + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, + nNoCommandLineArgs, szFileName, sizeof (szFileName))) + { + RelativePath2Absolute (szFileName); + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + CmdLineVolumeSpecified = TRUE; + } + break; + + case OptionQuit: + { + char szTmp[32]; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + nArgPos, &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + if (!_stricmp (szTmp, "UAC")) // Used to indicate non-install elevation + break; + + if (!_stricmp (szTmp, "preferences")) + { + Quit = TRUE; + UsePreferences = TRUE; + break; + } + + if (!_stricmp (szTmp, "background")) + bEnableBkgTask = TRUE; + } + + Quit = TRUE; + UsePreferences = FALSE; + } + break; + + case OptionSilent: + Silent = TRUE; + break; + + case OptionTokenLib: + if (GetArgumentValue (lpszCommandLineArgs, nArgPos, &i, nNoCommandLineArgs, SecurityTokenLibraryPath, sizeof (SecurityTokenLibraryPath)) == HAS_ARGUMENT) + InitSecurityTokenLibrary(); + else + Error ("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; + + // no option = file name + default: + { + strcpy_s (szFileName, array_capacity (szFileName), lpszCommandLineArgs[i]); + RelativePath2Absolute (szFileName); + + if (nNoCommandLineArgs == 1) + CmdLineVolumeSpecified = TRUE; + AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory); + } + } + } + } + + /* Free up the command line arguments */ + while (--nNoCommandLineArgs >= 0) + { + free (lpszCommandLineArgs[nNoCommandLineArgs]); + } +} + + +static SERVICE_STATUS SystemFavoritesServiceStatus; +static SERVICE_STATUS_HANDLE SystemFavoritesServiceStatusHandle; + + +static void SystemFavoritesServiceLogError (const string &errorMessage) +{ + HANDLE eventSource = RegisterEventSource (NULL, TC_SYSTEM_FAVORITES_SERVICE_NAME); + + if (eventSource) + { + LPCTSTR strings[] = { TC_SYSTEM_FAVORITES_SERVICE_NAME, errorMessage.c_str() }; + ReportEvent (eventSource, EVENTLOG_ERROR_TYPE, 0, 0xC0000001, NULL, array_capacity (strings), 0, strings, NULL); + + DeregisterEventSource (eventSource); + } +} + + +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) +{ + 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, 60000); + + try + { + MountFavoriteVolumes (TRUE); + } + catch (...) { } + + SystemFavoritesServiceSetStatus (SERVICE_RUNNING); + SystemFavoritesServiceSetStatus (SERVICE_STOPPED); +} + + +static BOOL StartSystemFavoritesService () +{ + ServiceMode = TRUE; + Silent = TRUE; + DeviceChangeBroadcastDisabled = 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; +} + + +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, char *lpszCommandLine, int nCmdShow) +{ + int argc; + LPWSTR *argv = CommandLineToArgvW (GetCommandLineW(), &argc); + + if (argv && argc == 2 && SingleStringToWide (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)); + + try + { + BootEncObj = new BootEncryption (NULL); + } + catch (Exception &e) + { + e.Show (NULL); + } + + if (BootEncObj == NULL) + AbortProcess ("INIT_SYS_ENC"); + + InitCommonControls (); + InitApp (hInstance, lpszCommandLine); + + RegisterRedTick(hInstance); + + /* Allocate, dup, then store away the application title */ + lpszTitle = L"TrueCrypt"; + + status = DriverAttach (); + if (status != 0) + { + if (status == ERR_OS_ERROR) + handleWin32Error (NULL); + else + handleError (NULL, status); + + AbortProcess ("NODRIVER"); + } + + /* Create the main dialog box */ + DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_MOUNT_DLG), NULL, (DLGPROC) MainDialogProc, + (LPARAM) lpszCommandLine); + + /* Terminate */ + return 0; +} + + +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, "TrueCryptTaskBarIcon"); + if (TaskBarIconMutex == NULL || GetLastError () == ERROR_ALREADY_EXISTS) + { + 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 + + wcscpy (tnid.szTip, L"TrueCrypt"); + + 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) + { + 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; + } + } + } + } +} + + +BOOL MountFavoriteVolumes (BOOL systemFavorites, BOOL logOnMount, BOOL hotKeyMount, const FavoriteVolume &favoriteVolumeToMount) +{ + BOOL status = TRUE; + BOOL lastbExplore; + BOOL userForcedReadOnly = FALSE; + + mountOptions = defaultMountOptions; + + VolumePassword.Length = 0; + MultipleMountOperationInProgress = (favoriteVolumeToMount.Path.empty() || FavoriteMountOnArrivalInProgress); + + vector favorites; + + if (systemFavorites) + { + try + { + LoadFavoriteVolumes (favorites, true); + } + catch (...) + { + return false; + } + } + else if (!favoriteVolumeToMount.Path.empty()) + favorites.push_back (favoriteVolumeToMount); + else + favorites = FavoriteVolumes; + + foreach (const FavoriteVolume &favorite, favorites) + { + if (favorite.DisconnectedDevice + || (logOnMount && !favorite.MountOnLogOn) + || (hotKeyMount && favorite.DisableHotkeyMount)) + { + continue; + } + + int drive; + drive = toupper (favorite.MountPoint[0]) - 'A'; + + mountOptions.ReadOnly = favorite.ReadOnly || userForcedReadOnly; + mountOptions.Removable = favorite.Removable; + + if (favorite.SystemEncryption) + { + mountOptions.PartitionInInactiveSysEncScope = TRUE; + bPrebootPasswordDlgMode = TRUE; + } + else + { + mountOptions.PartitionInInactiveSysEncScope = FALSE; + bPrebootPasswordDlgMode = FALSE; + } + + if ((LastKnownMountList.ulMountedDrives & (1 << drive)) == 0) + { + MountVolumesAsSystemFavorite = systemFavorites; + + string mountPoint = (char) (drive + 'A') + string (":\\"); + char 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, sizeof (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) + { + if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), MainDlg, MountOptionsDlgProc, (LPARAM) &mountOptions) == IDCANCEL) + { + status = FALSE; + goto skipMount; + } + } + + BOOL prevReadOnly = mountOptions.ReadOnly; + + if (!Mount (MainDlg, drive, (char *) favorite.Path.c_str())) + status = FALSE; + + 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] = (char) (freeDrive + 'A'); + SetVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint); + } + } + else + SetVolumeMountPoint (mountPoint.c_str(), prevVolumeAtMountPoint); + } + + LoadDriveLetters (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 (string ("The filesystem of the volume mounted as ") + (char) (drive + 'A') + ": was not cleanly dismounted and needs to be checked for errors."); + } + } + else if (!systemFavorites && !favoriteVolumeToMount.Path.empty()) + Error ("DRIVE_LETTER_UNAVAILABLE"); + } + + MultipleMountOperationInProgress = FALSE; + burn (&VolumePassword, sizeof (VolumePassword)); + + if (status && CloseSecurityTokenSessionsAfterMount) + SecurityToken::CloseAllSessions(); + + return status; +} + + +static void SaveDefaultKeyFilesParam (void) +{ + if (defaultKeyFilesParam.FirstKeyFile == NULL) + { + /* No keyfiles selected */ + remove (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES)); + } + else + { + FILE *f; + KeyFile *kf = FirstKeyFile; + + f = fopen (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES), "w"); + if (f == NULL) + { + handleWin32Error (MainDlg); + return; + } + + XmlWriteHeader (f); + + fputs ("\n\t", f); + + while (kf != NULL) + { + char q[TC_MAX_PATH * 2]; + + XmlQuoteText (kf->FileName, q, sizeof (q)); + fprintf (f, "\n\t\t%s", q); + + kf = kf->Next; + } + + fputs ("\n\t", f); + + XmlWriteFooter (f); + + CheckFileStreamWriteErrors (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") == IDYES) + { + KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); + defaultKeyFilesParam.EnableKeyFiles = param.EnableKeyFiles; + defaultKeyFilesParam.FirstKeyFile = param.FirstKeyFile; + + RestoreDefaultKeyFilesParam (); + SaveDefaultKeyFilesParam (); + } + } +} + + +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")); + + 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"); + + 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"); + + if (bPlaySoundOnSuccessfulHkDismount) + MessageBeep (0xFFFFFFFF); + } + TaskBarIconRemove (hwndDlg); + EndMainDlg (hwndDlg); + break; + + case HK_MOUNT_FAVORITE_VOLUMES: + MountFavoriteVolumes (FALSE, FALSE, TRUE); + break; + + case HK_SHOW_HIDE_MAIN_WINDOW: + ChangeMainWindowVisibility (); + break; + + case HK_CLOSE_SECURITY_TOKEN_SESSIONS: + SecurityToken::CloseAllSessions(); + + InfoBalloon (NULL, "ALL_TOKEN_SESSIONS_CLOSED"); + + 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, char *lpszVolume) +{ + int nStatus = ERR_OS_ERROR; + wchar_t szTmp[4096]; + int fBackup = -1; + OpenVolumeContext volume; + OpenVolumeContext hiddenVolume; + Password hiddenVolPassword; + byte temporaryKey[MASTER_KEYDATA_SIZE]; + byte originalK2[MASTER_KEYDATA_SIZE]; + + volume.VolumeIsOpen = FALSE; + hiddenVolume.VolumeIsOpen = FALSE; + + switch (IsSystemDevicePath (lpszVolume, hwndDlg, TRUE)) + { + case 1: + case 2: + if (AskErrNoYes ("BACKUP_HEADER_NOT_FOR_SYS_DEVICE") == IDYES) + CreateRescueDisk (); + + return 0; + } + + if (IsMountedVolume (lpszVolume)) + { + Warning ("DISMOUNT_FIRST"); + goto ret; + } + + if (!VolumePathExists (lpszVolume)) + { + handleWin32Error (hwndDlg); + goto ret; + } + + Info ("EXTERNAL_VOL_HEADER_BAK_FIRST_INFO"); + + + 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); + + while (TRUE) + { + if (!AskVolumePassword (hwndDlg, askPassword, type == TC_VOLUME_TYPE_HIDDEN ? "ENTER_HIDDEN_VOL_PASSWORD" : "ENTER_NORMAL_VOL_PASSWORD", FALSE)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + + WaitCursor(); + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (askPassword, FirstKeyFile); + + nStatus = OpenVolume (askVol, lpszVolume, askPassword, 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); + 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)) + { + case 1: + break; + case 2: + goto noHidden; + + default: + nStatus = ERR_SUCCESS; + goto ret; + } + } + + break; + } + + if (nStatus != ERR_PASSWORD_WRONG) + goto error; + + handleError (hwndDlg, nStatus); + } + } +noHidden: + + if (hiddenVolume.VolumeIsOpen && volume.CryptoInfo->LegacyVolume != hiddenVolume.CryptoInfo->LegacyVolume) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + swprintf (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 = _open(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) + { + nStatus = ERR_PARAMETER_INCORRECT; + goto error; + } + + NormalCursor(); + UserEnrichRandomPool (hwndDlg); + WaitCursor(); + + // Temporary keys + if (!RandgetBytes (temporaryKey, EAGetKeySize (volume.CryptoInfo->ea), TRUE) + || !RandgetBytes (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 ((char *) backup, FALSE, volume.CryptoInfo, &VolumePassword, FALSE); + if (nStatus != ERR_SUCCESS) + goto error; + + if (hiddenVolume.VolumeIsOpen) + { + nStatus = ReEncryptVolumeHeader ((char *) backup + (legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE), + FALSE, hiddenVolume.CryptoInfo, &hiddenVolPassword, 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"); + +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); + + burn (&VolumePassword, sizeof (VolumePassword)); + burn (&hiddenVolPassword, sizeof (hiddenVolPassword)); + burn (temporaryKey, sizeof (temporaryKey)); + burn (originalK2, sizeof (originalK2)); + + RestoreDefaultKeyFilesParam(); + RandStop (FALSE); + NormalCursor(); + + return nStatus; +} + + +int RestoreVolumeHeader (HWND hwndDlg, char *lpszVolume) +{ + int nDosLinkCreated = -1, nStatus = ERR_OS_ERROR; + char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; + char szFileName[TC_MAX_PATH]; + char 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; + + switch (IsSystemDevicePath (lpszVolume, hwndDlg, TRUE)) + { + case 1: + case 2: + if (AskErrNoYes ("RESTORE_HEADER_NOT_FOR_SYS_DEVICE") == IDYES) + CreateRescueDisk (); + + 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"); + return 0; + } + + if (!VolumePathExists (lpszVolume)) + { + handleWin32Error (hwndDlg); + 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)) + { + case 1: + restoreInternalBackup = TRUE; + break; + case 2: + restoreInternalBackup = FALSE; + break; + default: + return 0; + } + + OpenVolumeContext volume; + volume.VolumeIsOpen = FALSE; + + WaitCursor(); + + if (restoreInternalBackup) + { + // Restore header from the internal backup + + // Open the volume using backup header + while (TRUE) + { + strncpy (PasswordDlgVolume, lpszVolume, sizeof (PasswordDlgVolume)); + if (!AskVolumePassword (hwndDlg, &VolumePassword, NULL, FALSE)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + + WaitCursor(); + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (&VolumePassword, FirstKeyFile); + + nStatus = OpenVolume (&volume, lpszVolume, &VolumePassword, TRUE, bPreserveTimestamp, TRUE); + + NormalCursor(); + + if (nStatus == ERR_SUCCESS) + break; + + if (nStatus != ERR_PASSWORD_WRONG) + goto error; + + handleError (hwndDlg, nStatus); + } + + if (volume.CryptoInfo->LegacyVolume) + { + Error ("VOLUME_HAS_NO_BACKUP_HEADER"); + nStatus = ERROR_SUCCESS; + goto error; + } + + // Create a new header with a new salt + char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + + nStatus = ReEncryptVolumeHeader (buffer, FALSE, volume.CryptoInfo, &VolumePassword, 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 + + swprintf (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, lpszVolume, &bDevice); + + if (bDevice == FALSE) + strcpy (szCFDevice, szDiskFile); + else + { + nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, 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"); + nStatus = ERR_SUCCESS; + goto error; + } + + // Open the header + while (TRUE) + { + if (!AskVolumePassword (hwndDlg, &VolumePassword, "ENTER_HEADER_BACKUP_PASSWORD", FALSE)) + { + nStatus = ERR_SUCCESS; + goto ret; + } + + if (KeyFilesEnable && FirstKeyFile) + KeyFilesApply (&VolumePassword, FirstKeyFile); + + // 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, &restoredCryptoInfo, NULL); + if (nStatus == ERR_SUCCESS) + break; + } + + if (nStatus == ERR_SUCCESS) + break; + + if (nStatus != ERR_PASSWORD_WRONG) + goto error; + + handleError (hwndDlg, nStatus); + } + + 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 (buffer, FALSE, restoredCryptoInfo, &VolumePassword, 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 (buffer, FALSE, restoredCryptoInfo, &VolumePassword, 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"); +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); + + burn (&VolumePassword, sizeof (VolumePassword)); + 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); + + 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) + { + stringstream 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"); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + BOOL disableHW = !IsDlgButtonChecked (hwndDlg, IDC_ENABLE_HARDWARE_ENCRYPTION); + + try + { + try + { + BootEncStatus = BootEncObj->GetStatus(); + } + 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"); + + 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); + } + + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION, disableHW); + + DWORD bytesReturned; + if (!DeviceIoControl (hDriver, TC_IOCTL_REREAD_DRIVER_CONFIG, NULL, 0, NULL, 0, &bytesReturned, NULL)) + handleWin32Error (hwndDlg); + + 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 ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME, cpuFreeCount); + Warning ("SETTING_REQUIRES_REBOOT"); + } + + 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") == 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") == 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"); // 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: + { + char securityTokenLibraryPath[MAX_PATH]; + GetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, securityTokenLibraryPath, sizeof (securityTokenLibraryPath)); + + if (securityTokenLibraryPath[0] == 0) + { + try + { + SecurityToken::CloseLibrary(); + } + catch (...) { } + + SecurityTokenLibraryPath[0] = 0; + } + else + { + char prevSecurityTokenLibraryPath[MAX_PATH]; + strcpy (prevSecurityTokenLibraryPath, SecurityTokenLibraryPath); + strcpy (SecurityTokenLibraryPath, securityTokenLibraryPath); + + if (!InitSecurityTokenLibrary()) + { + strcpy (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: + { + char systemDir[MAX_PATH]; + GetSystemDirectory (systemDir, sizeof (systemDir)); + WIN32_FIND_DATA findData; + bool found = false; + + WaitCursor(); + + HANDLE find = FindFirstFile ((string (systemDir) + "\\*.dll").c_str(), &findData); + while (!found && find != INVALID_HANDLE_VALUE) + { + string dllPathname = string (systemDir) + "\\" + 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"); + + return 1; + } + + case IDC_SELECT_PKCS11_MODULE: + { + char securityTokenLibraryPath[MAX_PATH]; + char systemDir[MAX_PATH]; + wchar_t browseFilter[1024]; + + Info ("SELECT_PKCS11_MODULE_HELP"); + + wsprintfW (browseFilter, L"%ls (*.dll)%c*.dll%c%c", GetString ("DLL_FILES"), 0, 0, 0); + GetSystemDirectory (systemDir, sizeof (systemDir)); + + if (BrowseFilesInDir (hwndDlg, "SELECT_PKCS11_MODULE", systemDir, securityTokenLibraryPath, TRUE, FALSE, browseFilter)) + SetDlgItemText (hwndDlg, IDC_PKCS11_MODULE, securityTokenLibraryPath); + 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"); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + try + { + LocalizeDialog (hwndDlg, "IDD_SYSENC_SETTINGS"); + + uint32 driverConfig = ReadDriverConfigurationFlags(); + byte userConfig; + string customUserMessage; + uint16 bootLoaderVersion; + + BootEncObj->ReadBootSectorConfig (nullptr, 0, &userConfig, &customUserMessage, &bootLoaderVersion); + + if (bootLoaderVersion != VERSION_NUM) + Warning ("BOOT_LOADER_VERSION_INCORRECT_PREFERENCES"); + + SendMessage (GetDlgItem (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE), EM_LIMITTEXT, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, 0); + SetDlgItemText (hwndDlg, IDC_CUSTOM_BOOT_LOADER_MESSAGE, customUserMessage.c_str()); + + 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, (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD) ? 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: + { + if (!BootEncObj->GetStatus().DriveMounted) + { + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + char customUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1]; + GetDlgItemText (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_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 + { + BootEncObj->WriteBootSectorUserConfig (userConfig, customUserMessage); + SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD, IsDlgButtonChecked (hwndDlg, IDC_BOOT_LOADER_CACHE_PASSWORD)); + } + catch (Exception &e) + { + e.Show (hwndDlg); + return 1; + } + + EndDialog (hwndDlg, lw); + return 1; + } + + case IDC_DISABLE_BOOT_LOADER_OUTPUT: + if ((IsDlgButtonChecked (hwndDlg, IDC_DISABLE_BOOT_LOADER_OUTPUT)) + && AskWarnYesNo ("CUSTOM_BOOT_LOADER_MESSAGE_PROMPT") == 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"); + + break; + } + return 0; + } + + return 0; +} + + +void MountSelectedVolume (HWND hwndDlg, BOOL mountWithOptions) +{ + if (!VolumeSelected(hwndDlg)) + { + Warning ("NO_VOLUME_SELECTED"); + } + else if (LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))) == TC_MLIST_ITEM_FREE) + { + mountOptions = defaultMountOptions; + bPrebootPasswordDlgMode = FALSE; + + if (mountWithOptions || GetAsyncKeyState (VK_CONTROL) < 0) + { + if (IDCANCEL == DialogBoxParamW (hInst, + MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg, + (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions)) + return; + + if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles) + KeyFilesApply (&mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile); + } + + if (CheckMountList ()) + Mount (hwndDlg, 0, 0); + } + else + Warning ("SELECT_FREE_DRIVE"); +} + + +BOOL GetExecutableImageInformation (const string &path, string &version, string &description, string &companyName, string &productName) +{ + DWORD handle; + DWORD size = GetFileVersionInfoSize (path.c_str(), &handle); + if (size == 0) + return FALSE; + + void *buf = err_malloc (size); + finally_do_arg (void*, buf, { free (finally_arg); }); + + if (!GetFileVersionInfo (path.c_str(), handle, size, buf)) + return FALSE; + + version = description = companyName = productName = ""; + + UINT varSize; + VS_FIXEDFILEINFO *fileInfo; + if (VerQueryValue (buf, "\\", (LPVOID *) &fileInfo, &varSize) && varSize > 0) + { + stringstream s; + s << HIWORD (fileInfo->dwFileVersionMS) << '.' << LOWORD (fileInfo->dwFileVersionMS) << '.' << HIWORD (fileInfo->dwFileVersionLS) << '.' << LOWORD (fileInfo->dwFileVersionLS); + version = s.str(); + } + + DWORD *langCodes; + if (VerQueryValue (buf, "\\VarFileInfo\\Translation", (LPVOID *) &langCodes, &varSize) && varSize >= sizeof (DWORD)) + { + char prefix[128]; + sprintf_s (prefix, sizeof (prefix), "\\StringFileInfo\\%04x%04x\\", LOWORD (langCodes[0]), HIWORD (langCodes[0])); + + char *str; + if (VerQueryValue (buf, (string (prefix) + "FileDescription").c_str(), (LPVOID *) &str, &varSize) && varSize > 0) + description = str; + + if (VerQueryValue (buf, (string (prefix) + "CompanyName").c_str(), (LPVOID *) &str, &varSize) && varSize > 0) + companyName = str; + + if (VerQueryValue (buf, (string (prefix) + "ProductName").c_str(), (LPVOID *) &str, &varSize) && varSize > 0) + productName = str; + } + + return TRUE; +} + + +void AnalyzeKernelMiniDump (HWND hwndDlg) +{ + char winDir[MAX_PATH] = { 0 }; + GetWindowsDirectory (winDir, sizeof (winDir)); + string memDumpPath = string (winDir) + "\\MEMORY.DMP"; + string tmpDumpPath; + + string dumpPath = FindLatestFileOrDirectory (string (winDir) + "\\Minidump", "*.dmp", false, true); + if (dumpPath.empty()) + { + Error ("NO_MINIDUMP_FOUND"); + return; + } + + WIN32_FIND_DATA findData; + HANDLE find = FindFirstFile (memDumpPath.c_str(), &findData); + + if (find != INVALID_HANDLE_VALUE) + { + ULARGE_INTEGER memDumpTime, miniDumpTime; + memDumpTime.HighPart = findData.ftLastWriteTime.dwHighDateTime; + memDumpTime.LowPart = findData.ftLastWriteTime.dwLowDateTime; + + FindClose (find); + + find = FindFirstFile (dumpPath.c_str(), &findData); + if (find != INVALID_HANDLE_VALUE) + { + miniDumpTime.HighPart = findData.ftLastWriteTime.dwHighDateTime; + miniDumpTime.LowPart = findData.ftLastWriteTime.dwLowDateTime; + + if (_abs64 (miniDumpTime.QuadPart - memDumpTime.QuadPart) < 10I64 * 1000 * 1000 * 60 * 5) + { + // Rename MEMORY.DMP file first as it can be deleted by Windows when system crash dialog is closed + tmpDumpPath = memDumpPath + ".true_crypt.dmp"; // Application name must be mangled to avoid interfering with crash analysis + + if (MoveFile (memDumpPath.c_str(), tmpDumpPath.c_str())) + dumpPath = tmpDumpPath; + else + tmpDumpPath.clear(); + } + + FindClose (find); + } + } + + finally_do_arg2 (string, tmpDumpPath, string, memDumpPath, + { + if (!finally_arg.empty()) + { + if (AskYesNo ("ASK_DELETE_KERNEL_CRASH_DUMP") == IDYES) + DeleteFile (finally_arg.c_str()); + else + MoveFile (finally_arg.c_str(), finally_arg2.c_str()); + } + }); + + STARTUPINFO startupInfo; + PROCESS_INFORMATION procInfo; + + ZeroMemory (&startupInfo, sizeof (startupInfo)); + ZeroMemory (&procInfo, sizeof (procInfo)); + + if (!IsApplicationInstalled (Is64BitOs() ? "Debugging Tools for Windows (x64)" : "Debugging Tools for Windows (x86)")) + { + if (AskOkCancel ("ASK_DEBUGGER_INSTALL") != IDOK) + return; + + if (!CreateProcess (NULL, (LPSTR) (string ("msiexec.exe /qb /i " TC_APPLINK "&dest=ms-debug-tools-x") + (Is64BitOs() ? "64" : "86")).c_str(), + NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &procInfo)) + { + handleWin32Error (hwndDlg); + return; + } + + WaitCursor(); + WaitForSingleObject (procInfo.hProcess, INFINITE); + NormalCursor(); + + DWORD exitCode; + if (!GetExitCodeProcess (procInfo.hProcess, &exitCode) || exitCode != 0) + return; + } + + if (AskOkCancel ("SYSTEM_CRASH_ANALYSIS_INFO") == IDCANCEL) + return; + + ZeroMemory (&startupInfo, sizeof (startupInfo)); + ZeroMemory (&procInfo, sizeof (procInfo)); + + SECURITY_ATTRIBUTES securityAttrib; + securityAttrib.bInheritHandle = TRUE; + securityAttrib.nLength = sizeof (securityAttrib); + securityAttrib.lpSecurityDescriptor = NULL; + + HANDLE hChildStdoutWrite = INVALID_HANDLE_VALUE; + HANDLE hChildStdoutRead = INVALID_HANDLE_VALUE; + if (!CreatePipe (&hChildStdoutRead, &hChildStdoutWrite, &securityAttrib, 0)) + { + handleWin32Error (hwndDlg); + return; + } + SetHandleInformation (hChildStdoutRead, HANDLE_FLAG_INHERIT, 0); + + startupInfo.hStdInput = INVALID_HANDLE_VALUE; + startupInfo.hStdOutput = hChildStdoutWrite; + startupInfo.cb = sizeof (startupInfo); + startupInfo.hStdError = hChildStdoutWrite; + startupInfo.dwFlags |= STARTF_USESTDHANDLES; + + list kdPaths; + string kdPath; + char progPath[MAX_PATH]; + if (SHGetSpecialFolderPath (hwndDlg, progPath, CSIDL_PROGRAM_FILES, FALSE)) + { + if (Is64BitOs()) + { + string s = progPath; + size_t p = s.find (" (x86)"); + if (p != string::npos) + { + s = s.substr (0, p); + if (_access (s.c_str(), 0) != -1) + strcpy_s (progPath, sizeof (progPath), s.c_str()); + } + } + + kdPath = string (progPath) + "\\Debugging Tools for Windows (" + (Is64BitOs() ? "x64" : "x86") + ")\\kd.exe"; + kdPaths.push_back (kdPath); + } + + kdPath = FindLatestFileOrDirectory (string (winDir).substr (0, 1) + ":\\WinDDK", "*", true, false); + kdPath += "\\Debuggers\\kd.exe"; + kdPaths.push_back (kdPath); + + kdPaths.push_back ("kd.exe"); + + bool kdRunning = false; + foreach (const string &kdPath, kdPaths) + { + if (CreateProcess (NULL, (LPSTR) ("\"" + kdPath + "\" -z \"" + dumpPath + "\" -y http://msdl.microsoft.com/download/symbols -c \".bugcheck; !analyze -v; q\"").c_str(), + NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &procInfo)) + { + kdRunning = true; + break; + } + } + + if (!kdRunning) + { + handleWin32Error (hwndDlg); + Error ("DEBUGGER_NOT_FOUND"); + return; + } + + EnableElevatedCursorChange (hwndDlg); + WaitCursor(); + + CloseHandle (procInfo.hProcess); + CloseHandle (procInfo.hThread); + CloseHandle (hChildStdoutWrite); + + string output; + + while (TRUE) + { + DWORD bytesReceived; + char pipeBuffer [4096]; + + if (!ReadFile (hChildStdoutRead, pipeBuffer, sizeof (pipeBuffer), &bytesReceived, NULL)) + break; + + output.insert (output.size(), pipeBuffer, bytesReceived); + } + + NormalCursor(); + + bool otherDriver = (StringToUpperCase (output).find (StringToUpperCase (TC_APP_NAME)) == string::npos); + + size_t p, p2; + while ((p = output.find ('`')) != string::npos) + output.erase (output.begin() + p); + + p = output.find ("Bugcheck code "); + if (p == string::npos) + { + Error ("ERR_PARAMETER_INCORRECT"); + return; + } + + uint64 bugcheckCode; + int n = sscanf (output.substr (p + 14, 8).c_str(), "%I64X", &bugcheckCode); + if (n != 1) + { + Error ("ERR_PARAMETER_INCORRECT"); + return; + } + + p = output.find ("Arguments ", p); + + uint64 bugcheckArgs[4]; + n = sscanf (output.substr (p + 10, (Is64BitOs() ? 17 : 9) * 4).c_str(), "%I64X %I64X %I64X %I64X", &bugcheckArgs[0], &bugcheckArgs[1], &bugcheckArgs[2], &bugcheckArgs[3]); + if (n != 4) + { + Error ("ERR_PARAMETER_INCORRECT"); + return; + } + + // Image name + string imageName, imageVersion; + p = output.find ("IMAGE_NAME:"); + if (p != string::npos) + { + p += 13; + p2 = output.find ('\n', p); + if (p2 != string::npos) + imageName = output.substr (p, p2 - p); + } + + // Stack trace + p = output.find ("STACK_TEXT:"); + if (p == string::npos) + { + Error ("ERR_PARAMETER_INCORRECT"); + return; + } + + p2 = output.find ("FOLLOWUP_IP:", p); + if (p2 == string::npos) + p2 = output.find ("STACK_COMMAND:", p); + if (p2 == string::npos) + p2 = output.size(); + + output = output.substr (p, p2 - p); + + list retAddrs; + p = 0; + while ((p = output.find ("+", p)) != string::npos) + { + size_t p1 = output.rfind (" ", p); + if (p1 == string::npos) + break; + + p = output.find ('\n', p); + if (p == string::npos) + p = output.size() - 1; + + string s = output.substr (p1 + 1, p - p1 - 1); + + if (s.find ('(') == 0) + s = s.substr (1); + if (s.rfind (')') == s.size() - 1) + s = s.substr (0, s.size() - 1); + + retAddrs.push_back (s); + } + + char url[MAX_URL_LENGTH]; + sprintf (url, TC_APPLINK_SECURE "&dest=syserr-report&os=%s&osver=%d.%d.%d&arch=%s&err=%I64x&arg1=%I64x&arg2=%I64x&arg3=%I64x&arg4=%I64x&flag=%s&drv=%s", + GetWindowsEdition().c_str(), + CurrentOSMajor, + CurrentOSMinor, + CurrentOSServicePack, + Is64BitOs() ? "x64" : "x86", + bugcheckCode, + bugcheckArgs[0], + bugcheckArgs[1], + bugcheckArgs[2], + bugcheckArgs[3], + otherDriver ? "0" : "1", + imageName.empty() ? "-" : imageName.c_str() + ); + + stringstream stackTraceArgs; + int i = 0; + foreach (const string &retAddr, retAddrs) + { + stackTraceArgs << "&st" << i++ << "=" << retAddr; + } + + wstring msg; + + if (!imageName.empty() && StringToUpperCase (imageName) != StringToUpperCase (TC_APP_NAME) + ".SYS") + { + msg += wstring (GetString ("SYSTEM_CRASH_UPDATE_DRIVER")) + L"\n\n" + SingleStringToWide (imageName); + + string description, company, product; + if (GetExecutableImageInformation (string (winDir) + "\\System32\\drivers\\" + imageName, imageVersion, description, company, product)) + { + string s; + if (!description.empty()) + s += description; + if (!company.empty()) + s += "; " + company; + if (!product.empty()) + s += "; " + product; + + if (s.find ("; ") == 0) + s = s.substr (3); + + if (!s.empty()) + msg += SingleStringToWide (" (" + s + ")"); + } + + msg += L"\n\n"; + } + + if (otherDriver) + { + msg += GetString ("SYSTEM_CRASH_NO_TRUECRYPT"); + msg += L"\n\n"; + } + + string urlStr = string (url) + "&drvver=" + (imageVersion.empty() ? "-" : imageVersion) + stackTraceArgs.str(); + + for (size_t i = 0; i < urlStr.size(); ++i) + { + if (urlStr[i] == '+') + urlStr[i] = '.'; + } + + msg += GetString ("SYSTEM_CRASH_REPORT"); + msg += L"\n\n"; + + msg += SingleStringToWide (urlStr); + + msg += L"\n\n"; + msg += GetString ("ASK_SEND_ERROR_REPORT"); + + if (AskYesNoString (msg.c_str()) == IDYES) + ShellExecute (NULL, "open", urlStr.c_str(), NULL, NULL, SW_SHOWNORMAL); +} + + +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) GetWindowLongPtr (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 CallWindowProc (wp, hwnd, message, wParam, lParam); +} + + +void HookMouseWheel (HWND hwndDlg, UINT ctrlId) +{ + HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); + + SetWindowLongPtr (hwndCtrl, GWLP_USERDATA, (LONG_PTR) GetWindowLongPtr (hwndCtrl, GWLP_WNDPROC)); + SetWindowLongPtr (hwndCtrl, GWLP_WNDPROC, (LONG_PTR) MouseWheelProc); +} diff --git a/src/Mount/Mount.h b/src/Mount/Mount.h new file mode 100644 index 00000000..4f80479e --- /dev/null +++ b/src/Mount/Mount.h @@ -0,0 +1,115 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of Encryption for the Masses 2.02a, which is + Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License + Agreement for Encryption for the Masses'. Modifications and additions to + the original source code (contained in this file) and all other portions + of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association + and are governed by the TrueCrypt License 3.0 the full text of which is + contained in the file License.txt included in TrueCrypt binary and source + code distribution packages. */ + +#ifdef __cplusplus + +#include "Favorites.h" + +extern "C" { +#endif + +enum mount_list_item_types +{ + TC_MLIST_ITEM_FREE = 0, + TC_MLIST_ITEM_NONSYS_VOL, + TC_MLIST_ITEM_SYS_PARTITION, + TC_MLIST_ITEM_SYS_DRIVE +}; + +#define TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES 0x1 + +#define TRAYICON_MENU_DRIVE_OFFSET 9000 +#define TC_FAVORITE_MENU_CMD_ID_OFFSET 10000 +#define TC_FAVORITE_MENU_CMD_ID_OFFSET_END (TC_FAVORITE_MENU_CMD_ID_OFFSET + 1000) + +#define WM_COPY_SET_VOLUME_NAME "VNAM" + +#define ENC_SYSDRIVE_PSEUDO_DRIVE_LETTER ('A' - 1) + +/* Password Change dialog modes */ +enum +{ + PCDM_CHANGE_PASSWORD = 0, + PCDM_CHANGE_PKCS5_PRF, + PCDM_ADD_REMOVE_VOL_KEYFILES, + PCDM_REMOVE_ALL_KEYFILES_FROM_VOL +}; + +typedef struct +{ + BOOL bHidVolDamagePrevReported[26]; +} VOLUME_NOTIFICATIONS_LIST; + + +extern VOLUME_NOTIFICATIONS_LIST VolumeNotificationsList; + +extern BOOL bEnableBkgTask; +extern BOOL bCloseBkgTaskWhenNoVolumes; +extern BOOL bPlaySoundOnSuccessfulHkDismount; +extern BOOL bDisplayBalloonOnSuccessfulHkDismount; +extern BOOL bExplore; + +static void localcleanup ( void ); +void EndMainDlg ( HWND hwndDlg ); +void EnableDisableButtons ( HWND hwndDlg ); +BOOL VolumeSelected (HWND hwndDlg ); +void LoadSettings ( HWND hwndDlg ); +void SaveSettings ( HWND hwndDlg ); +BOOL SelectItem ( HWND hTree , char nLetter ); +void LoadDriveLetters ( HWND hTree, int drive ); +BOOL CALLBACK PasswordChangeDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam ); +BOOL CALLBACK PasswordDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam ); +BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +void BuildTree ( HWND hTree ); +LPARAM GetSelectedLong ( HWND hTree ); +LPARAM GetItemLong ( HWND hTree, int itemNo ); +BOOL CALLBACK CommandHelpDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam ); +BOOL CALLBACK MainDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ); +void ExtractCommandLine ( HWND hwndDlg , char *lpszCommandLine ); +static void WipeCache (HWND hwndDlg, BOOL silent); +void OpenVolumeExplorerWindow (int driveNo); +BOOL TaskBarIconAdd (HWND hwnd); +BOOL TaskBarIconRemove (HWND hwnd); +BOOL TaskBarIconChange (HWND hwnd, int iconId); +void DismountIdleVolumes (); +static void SaveDefaultKeyFilesParam (void); +static BOOL Dismount (HWND hwndDlg, int nDosDriveNo); +static BOOL DismountAll (HWND hwndDlg, BOOL forceUnmount, BOOL interact, int dismountMaxRetries, int dismountAutoRetryDelay); +static void KeyfileDefaultsDlg (HWND hwndDlg); +static void HandleHotKey (HWND hwndDlg, WPARAM wParam); +static BOOL CheckMountList (); +int GetCipherBlockSizeByDriveNo (int nDosDriveNo); +int GetModeOfOperationByDriveNo (int nDosDriveNo); +void ChangeMainWindowVisibility (); +void LaunchVolCreationWizard (HWND hwndDlg); +BOOL WholeSysDriveEncryption (BOOL bSilent); +BOOL CheckSysEncMountWithoutPBA (const char *devicePath, BOOL quiet); +BOOL TCBootLoaderOnInactiveSysEncDrive (void); +void CreateRescueDisk (void); +int BackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, char *lpszVolume); +int RestoreVolumeHeader (HWND hwndDlg, char *lpszVolume); +void SecurityTokenPreferencesDialog (HWND hwndDlg); +static BOOL CALLBACK PerformanceSettingsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static BOOL CALLBACK BootLoaderPreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +void MountSelectedVolume (HWND hwndDlg, BOOL mountWithOptions); +uint32 ReadDriverConfigurationFlags (); +void AnalyzeKernelMiniDump (HWND hwndDlg); +void HookMouseWheel (HWND hwndDlg, UINT ctrlId); +static BOOL HandleDriveListMouseWheelEvent (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bListMustBePointed); + +#ifdef __cplusplus +} + +void SetDriverConfigurationFlag (uint32 flag, BOOL state); +BOOL MountFavoriteVolumes (BOOL systemFavorites = FALSE, BOOL logOnMount = FALSE, BOOL hotKeyMount = FALSE, const TrueCrypt::FavoriteVolume &favoriteVolumeToMount = TrueCrypt::FavoriteVolume()); +BOOL GetExecutableImageInformation (const string &path, string &version, string &description, string &companyName, string &productName); + +#endif diff --git a/src/Mount/Mount.manifest b/src/Mount/Mount.manifest new file mode 100644 index 00000000..48616cfc --- /dev/null +++ b/src/Mount/Mount.manifest @@ -0,0 +1,21 @@ + + + + + + + + + + + + true + + + + + + + + + \ No newline at end of file diff --git a/src/Mount/Mount.rc b/src/Mount/Mount.rc new file mode 100644 index 00000000..5229c045 --- /dev/null +++ b/src/Mount/Mount.rc @@ -0,0 +1,635 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" +#include "..\\common\\resource.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// HEADER +// + +IDR_MOUNT_RSRC_HEADER HEADER "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// TYPELIB +// + +IDR_MOUNT_TLB TYPELIB "Mount.tlb" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_PREFERENCES_DLG DIALOGEX 0, 0, 336, 282 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt - Preferences" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Mount volumes as read-only",IDC_PREF_MOUNT_READONLY, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,11,11,150,16 + CONTROL "Mount volumes as removable media",IDC_PREF_MOUNT_REMOVABLE, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,162,11,165,16 + CONTROL "Enabled",IDC_PREF_BKG_TASK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,44,111,10 + CONTROL "Exit when there are no mounted volumes",IDC_CLOSE_BKG_TASK_WHEN_NOVOL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,140,44,188,10 + CONTROL "Start TrueCrypt Background Task",IDC_PREF_LOGON_START, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,75,126,10 + CONTROL "Mount all device-hosted TrueCrypt volumes",IDC_PREF_LOGON_MOUNT_DEVICES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,140,75,188,10 + CONTROL "User logs off",IDC_PREF_DISMOUNT_LOGOFF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,81,104,114,11 + CONTROL "Entering power saving mode",IDC_PREF_DISMOUNT_POWERSAVING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,197,109,130,11 + CONTROL "Screen saver is launched",IDC_PREF_DISMOUNT_SCREENSAVER, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,81,115,114,10 + CONTROL "Auto-dismount volume after no data has been read/written to it for",IDC_PREF_DISMOUNT_INACTIVE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,128,246,11 + EDITTEXT IDC_PREF_DISMOUNT_INACTIVE_TIME,258,127,27,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT + CONTROL "Force auto-dismount even if volume contains open files or directories",IDC_PREF_FORCE_AUTO_DISMOUNT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,141,294,10 + CONTROL "Open Explorer window for successfully mounted volume",IDC_PREF_OPEN_EXPLORER, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,171,316,11 + CONTROL "Use a different taskbar icon when there are mounted volumes",IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,184,314,10 + CONTROL "Preserve modification timestamp of file containers",IDC_PRESERVE_TIMESTAMPS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,196,316,10 + CONTROL "Cache passwords in driver memory",IDC_PREF_CACHE_PASSWORDS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,227,146,11 + CONTROL "Wipe cached passwords on exit",IDC_PREF_WIPE_CACHE_ON_EXIT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,227,165,11 + CONTROL "Wipe cached passwords on auto-dismount",IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,239,296,11 + PUSHBUTTON "More Settings...",IDC_MORE_SETTINGS,5,262,85,14 + DEFPUSHBUTTON "OK",IDOK,225,262,50,14 + PUSHBUTTON "Cancel",IDCANCEL,281,262,50,14 + GROUPBOX "Windows",IDT_WINDOWS_RELATED_SETTING,4,160,328,52 + GROUPBOX "Default Mount Options",IDT_DEFAULT_MOUNT_OPTIONS,4,3,328,26 + GROUPBOX "TrueCrypt Background Task",IDT_TASKBAR_ICON,4,33,328,26 + GROUPBOX "Auto-Dismount",IDT_AUTO_DISMOUNT,4,94,328,62 + LTEXT "minutes",IDT_MINUTES,289,129,39,10 + LTEXT "Dismount all when:",IDT_AUTO_DISMOUNT_ON,9,110,71,17 + GROUPBOX "Password Cache",IDT_PW_CACHE_OPTIONS,4,216,328,39 + GROUPBOX "Actions to perform upon logon to Windows",IDT_LOGON,4,63,328,28 +END + +IDD_VOLUME_PROPERTIES DIALOGEX 60, 30, 284, 186 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt Volume Properties" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,114,166,55,14 + CONTROL "",IDC_VOLUME_PROPERTIES_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,6,269,154 +END + +IDD_PASSWORDCHANGE_DLG DIALOGEX 0, 0, 316, 162 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Change Password or Keyfiles" +CLASS "CustomDlg" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_OLD_PASSWORD,89,14,147,13,ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Use keyfiles",IDC_ENABLE_KEYFILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,34,86,10 + PUSHBUTTON "Keyfiles...",IDC_KEYFILES,177,32,59,14 + CONTROL "Display password",IDC_SHOW_PASSWORD_CHPWD_ORI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,46,138,10,WS_EX_TRANSPARENT + EDITTEXT IDC_PASSWORD,89,74,147,13,ES_PASSWORD | ES_AUTOHSCROLL + EDITTEXT IDC_VERIFY,89,90,147,13,ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Use keyfiles",IDC_ENABLE_NEW_KEYFILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,109,86,11 + PUSHBUTTON "Keyfiles...",IDC_NEW_KEYFILES,177,107,59,14 + CONTROL "Display password",IDC_SHOW_PASSWORD_CHPWD_NEW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,121,139,11,WS_EX_TRANSPARENT + COMBOBOX IDC_PKCS5_PRF_ID,89,136,91,90,CBS_DROPDOWNLIST | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,251,7,59,14 + PUSHBUTTON "Cancel",IDCANCEL,251,24,59,14 + RTEXT "Password:",IDT_PASSWORD,12,16,72,8 + RTEXT "Password:",IDT_NEW_PASSWORD,8,77,76,8 + RTEXT "Confirm Password:",IDT_CONFIRM_PASSWORD,9,93,75,16 + RTEXT "PKCS-5 PRF:",IDT_PKCS5_PRF,9,137,74,10,SS_CENTERIMAGE + GROUPBOX "Current",IDT_CURRENT,6,3,238,58 + GROUPBOX "New",IDT_NEW,6,63,238,93 +END + +IDD_MOUNT_DLG DIALOGEX 0, 0, 375, 271 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt" +MENU IDR_MENU +CLASS "CustomDlg" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + CONTROL "",IDC_DRIVELIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,5,360,135 + PUSHBUTTON "&Create Volume",IDC_CREATE_VOLUME,16,159,84,14 + PUSHBUTTON "&Volume Properties...",IDC_VOLUME_PROPERTIES,146,159,84,14 + PUSHBUTTON "&Wipe Cache",IDC_WIPE_CACHE,276,159,84,14 + COMBOBOX IDC_VOLUME,56,192,212,74,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + CONTROL "&Never save history",IDC_NO_HISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,56,207,122,10 + PUSHBUTTON "Volume &Tools...",IDC_VOLUME_TOOLS,184,211,84,14 + PUSHBUTTON "Select &File...",IDC_SELECT_FILE,276,192,84,14 + PUSHBUTTON "Select D&evice...",IDC_SELECT_DEVICE,276,211,84,14 + DEFPUSHBUTTON "OK",IDOK,8,243,84,18,WS_GROUP + PUSHBUTTON "&Auto-Mount Devices",IDC_MOUNTALL,100,243,84,18 + PUSHBUTTON "Di&smount All",IDC_UNMOUNTALL,192,243,84,18,WS_GROUP + PUSHBUTTON "E&xit",IDC_EXIT,284,243,84,18,WS_GROUP + CONTROL 112,IDC_LOGO,"Static",SS_BITMAP | SS_NOTIFY | WS_BORDER,16,192,27,31 + GROUPBOX "Volume",IDT_VOLUME,8,179,360,53 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,2,0,372,147 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,282,242,88,20 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,190,242,88,20 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,6,242,88,20 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,98,242,88,20 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,2,151,372,119 +END + +IDD_PASSWORD_DLG DIALOGEX 0, 0, 280, 68 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION +CAPTION "Enter TrueCrypt Volume Password" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_PASSWORD,48,8,153,14,ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Cache passwords and keyfil&es in memory",IDC_CACHE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,27,153,10 + CONTROL "&Display password",IDC_SHOW_PASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,40,83,10 + CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52,52,83,11 + PUSHBUTTON "&Keyfiles...",IDC_KEY_FILES,137,49,64,14 + PUSHBUTTON "Mount Opti&ons...",IDC_MOUNT_OPTIONS,208,49,64,14 + DEFPUSHBUTTON "OK",IDOK,208,8,64,14 + PUSHBUTTON "Cancel",IDCANCEL,208,25,64,14 + RTEXT "Password:",IDT_PASSWORD,0,10,46,19 +END + +IDD_TRAVELER_DLG DIALOGEX 0, 0, 300, 269 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt Traveler Disk Setup" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_DIRECTORY,17,29,205,13,ES_AUTOHSCROLL + PUSHBUTTON "Browse...",IDC_BROWSE_DIRS,228,28,57,14 + CONTROL "Include TrueCrypt Volume Creation Wizard",IDC_COPY_WIZARD, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,48,258,10 + CONTROL "Do nothing",IDC_AUTORUN_DISABLE,"Button",BS_AUTORADIOBUTTON,15,97,262,10 + CONTROL "&Start TrueCrypt",IDC_AUTORUN_START,"Button",BS_AUTORADIOBUTTON,15,108,262,11 + CONTROL "&Auto-mount TrueCrypt volume (specified below)",IDC_AUTORUN_MOUNT, + "Button",BS_AUTORADIOBUTTON,15,120,262,11 + EDITTEXT IDC_VOLUME_NAME,21,157,194,13,ES_AUTOHSCROLL | WS_DISABLED + PUSHBUTTON "Browse...",IDC_BROWSE_FILES,221,156,57,14,WS_DISABLED + COMBOBOX IDC_DRIVELIST,120,175,96,69,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP + CONTROL "Open &Explorer window for mounted volume",IDC_TRAVEL_OPEN_EXPLORER, + "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,22,193,256,10 + CONTROL "Mount volume as read-&only",IDC_MOUNT_READONLY,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,22,206,256,10 + CONTROL "&Cache password in driver memory",IDC_TRAV_CACHE_PASSWORDS, + "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,22,219,256,10 + DEFPUSHBUTTON "Create",IDC_CREATE,173,249,57,14 + PUSHBUTTON "Close",IDCLOSE,236,249,57,14 + GROUPBOX "File Settings",IDT_FILE_SETTINGS,6,7,287,59 + GROUPBOX "AutoRun Configuration (autorun.inf)",IDT_AUTORUN,5,70,288,172 + LTEXT "TrueCrypt volume to mount (relative to traveler disk root):",IDT_TRAVELER_MOUNT,21,147,248,8,WS_DISABLED + RTEXT "Mount volume as drive letter:",IDT_MOUNT_LETTER,18,177,99,8,WS_DISABLED + LTEXT "Create traveler disk files at (traveler disk root directory):",IDT_TRAVEL_ROOT,18,19,259,8 + GROUPBOX "Mount Settings",IDT_MOUNT_SETTINGS,13,134,272,100,WS_DISABLED + LTEXT "Upon insertion of traveler disk: ",IDT_TRAVEL_INSERTION,13,84,263,8 +END + +IDD_HOTKEYS_DLG DIALOGEX 0, 0, 381, 239 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt - System-Wide Hot Keys" +CLASS "CustomDlg" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + CONTROL "",IDC_HOTKEY_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,367,93 + EDITTEXT IDC_HOTKEY_KEY,108,121,190,13,ES_AUTOHSCROLL + PUSHBUTTON "Assign",IDC_HOTKEY_ASSIGN,304,121,59,14 + CONTROL "Ctrl",IDC_HK_MOD_CTRL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,109,139,46,10,WS_EX_TRANSPARENT + CONTROL "Shift",IDC_HK_MOD_SHIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,139,49,10,WS_EX_TRANSPARENT + CONTROL "Alt",IDC_HK_MOD_ALT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,216,139,43,10,WS_EX_TRANSPARENT + CONTROL "Win",IDC_HK_MOD_WIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,266,139,34,10,WS_EX_TRANSPARENT + PUSHBUTTON "Remove",IDC_HOTKEY_REMOVE,304,139,59,14 + CONTROL "Play system notification sound after successful hot-key dismount",IDC_HK_DISMOUNT_PLAY_SOUND, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,182,348,10 + CONTROL "Display balloon tooltip after successful hot-key dismount",IDC_HK_DISMOUNT_BALLOON_TOOLTIP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,194,351,10,WS_EX_TRANSPARENT + DEFPUSHBUTTON "OK",IDOK,249,218,59,14 + PUSHBUTTON "Cancel",IDCANCEL,315,218,59,14 + PUSHBUTTON "Reset",IDC_RESET_HOTKEYS,7,218,59,14 + RTEXT "Key to assign:",IDT_HOTKEY_KEY,15,123,86,8 + GROUPBOX "Hot Key Options",IDT_DISMOUNT_ACTION,7,169,367,42 + GROUPBOX "Shortcut",IDT_ASSIGN_HOTKEY,7,108,367,53 +END + +IDD_TOKEN_PREFERENCES DIALOGEX 0, 0, 316, 199 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt - Security Token Preferences" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_PKCS11_MODULE,16,23,204,13,ES_AUTOHSCROLL + PUSHBUTTON "Select &Library...",IDC_SELECT_PKCS11_MODULE,226,22,75,14 + PUSHBUTTON "Auto-&Detect Library",IDC_AUTO_DETECT_PKCS11_MODULE,16,41,112,14 + CONTROL "&Close token session (log out) after a volume is successfully mounted",IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,16,154,284,9 + DEFPUSHBUTTON "OK",IDOK,205,178,50,14 + PUSHBUTTON "Cancel",IDCANCEL,259,178,50,14 + GROUPBOX "PKCS #11 Library Path",IDT_PKCS11_LIB_PATH,7,7,302,129 + GROUPBOX "Security Options",IDT_SECURITY_OPTIONS,7,140,302,30 + LTEXT "",IDT_PKCS11_LIB_HELP,16,63,286,65 +END + +IDD_SYSENC_SETTINGS DIALOGEX 0, 0, 370, 242 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt - System Encryption Settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Do not &show any texts in the pre-boot authentication screen (except the below custom message)",IDC_DISABLE_BOOT_LOADER_OUTPUT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,22,339,9 + EDITTEXT IDC_CUSTOM_BOOT_LOADER_MESSAGE,18,52,216,14,ES_AUTOHSCROLL + CONTROL "&Cache pre-boot authentication password in driver memory (for mounting of non-system volumes)",IDC_BOOT_LOADER_CACHE_PASSWORD, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,178,339,10 + CONTROL "Allow pre-boot &authentication to be bypassed by pressing the Esc key (enables boot manager)",IDC_ALLOW_ESC_PBA_BYPASS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,193,340,10 + DEFPUSHBUTTON "OK",IDOK,257,220,50,14 + PUSHBUTTON "Cancel",IDCANCEL,313,220,50,14 + LTEXT "Display this custom message in the pre-boot authentication screen (24 characters maximum):",IDT_CUSTOM_BOOT_LOADER_MESSAGE,18,41,337,8 + GROUPBOX "Boot Loader Screen Options",IDT_BOOT_LOADER_SCREEN_OPTIONS,8,7,355,150 + GROUPBOX "Security Options",IDT_SECURITY_OPTIONS,8,163,355,49 + LTEXT "",IDC_CUSTOM_BOOT_LOADER_MESSAGE_HELP,18,74,337,73 +END + +IDD_PERFORMANCE_SETTINGS DIALOGEX 0, 0, 370, 206 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt - Performance Options" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_HW_AES_SUPPORTED_BY_CPU,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,294,21,57,12,WS_EX_CLIENTEDGE + CONTROL "Accelerate AES encryption/decryption by using the AES instructions of the processor (if available)",IDC_ENABLE_HARDWARE_ENCRYPTION, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,18,41,340,17 + LTEXT "More information",IDC_MORE_INFO_ON_HW_ACCELERATION,18,61,165,10,SS_NOTIFY + CONTROL "Do not use the following number of processors for encryption/decryption:",IDC_LIMIT_ENC_THREAD_POOL, + "Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,18,103,283,11 + COMBOBOX IDC_ENCRYPTION_FREE_CPU_COUNT,304,101,48,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "More information",IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION,18,159,165,10,SS_NOTIFY + PUSHBUTTON "&Benchmark",IDC_BENCHMARK,7,185,59,14 + DEFPUSHBUTTON "OK",IDOK,257,185,50,14 + PUSHBUTTON "Cancel",IDCANCEL,313,185,50,14 + LTEXT "Processor (CPU) in this computer supports hardware acceleration for AES:",IDT_HW_AES_SUPPORTED_BY_CPU,18,23,273,9 + GROUPBOX "Hardware Acceleration",IDT_ACCELERATION_OPTIONS,7,6,355,74 + GROUPBOX "Thread-Based Parallelization",IDT_PARALLELIZATION_OPTIONS,7,84,355,93 + LTEXT "",IDT_LIMIT_ENC_THREAD_POOL_NOTE,18,126,334,33 +END + +IDD_FAVORITE_VOLUMES DIALOGEX 0, 0, 380, 276 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "TrueCrypt - Favorite Volumes" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_FAVORITE_VOLUMES_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,366,92 + PUSHBUTTON "Move &Up",IDC_FAVORITE_MOVE_UP,7,104,63,14 + PUSHBUTTON "Move &Down",IDC_FAVORITE_MOVE_DOWN,74,104,63,14 + PUSHBUTTON "&Remove",IDC_FAVORITE_REMOVE,310,104,63,14 + EDITTEXT IDC_FAVORITE_LABEL,16,142,204,13,ES_AUTOHSCROLL + CONTROL "Mount selected volume as read-o&nly",IDC_FAVORITE_MOUNT_READONLY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,162,349,10 + CONTROL "Mount selected volume as remo&vable medium",IDC_FAVORITE_MOUNT_REMOVABLE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,176,349,10 + CONTROL "Mount selected volume upon log&on",IDC_FAVORITE_MOUNT_ON_LOGON, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,190,349,10 + CONTROL "Mount selected volume when its host device gets &connected",IDC_FAVORITE_MOUNT_ON_ARRIVAL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,204,349,10 + CONTROL "Open &Explorer window for selected volume when successfully mounted",IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,218,349,11 + CONTROL "Do not mount selected volume when 'Mount Favorite Volumes' &hot key is pressed",IDC_FAVORITE_DISABLE_HOTKEY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,232,349,11 + LTEXT "Help on favorite volumes",IDC_FAVORITES_HELP_LINK,17,259,237,10,SS_NOTIFY + DEFPUSHBUTTON "OK",IDOK,269,257,50,14 + PUSHBUTTON "Cancel",IDCANCEL,323,257,50,14 + GROUPBOX "",IDC_FAV_VOL_OPTIONS_GROUP_BOX,7,121,366,130 + LTEXT "Label of selected favorite volume:",IDT_FAVORITE_LABEL,18,132,202,8 + GROUPBOX "Global Settings",IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX,7,202,366,49 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_PREFERENCES_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 329 + TOPMARGIN, 7 + BOTTOMMARGIN, 280 + END + + IDD_VOLUME_PROPERTIES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 277 + TOPMARGIN, 7 + BOTTOMMARGIN, 179 + END + + IDD_PASSWORDCHANGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 309 + TOPMARGIN, 7 + BOTTOMMARGIN, 155 + END + + IDD_MOUNT_DLG, DIALOG + BEGIN + RIGHTMARGIN, 369 + BOTTOMMARGIN, 269 + END + + IDD_PASSWORD_DLG, DIALOG + BEGIN + BOTTOMMARGIN, 63 + END + + IDD_TRAVELER_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 293 + TOPMARGIN, 7 + BOTTOMMARGIN, 262 + END + + IDD_HOTKEYS_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 374 + TOPMARGIN, 7 + BOTTOMMARGIN, 232 + END + + IDD_TOKEN_PREFERENCES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 309 + TOPMARGIN, 7 + BOTTOMMARGIN, 192 + END + + IDD_SYSENC_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 363 + TOPMARGIN, 7 + END + + IDD_PERFORMANCE_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 363 + TOPMARGIN, 7 + BOTTOMMARGIN, 199 + END + + IDD_FAVORITE_VOLUMES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 373 + TOPMARGIN, 7 + BOTTOMMARGIN, 269 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 7,1,1,0 + PRODUCTVERSION 7,1,1,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "TrueCrypt Foundation" + VALUE "FileDescription", "TrueCrypt" + VALUE "FileVersion", "7.1a" + VALUE "LegalTrademarks", "TrueCrypt" + VALUE "OriginalFilename", "TrueCrypt.exe" + VALUE "ProductName", "TrueCrypt" + VALUE "ProductVersion", "7.1a" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""..\\\\common\\\\resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""..\\\\common\\\\common.rc""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_DRIVEICON BITMAP "Drive_icon_96dpi.bmp" +IDB_DRIVEICON_MASK BITMAP "Drive_icon_mask_96dpi.bmp" +IDB_LOGO_96DPI BITMAP "Logo_96dpi.bmp" +IDB_LOGO_288DPI BITMAP "Logo_288dpi.bmp" +IDB_SYS_DRIVEICON BITMAP "System_drive_icon_96dpi.bmp" +IDB_SYS_DRIVEICON_MASK BITMAP "System_drive_icon_mask_96dpi.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU MENU +BEGIN + POPUP "&Volumes" + BEGIN + MENUITEM "Select File...", IDM_SELECT_FILE + MENUITEM "Select Device...", IDM_SELECT_DEVICE + MENUITEM SEPARATOR + MENUITEM "Create New Volume...", IDM_CREATE_VOLUME + MENUITEM "Resume Interrupted Process", IDM_RESUME_INTERRUPTED_PROC + MENUITEM SEPARATOR + MENUITEM "Mount Volume", IDM_MOUNT_VOLUME + MENUITEM "Mount Volume with Options", IDM_MOUNT_VOLUME_OPTIONS + MENUITEM "Auto-Mount All Device-Hosted Volumes", IDM_MOUNTALL + MENUITEM SEPARATOR + MENUITEM "Dismount Volume", IDM_UNMOUNT_VOLUME + MENUITEM "Dismount All Mounted Volumes", IDM_UNMOUNTALL + MENUITEM SEPARATOR + MENUITEM "Change Volume Password...", IDM_CHANGE_PASSWORD + MENUITEM "Add/Remove Keyfiles to/from Volume...", IDM_ADD_REMOVE_VOL_KEYFILES + MENUITEM "Remove All Keyfiles from Volume...", IDM_REMOVE_ALL_KEYFILES_FROM_VOL + MENUITEM "Set Header Key Derivation Algorithm...", IDM_CHANGE_HEADER_KEY_DERIV_ALGO + MENUITEM SEPARATOR + MENUITEM "Volume Properties", IDM_VOLUME_PROPERTIES + END + POPUP "S&ystem" + BEGIN + MENUITEM "Encrypt System Partition/Drive...", IDM_ENCRYPT_SYSTEM_DEVICE + MENUITEM "Permanently Decrypt System Partition/Drive", IDM_PERMANENTLY_DECRYPT_SYS + MENUITEM "Resume Interrupted Process", IDM_SYSENC_RESUME + MENUITEM SEPARATOR + MENUITEM "Create Hidden Operating System...", IDM_CREATE_HIDDEN_OS + MENUITEM SEPARATOR + MENUITEM "Create Rescue Disk...", IDM_CREATE_RESCUE_DISK + MENUITEM "Verify Rescue Disk", IDM_VERIFY_RESCUE_DISK + MENUITEM SEPARATOR + MENUITEM "Mount Without Pre-Boot &Authentication...", IDM_MOUNT_SYSENC_PART_WITHOUT_PBA + MENUITEM SEPARATOR + MENUITEM "Change Password...", IDM_CHANGE_SYS_PASSWORD + MENUITEM "Set Header Key Derivation Algorithm...", IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO + MENUITEM SEPARATOR + MENUITEM "Properties...", IDM_SYSTEM_ENCRYPTION_STATUS + MENUITEM SEPARATOR + MENUITEM "Settings...", IDM_SYS_ENC_SETTINGS + END + POPUP "Favor&ites" + BEGIN + MENUITEM "Add Mounted Volume to Favorites...", IDM_ADD_VOLUME_TO_FAVORITES + MENUITEM "Add Mounted Volume to System Favorites...", IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES + MENUITEM SEPARATOR + MENUITEM "Organize Favorite Volumes...", IDM_ORGANIZE_FAVORITES + MENUITEM "Organize System Favorite Volumes...", IDM_ORGANIZE_SYSTEM_FAVORITES + MENUITEM SEPARATOR + MENUITEM "Mount Favorite Volumes", IDM_MOUNT_FAVORITE_VOLUMES + END + POPUP "T&ools" + BEGIN + MENUITEM "Benchmark...", IDM_BENCHMARK + MENUITEM "Test Vectors...", IDM_TEST_VECTORS + MENUITEM SEPARATOR + MENUITEM "Traveler Disk Setup...", IDM_TRAVELER + MENUITEM "Volume Creation Wizard", IDM_VOLUME_WIZARD + MENUITEM SEPARATOR + MENUITEM "Keyfile Generator", IDM_KEYFILE_GENERATOR + MENUITEM "Manage Security Token Keyfiles...", IDM_MANAGE_TOKEN_KEYFILES + MENUITEM "Close All Security Token Sessions", IDM_CLOSE_ALL_TOKEN_SESSIONS + MENUITEM SEPARATOR + MENUITEM "Backup Volume Header...", IDM_BACKUP_VOL_HEADER + MENUITEM "Restore Volume Header...", IDM_RESTORE_VOL_HEADER + MENUITEM SEPARATOR + MENUITEM "Refresh Drive Letters", IDM_REFRESH_DRIVE_LETTERS + MENUITEM SEPARATOR + MENUITEM "Clear Volume History", IDM_CLEAR_HISTORY + MENUITEM "Wipe Cached Passwords", IDM_WIPE_CACHE + END + POPUP "Settin&gs" + BEGIN + MENUITEM "Language...", IDM_LANGUAGE + MENUITEM "Hot Keys...", IDM_HOTKEY_SETTINGS + MENUITEM SEPARATOR + MENUITEM "System Encryption...", IDM_SYSENC_SETTINGS + MENUITEM "System Favorite Volumes...", IDM_SYS_FAVORITES_SETTINGS + MENUITEM SEPARATOR + MENUITEM "Performance...", IDM_PERFORMANCE_SETTINGS + MENUITEM SEPARATOR + MENUITEM "Default Keyfiles...", IDM_DEFAULT_KEYFILES + MENUITEM "Security Tokens...", IDM_TOKEN_PREFERENCES + MENUITEM SEPARATOR + MENUITEM "Preferences...", IDM_PREFERENCES + END + POPUP "Hel&p" + BEGIN + MENUITEM "User's Guide", IDM_HELP + MENUITEM "Online Help", IDM_ONLINE_HELP + MENUITEM "Beginner's Tutorial", IDM_ONLINE_TUTORIAL + MENUITEM "Frequently Asked Questions", IDM_FAQ + MENUITEM SEPARATOR + MENUITEM "TrueCrypt Website", IDM_WEBSITE + MENUITEM "Downloads", IDM_TC_DOWNLOADS + MENUITEM "News", IDM_NEWS + MENUITEM "Version History", IDM_VERSION_HISTORY + MENUITEM SEPARATOR + MENUITEM "Analyze a System Crash...", IDM_ANALYZE_SYSTEM_CRASH + MENUITEM SEPARATOR + MENUITEM "Contact", IDM_CONTACT + MENUITEM "Legal Notices", IDM_LICENSE + MENUITEM "About", IDM_ABOUT + END + MENUITEM "&Homepage ", IDM_HOMEPAGE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_UACSTRING "TrueCrypt" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "..\\common\\common.rc" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/Mount/Mount.vcproj b/src/Mount/Mount.vcproj new file mode 100644 index 00000000..8d6532bb --- /dev/null +++ b/src/Mount/Mount.vcproj @@ -0,0 +1,689 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mount/Resource.h b/src/Mount/Resource.h new file mode 100644 index 00000000..c410d36b --- /dev/null +++ b/src/Mount/Resource.h @@ -0,0 +1,234 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Mount.rc +// +#define IDR_MOUNT_TLB 1 +#define IDD_MOUNT_DLG 101 +#define IDD_PASSWORDCHANGE_DLG 102 +#define IDB_DRIVEICON 103 +#define IDD_PASSWORD_DLG 104 +#define IDB_DRIVEICON_MASK 105 +#define IDR_MENU 106 +#define IDD_PREFERENCES_DLG 107 +#define IDD_VOLUME_PROPERTIES 108 +#define IDR_MOUNT_RSRC_HEADER 109 +#define IDS_UACSTRING 110 +#define IDB_LOGO_288DPI 111 +#define IDB_LOGO_96DPI 112 +#define IDB_SYS_DRIVEICON 113 +#define IDB_SYS_DRIVEICON_MASK 114 +#define IDD_TOKEN_PREFERENCES 115 +#define IDD_SYSENC_SETTINGS 116 +#define IDD_FAVORITE_VOLUMES 117 +#define IDC_PREF_MOUNT_READONLY 1000 +#define IDC_PREF_MOUNT_REMOVABLE 1001 +#define IDC_VERIFY 1002 +#define IDC_PREF_BKG_TASK_ENABLE 1003 +#define IDC_OLD_PASSWORD 1004 +#define IDC_CACHE 1005 +#define IDC_NO_HISTORY 1006 +#define IDC_DRIVELIST 1007 +#define IDC_PREF_OPEN_EXPLORER 1008 +#define IDC_ENABLE_KEYFILES 1009 +#define IDC_VOLUME_PROPERTIES_LIST 1010 +#define IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED 1011 +#define IDC_ENABLE_NEW_KEYFILES 1012 +#define IDC_PRESERVE_TIMESTAMPS 1013 +#define IDC_PREF_WIPE_CACHE_ON_EXIT 1014 +#define IDC_PKCS5_PRF_ID 1015 +#define IDC_PREF_CACHE_PASSWORDS 1016 +#define IDC_DIRECTORY 1017 +#define IDC_PREF_DISMOUNT_LOGOFF 1018 +#define IDC_BROWSE_DIRS 1019 +#define IDC_PREF_DISMOUNT_INACTIVE 1020 +#define IDC_AUTORUN_DISABLE 1021 +#define IDC_AUTORUN_START 1022 +#define IDC_BENCHMARK 1023 +#define IDC_AUTORUN_MOUNT 1024 +#define IDC_VOLUME_NAME 1025 +#define IDC_COPY_WIZARD 1026 +#define IDC_MOUNT_OPTIONS 1027 +#define IDT_TRAVELER_MOUNT 1028 +#define IDT_MOUNT_LETTER 1029 +#define IDT_MOUNT_SETTINGS 1030 +#define IDC_KEY_FILES 1031 +#define IDC_NEW_KEYFILES 1032 +#define IDC_KEYFILES 1033 +#define IDC_VOLUME 1034 +#define IDC_PASSWORD 1035 +#define IDC_BROWSE_FILES 1036 +#define IDC_SELECT_DEVICE 1037 +#define IDC_CREATE_VOLUME 1038 +#define IDC_VOLUME_TOOLS 1039 +#define IDC_WIPE_CACHE 1040 +#define IDC_MOUNTALL 1041 +#define IDD_TRAVELER_DLG 1042 +#define IDC_SELECT_FILE 1043 +#define IDD_HOTKEYS_DLG 1044 +#define IDC_VOLUME_PROPERTIES 1045 +#define IDT_FILE_SETTINGS 1046 +#define IDD_PERFORMANCE_SETTINGS 1047 +#define IDT_AUTORUN 1048 +#define IDT_TRAVEL_INSERTION 1049 +#define IDT_TRAVEL_ROOT 1050 +#define IDT_VOLUME 1051 +#define IDT_PASSWORD 1052 +#define IDT_CURRENT 1053 +#define IDT_NEW 1054 +#define IDT_NEW_PASSWORD 1055 +#define IDT_CONFIRM_PASSWORD 1056 +#define IDT_PKCS5_PRF 1057 +#define IDT_PW_CACHE_OPTIONS 1058 +#define IDT_DEFAULT_MOUNT_OPTIONS 1059 +#define IDT_WINDOWS_RELATED_SETTING 1060 +#define IDC_CREATE 1061 +#define IDC_EXIT 1062 +#define IDC_TRAVEL_OPEN_EXPLORER 1063 +#define IDC_TRAV_CACHE_PASSWORDS 1064 +#define IDC_UNMOUNTALL 1065 +#define IDT_TASKBAR_ICON 1066 +#define IDT_AUTO_DISMOUNT 1067 +#define IDC_PREF_FORCE_AUTO_DISMOUNT 1068 +#define IDC_PREF_DISMOUNT_INACTIVE_TIME 1069 +#define IDT_MINUTES 1070 +#define IDC_PREF_DISMOUNT_SCREENSAVER 1071 +#define IDC_PREF_DISMOUNT_POWERSAVING 1072 +#define IDT_AUTO_DISMOUNT_ON 1073 +#define IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT 1074 +#define IDC_CLOSE_BKG_TASK_WHEN_NOVOL 1075 +#define IDC_MORE_INFO_ON_HW_ACCELERATION 1076 +#define IDT_LOGON 1077 +#define IDC_MORE_INFO_ON_THREAD_BASED_PARALLELIZATION 1078 +#define IDC_PREF_LOGON_START 1079 +#define IDC_PREF_LOGON_MOUNT_DEVICES 1080 +#define IDC_SHOW_PASSWORD_CHPWD_NEW 1081 +#define IDC_HK_DISMOUNT_BALLOON_TOOLTIP 1082 +#define IDC_SHOW_PASSWORD_CHPWD_ORI 1083 +#define IDC_HK_DISMOUNT_PLAY_SOUND 1084 +#define IDC_HOTKEY_ASSIGN 1085 +#define IDC_HOTKEY_REMOVE 1086 +#define IDC_HOTKEY_KEY 1087 +#define IDT_HOTKEY_KEY 1088 +#define IDC_HOTKEY_LIST 1089 +#define IDC_RESET_HOTKEYS 1090 +#define IDT_DISMOUNT_ACTION 1091 +#define IDT_ASSIGN_HOTKEY 1092 +#define IDC_HK_MOD_SHIFT 1093 +#define IDC_HK_MOD_CTRL 1094 +#define IDC_HK_MOD_ALT 1095 +#define IDC_HK_MOD_WIN 1096 +#define IDC_SHOW_PASSWORD 1097 +#define IDC_LOGO 1098 +#define IDT_PKCS11_LIB_PATH 1099 +#define IDC_PKCS11_MODULE 1100 +#define IDC_SELECT_PKCS11_MODULE 1101 +#define IDC_AUTO_DETECT_PKCS11_MODULE 1102 +#define IDC_CLOSE_TOKEN_SESSION_AFTER_MOUNT 1103 +#define IDT_SECURITY_OPTIONS 1104 +#define IDC_DISABLE_BOOT_LOADER_OUTPUT 1105 +#define IDC_ALLOW_ESC_PBA_BYPASS 1106 +#define IDC_CUSTOM_BOOT_LOADER_MESSAGE 1107 +#define IDC_BOOT_LOADER_CACHE_PASSWORD 1108 +#define IDC_MORE_SETTINGS 1109 +#define IDT_CUSTOM_BOOT_LOADER_MESSAGE 1110 +#define IDC_CUSTOM_BOOT_LOADER_MESSAGE_HELP 1111 +#define IDT_BOOT_LOADER_SCREEN_OPTIONS 1112 +#define IDT_PKCS11_LIB_HELP 1113 +#define IDT_ACCELERATION_OPTIONS 1114 +#define IDC_ENABLE_HARDWARE_ENCRYPTION 1115 +#define IDC_FAVORITE_VOLUMES_LIST 1116 +#define IDC_FAVORITE_MOUNT_READONLY 1117 +#define IDC_FAVORITE_MOUNT_REMOVABLE 1118 +#define IDC_FAVORITE_MOUNT_ON_ARRIVAL 1119 +#define IDC_FAVORITE_LABEL 1120 +#define IDT_FAVORITE_LABEL 1121 +#define IDC_FAVORITE_MOUNT_ON_LOGON 1122 +#define IDC_FAVORITE_DISABLE_HOTKEY 1123 +#define IDC_FAVORITE_MOVE_UP 1124 +#define IDC_FAVORITE_MOVE_DOWN 1125 +#define IDC_FAVORITE_REMOVE 1126 +#define IDT_HW_AES_SUPPORTED_BY_CPU 1127 +#define IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT 1128 +#define IDC_HW_AES_SUPPORTED_BY_CPU 1129 +#define IDC_LIMIT_ENC_THREAD_POOL 1130 +#define IDC_ENCRYPTION_FREE_CPU_COUNT 1131 +#define IDT_PARALLELIZATION_OPTIONS 1132 +#define IDT_LIMIT_ENC_THREAD_POOL_NOTE 1133 +#define IDC_FAV_VOL_OPTIONS_GROUP_BOX 1134 +#define IDC_FAVORITES_HELP_LINK 1135 +#define IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX 1136 +#define IDM_HELP 40001 +#define IDM_ABOUT 40002 +#define IDM_UNMOUNT_VOLUME 40003 +#define IDM_CLEAR_HISTORY 40004 +#define IDM_BENCHMARK 40005 +#define IDM_TRAVELER 40006 +#define IDM_MOUNT_VOLUME_OPTIONS 40007 +#define IDM_FAQ 40008 +#define IDM_REFRESH_DRIVE_LETTERS 40009 +#define IDM_DEFAULT_KEYFILES 40010 +#define IDM_WEBSITE 40011 +#define IDM_MOUNTALL 40012 +#define IDM_UNMOUNTALL 40013 +#define IDM_MOUNT_VOLUME 40014 +#define IDM_CHANGE_PASSWORD 40015 +#define IDM_VOLUME_WIZARD 40016 +#define IDM_CREATE_VOLUME 40017 +#define IDM_WIPE_CACHE 40018 +#define IDM_PREFERENCES 40019 +#define IDM_LICENSE 40020 +#define IDM_SELECT_FILE 40021 +#define IDM_SELECT_DEVICE 40022 +#define IDM_VOLUME_PROPERTIES 40023 +#define IDM_LANGUAGE 40024 +#define IDM_MOUNT_FAVORITE_VOLUMES 40025 +#define IDM_BACKUP_VOL_HEADER 40026 +#define IDM_RESTORE_VOL_HEADER 40027 +#define IDM_HOTKEY_SETTINGS 40028 +#define IDM_TC_DOWNLOADS 40029 +#define IDM_NEWS 40030 +#define IDM_CONTACT 40031 +#define IDM_VERSION_HISTORY 40032 +#define IDM_HOMEPAGE 40033 +#define IDM_TEST_VECTORS 40034 +#define IDM_ADD_REMOVE_VOL_KEYFILES 40035 +#define IDM_REMOVE_ALL_KEYFILES_FROM_VOL 40036 +#define IDM_CHANGE_HEADER_KEY_DERIV_ALGO 40037 +#define IDM_KEYFILE_GENERATOR 40038 +#define IDM_ONLINE_TUTORIAL 40039 +#define IDM_ONLINE_HELP 40040 +#define IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO 40041 +#define IDM_CHANGE_SYS_PASSWORD 40042 +#define IDM_CREATE_RESCUE_DISK 40043 +#define IDM_PERMANENTLY_DECRYPT_SYS 40044 +#define IDM_VERIFY_RESCUE_DISK 40045 +#define IDM_SYSTEM_ENCRYPTION_STATUS 40046 +#define IDM_ENCRYPT_SYSTEM_DEVICE 40047 +#define IDM_SYSENC_RESUME 40048 +#define IDM_MOUNT_SYSENC_PART_WITHOUT_PBA 40049 +#define IDM_CREATE_HIDDEN_OS 40050 +#define IDM_TOKEN_PREFERENCES 40051 +#define IDM_CLOSE_ALL_TOKEN_SESSIONS 40052 +#define IDM_SYS_ENC_SETTINGS 40053 +#define IDM_SYSENC_SETTINGS 40054 +#define IDM_RESUME_INTERRUPTED_PROC 40055 +#define IDM_MANAGE_TOKEN_KEYFILES 40056 +#define IDM_SYS_FAVORITES_SETTINGS 40057 +#define IDM_ORGANIZE_FAVORITES 40058 +#define IDM_ORGANIZE_SYSTEM_FAVORITES 40059 +#define IDM_ADD_VOLUME_TO_FAVORITES 40060 +#define IDM_ADD_VOLUME_TO_SYSTEM_FAVORITES 40061 +#define IDM_PERFORMANCE_SETTINGS 40062 +#define IDM_ANALYZE_SYSTEM_CRASH 40063 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 118 +#define _APS_NEXT_COMMAND_VALUE 40064 +#define _APS_NEXT_CONTROL_VALUE 1137 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/Mount/System_drive_icon_96dpi.bmp b/src/Mount/System_drive_icon_96dpi.bmp new file mode 100644 index 00000000..5838fb0f Binary files /dev/null and b/src/Mount/System_drive_icon_96dpi.bmp differ diff --git a/src/Mount/System_drive_icon_mask_96dpi.bmp b/src/Mount/System_drive_icon_mask_96dpi.bmp new file mode 100644 index 00000000..a0439d04 Binary files /dev/null and b/src/Mount/System_drive_icon_mask_96dpi.bmp differ -- cgit v1.2.3