PageRenderTime 47ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Mount/Favorites.cpp

https://github.com/pcmac77/truecrypt-android
C++ | 859 lines | 667 code | 167 blank | 25 comment | 139 complexity | ae8088f38bf25e9fb7573b4c334d0bad MD5 | raw file
  1. /*
  2. Copyright (c) 2010 TrueCrypt Developers Association. All rights reserved.
  3. Governed by the TrueCrypt License 3.0 the full text of which is contained in
  4. the file License.txt included in TrueCrypt binary and source code distribution
  5. packages.
  6. */
  7. #include "Tcdefs.h"
  8. #include "Platform/Finally.h"
  9. #include "Platform/ForEach.h"
  10. #include "BootEncryption.h"
  11. #include "Dlgcode.h"
  12. #include "Language.h"
  13. #include "Mount.h"
  14. #include "Resource.h"
  15. #include "Xml.h"
  16. #include "Favorites.h"
  17. using namespace std;
  18. namespace TrueCrypt
  19. {
  20. vector <FavoriteVolume> FavoriteVolumes;
  21. vector <FavoriteVolume> SystemFavoriteVolumes;
  22. list <FavoriteVolume> FavoritesOnArrivalMountRequired;
  23. list <FavoriteVolume> FavoritesMountedOnArrivalStillConnected;
  24. HMENU FavoriteVolumesMenu;
  25. BOOL AddMountedVolumeToFavorites (HWND hwndDlg, int driveNo, bool systemFavorites)
  26. {
  27. VOLUME_PROPERTIES_STRUCT prop;
  28. DWORD bytesReturned;
  29. memset (&prop, 0, sizeof (prop));
  30. prop.driveNo = driveNo;
  31. if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &bytesReturned, NULL))
  32. {
  33. handleWin32Error (hwndDlg);
  34. return FALSE;
  35. }
  36. FavoriteVolume favorite;
  37. favorite.MountPoint = "X:\\";
  38. favorite.MountPoint[0] = (char) (prop.driveNo + 'A');
  39. favorite.Path = WideToSingleString ((wchar_t *) prop.wszVolume);
  40. if (favorite.Path.find ("\\??\\") == 0)
  41. favorite.Path = favorite.Path.substr (4);
  42. if (IsVolumeDeviceHosted (favorite.Path.c_str()))
  43. {
  44. // Get GUID path
  45. string volumeDevPath = favorite.Path;
  46. wchar_t resolvedVolumeDevPath[TC_MAX_PATH];
  47. if (ResolveSymbolicLink (SingleStringToWide (volumeDevPath).c_str(), resolvedVolumeDevPath))
  48. volumeDevPath = WideToSingleString (resolvedVolumeDevPath);
  49. char volumeName[TC_MAX_PATH];
  50. HANDLE find = FindFirstVolume (volumeName, sizeof (volumeName));
  51. if (find != INVALID_HANDLE_VALUE)
  52. {
  53. do
  54. {
  55. char findVolumeDevPath[TC_MAX_PATH];
  56. string vn = volumeName;
  57. if (QueryDosDevice (vn.substr (4, vn.size() - 5).c_str(), findVolumeDevPath, sizeof (findVolumeDevPath)) != 0
  58. && volumeDevPath == findVolumeDevPath)
  59. {
  60. favorite.VolumePathId = volumeName;
  61. break;
  62. }
  63. } while (FindNextVolume (find, volumeName, sizeof (volumeName)));
  64. FindVolumeClose (find);
  65. }
  66. }
  67. favorite.ReadOnly = prop.readOnly ? true : false;
  68. favorite.Removable = prop.removable ? true : false;
  69. favorite.SystemEncryption = prop.partitionInInactiveSysEncScope ? true : false;
  70. favorite.OpenExplorerWindow = (bExplore == TRUE);
  71. if (favorite.VolumePathId.empty()
  72. && IsVolumeDeviceHosted (favorite.Path.c_str())
  73. && favorite.Path.find ("\\\\?\\Volume{") != 0)
  74. {
  75. Warning (favorite.Path.find ("\\Partition0") == string::npos ? "FAVORITE_ADD_PARTITION_TYPE_WARNING" : "FAVORITE_ADD_DRIVE_DEV_WARNING");
  76. }
  77. return OrganizeFavoriteVolumes (hwndDlg, systemFavorites, favorite);
  78. }
  79. static BOOL CALLBACK FavoriteVolumesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  80. {
  81. /* This dialog is used both for System Favorites and non-system Favorites.
  82. The following options have different meaning in System Favorites mode:
  83. IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT => MOUNT_SYSTEM_FAVORITES_ON_BOOT
  84. IDC_FAVORITE_DISABLE_HOTKEY => DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  85. */
  86. WORD lw = LOWORD (wParam);
  87. static bool SystemFavoritesMode;
  88. static vector <FavoriteVolume> Favorites;
  89. static int SelectedItem;
  90. static HWND FavoriteListControl;
  91. switch (msg)
  92. {
  93. case WM_INITDIALOG:
  94. {
  95. try
  96. {
  97. FavoriteListControl = GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST);
  98. FavoriteVolumesDlgProcArguments *args = (FavoriteVolumesDlgProcArguments *) lParam;
  99. SystemFavoritesMode = args->SystemFavorites;
  100. LocalizeDialog (hwndDlg, SystemFavoritesMode ? "SYSTEM_FAVORITES_DLG_TITLE" : "IDD_FAVORITE_VOLUMES");
  101. if (SystemFavoritesMode)
  102. {
  103. RECT rec;
  104. BootEncryptionStatus bootEncStatus = BootEncryption (hwndDlg).GetStatus();
  105. if (!bootEncStatus.DriveMounted)
  106. throw ErrorException ("SYS_FAVORITES_REQUIRE_PBA");
  107. ShowWindow (GetDlgItem(hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON), SW_HIDE);
  108. ShowWindow (GetDlgItem(hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL), SW_HIDE);
  109. // MOUNT_SYSTEM_FAVORITES_ON_BOOT
  110. SetWindowTextW (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), GetString ("MOUNT_SYSTEM_FAVORITES_ON_BOOT"));
  111. // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  112. SetWindowTextW (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), GetString ("DISABLE_NONADMIN_SYS_FAVORITES_ACCESS"));
  113. // Group box
  114. GetClientRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &rec);
  115. SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, 0, 0,
  116. rec.right,
  117. rec.bottom - CompensateYDPI (90),
  118. SWP_NOMOVE | SWP_NOZORDER);
  119. InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
  120. }
  121. else
  122. {
  123. ShowWindow (GetDlgItem(hwndDlg, IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX), SW_HIDE);
  124. }
  125. Favorites.clear();
  126. LVCOLUMNW column;
  127. SendMessageW (FavoriteListControl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  128. memset (&column, 0, sizeof (column));
  129. column.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
  130. column.pszText = GetString ("DRIVE");
  131. column.cx = CompensateXDPI (38);
  132. column.fmt = LVCFMT_CENTER;
  133. SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
  134. ++column.iSubItem;
  135. column.fmt = LVCFMT_LEFT;
  136. column.pszText = GetString ("LABEL");
  137. column.cx = CompensateXDPI (160);
  138. SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 2, (LPARAM) &column);
  139. ++column.iSubItem;
  140. column.fmt = LVCFMT_LEFT;
  141. column.pszText = GetString ("VOLUME");
  142. column.cx = CompensateXDPI (330);
  143. SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 3, (LPARAM) &column);
  144. SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false);
  145. if (SystemFavoritesMode)
  146. LoadFavoriteVolumes (Favorites, true);
  147. else
  148. Favorites = FavoriteVolumes;
  149. if (args->AddFavoriteVolume)
  150. Favorites.push_back (args->NewFavoriteVolume);
  151. FillListControl (FavoriteListControl, Favorites);
  152. SelectedItem = -1;
  153. if (args->AddFavoriteVolume)
  154. {
  155. ListView_SetItemState (FavoriteListControl, Favorites.size() - 1, LVIS_SELECTED, LVIS_SELECTED);
  156. ListView_EnsureVisible (FavoriteListControl, Favorites.size() - 1, FALSE);
  157. }
  158. if (SystemFavoritesMode)
  159. SetDlgItemTextW (hwndDlg, IDC_FAVORITES_HELP_LINK, GetString ("SYS_FAVORITES_HELP_LINK"));
  160. ToHyperlink (hwndDlg, IDC_FAVORITES_HELP_LINK);
  161. }
  162. catch (Exception &e)
  163. {
  164. e.Show (hwndDlg);
  165. EndDialog (hwndDlg, IDCLOSE);
  166. }
  167. }
  168. return 1;
  169. case WM_COMMAND:
  170. switch (lw)
  171. {
  172. case IDOK:
  173. /* Global System Favorites settings */
  174. if (SystemFavoritesMode)
  175. {
  176. BootEncryption BootEncObj (NULL);
  177. if (BootEncObj.GetStatus().DriveMounted)
  178. {
  179. try
  180. {
  181. uint32 reqConfig = IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT) ? TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES : 0;
  182. if (reqConfig != (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES))
  183. BootEncObj.RegisterSystemFavoritesService (reqConfig ? TRUE : FALSE);
  184. SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS, IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY));
  185. }
  186. catch (Exception &e)
  187. {
  188. e.Show (hwndDlg);
  189. }
  190. }
  191. }
  192. /* (System) Favorites list */
  193. if (SelectedItem != -1 && !Favorites.empty())
  194. SetFavoriteVolume (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode);
  195. if (SaveFavoriteVolumes (Favorites, SystemFavoritesMode))
  196. {
  197. if (!SystemFavoritesMode)
  198. {
  199. bMountFavoritesOnLogon = FALSE;
  200. foreach (const FavoriteVolume &favorite, Favorites)
  201. {
  202. if (favorite.MountOnLogOn)
  203. {
  204. bMountFavoritesOnLogon = TRUE;
  205. break;
  206. }
  207. }
  208. if (!bEnableBkgTask || bCloseBkgTaskWhenNoVolumes || IsNonInstallMode())
  209. {
  210. foreach (const FavoriteVolume favorite, Favorites)
  211. {
  212. if (favorite.MountOnArrival)
  213. {
  214. Warning ("FAVORITE_ARRIVAL_MOUNT_BACKGROUND_TASK_ERR");
  215. break;
  216. }
  217. }
  218. }
  219. FavoriteVolumes = Favorites;
  220. ManageStartupSeq();
  221. SaveSettings (hwndDlg);
  222. }
  223. else
  224. SystemFavoriteVolumes = Favorites;
  225. OnFavoriteVolumesUpdated();
  226. LoadDriveLetters (GetDlgItem (MainDlg, IDC_DRIVELIST), 0);
  227. EndDialog (hwndDlg, IDOK);
  228. }
  229. return 1;
  230. case IDCANCEL:
  231. EndDialog (hwndDlg, IDCLOSE);
  232. return 1;
  233. case IDC_FAVORITE_MOVE_DOWN:
  234. if (SelectedItem != -1 && Favorites.size() > (size_t) SelectedItem + 1)
  235. {
  236. swap (Favorites[SelectedItem], Favorites[SelectedItem + 1]);
  237. FillListControl (FavoriteListControl, Favorites);
  238. ++SelectedItem;
  239. ListView_SetItemState (FavoriteListControl, SelectedItem, LVIS_SELECTED, LVIS_SELECTED);
  240. ListView_EnsureVisible (FavoriteListControl, SelectedItem, FALSE);
  241. }
  242. return 1;
  243. case IDC_FAVORITE_MOVE_UP:
  244. if (SelectedItem > 0)
  245. {
  246. swap (Favorites[SelectedItem], Favorites[SelectedItem - 1]);
  247. FillListControl (FavoriteListControl, Favorites);
  248. --SelectedItem;
  249. ListView_SetItemState (FavoriteListControl, SelectedItem, LVIS_SELECTED, LVIS_SELECTED);
  250. ListView_EnsureVisible (FavoriteListControl, SelectedItem, FALSE);
  251. }
  252. return 1;
  253. case IDC_FAVORITE_REMOVE:
  254. if (SelectedItem != -1)
  255. {
  256. Favorites.erase (Favorites.begin() + SelectedItem);
  257. FillListControl (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST), Favorites);
  258. SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false);
  259. SelectedItem = -1;
  260. }
  261. return 1;
  262. case IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT: // Note that this option means "MOUNT_SYSTEM_FAVORITES_ON_BOOT" when SystemFavoritesMode is true
  263. if (SystemFavoritesMode)
  264. {
  265. // MOUNT_SYSTEM_FAVORITES_ON_BOOT
  266. if (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT))
  267. {
  268. WarningDirect ((wstring (GetString ("SYS_FAVORITES_KEYBOARD_WARNING")) + L"\n\n" + GetString ("BOOT_PASSWORD_CACHE_KEYBOARD_WARNING")).c_str());
  269. if (!IsServerOS() && !IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY))
  270. Info ("SYS_FAVORITES_ADMIN_ONLY_INFO");
  271. }
  272. }
  273. return 1;
  274. case IDC_FAVORITE_DISABLE_HOTKEY: // Note that this option means "DISABLE_NONADMIN_SYS_FAVORITES_ACCESS" when SystemFavoritesMode is true
  275. if (SystemFavoritesMode)
  276. {
  277. // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  278. if (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY))
  279. WarningDirect ((wstring (GetString ("SYS_FAVORITES_ADMIN_ONLY_WARNING")) + L"\n\n" + GetString ("SETTING_REQUIRES_REBOOT")).c_str());
  280. else
  281. Warning ("SETTING_REQUIRES_REBOOT");
  282. }
  283. return 1;
  284. case IDC_FAVORITES_HELP_LINK:
  285. Applink (SystemFavoritesMode ? "sysfavorites" : "favorites", TRUE, "");
  286. return 1;
  287. }
  288. return 0;
  289. case WM_NOTIFY:
  290. if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
  291. {
  292. static bool reentry = false;
  293. if (reentry)
  294. break;
  295. reentry = true;
  296. if (SelectedItem != -1)
  297. {
  298. SetFavoriteVolume (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode);
  299. FillListControlSubItems (FavoriteListControl, SelectedItem, Favorites[SelectedItem]);
  300. }
  301. SelectedItem = ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST), -1, LVIS_SELECTED);
  302. if (SelectedItem != -1)
  303. SetControls (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode);
  304. else
  305. SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false);
  306. reentry = false;
  307. return 1;
  308. }
  309. break;
  310. case WM_CLOSE:
  311. EndDialog (hwndDlg, IDCLOSE);
  312. return 1;
  313. }
  314. return 0;
  315. }
  316. static void FillFavoriteVolumesMenu ()
  317. {
  318. while (DeleteMenu (FavoriteVolumesMenu, 7, MF_BYPOSITION)) { }
  319. if (FavoriteVolumes.empty())
  320. return;
  321. AppendMenu (FavoriteVolumesMenu, MF_SEPARATOR, 0, NULL);
  322. int i = 0;
  323. foreach (const FavoriteVolume &favorite, FavoriteVolumes)
  324. {
  325. UINT flags = MF_STRING;
  326. if (favorite.DisconnectedDevice)
  327. flags |= MF_GRAYED;
  328. wstring menuText = SingleStringToWide (favorite.Path);
  329. if (favorite.DisconnectedDevice)
  330. menuText = wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")";
  331. if (!favorite.Label.empty())
  332. {
  333. if (favorite.DisconnectedDevice)
  334. menuText = favorite.Label + L" " + menuText;
  335. else
  336. menuText = favorite.Label;
  337. }
  338. AppendMenuW (FavoriteVolumesMenu, flags, TC_FAVORITE_MENU_CMD_ID_OFFSET + i++,
  339. (menuText + L"\t" + SingleStringToWide (favorite.MountPoint).substr (0, 2)).c_str());
  340. }
  341. }
  342. static void FillListControl (HWND favoriteListControl, vector <FavoriteVolume> &favorites)
  343. {
  344. SendMessage (favoriteListControl, LVM_DELETEALLITEMS, 0, 0);
  345. int line = 0;
  346. foreach (const FavoriteVolume favorite, favorites)
  347. {
  348. ListItemAdd (favoriteListControl, line, (char *) favorite.MountPoint.substr (0, 2).c_str());
  349. FillListControlSubItems (favoriteListControl, line++, favorite);
  350. }
  351. }
  352. static void FillListControlSubItems (HWND FavoriteListControl, int line, const FavoriteVolume &favorite)
  353. {
  354. ListSubItemSetW (FavoriteListControl, line, 1, (wchar_t *) favorite.Label.c_str());
  355. if (favorite.DisconnectedDevice)
  356. ListSubItemSetW (FavoriteListControl, line, 2, (wchar_t *) (wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")").c_str());
  357. else
  358. ListSubItemSet (FavoriteListControl, line, 2, (char *) favorite.Path.c_str());
  359. }
  360. wstring GetFavoriteVolumeLabel (const string &volumePath)
  361. {
  362. foreach (const FavoriteVolume &favorite, FavoriteVolumes)
  363. {
  364. if (favorite.Path == volumePath)
  365. return favorite.Label;
  366. }
  367. foreach (const FavoriteVolume &favorite, SystemFavoriteVolumes)
  368. {
  369. if (favorite.Path == volumePath)
  370. return favorite.Label;
  371. }
  372. return wstring();
  373. }
  374. void LoadFavoriteVolumes ()
  375. {
  376. LoadFavoriteVolumes (FavoriteVolumes, false);
  377. try
  378. {
  379. LoadFavoriteVolumes (SystemFavoriteVolumes, true, true);
  380. }
  381. catch (...) { } // Ignore errors as SystemFavoriteVolumes list is used only for resolving volume paths to labels
  382. OnFavoriteVolumesUpdated();
  383. }
  384. void LoadFavoriteVolumes (vector <FavoriteVolume> &favorites, bool systemFavorites, bool noUacElevation)
  385. {
  386. favorites.clear();
  387. string favoritesFilePath = systemFavorites ? GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES) : GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES);
  388. if (systemFavorites && !IsAdmin() && !noUacElevation)
  389. {
  390. favoritesFilePath = GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES);
  391. try
  392. {
  393. BootEncryption bootEnc (MainDlg);
  394. bootEnc.CopyFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str(), favoritesFilePath.c_str());
  395. }
  396. catch (SystemException &e)
  397. {
  398. if (e.ErrorCode == ERROR_FILE_NOT_FOUND)
  399. return;
  400. throw;
  401. }
  402. }
  403. DWORD size;
  404. char *favoritesXml = LoadFile (favoritesFilePath.c_str(), &size);
  405. if (systemFavorites && !IsAdmin() && !noUacElevation)
  406. DeleteFile (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES));
  407. char *xml = favoritesXml;
  408. char mountPoint[MAX_PATH], volume[MAX_PATH];
  409. if (xml == NULL)
  410. return;
  411. while (xml = XmlFindElement (xml, "volume"))
  412. {
  413. FavoriteVolume favorite;
  414. XmlGetAttributeText (xml, "mountpoint", mountPoint, sizeof (mountPoint));
  415. favorite.MountPoint = mountPoint;
  416. XmlGetNodeText (xml, volume, sizeof (volume));
  417. favorite.Path = volume;
  418. char label[1024];
  419. XmlGetAttributeText (xml, "label", label, sizeof (label));
  420. favorite.Label = Utf8StringToWide (label);
  421. char boolVal[2];
  422. XmlGetAttributeText (xml, "readonly", boolVal, sizeof (boolVal));
  423. if (boolVal[0])
  424. favorite.ReadOnly = (boolVal[0] == '1');
  425. XmlGetAttributeText (xml, "removable", boolVal, sizeof (boolVal));
  426. if (boolVal[0])
  427. favorite.Removable = (boolVal[0] == '1');
  428. XmlGetAttributeText (xml, "system", boolVal, sizeof (boolVal));
  429. if (boolVal[0])
  430. favorite.SystemEncryption = (boolVal[0] == '1');
  431. XmlGetAttributeText (xml, "noHotKeyMount", boolVal, sizeof (boolVal));
  432. if (boolVal[0])
  433. favorite.DisableHotkeyMount = (boolVal[0] == '1');
  434. XmlGetAttributeText (xml, "openExplorerWindow", boolVal, sizeof (boolVal));
  435. if (boolVal[0])
  436. favorite.OpenExplorerWindow = (boolVal[0] == '1');
  437. XmlGetAttributeText (xml, "mountOnArrival", boolVal, sizeof (boolVal));
  438. if (boolVal[0])
  439. favorite.MountOnArrival = (boolVal[0] == '1');
  440. XmlGetAttributeText (xml, "mountOnLogOn", boolVal, sizeof (boolVal));
  441. if (boolVal[0])
  442. favorite.MountOnLogOn = (boolVal[0] == '1');
  443. if (favorite.Path.find ("\\\\?\\Volume{") == 0 && favorite.Path.rfind ("}\\") == favorite.Path.size() - 2)
  444. {
  445. string resolvedPath = VolumeGuidPathToDevicePath (favorite.Path);
  446. if (!resolvedPath.empty())
  447. {
  448. favorite.DisconnectedDevice = false;
  449. favorite.VolumePathId = favorite.Path;
  450. favorite.Path = resolvedPath;
  451. }
  452. else
  453. favorite.DisconnectedDevice = true;
  454. }
  455. favorites.push_back (favorite);
  456. xml++;
  457. }
  458. free (favoritesXml);
  459. }
  460. static void OnFavoriteVolumesUpdated ()
  461. {
  462. FillFavoriteVolumesMenu();
  463. FavoritesOnArrivalMountRequired.clear();
  464. foreach (const FavoriteVolume favorite, FavoriteVolumes)
  465. {
  466. if (favorite.MountOnArrival)
  467. {
  468. FavoritesOnArrivalMountRequired.push_back (favorite);
  469. if (IsMountedVolume (favorite.Path.c_str()))
  470. {
  471. bool present = false;
  472. foreach (const FavoriteVolume favoriteConnected, FavoritesMountedOnArrivalStillConnected)
  473. {
  474. if (favorite.Path == favoriteConnected.Path)
  475. {
  476. present = true;
  477. break;
  478. }
  479. }
  480. if (!present)
  481. FavoritesMountedOnArrivalStillConnected.push_back (favorite);
  482. }
  483. }
  484. }
  485. }
  486. BOOL OrganizeFavoriteVolumes (HWND hwndDlg, bool systemFavorites, const FavoriteVolume &newFavorite)
  487. {
  488. FavoriteVolumesDlgProcArguments args;
  489. args.SystemFavorites = systemFavorites;
  490. if (!newFavorite.Path.empty())
  491. {
  492. args.AddFavoriteVolume = true;
  493. args.NewFavoriteVolume = newFavorite;
  494. }
  495. else
  496. args.AddFavoriteVolume = false;
  497. return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_FAVORITE_VOLUMES), hwndDlg, (DLGPROC) FavoriteVolumesDlgProc, (LPARAM) &args) == IDOK;
  498. }
  499. static bool SaveFavoriteVolumes (const vector <FavoriteVolume> &favorites, bool systemFavorites)
  500. {
  501. FILE *f;
  502. int cnt = 0;
  503. f = fopen (GetConfigPath (systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES), "w,ccs=UTF-8");
  504. if (f == NULL)
  505. {
  506. handleWin32Error (MainDlg);
  507. return false;
  508. }
  509. XmlWriteHeaderW (f);
  510. fputws (L"\n\t<favorites>", f);
  511. foreach (const FavoriteVolume &favorite, favorites)
  512. {
  513. char tq[2048];
  514. if (systemFavorites && favorite.Path.find ("\\\\") == 0 && favorite.Path.find ("Volume{") == string::npos)
  515. Warning ("SYSTEM_FAVORITE_NETWORK_PATH_ERR");
  516. XmlQuoteText (!favorite.VolumePathId.empty() ? favorite.VolumePathId.c_str() : favorite.Path.c_str(), tq, sizeof (tq));
  517. wstring s = L"\n\t\t<volume mountpoint=\"" + SingleStringToWide (favorite.MountPoint) + L"\"";
  518. if (!favorite.Label.empty())
  519. s += L" label=\"" + favorite.Label + L"\"";
  520. if (favorite.ReadOnly)
  521. s += L" readonly=\"1\"";
  522. if (favorite.Removable)
  523. s += L" removable=\"1\"";
  524. if (favorite.SystemEncryption)
  525. s += L" system=\"1\"";
  526. if (favorite.MountOnArrival)
  527. s += L" mountOnArrival=\"1\"";
  528. if (favorite.MountOnLogOn)
  529. s += L" mountOnLogOn=\"1\"";
  530. if (favorite.DisableHotkeyMount)
  531. s += L" noHotKeyMount=\"1\"";
  532. if (favorite.OpenExplorerWindow)
  533. s += L" openExplorerWindow=\"1\"";
  534. s += L">" + SingleStringToWide (tq) + L"</volume>";
  535. fwprintf (f, L"%ws", s.c_str());
  536. cnt++;
  537. }
  538. fputws (L"\n\t</favorites>", f);
  539. XmlWriteFooterW (f);
  540. if (!CheckFileStreamWriteErrors (f, systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES))
  541. {
  542. fclose (f);
  543. return false;
  544. }
  545. fclose (f);
  546. BootEncryption bootEnc (MainDlg);
  547. if (systemFavorites)
  548. {
  549. finally_do ({ remove (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES)); });
  550. try
  551. {
  552. bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str());
  553. }
  554. catch (UserAbort&) { return false; }
  555. catch (...) { }
  556. try
  557. {
  558. if (cnt != 0)
  559. {
  560. bootEnc.CopyFileAdmin (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES), GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str());
  561. if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES))
  562. Info ("SYS_FAVORITE_VOLUMES_SAVED");
  563. }
  564. }
  565. catch (Exception &e)
  566. {
  567. e.Show (NULL);
  568. }
  569. }
  570. if (cnt == 0)
  571. {
  572. if (systemFavorites)
  573. {
  574. try
  575. {
  576. bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES).c_str());
  577. }
  578. catch (...) { }
  579. }
  580. else
  581. remove (GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES));
  582. }
  583. return true;
  584. }
  585. static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable)
  586. {
  587. SetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, favorite.Label.c_str());
  588. SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON, favorite.MountOnLogOn);
  589. SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL, favorite.MountOnArrival);
  590. SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_READONLY, favorite.ReadOnly);
  591. SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE, favorite.Removable);
  592. if (systemFavoritesMode)
  593. {
  594. uint32 driverConfig = ReadDriverConfigurationFlags();
  595. // MOUNT_SYSTEM_FAVORITES_ON_BOOT
  596. CheckDlgButton (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES) ? BST_CHECKED : BST_UNCHECKED);
  597. // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  598. CheckDlgButton (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY, (driverConfig & TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS) ? BST_CHECKED : BST_UNCHECKED);
  599. }
  600. else
  601. {
  602. SetCheckBox (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, favorite.OpenExplorerWindow);
  603. SetCheckBox (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY, favorite.DisableHotkeyMount);
  604. }
  605. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOVE_UP), enable);
  606. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOVE_DOWN), enable);
  607. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_REMOVE), enable);
  608. EnableWindow (GetDlgItem (hwndDlg, IDT_FAVORITE_LABEL), enable);
  609. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_LABEL), enable);
  610. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON), enable && !systemFavoritesMode);
  611. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL), enable && !systemFavoritesMode);
  612. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_READONLY), enable);
  613. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE), enable);
  614. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), enable || systemFavoritesMode);
  615. EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), enable || systemFavoritesMode);
  616. }
  617. static void SetFavoriteVolume (HWND hwndDlg, FavoriteVolume &favorite, bool systemFavoritesMode)
  618. {
  619. wchar_t label[1024];
  620. if (GetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, label, ARRAYSIZE (label)) != 0)
  621. favorite.Label = label;
  622. else
  623. favorite.Label.clear();
  624. favorite.ReadOnly = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_READONLY) != 0);
  625. favorite.Removable = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE) != 0);
  626. if (!systemFavoritesMode)
  627. {
  628. favorite.MountOnLogOn = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON) != 0);
  629. favorite.MountOnArrival = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL) != 0);
  630. favorite.DisableHotkeyMount = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY) != 0);
  631. favorite.OpenExplorerWindow = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT) != 0);
  632. }
  633. if (favorite.VolumePathId.empty()
  634. && IsVolumeDeviceHosted (favorite.Path.c_str())
  635. && favorite.Path.find ("\\\\?\\Volume{") != 0)
  636. {
  637. bool partition = (favorite.Path.find ("\\Partition0") == string::npos);
  638. if (!favorite.Label.empty())
  639. {
  640. ErrorDirect ((GetString (partition ? "FAVORITE_LABEL_PARTITION_TYPE_ERR" : "FAVORITE_LABEL_DEVICE_PATH_ERR") + wstring (L"\n\n") + SingleStringToWide (favorite.Path)).c_str());
  641. favorite.Label.clear();
  642. }
  643. if (favorite.MountOnArrival)
  644. {
  645. ErrorDirect ((GetString (partition ? "FAVORITE_ARRIVAL_MOUNT_PARTITION_TYPE_ERR" : "FAVORITE_ARRIVAL_MOUNT_DEVICE_PATH_ERR") + wstring (L"\n\n") + SingleStringToWide (favorite.Path)).c_str());
  646. favorite.MountOnArrival = false;
  647. }
  648. }
  649. if (favorite.MountOnArrival && favorite.Path.find ("\\\\") == 0 && favorite.Path.find ("Volume{") == string::npos)
  650. {
  651. Error ("FAVORITE_ARRIVAL_MOUNT_NETWORK_PATH_ERR");
  652. favorite.MountOnArrival = false;
  653. }
  654. }
  655. void UpdateDeviceHostedFavoriteVolumes ()
  656. {
  657. try
  658. {
  659. LoadFavoriteVolumes();
  660. }
  661. catch (Exception &e)
  662. {
  663. e.Show (MainDlg);
  664. }
  665. }
  666. }