VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Mount/Favorites.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mount/Favorites.cpp')
-rw-r--r--src/Mount/Favorites.cpp2048
1 files changed, 1024 insertions, 1024 deletions
diff --git a/src/Mount/Favorites.cpp b/src/Mount/Favorites.cpp
index 10eb648..77127c2 100644
--- a/src/Mount/Favorites.cpp
+++ b/src/Mount/Favorites.cpp
@@ -1,1024 +1,1024 @@
-/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Tcdefs.h"
-#include "Platform/Finally.h"
-#include "Platform/ForEach.h"
-#include "BootEncryption.h"
-#include "Dlgcode.h"
-#include "Language.h"
-#include "Mount.h"
-#include "Common/Resource.h"
-#include "Resource.h"
-#include "Xml.h"
-#include "Favorites.h"
-
-using namespace std;
-
-namespace VeraCrypt
-{
- 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, SRC_POS);
- return FALSE;
- }
-
- FavoriteVolume favorite;
- favorite.MountPoint = L"X:\\";
- favorite.MountPoint[0] = (wchar_t) (prop.driveNo + L'A');
-
- favorite.Path = prop.wszVolume;
- if (favorite.Path.find (L"\\??\\") == 0)
- favorite.Path = favorite.Path.substr (4);
-
- if (wcslen (prop.wszLabel))
- {
- favorite.Label = prop.wszLabel;
- favorite.UseLabelInExplorer = true;
- }
-
- if (IsVolumeDeviceHosted (favorite.Path.c_str()))
- {
- // Get GUID path
- wstring volumeDevPath = favorite.Path;
-
- wchar_t resolvedVolumeDevPath[TC_MAX_PATH];
- if (ResolveSymbolicLink (volumeDevPath.c_str(), resolvedVolumeDevPath, sizeof(resolvedVolumeDevPath)))
- volumeDevPath = resolvedVolumeDevPath;
-
- wchar_t volumeName[TC_MAX_PATH];
- HANDLE find = FindFirstVolume (volumeName, ARRAYSIZE (volumeName));
-
- if (find != INVALID_HANDLE_VALUE)
- {
- do
- {
- wchar_t findVolumeDevPath[TC_MAX_PATH];
- wstring vn = volumeName;
-
- if (QueryDosDevice (vn.substr (4, vn.size() - 5).c_str(), findVolumeDevPath, ARRAYSIZE (findVolumeDevPath)) != 0
- && volumeDevPath == findVolumeDevPath)
- {
- favorite.VolumePathId = volumeName;
- break;
- }
-
- } while (FindNextVolume (find, volumeName, ARRAYSIZE (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);
- favorite.Pim = prop.volumePim;
- memcpy (favorite.VolumeID, prop.volumeID, VOLUME_ID_SIZE);
-
- if (favorite.VolumePathId.empty()
- && IsVolumeDeviceHosted (favorite.Path.c_str())
- && favorite.Path.find (L"\\\\?\\Volume{") != 0)
- {
- Warning (favorite.Path.find (L"\\Partition0") == wstring::npos ? "FAVORITE_ADD_PARTITION_TYPE_WARNING" : "FAVORITE_ADD_DRIVE_DEV_WARNING", hwndDlg);
- }
-
- 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);
- WORD hw = HIWORD (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", SRC_POS);
-
- 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 (95),
- 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 (hwndDlg, 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", hwndDlg);
- break;
- }
- }
- }
-
- FavoriteVolumes = Favorites;
-
- ManageStartupSeq();
- SaveSettings (hwndDlg);
- }
- else
- SystemFavoriteVolumes = Favorites;
-
- OnFavoriteVolumesUpdated();
- LoadDriveLetters (hwndDlg, 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(), hwndDlg);
-
- if (!IsServerOS() && !IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY))
- Info ("SYS_FAVORITES_ADMIN_ONLY_INFO", hwndDlg);
- }
- }
- 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(), hwndDlg);
- else
- Warning ("SETTING_REQUIRES_REBOOT", hwndDlg);
- }
- return 1;
-
- case IDC_FAVORITES_HELP_LINK:
- Applink (SystemFavoritesMode ? "sysfavorites" : "favorites", TRUE, "");
- return 1;
- case IDC_SHOW_PIM:
- HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PIM, IDC_PIM, 0);
- return 1;
-
- case IDC_PIM:
- if (hw == EN_CHANGE)
- {
- int pim = GetPim (hwndDlg, IDC_PIM);
- if (pim > (SystemFavoritesMode? MAX_BOOT_PIM_VALUE: MAX_PIM_VALUE))
- {
- SetDlgItemText (hwndDlg, IDC_PIM, L"");
- SetFocus (GetDlgItem(hwndDlg, IDC_PIM));
- Warning (SystemFavoritesMode? "PIM_SYSENC_TOO_BIG": "PIM_TOO_BIG", hwndDlg);
- return 1;
- }
- }
- break;
- }
-
- 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;
- case WM_CTLCOLORSTATIC:
- {
- HDC hdc = (HDC) wParam;
- HWND hw = (HWND) lParam;
- if (hw == GetDlgItem(hwndDlg, IDC_FAVORITE_VOLUME_ID))
- {
- // This the favorite ID field. Make its background like normal edit
- HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW);
- ::SelectObject(hdc, hbr);
- return (BOOL) hbr;
- }
- }
- break;
- }
-
- return 0;
- }
-
-
- static void FillFavoriteVolumesMenu ()
- {
- while (DeleteMenu (FavoriteVolumesMenu, 7, MF_BYPOSITION)) { }
-
- if (FavoriteVolumes.empty())
- return;
-
- AppendMenu (FavoriteVolumesMenu, MF_SEPARATOR, 0, L"");
-
- int i = 0;
- foreach (const FavoriteVolume &favorite, FavoriteVolumes)
- {
- UINT flags = MF_STRING;
-
- if (favorite.DisconnectedDevice)
- flags |= MF_GRAYED;
-
- wstring menuText = 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" + 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, (wchar_t *) favorite.MountPoint.substr (0, 2).c_str());
- FillListControlSubItems (favoriteListControl, line++, favorite);
- }
- }
-
-
- static void FillListControlSubItems (HWND FavoriteListControl, int line, const FavoriteVolume &favorite)
- {
- ListSubItemSet (FavoriteListControl, line, 1, (wchar_t *) favorite.Label.c_str());
-
- if (favorite.DisconnectedDevice)
- ListSubItemSet (FavoriteListControl, line, 2, (wchar_t *) (wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")").c_str());
- else
- ListSubItemSet (FavoriteListControl, line, 2, (wchar_t *) favorite.Path.c_str());
- }
-
-
- wstring GetFavoriteVolumeLabel (const wstring &volumePath, bool& useInExplorer)
- {
- foreach (const FavoriteVolume &favorite, FavoriteVolumes)
- {
- if (favorite.Path == volumePath)
- {
- useInExplorer = favorite.UseLabelInExplorer;
- return favorite.Label;
- }
- }
-
- foreach (const FavoriteVolume &favorite, SystemFavoriteVolumes)
- {
- if (favorite.Path == volumePath)
- {
- useInExplorer = favorite.UseLabelInExplorer;
- return favorite.Label;
- }
- }
-
- useInExplorer = false;
- 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();
- wstring favoritesFilePath = systemFavorites ? GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false) : 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, false).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 = Utf8StringToWide (mountPoint);
-
- XmlGetNodeText (xml, volume, sizeof (volume));
- favorite.Path = Utf8StringToWide (volume);
-
- char label[1024];
-
- XmlGetAttributeText (xml, "ID", label, sizeof (label));
- if (strlen (label) == (2*VOLUME_ID_SIZE))
- {
- std::vector<byte> arr;
- if (HexWideStringToArray (Utf8StringToWide (label).c_str(), arr) && arr.size() == VOLUME_ID_SIZE)
- {
- memcpy (favorite.VolumeID, &arr[0], VOLUME_ID_SIZE);
- }
- }
-
- XmlGetAttributeText (xml, "label", label, sizeof (label));
- favorite.Label = Utf8StringToWide (label);
-
- XmlGetAttributeText (xml, "pim", label, sizeof (label));
- if (strlen(label) == 0)
- {
- /* support old attribute name before it was changed to PIM*/
- XmlGetAttributeText (xml, "pin", label, sizeof (label));
- }
- favorite.Pim = strtol (label, NULL, 10);
- if (favorite.Pim < 0 || favorite.Pim > (systemFavorites? MAX_BOOT_PIM_VALUE : MAX_PIM_VALUE))
- favorite.Pim = 0;
-
- 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');
-
- XmlGetAttributeText (xml, "useLabelInExplorer", boolVal, sizeof (boolVal));
- if (boolVal[0])
- favorite.UseLabelInExplorer = (boolVal[0] == '1') && !favorite.ReadOnly;
-
- XmlGetAttributeText (xml, "useVolumeID", boolVal, sizeof (boolVal));
- if (boolVal[0])
- favorite.UseVolumeID = (boolVal[0] == '1') && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID));
-
- if (favorite.Path.find (L"\\\\?\\Volume{") == 0 && favorite.Path.rfind (L"}\\") == favorite.Path.size() - 2)
- {
- wstring 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;
- }
-
-
- bool SaveFavoriteVolumes (HWND hwndDlg, const vector <FavoriteVolume> &favorites, bool systemFavorites)
- {
- FILE *f;
- int cnt = 0;
-
- f = _wfopen (GetConfigPath (systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES), L"w,ccs=UTF-8");
- if (f == NULL)
- {
- handleWin32Error (MainDlg, SRC_POS);
- return false;
- }
-
- XmlWriteHeader (f);
- fputws (L"\n\t<favorites>", f);
-
- foreach (const FavoriteVolume &favorite, favorites)
- {
- wchar_t tq[2048];
-
- if (systemFavorites && favorite.Path.find (L"\\\\") == 0 && favorite.Path.find (L"Volume{") == wstring::npos)
- Warning ("SYSTEM_FAVORITE_NETWORK_PATH_ERR", hwndDlg);
-
- XmlQuoteTextW (!favorite.VolumePathId.empty() ? favorite.VolumePathId.c_str() : favorite.Path.c_str(), tq, ARRAYSIZE (tq));
-
- wstring s = L"\n\t\t<volume mountpoint=\"" + favorite.MountPoint + L"\"";
-
- if (!IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)))
- s += L" ID=\"" + ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)) + L"\"";
-
- if (!favorite.Label.empty())
- s += L" label=\"" + favorite.Label + L"\"";
-
- if (favorite.Pim > 0)
- s += L" pim=\"" + IntToWideString(favorite.Pim) + 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\"";
-
- if (favorite.UseLabelInExplorer && !favorite.ReadOnly)
- s += L" useLabelInExplorer=\"1\"";
-
- if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)))
- s += L" useVolumeID=\"1\"";
-
- s += L">" + wstring (tq) + L"</volume>";
-
- fwprintf (f, L"%ws", s.c_str());
- cnt++;
- }
-
- fputws (L"\n\t</favorites>", f);
- XmlWriteFooter (f);
-
- if (!CheckFileStreamWriteErrors (hwndDlg, 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 ({ _wremove (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES)); });
-
- try
- {
- bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).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, false).c_str());
-
- if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES))
- Info ("SYS_FAVORITE_VOLUMES_SAVED", hwndDlg);
- }
- }
- catch (Exception &e)
- {
- e.Show (NULL);
- }
- }
-
- if (cnt == 0)
- {
- if (systemFavorites)
- {
- try
- {
- bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).c_str());
- }
- catch (...) { }
- }
- else
- _wremove (GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES));
- }
-
- return true;
- }
-
-
- static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable)
- {
- BOOL bIsDevice = favorite.DisconnectedDevice || IsVolumeDeviceHosted (favorite.Path.c_str()) || !enable;
- if (favorite.Pim > 0)
- {
- wchar_t szTmp[MAX_PIM + 1];
- StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", favorite.Pim);
- SetDlgItemText (hwndDlg, IDC_PIM, szTmp);
- }
- else
- SetDlgItemText (hwndDlg, IDC_PIM, L"");
- SetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, favorite.Label.c_str());
- SetCheckBox (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER, favorite.UseLabelInExplorer);
- 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);
- SetCheckBox (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID, favorite.UseVolumeID && bIsDevice);
-
- if (IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)) || !bIsDevice)
- {
- SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, L"");
- }
- else
- SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)).c_str());
-
- 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_PIM), enable);
- EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), enable);
- EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PIM), enable);
- EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), enable);
- EnableWindow (GetDlgItem (hwndDlg, IDT_FAVORITE_LABEL), enable);
- EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_LABEL), enable);
- EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER), 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);
- EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), enable && bIsDevice);
- EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), enable && bIsDevice);
- EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), enable && bIsDevice && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)));
-
- ShowWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
- ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
- ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
-
- // Group box
- RECT boxRect, checkRect, labelRect;
-
- GetWindowRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &boxRect);
- GetWindowRect (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), &checkRect);
- GetWindowRect (GetDlgItem (hwndDlg, IDT_VOLUME_ID), &labelRect);
-
- if (!bIsDevice && (boxRect.top < checkRect.top))
- {
- POINT pt = {boxRect.left, checkRect.bottom};
- ScreenToClient (hwndDlg, &pt);
- SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y,
- boxRect.right - boxRect.left,
- boxRect.bottom - checkRect.bottom,
- SWP_NOZORDER);
-
- InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
- }
-
- if (bIsDevice && (boxRect.top >= checkRect.top))
- {
- POINT pt = {boxRect.left, labelRect.top - CompensateYDPI (10)};
- ScreenToClient (hwndDlg, &pt);
- SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y,
- boxRect.right - boxRect.left,
- boxRect.bottom - labelRect.top + CompensateYDPI (10),
- SWP_NOZORDER);
-
- InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
- }
- }
-
-
- 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.Pim = GetPim (hwndDlg, IDC_PIM);
- favorite.UseLabelInExplorer = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER) != 0);
- favorite.UseVolumeID = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID) != 0);
-
- 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 (L"\\\\?\\Volume{") != 0)
- {
- bool partition = (favorite.Path.find (L"\\Partition0") == wstring::npos);
-
- if (!favorite.Label.empty())
- {
- ErrorDirect ((GetString (partition ? "FAVORITE_LABEL_PARTITION_TYPE_ERR" : "FAVORITE_LABEL_DEVICE_PATH_ERR") + wstring (L"\n\n") + favorite.Path).c_str(), hwndDlg);
- 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") + favorite.Path).c_str(), hwndDlg);
- favorite.MountOnArrival = false;
- }
- }
-
- if (favorite.MountOnArrival && favorite.Path.find (L"\\\\") == 0 && favorite.Path.find (L"Volume{") == wstring::npos)
- {
- Error ("FAVORITE_ARRIVAL_MOUNT_NETWORK_PATH_ERR", hwndDlg);
- favorite.MountOnArrival = false;
- }
- }
-
-
- void UpdateDeviceHostedFavoriteVolumes ()
- {
- try
- {
- LoadFavoriteVolumes();
- }
- catch (Exception &e)
- {
- e.Show (MainDlg);
- }
- }
-}
+/*
+ Derived from source code of TrueCrypt 7.1a, which is
+ Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
+ by the TrueCrypt License 3.0.
+
+ Modifications and additions to the original source code (contained in this file)
+ and all other portions of this file are Copyright (c) 2013-2016 IDRIX
+ and are governed by the Apache License 2.0 the full text of which is
+ contained in the file License.txt included in VeraCrypt binary and source
+ code distribution packages.
+*/
+
+#include "Tcdefs.h"
+#include "Platform/Finally.h"
+#include "Platform/ForEach.h"
+#include "BootEncryption.h"
+#include "Dlgcode.h"
+#include "Language.h"
+#include "Mount.h"
+#include "Common/Resource.h"
+#include "Resource.h"
+#include "Xml.h"
+#include "Favorites.h"
+
+using namespace std;
+
+namespace VeraCrypt
+{
+ 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, SRC_POS);
+ return FALSE;
+ }
+
+ FavoriteVolume favorite;
+ favorite.MountPoint = L"X:\\";
+ favorite.MountPoint[0] = (wchar_t) (prop.driveNo + L'A');
+
+ favorite.Path = prop.wszVolume;
+ if (favorite.Path.find (L"\\??\\") == 0)
+ favorite.Path = favorite.Path.substr (4);
+
+ if (wcslen (prop.wszLabel))
+ {
+ favorite.Label = prop.wszLabel;
+ favorite.UseLabelInExplorer = true;
+ }
+
+ if (IsVolumeDeviceHosted (favorite.Path.c_str()))
+ {
+ // Get GUID path
+ wstring volumeDevPath = favorite.Path;
+
+ wchar_t resolvedVolumeDevPath[TC_MAX_PATH];
+ if (ResolveSymbolicLink (volumeDevPath.c_str(), resolvedVolumeDevPath, sizeof(resolvedVolumeDevPath)))
+ volumeDevPath = resolvedVolumeDevPath;
+
+ wchar_t volumeName[TC_MAX_PATH];
+ HANDLE find = FindFirstVolume (volumeName, ARRAYSIZE (volumeName));
+
+ if (find != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ wchar_t findVolumeDevPath[TC_MAX_PATH];
+ wstring vn = volumeName;
+
+ if (QueryDosDevice (vn.substr (4, vn.size() - 5).c_str(), findVolumeDevPath, ARRAYSIZE (findVolumeDevPath)) != 0
+ && volumeDevPath == findVolumeDevPath)
+ {
+ favorite.VolumePathId = volumeName;
+ break;
+ }
+
+ } while (FindNextVolume (find, volumeName, ARRAYSIZE (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);
+ favorite.Pim = prop.volumePim;
+ memcpy (favorite.VolumeID, prop.volumeID, VOLUME_ID_SIZE);
+
+ if (favorite.VolumePathId.empty()
+ && IsVolumeDeviceHosted (favorite.Path.c_str())
+ && favorite.Path.find (L"\\\\?\\Volume{") != 0)
+ {
+ Warning (favorite.Path.find (L"\\Partition0") == wstring::npos ? "FAVORITE_ADD_PARTITION_TYPE_WARNING" : "FAVORITE_ADD_DRIVE_DEV_WARNING", hwndDlg);
+ }
+
+ 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);
+ WORD hw = HIWORD (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", SRC_POS);
+
+ 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 (95),
+ 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 (hwndDlg, 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", hwndDlg);
+ break;
+ }
+ }
+ }
+
+ FavoriteVolumes = Favorites;
+
+ ManageStartupSeq();
+ SaveSettings (hwndDlg);
+ }
+ else
+ SystemFavoriteVolumes = Favorites;
+
+ OnFavoriteVolumesUpdated();
+ LoadDriveLetters (hwndDlg, 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(), hwndDlg);
+
+ if (!IsServerOS() && !IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY))
+ Info ("SYS_FAVORITES_ADMIN_ONLY_INFO", hwndDlg);
+ }
+ }
+ 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(), hwndDlg);
+ else
+ Warning ("SETTING_REQUIRES_REBOOT", hwndDlg);
+ }
+ return 1;
+
+ case IDC_FAVORITES_HELP_LINK:
+ Applink (SystemFavoritesMode ? "sysfavorites" : "favorites", TRUE, "");
+ return 1;
+ case IDC_SHOW_PIM:
+ HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PIM, IDC_PIM, 0);
+ return 1;
+
+ case IDC_PIM:
+ if (hw == EN_CHANGE)
+ {
+ int pim = GetPim (hwndDlg, IDC_PIM);
+ if (pim > (SystemFavoritesMode? MAX_BOOT_PIM_VALUE: MAX_PIM_VALUE))
+ {
+ SetDlgItemText (hwndDlg, IDC_PIM, L"");
+ SetFocus (GetDlgItem(hwndDlg, IDC_PIM));
+ Warning (SystemFavoritesMode? "PIM_SYSENC_TOO_BIG": "PIM_TOO_BIG", hwndDlg);
+ return 1;
+ }
+ }
+ break;
+ }
+
+ 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;
+ case WM_CTLCOLORSTATIC:
+ {
+ HDC hdc = (HDC) wParam;
+ HWND hw = (HWND) lParam;
+ if (hw == GetDlgItem(hwndDlg, IDC_FAVORITE_VOLUME_ID))
+ {
+ // This the favorite ID field. Make its background like normal edit
+ HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW);
+ ::SelectObject(hdc, hbr);
+ return (BOOL) hbr;
+ }
+ }
+ break;
+ }
+
+ return 0;
+ }
+
+
+ static void FillFavoriteVolumesMenu ()
+ {
+ while (DeleteMenu (FavoriteVolumesMenu, 7, MF_BYPOSITION)) { }
+
+ if (FavoriteVolumes.empty())
+ return;
+
+ AppendMenu (FavoriteVolumesMenu, MF_SEPARATOR, 0, L"");
+
+ int i = 0;
+ foreach (const FavoriteVolume &favorite, FavoriteVolumes)
+ {
+ UINT flags = MF_STRING;
+
+ if (favorite.DisconnectedDevice)
+ flags |= MF_GRAYED;
+
+ wstring menuText = 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" + 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, (wchar_t *) favorite.MountPoint.substr (0, 2).c_str());
+ FillListControlSubItems (favoriteListControl, line++, favorite);
+ }
+ }
+
+
+ static void FillListControlSubItems (HWND FavoriteListControl, int line, const FavoriteVolume &favorite)
+ {
+ ListSubItemSet (FavoriteListControl, line, 1, (wchar_t *) favorite.Label.c_str());
+
+ if (favorite.DisconnectedDevice)
+ ListSubItemSet (FavoriteListControl, line, 2, (wchar_t *) (wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")").c_str());
+ else
+ ListSubItemSet (FavoriteListControl, line, 2, (wchar_t *) favorite.Path.c_str());
+ }
+
+
+ wstring GetFavoriteVolumeLabel (const wstring &volumePath, bool& useInExplorer)
+ {
+ foreach (const FavoriteVolume &favorite, FavoriteVolumes)
+ {
+ if (favorite.Path == volumePath)
+ {
+ useInExplorer = favorite.UseLabelInExplorer;
+ return favorite.Label;
+ }
+ }
+
+ foreach (const FavoriteVolume &favorite, SystemFavoriteVolumes)
+ {
+ if (favorite.Path == volumePath)
+ {
+ useInExplorer = favorite.UseLabelInExplorer;
+ return favorite.Label;
+ }
+ }
+
+ useInExplorer = false;
+ 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();
+ wstring favoritesFilePath = systemFavorites ? GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false) : 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, false).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 = Utf8StringToWide (mountPoint);
+
+ XmlGetNodeText (xml, volume, sizeof (volume));
+ favorite.Path = Utf8StringToWide (volume);
+
+ char label[1024];
+
+ XmlGetAttributeText (xml, "ID", label, sizeof (label));
+ if (strlen (label) == (2*VOLUME_ID_SIZE))
+ {
+ std::vector<byte> arr;
+ if (HexWideStringToArray (Utf8StringToWide (label).c_str(), arr) && arr.size() == VOLUME_ID_SIZE)
+ {
+ memcpy (favorite.VolumeID, &arr[0], VOLUME_ID_SIZE);
+ }
+ }
+
+ XmlGetAttributeText (xml, "label", label, sizeof (label));
+ favorite.Label = Utf8StringToWide (label);
+
+ XmlGetAttributeText (xml, "pim", label, sizeof (label));
+ if (strlen(label) == 0)
+ {
+ /* support old attribute name before it was changed to PIM*/
+ XmlGetAttributeText (xml, "pin", label, sizeof (label));
+ }
+ favorite.Pim = strtol (label, NULL, 10);
+ if (favorite.Pim < 0 || favorite.Pim > (systemFavorites? MAX_BOOT_PIM_VALUE : MAX_PIM_VALUE))
+ favorite.Pim = 0;
+
+ 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');
+
+ XmlGetAttributeText (xml, "useLabelInExplorer", boolVal, sizeof (boolVal));
+ if (boolVal[0])
+ favorite.UseLabelInExplorer = (boolVal[0] == '1') && !favorite.ReadOnly;
+
+ XmlGetAttributeText (xml, "useVolumeID", boolVal, sizeof (boolVal));
+ if (boolVal[0])
+ favorite.UseVolumeID = (boolVal[0] == '1') && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID));
+
+ if (favorite.Path.find (L"\\\\?\\Volume{") == 0 && favorite.Path.rfind (L"}\\") == favorite.Path.size() - 2)
+ {
+ wstring 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;
+ }
+
+
+ bool SaveFavoriteVolumes (HWND hwndDlg, const vector <FavoriteVolume> &favorites, bool systemFavorites)
+ {
+ FILE *f;
+ int cnt = 0;
+
+ f = _wfopen (GetConfigPath (systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES), L"w,ccs=UTF-8");
+ if (f == NULL)
+ {
+ handleWin32Error (MainDlg, SRC_POS);
+ return false;
+ }
+
+ XmlWriteHeader (f);
+ fputws (L"\n\t<favorites>", f);
+
+ foreach (const FavoriteVolume &favorite, favorites)
+ {
+ wchar_t tq[2048];
+
+ if (systemFavorites && favorite.Path.find (L"\\\\") == 0 && favorite.Path.find (L"Volume{") == wstring::npos)
+ Warning ("SYSTEM_FAVORITE_NETWORK_PATH_ERR", hwndDlg);
+
+ XmlQuoteTextW (!favorite.VolumePathId.empty() ? favorite.VolumePathId.c_str() : favorite.Path.c_str(), tq, ARRAYSIZE (tq));
+
+ wstring s = L"\n\t\t<volume mountpoint=\"" + favorite.MountPoint + L"\"";
+
+ if (!IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)))
+ s += L" ID=\"" + ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)) + L"\"";
+
+ if (!favorite.Label.empty())
+ s += L" label=\"" + favorite.Label + L"\"";
+
+ if (favorite.Pim > 0)
+ s += L" pim=\"" + IntToWideString(favorite.Pim) + 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\"";
+
+ if (favorite.UseLabelInExplorer && !favorite.ReadOnly)
+ s += L" useLabelInExplorer=\"1\"";
+
+ if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)))
+ s += L" useVolumeID=\"1\"";
+
+ s += L">" + wstring (tq) + L"</volume>";
+
+ fwprintf (f, L"%ws", s.c_str());
+ cnt++;
+ }
+
+ fputws (L"\n\t</favorites>", f);
+ XmlWriteFooter (f);
+
+ if (!CheckFileStreamWriteErrors (hwndDlg, 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 ({ _wremove (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES)); });
+
+ try
+ {
+ bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).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, false).c_str());
+
+ if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES))
+ Info ("SYS_FAVORITE_VOLUMES_SAVED", hwndDlg);
+ }
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ }
+ }
+
+ if (cnt == 0)
+ {
+ if (systemFavorites)
+ {
+ try
+ {
+ bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).c_str());
+ }
+ catch (...) { }
+ }
+ else
+ _wremove (GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES));
+ }
+
+ return true;
+ }
+
+
+ static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable)
+ {
+ BOOL bIsDevice = favorite.DisconnectedDevice || IsVolumeDeviceHosted (favorite.Path.c_str()) || !enable;
+ if (favorite.Pim > 0)
+ {
+ wchar_t szTmp[MAX_PIM + 1];
+ StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", favorite.Pim);
+ SetDlgItemText (hwndDlg, IDC_PIM, szTmp);
+ }
+ else
+ SetDlgItemText (hwndDlg, IDC_PIM, L"");
+ SetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, favorite.Label.c_str());
+ SetCheckBox (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER, favorite.UseLabelInExplorer);
+ 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);
+ SetCheckBox (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID, favorite.UseVolumeID && bIsDevice);
+
+ if (IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)) || !bIsDevice)
+ {
+ SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, L"");
+ }
+ else
+ SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)).c_str());
+
+ 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_PIM), enable);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), enable);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PIM), enable);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), enable);
+ EnableWindow (GetDlgItem (hwndDlg, IDT_FAVORITE_LABEL), enable);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_LABEL), enable);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER), 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);
+ EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), enable && bIsDevice);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), enable && bIsDevice);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), enable && bIsDevice && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)));
+
+ ShowWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
+ ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
+ ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
+
+ // Group box
+ RECT boxRect, checkRect, labelRect;
+
+ GetWindowRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &boxRect);
+ GetWindowRect (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), &checkRect);
+ GetWindowRect (GetDlgItem (hwndDlg, IDT_VOLUME_ID), &labelRect);
+
+ if (!bIsDevice && (boxRect.top < checkRect.top))
+ {
+ POINT pt = {boxRect.left, checkRect.bottom};
+ ScreenToClient (hwndDlg, &pt);
+ SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y,
+ boxRect.right - boxRect.left,
+ boxRect.bottom - checkRect.bottom,
+ SWP_NOZORDER);
+
+ InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
+ }
+
+ if (bIsDevice && (boxRect.top >= checkRect.top))
+ {
+ POINT pt = {boxRect.left, labelRect.top - CompensateYDPI (10)};
+ ScreenToClient (hwndDlg, &pt);
+ SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y,
+ boxRect.right - boxRect.left,
+ boxRect.bottom - labelRect.top + CompensateYDPI (10),
+ SWP_NOZORDER);
+
+ InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
+ }
+ }
+
+
+ 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.Pim = GetPim (hwndDlg, IDC_PIM);
+ favorite.UseLabelInExplorer = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER) != 0);
+ favorite.UseVolumeID = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID) != 0);
+
+ 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 (L"\\\\?\\Volume{") != 0)
+ {
+ bool partition = (favorite.Path.find (L"\\Partition0") == wstring::npos);
+
+ if (!favorite.Label.empty())
+ {
+ ErrorDirect ((GetString (partition ? "FAVORITE_LABEL_PARTITION_TYPE_ERR" : "FAVORITE_LABEL_DEVICE_PATH_ERR") + wstring (L"\n\n") + favorite.Path).c_str(), hwndDlg);
+ 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") + favorite.Path).c_str(), hwndDlg);
+ favorite.MountOnArrival = false;
+ }
+ }
+
+ if (favorite.MountOnArrival && favorite.Path.find (L"\\\\") == 0 && favorite.Path.find (L"Volume{") == wstring::npos)
+ {
+ Error ("FAVORITE_ARRIVAL_MOUNT_NETWORK_PATH_ERR", hwndDlg);
+ favorite.MountOnArrival = false;
+ }
+ }
+
+
+ void UpdateDeviceHostedFavoriteVolumes ()
+ {
+ try
+ {
+ LoadFavoriteVolumes();
+ }
+ catch (Exception &e)
+ {
+ e.Show (MainDlg);
+ }
+ }
+}