VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Mount
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mount')
-rw-r--r--src/Mount/Drive_icon_96dpi.bmpbin0 -> 1206 bytes
-rw-r--r--src/Mount/Drive_icon_mask_96dpi.bmpbin0 -> 110 bytes
-rw-r--r--src/Mount/Favorites.cpp867
-rw-r--r--src/Mount/Favorites.h74
-rw-r--r--src/Mount/Hotkeys.c525
-rw-r--r--src/Mount/Hotkeys.h48
-rw-r--r--src/Mount/Logo_288dpi.bmpbin0 -> 50166 bytes
-rw-r--r--src/Mount/Logo_96dpi.bmpbin0 -> 5622 bytes
-rw-r--r--src/Mount/MainCom.cpp267
-rw-r--r--src/Mount/MainCom.h32
-rw-r--r--src/Mount/MainCom.idl50
-rw-r--r--src/Mount/Mount.c8999
-rw-r--r--src/Mount/Mount.h115
-rw-r--r--src/Mount/Mount.manifest21
-rw-r--r--src/Mount/Mount.rc635
-rw-r--r--src/Mount/Mount.vcproj689
-rw-r--r--src/Mount/Resource.h234
-rw-r--r--src/Mount/System_drive_icon_96dpi.bmpbin0 -> 1206 bytes
-rw-r--r--src/Mount/System_drive_icon_mask_96dpi.bmpbin0 -> 110 bytes
19 files changed, 12556 insertions, 0 deletions
diff --git a/src/Mount/Drive_icon_96dpi.bmp b/src/Mount/Drive_icon_96dpi.bmp
new file mode 100644
index 00000000..8c97b566
--- /dev/null
+++ b/src/Mount/Drive_icon_96dpi.bmp
Binary files 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
--- /dev/null
+++ b/src/Mount/Drive_icon_mask_96dpi.bmp
Binary files 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 <FavoriteVolume> FavoriteVolumes;
+ vector <FavoriteVolume> SystemFavoriteVolumes;
+ list <FavoriteVolume> FavoritesOnArrivalMountRequired;
+ list <FavoriteVolume> 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 <FavoriteVolume> 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 <FavoriteVolume> &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 <FavoriteVolume> &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 <FavoriteVolume> &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<favorites>", 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<volume mountpoint=\"" + SingleStringToWide (favorite.MountPoint) + L"\"";
+
+ if (!favorite.Label.empty())
+ s += L" label=\"" + favorite.Label + L"\"";
+
+ if (favorite.ReadOnly)
+ s += L" readonly=\"1\"";
+
+ if (favorite.Removable)
+ s += L" removable=\"1\"";
+
+ if (favorite.SystemEncryption)
+ s += L" system=\"1\"";
+
+ if (favorite.MountOnArrival)
+ s += L" mountOnArrival=\"1\"";
+
+ if (favorite.MountOnLogOn)
+ s += L" mountOnLogOn=\"1\"";
+
+ if (favorite.DisableHotkeyMount)
+ s += L" noHotKeyMount=\"1\"";
+
+ if (favorite.OpenExplorerWindow)
+ s += L" openExplorerWindow=\"1\"";
+
+ s += L">" + SingleStringToWide (tq) + L"</volume>";
+
+ fwprintf (f, L"%ws", s.c_str());
+ cnt++;
+ }
+
+ fputws (L"\n\t</favorites>", 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 <Tcdefs.h>
+
+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 <FavoriteVolume> FavoriteVolumes;
+ extern list <FavoriteVolume> FavoritesOnArrivalMountRequired;
+ extern list <FavoriteVolume> 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 <FavoriteVolume> &favorites);
+ static void FillListControlSubItems (HWND favoriteListControl, int line, const FavoriteVolume &favorite);
+ wstring GetFavoriteVolumeLabel (const string &volumePath);
+ void LoadFavoriteVolumes ();
+ void LoadFavoriteVolumes (vector <FavoriteVolume> &favorites, bool systemFavorites, bool noUacElevation = false);
+ static void OnFavoriteVolumesUpdated ();
+ BOOL OrganizeFavoriteVolumes (HWND hwndDlg, bool systemFavorites, const FavoriteVolume &newFavorite = FavoriteVolume());
+ static bool SaveFavoriteVolumes (const vector <FavoriteVolume> &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 <windows.h>
+#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
--- /dev/null
+++ b/src/Mount/Logo_288dpi.bmp
Binary files differ
diff --git a/src/Mount/Logo_96dpi.bmp b/src/Mount/Logo_96dpi.bmp
new file mode 100644
index 00000000..b76984f9
--- /dev/null
+++ b/src/Mount/Logo_96dpi.bmp
Binary files 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 <atlcomcli.h>
+#include <atlconv.h>
+#include <windows.h>
+#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<TrueCryptMainCom> 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<ITrueCryptMainCom> 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<ITrueCryptMainCom> 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<ITrueCryptMainCom> 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<ITrueCryptMainCom> 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 <windows.h>
+
+#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 <time.h>
+#include <math.h>
+#include <dbt.h>
+#include <fcntl.h>
+#include <io.h>
+#include <shlobj.h>
+#include <sys/stat.h>
+#include <windowsx.h>
+
+#include "Apidrvr.h"
+#include "BootEncryption.h"
+#include "Cmdline.h"
+#include "Crypto.h"
+#include "Dlgcode.h"
+#include "Combo.h"
+#include "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) &param))
+ {
+ 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) &param))
+ {
+ 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, &param))
+ {
+ 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 <HostDevice> 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 <HostDevice> 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 (&current);
+
+ 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, &current, 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 <FavoriteVolume>::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 <FavoriteVolume> 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<defaultkeyfiles>", f);
+
+ while (kf != NULL)
+ {
+ char q[TC_MAX_PATH * 2];
+
+ XmlQuoteText (kf->FileName, q, sizeof (q));
+ fprintf (f, "\n\t\t<keyfile>%s</keyfile>", q);
+
+ kf = kf->Next;
+ }
+
+ fputs ("\n\t</defaultkeyfiles>", 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) &param) == 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 <string> 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 <string> 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 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <asmv3:application>
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ </application>
+ </compatibility>
+</assembly> \ 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 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="Mount"
+ ProjectGUID="{E4C40F94-E7F9-4981-86E4-186B46F993F3}"
+ RootNamespace="Mount"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(SolutionDir)/$(ProjectName)/$(ProjectName).tlb"
+ OutputDirectory=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\Common;..\Crypto;..\;$(PKCS11_INC)"
+ PreprocessorDefinitions="TCMOUNT;WIN32;DEBUG;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS"
+ MinimalRebuild="true"
+ ExceptionHandling="1"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="true"
+ EnableFunctionLevelLinking="false"
+ UsePrecompiledHeader="0"
+ BrowseInformation="0"
+ BrowseInformationFile=""
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4057;4100;4127;4201;4701;4706"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib setupapi.lib version.lib ..\Crypto\Debug\crypto.lib"
+ OutputFile="$(OutDir)/TrueCrypt.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/Mount.pdb"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AdditionalManifestFiles="Mount.manifest"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="md &quot;..\Debug\Setup Files&quot; 2&gt;NUL:&#x0D;&#x0A;copy Debug\TrueCrypt.exe &quot;..\Debug\Setup Files&quot; &gt;NUL:&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(SolutionDir)/$(ProjectName)/$(ProjectName).tlb"
+ OutputDirectory=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/w34189"
+ Optimization="2"
+ AdditionalIncludeDirectories="..\Common;..\Crypto;..\;$(PKCS11_INC)"
+ PreprocessorDefinitions="TCMOUNT;WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)/"
+ WarningLevel="4"
+ DebugInformationFormat="0"
+ DisableSpecificWarnings="4057;4100;4127;4201;4701;4706"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib setupapi.lib version.lib ..\Crypto\Release\crypto.lib"
+ OutputFile="$(OutDir)/TrueCrypt.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ GenerateDebugInformation="false"
+ GenerateMapFile="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AdditionalManifestFiles="Mount.manifest"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy Release\TrueCrypt.exe &quot;..\Release\Setup Files&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\Favorites.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Hotkeys.c"
+ >
+ </File>
+ <File
+ RelativePath=".\MainCom.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\MainCom.idl"
+ >
+ </File>
+ <File
+ RelativePath=".\Mount.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\Common\BaseCom.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\BootEncryption.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Cmdline.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Combo.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Crc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Crypto.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Dictionary.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\Dlgcode.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\EncryptionThreadPool.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Endian.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\GfMul.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Keyfiles.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\Language.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Password.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Pkcs5.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Random.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Registry.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\SecurityToken.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Tests.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Volumes.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Wipe.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Xml.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Xts.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\Common\Apidrvr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\BaseCom.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\BootEncryption.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Cmdline.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Combo.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Common.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Crc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Crypto.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Dictionary.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Dlgcode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\EncryptionThreadPool.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Exception.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Favorites.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\GfMul.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Hotkeys.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Keyfiles.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Language.h"
+ >
+ </File>
+ <File
+ RelativePath=".\MainCom.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Mount.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Password.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Pkcs5.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Random.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Registry.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\SecurityToken.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Tcdefs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Tests.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Volumes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Xml.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Xts.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\Drive_icon_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\Drive_icon_mask_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\Logo_288dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\Logo_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\Mount.manifest"
+ >
+ </File>
+ <File
+ RelativePath=".\Mount.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\Mount.tlb"
+ >
+ </File>
+ <File
+ RelativePath=".\System_drive_icon_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\System_drive_icon_mask_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\TrueCrypt_mounted.ico"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\TrueCrypt_volume.ico"
+ >
+ </File>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\Boot\Windows\Release_AES\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release_Twofish\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue_Serpent\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue_AES\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue_Twofish\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release_Serpent\BootLoader.com.gz"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release_Twofish\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release_Serpent\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue_Serpent\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue_AES\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Rescue_Twofish\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release_AES\BootSector.bin"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Common.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Boot\Windows\Release\Decompressor.com"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Language.xml"
+ >
+ </File>
+ <File
+ RelativePath="..\Resources\Texts\License.rtf"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Textual_logo_288dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Textual_logo_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Textual_logo_background.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\TrueCrypt.ico"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
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
--- /dev/null
+++ b/src/Mount/System_drive_icon_96dpi.bmp
Binary files 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
--- /dev/null
+++ b/src/Mount/System_drive_icon_mask_96dpi.bmp
Binary files differ