"Fossies" - the Fresh Open Source Software Archive

Member "src/Mount/Favorites.cpp" (10 Oct 2018, 35449 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Favorites.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.20_Source_vs_1.21_Source.

    1 /*
    2  Derived from source code of TrueCrypt 7.1a, which is
    3  Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
    4  by the TrueCrypt License 3.0.
    5 
    6  Modifications and additions to the original source code (contained in this file)
    7  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
    8  and are governed by the Apache License 2.0 the full text of which is
    9  contained in the file License.txt included in VeraCrypt binary and source
   10  code distribution packages.
   11 */
   12 
   13 #include "Tcdefs.h"
   14 #include "Platform/Finally.h"
   15 #include "Platform/ForEach.h"
   16 #include "BootEncryption.h"
   17 #include "Dlgcode.h"
   18 #include "Language.h"
   19 #include "Mount.h"
   20 #include "Common/Resource.h"
   21 #include "Resource.h"
   22 #include "Xml.h"
   23 #include "Favorites.h"
   24 #include "Pkcs5.h"
   25 
   26 using namespace std;
   27 
   28 namespace VeraCrypt
   29 {
   30     vector <FavoriteVolume> FavoriteVolumes;
   31     vector <FavoriteVolume> SystemFavoriteVolumes;
   32     list <FavoriteVolume> FavoritesOnArrivalMountRequired;
   33     list <FavoriteVolume> FavoritesMountedOnArrivalStillConnected;
   34     HMENU FavoriteVolumesMenu;
   35 
   36 
   37     BOOL AddMountedVolumeToFavorites (HWND hwndDlg, int driveNo, bool systemFavorites)
   38     {
   39         VOLUME_PROPERTIES_STRUCT prop;
   40         DWORD bytesReturned;
   41 
   42         memset (&prop, 0, sizeof (prop));
   43         prop.driveNo = driveNo;
   44 
   45         if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &bytesReturned, NULL))
   46         {
   47             handleWin32Error (hwndDlg, SRC_POS);
   48             return FALSE;
   49         }
   50 
   51         FavoriteVolume favorite;
   52         favorite.MountPoint = L"X:\\";
   53         favorite.MountPoint[0] = (wchar_t) (prop.driveNo + L'A');
   54 
   55         favorite.Path = prop.wszVolume;
   56         if (favorite.Path.find (L"\\??\\") == 0)
   57             favorite.Path = favorite.Path.substr (4);
   58 
   59         if (wcslen (prop.wszLabel))
   60         {
   61             favorite.Label = prop.wszLabel;
   62             favorite.UseLabelInExplorer = true;
   63         }
   64 
   65         if (IsVolumeDeviceHosted (favorite.Path.c_str()))
   66         {
   67             // Get GUID path
   68             wstring volumeDevPath = favorite.Path;
   69 
   70             wchar_t resolvedVolumeDevPath[TC_MAX_PATH];
   71             if (ResolveSymbolicLink (volumeDevPath.c_str(), resolvedVolumeDevPath, sizeof(resolvedVolumeDevPath)))
   72                 volumeDevPath = resolvedVolumeDevPath;
   73 
   74             wchar_t volumeName[TC_MAX_PATH];
   75             HANDLE find = FindFirstVolume (volumeName, ARRAYSIZE (volumeName));
   76 
   77             if (find != INVALID_HANDLE_VALUE)
   78             {
   79                 do
   80                 {
   81                     wchar_t findVolumeDevPath[TC_MAX_PATH];
   82                     wstring vn = volumeName;
   83 
   84                     if (QueryDosDevice (vn.substr (4, vn.size() - 5).c_str(), findVolumeDevPath, ARRAYSIZE (findVolumeDevPath)) != 0
   85                         && volumeDevPath == findVolumeDevPath)
   86                     {
   87                         favorite.VolumePathId = volumeName;
   88                         break;
   89                     }
   90 
   91                 } while (FindNextVolume (find, volumeName, ARRAYSIZE (volumeName)));
   92 
   93                 FindVolumeClose (find);
   94             }
   95         }
   96 
   97         favorite.ReadOnly = prop.readOnly ? true : false;
   98         favorite.Removable = prop.removable ? true : false;
   99         favorite.SystemEncryption = prop.partitionInInactiveSysEncScope ? true : false;
  100         favorite.OpenExplorerWindow = (bExplore == TRUE);
  101         favorite.Pim = prop.volumePim;
  102         favorite.Pkcs5 = prop.pkcs5;
  103         favorite.TrueCryptMode = (prop.pkcs5Iterations == get_pkcs5_iteration_count(prop.pkcs5, 0, TRUE, prop.partitionInInactiveSysEncScope))? 1 : 0;
  104         memcpy (favorite.VolumeID, prop.volumeID, VOLUME_ID_SIZE);
  105 
  106         if (favorite.VolumePathId.empty()
  107             && IsVolumeDeviceHosted (favorite.Path.c_str())
  108             && favorite.Path.find (L"\\\\?\\Volume{") != 0)
  109         {
  110             Warning (favorite.Path.find (L"\\Partition0") == wstring::npos ? "FAVORITE_ADD_PARTITION_TYPE_WARNING" : "FAVORITE_ADD_DRIVE_DEV_WARNING", hwndDlg);
  111         }
  112 
  113         return OrganizeFavoriteVolumes (hwndDlg, systemFavorites, favorite);
  114     }
  115 
  116 
  117     static BOOL CALLBACK FavoriteVolumesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  118     {
  119         /* This dialog is used both for System Favorites and non-system Favorites.
  120 
  121         The following options have different meaning in System Favorites mode:
  122 
  123         IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT => MOUNT_SYSTEM_FAVORITES_ON_BOOT
  124         IDC_FAVORITE_DISABLE_HOTKEY     => DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  125 
  126         */
  127 
  128         WORD lw = LOWORD (wParam);
  129         WORD hw = HIWORD (wParam);
  130         static bool SystemFavoritesMode;
  131         static vector <FavoriteVolume> Favorites;
  132         static int SelectedItem;
  133         static HWND FavoriteListControl;
  134 
  135         switch (msg)
  136         {
  137         case WM_INITDIALOG:
  138             {
  139                 try
  140                 {
  141                     FavoriteListControl = GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST);
  142 
  143                     FavoriteVolumesDlgProcArguments *args = (FavoriteVolumesDlgProcArguments *) lParam;
  144                     SystemFavoritesMode = args->SystemFavorites;
  145 
  146                     LocalizeDialog (hwndDlg, SystemFavoritesMode ? "SYSTEM_FAVORITES_DLG_TITLE" : "IDD_FAVORITE_VOLUMES");
  147 
  148                     if (SystemFavoritesMode)
  149                     {
  150                         RECT rec;
  151 
  152                         BootEncryptionStatus bootEncStatus = BootEncryption (hwndDlg).GetStatus();
  153 
  154                         if (!bootEncStatus.DriveMounted)
  155                             throw ErrorException ("SYS_FAVORITES_REQUIRE_PBA", SRC_POS);
  156 
  157                         ShowWindow (GetDlgItem(hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON), SW_HIDE);
  158                         ShowWindow (GetDlgItem(hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL), SW_HIDE);
  159 
  160                         // MOUNT_SYSTEM_FAVORITES_ON_BOOT
  161 
  162                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), GetString ("MOUNT_SYSTEM_FAVORITES_ON_BOOT"));
  163 
  164                         // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  165 
  166                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), GetString ("DISABLE_NONADMIN_SYS_FAVORITES_ACCESS"));
  167 
  168                         // Group box
  169 
  170                         GetClientRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &rec);
  171 
  172                         SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, 0, 0,
  173                             rec.right,
  174                             rec.bottom - CompensateYDPI (95),
  175                             SWP_NOMOVE | SWP_NOZORDER);
  176 
  177                         InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
  178                     }
  179                     else
  180                     {
  181                         ShowWindow (GetDlgItem(hwndDlg, IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX), SW_HIDE);
  182                     }
  183 
  184                     Favorites.clear();
  185 
  186                     LVCOLUMNW column;
  187                     SendMessageW (FavoriteListControl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  188 
  189                     memset (&column, 0, sizeof (column));
  190                     column.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
  191                     column.pszText = GetString ("DRIVE");
  192                     column.cx = CompensateXDPI (38);
  193                     column.fmt = LVCFMT_CENTER;
  194                     SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 1, (LPARAM) &column);
  195 
  196                     ++column.iSubItem;
  197                     column.fmt = LVCFMT_LEFT;
  198                     column.pszText = GetString ("LABEL");
  199                     column.cx = CompensateXDPI (160);
  200                     SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 2, (LPARAM) &column);
  201 
  202                     ++column.iSubItem;
  203                     column.fmt = LVCFMT_LEFT;
  204                     column.pszText = GetString ("VOLUME");
  205                     column.cx = CompensateXDPI (330);
  206                     SendMessageW (FavoriteListControl, LVM_INSERTCOLUMNW, 3, (LPARAM) &column);
  207 
  208                     SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false);
  209 
  210                     if (SystemFavoritesMode)
  211                         LoadFavoriteVolumes (Favorites, true);
  212                     else
  213                         Favorites = FavoriteVolumes;
  214 
  215                     if (args->AddFavoriteVolume)
  216                         Favorites.push_back (args->NewFavoriteVolume);
  217 
  218                     FillListControl (FavoriteListControl, Favorites);
  219 
  220                     SelectedItem = -1;
  221 
  222                     if (args->AddFavoriteVolume)
  223                     {
  224                         ListView_SetItemState (FavoriteListControl, Favorites.size() - 1, LVIS_SELECTED, LVIS_SELECTED);
  225                         ListView_EnsureVisible (FavoriteListControl, Favorites.size() - 1, FALSE);
  226                     }
  227 
  228                     if (SystemFavoritesMode)
  229                         SetDlgItemTextW (hwndDlg, IDC_FAVORITES_HELP_LINK, GetString ("SYS_FAVORITES_HELP_LINK"));
  230 
  231                     ToHyperlink (hwndDlg, IDC_FAVORITES_HELP_LINK);
  232                 }
  233                 catch (Exception &e)
  234                 {
  235                     e.Show (hwndDlg);
  236                     EndDialog (hwndDlg, IDCLOSE);
  237                 }
  238             }
  239             return 1;
  240 
  241         case WM_COMMAND:
  242 
  243             switch (lw)
  244             {
  245             case IDOK:
  246 
  247                 /* Global System Favorites settings */
  248 
  249                 if (SystemFavoritesMode)
  250                 {
  251                     BootEncryption BootEncObj (NULL);
  252 
  253                     if (BootEncObj.GetStatus().DriveMounted)
  254                     {
  255                         try
  256                         {
  257                             uint32 reqConfig = IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT) ? TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES : 0;
  258                             if (reqConfig != (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES))
  259                                 BootEncObj.RegisterSystemFavoritesService (reqConfig ? TRUE : FALSE);
  260 
  261                             SetDriverConfigurationFlag (TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS, IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY));
  262                         }
  263                         catch (Exception &e)
  264                         {
  265                             e.Show (hwndDlg);
  266                         }
  267                     }
  268                 }
  269 
  270                 /* (System) Favorites list */
  271 
  272                 if (SelectedItem != -1 && !Favorites.empty())
  273                     SetFavoriteVolume (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode);
  274 
  275                 if (SaveFavoriteVolumes (hwndDlg, Favorites, SystemFavoritesMode))
  276                 {
  277                     if (!SystemFavoritesMode)
  278                     {
  279                         bMountFavoritesOnLogon = FALSE;
  280 
  281                         foreach (const FavoriteVolume &favorite, Favorites)
  282                         {
  283                             if (favorite.MountOnLogOn)
  284                             {
  285                                 bMountFavoritesOnLogon = TRUE;
  286                                 break;
  287                             }
  288                         }
  289 
  290                         if (!bEnableBkgTask || bCloseBkgTaskWhenNoVolumes || IsNonInstallMode())
  291                         {
  292                             foreach (const FavoriteVolume favorite, Favorites)
  293                             {
  294                                 if (favorite.MountOnArrival)
  295                                 {
  296                                     Warning ("FAVORITE_ARRIVAL_MOUNT_BACKGROUND_TASK_ERR", hwndDlg);
  297                                     break;
  298                                 }
  299                             }
  300                         }
  301 
  302                         FavoriteVolumes = Favorites;
  303 
  304                         ManageStartupSeq();
  305                         SaveSettings (hwndDlg);
  306                     }
  307                     else
  308                         SystemFavoriteVolumes = Favorites;
  309 
  310                     OnFavoriteVolumesUpdated();
  311                     LoadDriveLetters (hwndDlg, GetDlgItem (MainDlg, IDC_DRIVELIST), 0);
  312 
  313                     EndDialog (hwndDlg, IDOK);
  314                 }
  315 
  316                 return 1;
  317 
  318             case IDCANCEL:
  319                 EndDialog (hwndDlg, IDCLOSE);
  320                 return 1;
  321 
  322             case IDC_FAVORITE_MOVE_DOWN:
  323                 if (SelectedItem != -1 && Favorites.size() > (size_t) SelectedItem + 1)
  324                 {
  325                     swap (Favorites[SelectedItem], Favorites[SelectedItem + 1]);
  326 
  327                     FillListControl (FavoriteListControl, Favorites);
  328                     ++SelectedItem;
  329                     ListView_SetItemState (FavoriteListControl, SelectedItem, LVIS_SELECTED, LVIS_SELECTED);
  330                     ListView_EnsureVisible (FavoriteListControl, SelectedItem, FALSE);
  331                 }
  332                 return 1;
  333 
  334             case IDC_FAVORITE_MOVE_UP:
  335                 if (SelectedItem > 0)
  336                 {
  337                     swap (Favorites[SelectedItem], Favorites[SelectedItem - 1]);
  338 
  339                     FillListControl (FavoriteListControl, Favorites);
  340                     --SelectedItem;
  341                     ListView_SetItemState (FavoriteListControl, SelectedItem, LVIS_SELECTED, LVIS_SELECTED);
  342                     ListView_EnsureVisible (FavoriteListControl, SelectedItem, FALSE);
  343                 }
  344                 return 1;
  345 
  346             case IDC_FAVORITE_REMOVE:
  347                 if (SelectedItem != -1)
  348                 {
  349                     Favorites.erase (Favorites.begin() + SelectedItem);
  350                     FillListControl (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST), Favorites);
  351                     SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false);
  352                     SelectedItem = -1;
  353                 }
  354                 return 1;
  355 
  356 
  357             case IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT:   // Note that this option means "MOUNT_SYSTEM_FAVORITES_ON_BOOT" when SystemFavoritesMode is true
  358                 if (SystemFavoritesMode)
  359                 {
  360                     // MOUNT_SYSTEM_FAVORITES_ON_BOOT
  361 
  362                     if (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT))
  363                     {
  364                         WarningDirect ((wstring (GetString ("SYS_FAVORITES_KEYBOARD_WARNING")) + L"\n\n" + GetString ("BOOT_PASSWORD_CACHE_KEYBOARD_WARNING")).c_str(), hwndDlg);
  365 
  366                         if (!IsServerOS() && !IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY))
  367                             Info ("SYS_FAVORITES_ADMIN_ONLY_INFO", hwndDlg);
  368                     }
  369                 }
  370                 return 1;
  371 
  372             case IDC_FAVORITE_DISABLE_HOTKEY: // Note that this option means "DISABLE_NONADMIN_SYS_FAVORITES_ACCESS" when SystemFavoritesMode is true
  373                 if (SystemFavoritesMode)
  374                 {
  375                     // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  376 
  377                     if (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY))
  378                         WarningDirect ((wstring (GetString ("SYS_FAVORITES_ADMIN_ONLY_WARNING")) + L"\n\n" + GetString ("SETTING_REQUIRES_REBOOT")).c_str(), hwndDlg);
  379                     else
  380                         Warning ("SETTING_REQUIRES_REBOOT", hwndDlg);
  381                 }
  382                 return 1;
  383 
  384             case IDC_FAVORITES_HELP_LINK:
  385                 Applink (SystemFavoritesMode ? "sysfavorites" : "favorites");
  386                 return 1;
  387             case IDC_SHOW_PIM:
  388                 HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PIM, IDC_PIM, 0);
  389                 return 1;
  390 
  391             case IDC_PIM:
  392                 if (hw == EN_CHANGE)
  393                 {
  394                     int pim = GetPim (hwndDlg, IDC_PIM, -1);
  395                     if (pim > (SystemFavoritesMode? MAX_BOOT_PIM_VALUE: MAX_PIM_VALUE))
  396                     {
  397                         SetDlgItemText (hwndDlg, IDC_PIM, L"");
  398                         SetFocus (GetDlgItem(hwndDlg, IDC_PIM));
  399                         Warning (SystemFavoritesMode? "PIM_SYSENC_TOO_BIG": "PIM_TOO_BIG", hwndDlg);
  400                         return 1;
  401                     }
  402                 }
  403                 break;
  404             }
  405 
  406             return 0;
  407 
  408         case WM_NOTIFY:
  409             if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
  410             {
  411                 static bool reentry = false;
  412                 if (reentry)
  413                     break;
  414 
  415                 reentry = true;
  416 
  417                 if (SelectedItem != -1)
  418                 {
  419                     SetFavoriteVolume (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode);
  420                     FillListControlSubItems (FavoriteListControl, SelectedItem, Favorites[SelectedItem]);
  421                 }
  422 
  423                 SelectedItem = ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUMES_LIST), -1, LVIS_SELECTED);
  424 
  425                 if (SelectedItem != -1)
  426                     SetControls (hwndDlg, Favorites[SelectedItem], SystemFavoritesMode);
  427                 else
  428                     SetControls (hwndDlg, FavoriteVolume(), SystemFavoritesMode, false);
  429 
  430                 reentry = false;
  431                 return 1;
  432             }
  433             break;
  434 
  435         case WM_CLOSE:
  436             EndDialog (hwndDlg, IDCLOSE);
  437             return 1;
  438         case WM_CTLCOLORSTATIC:
  439             {
  440                 HDC hdc = (HDC) wParam;
  441                 HWND hw = (HWND) lParam;
  442                 if (hw == GetDlgItem(hwndDlg, IDC_FAVORITE_VOLUME_ID))
  443                 {
  444                     // This the favorite ID field. Make its background like normal edit
  445                     HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW);
  446                     ::SelectObject(hdc, hbr);
  447                     return (BOOL) hbr;
  448                 }
  449             }
  450             break;
  451         }
  452 
  453         return 0;
  454     }
  455 
  456 
  457     static void FillFavoriteVolumesMenu ()
  458     {
  459         while (DeleteMenu (FavoriteVolumesMenu, 7, MF_BYPOSITION)) { }
  460 
  461         if (FavoriteVolumes.empty())
  462             return;
  463 
  464         AppendMenu (FavoriteVolumesMenu, MF_SEPARATOR, 0, L"");
  465 
  466         int i = 0;
  467         foreach (const FavoriteVolume &favorite, FavoriteVolumes)
  468         {
  469             UINT flags = MF_STRING;
  470 
  471             if (favorite.DisconnectedDevice)
  472                 flags |= MF_GRAYED;
  473 
  474             wstring menuText = favorite.Path;
  475             if (favorite.DisconnectedDevice)
  476                 menuText = favorite.Label.empty() ? wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")" : L"";
  477 
  478             if (!favorite.Label.empty())
  479             {
  480                 if (favorite.DisconnectedDevice)
  481                     menuText = favorite.Label + L" " + menuText;
  482                 else
  483                     menuText = favorite.Label;
  484             }
  485 
  486             AppendMenuW (FavoriteVolumesMenu, flags, TC_FAVORITE_MENU_CMD_ID_OFFSET + i++,
  487                 (menuText + L"\t" + favorite.MountPoint.substr (0, 2)).c_str());
  488         }
  489     }
  490 
  491 
  492     static void FillListControl (HWND favoriteListControl, vector <FavoriteVolume> &favorites)
  493     {
  494         SendMessage (favoriteListControl, LVM_DELETEALLITEMS, 0, 0);
  495 
  496         int line = 0;
  497         foreach (const FavoriteVolume favorite, favorites)
  498         {
  499             ListItemAdd (favoriteListControl, line, (wchar_t *) favorite.MountPoint.substr (0, 2).c_str());
  500             FillListControlSubItems (favoriteListControl, line++, favorite);
  501         }
  502     }
  503 
  504 
  505     static void FillListControlSubItems (HWND FavoriteListControl, int line, const FavoriteVolume &favorite)
  506     {
  507         ListSubItemSet (FavoriteListControl, line, 1, (wchar_t *) favorite.Label.c_str());
  508 
  509         if (favorite.DisconnectedDevice)
  510             ListSubItemSet (FavoriteListControl, line, 2, (wchar_t *) (wstring (L"(") + GetString ("FAVORITE_DISCONNECTED_DEV") + L")").c_str());
  511         else
  512             ListSubItemSet (FavoriteListControl, line, 2, (wchar_t *) favorite.Path.c_str());
  513     }
  514 
  515 
  516     wstring GetFavoriteVolumeLabel (const wstring &volumePath, bool& useInExplorer)
  517     {
  518         foreach (const FavoriteVolume &favorite, FavoriteVolumes)
  519         {
  520             if (favorite.Path == volumePath)
  521             {
  522                 useInExplorer = favorite.UseLabelInExplorer;
  523                 return favorite.Label;
  524             }
  525         }
  526 
  527         foreach (const FavoriteVolume &favorite, SystemFavoriteVolumes)
  528         {
  529             if (favorite.Path == volumePath)
  530             {
  531                 useInExplorer = favorite.UseLabelInExplorer;
  532                 return favorite.Label;
  533             }
  534         }
  535 
  536         useInExplorer = false;
  537         return wstring();
  538     }
  539 
  540 
  541     void LoadFavoriteVolumes ()
  542     {
  543         LoadFavoriteVolumes (FavoriteVolumes, false);
  544 
  545         try
  546         {
  547             LoadFavoriteVolumes (SystemFavoriteVolumes, true, true);
  548         }
  549         catch (...) { } // Ignore errors as SystemFavoriteVolumes list is used only for resolving volume paths to labels
  550 
  551         OnFavoriteVolumesUpdated();
  552     }
  553 
  554 
  555     void LoadFavoriteVolumes (vector <FavoriteVolume> &favorites, bool systemFavorites, bool noUacElevation)
  556     {
  557         favorites.clear();
  558         wstring favoritesFilePath = systemFavorites ? GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false) : GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES);
  559 
  560         if (systemFavorites && !IsAdmin() && !noUacElevation)
  561         {
  562             favoritesFilePath = GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES);
  563 
  564             try
  565             {
  566                 BootEncryption bootEnc (MainDlg);
  567                 bootEnc.CopyFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).c_str(), favoritesFilePath.c_str());
  568             }
  569             catch (SystemException &e)
  570             {
  571                 if (e.ErrorCode == ERROR_FILE_NOT_FOUND)
  572                     return;
  573 
  574                 throw;
  575             }
  576         }
  577 
  578         DWORD size;
  579         char *favoritesXml = LoadFile (favoritesFilePath.c_str(), &size);
  580 
  581         if (systemFavorites && !IsAdmin() && !noUacElevation)
  582             DeleteFile (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES));
  583 
  584         char *xml = favoritesXml;
  585         char mountPoint[MAX_PATH], volume[MAX_PATH];
  586 
  587         if (xml == NULL)
  588             return;
  589 
  590         while (xml = XmlFindElement (xml, "volume"))
  591         {
  592             FavoriteVolume favorite;
  593 
  594             XmlGetAttributeText (xml, "mountpoint", mountPoint, sizeof (mountPoint));
  595             favorite.MountPoint = Utf8StringToWide (mountPoint);
  596 
  597             XmlGetNodeText (xml, volume, sizeof (volume));
  598             favorite.Path = Utf8StringToWide (volume);
  599 
  600             char label[1024];
  601 
  602             XmlGetAttributeText (xml, "ID", label, sizeof (label));
  603             if (strlen (label) == (2*VOLUME_ID_SIZE))
  604             {
  605                 std::vector<byte> arr;
  606                 if (HexWideStringToArray (Utf8StringToWide (label).c_str(), arr) && arr.size() == VOLUME_ID_SIZE)
  607                 {
  608                     memcpy (favorite.VolumeID, &arr[0], VOLUME_ID_SIZE);
  609                 }
  610             }
  611 
  612             XmlGetAttributeText (xml, "label", label, sizeof (label));
  613             favorite.Label = Utf8StringToWide (label);
  614 
  615             XmlGetAttributeText (xml, "pim", label, sizeof (label));
  616             if (strlen(label) == 0)
  617             {
  618                 /* support old attribute name before it was changed to PIM*/
  619                 XmlGetAttributeText (xml, "pin", label, sizeof (label));
  620             }
  621             if (label[0])
  622             {
  623                 favorite.Pim = strtol (label, NULL, 10);
  624                 if (favorite.Pim < 0 || favorite.Pim > (systemFavorites? MAX_BOOT_PIM_VALUE : MAX_PIM_VALUE))
  625                     favorite.Pim = -1;
  626             }
  627             else
  628                 favorite.Pim = -1;
  629 
  630             char boolVal[2];
  631             XmlGetAttributeText (xml, "readonly", boolVal, sizeof (boolVal));
  632             if (boolVal[0])
  633                 favorite.ReadOnly = (boolVal[0] == '1');
  634 
  635             XmlGetAttributeText (xml, "removable", boolVal, sizeof (boolVal));
  636             if (boolVal[0])
  637                 favorite.Removable = (boolVal[0] == '1');
  638 
  639             XmlGetAttributeText (xml, "system", boolVal, sizeof (boolVal));
  640             if (boolVal[0])
  641                 favorite.SystemEncryption = (boolVal[0] == '1');
  642 
  643             XmlGetAttributeText (xml, "noHotKeyMount", boolVal, sizeof (boolVal));
  644             if (boolVal[0])
  645                 favorite.DisableHotkeyMount = (boolVal[0] == '1');
  646 
  647             XmlGetAttributeText (xml, "openExplorerWindow", boolVal, sizeof (boolVal));
  648             if (boolVal[0])
  649                 favorite.OpenExplorerWindow = (boolVal[0] == '1');
  650 
  651             XmlGetAttributeText (xml, "mountOnArrival", boolVal, sizeof (boolVal));
  652             if (boolVal[0])
  653                 favorite.MountOnArrival = (boolVal[0] == '1');
  654 
  655             XmlGetAttributeText (xml, "mountOnLogOn", boolVal, sizeof (boolVal));
  656             if (boolVal[0])
  657                 favorite.MountOnLogOn = (boolVal[0] == '1');
  658 
  659             XmlGetAttributeText (xml, "useLabelInExplorer", boolVal, sizeof (boolVal));
  660             if (boolVal[0])
  661                 favorite.UseLabelInExplorer = (boolVal[0] == '1') && !favorite.ReadOnly;
  662 
  663             XmlGetAttributeText (xml, "useVolumeID", boolVal, sizeof (boolVal));
  664             if (boolVal[0])
  665                 favorite.UseVolumeID = (boolVal[0] == '1') && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID));
  666 
  667             if (favorite.Path.find (L"\\\\?\\Volume{") == 0 && favorite.Path.rfind (L"}\\") == favorite.Path.size() - 2)
  668             {
  669                 wstring resolvedPath = VolumeGuidPathToDevicePath (favorite.Path);
  670                 if (!resolvedPath.empty())
  671                 {
  672                     favorite.DisconnectedDevice = false;
  673                     favorite.VolumePathId = favorite.Path;
  674                     favorite.Path = resolvedPath;
  675                 }
  676                 else
  677                     favorite.DisconnectedDevice = true;
  678             }
  679 
  680             XmlGetAttributeText (xml, "TrueCryptMode", boolVal, sizeof (boolVal));
  681             if (boolVal[0])
  682                 favorite.TrueCryptMode = (boolVal[0] == '1')? 1 : 0;
  683             else
  684                 favorite.TrueCryptMode = -1;
  685             
  686             if (favorite.TrueCryptMode > 0)
  687                 favorite.Pim = 0;
  688 
  689             XmlGetAttributeText (xml, "pkcs5", label, sizeof (label));
  690             if (label[0])
  691                 favorite.Pkcs5 = strtol (label, NULL, 10);
  692             else
  693                 favorite.Pkcs5 = -1;
  694             if  (   (favorite.Pkcs5 != -1) 
  695                 &&  (  (favorite.Pkcs5 < FIRST_PRF_ID)
  696                         || (favorite.Pkcs5 > LAST_PRF_ID)
  697                         || (favorite.TrueCryptMode == 1 && (0 == get_pkcs5_iteration_count (favorite.Pkcs5, 0, TRUE, favorite.SystemEncryption? TRUE : FALSE)))
  698                     )
  699                 )
  700             {
  701                 favorite.Pkcs5 = -1;
  702             }
  703 
  704             favorites.push_back (favorite);
  705             xml++;
  706         }
  707 
  708         free (favoritesXml);
  709     }
  710 
  711 
  712     static void OnFavoriteVolumesUpdated ()
  713     {
  714         FillFavoriteVolumesMenu();
  715 
  716         FavoritesOnArrivalMountRequired.clear();
  717 
  718         foreach (const FavoriteVolume favorite, FavoriteVolumes)
  719         {
  720             if (favorite.MountOnArrival)
  721             {
  722                 FavoritesOnArrivalMountRequired.push_back (favorite);
  723 
  724                 if (IsMountedVolume (favorite.Path.c_str()))
  725                 {
  726                     bool present = false;
  727 
  728                     foreach (const FavoriteVolume favoriteConnected, FavoritesMountedOnArrivalStillConnected)
  729                     {
  730                         if (favorite.Path == favoriteConnected.Path)
  731                         {
  732                             present = true;
  733                             break;
  734                         }
  735                     }
  736 
  737                     if (!present)
  738                         FavoritesMountedOnArrivalStillConnected.push_back (favorite);
  739                 }
  740             }
  741         }
  742     }
  743 
  744 
  745     BOOL OrganizeFavoriteVolumes (HWND hwndDlg, bool systemFavorites, const FavoriteVolume &newFavorite)
  746     {
  747         FavoriteVolumesDlgProcArguments args;
  748         args.SystemFavorites = systemFavorites;
  749 
  750         if (!newFavorite.Path.empty())
  751         {
  752             args.AddFavoriteVolume = true;
  753             args.NewFavoriteVolume = newFavorite;
  754         }
  755         else
  756             args.AddFavoriteVolume = false;
  757 
  758         return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_FAVORITE_VOLUMES), hwndDlg, (DLGPROC) FavoriteVolumesDlgProc, (LPARAM) &args) == IDOK;
  759     }
  760 
  761 
  762     bool SaveFavoriteVolumes (HWND hwndDlg, const vector <FavoriteVolume> &favorites, bool systemFavorites)
  763     {
  764         FILE *f;
  765         int cnt = 0;
  766 
  767         f = _wfopen (GetConfigPath (systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES), L"w,ccs=UTF-8");
  768         if (f == NULL)
  769         {
  770             handleWin32Error (MainDlg, SRC_POS);
  771             return false;
  772         }
  773 
  774         XmlWriteHeader (f);
  775         fputws (L"\n\t<favorites>", f);
  776 
  777         foreach (const FavoriteVolume &favorite, favorites)
  778         {
  779             wchar_t tq[2048];
  780 
  781             if (systemFavorites && favorite.Path.find (L"\\\\") == 0 && favorite.Path.find (L"Volume{") == wstring::npos)
  782                 Warning ("SYSTEM_FAVORITE_NETWORK_PATH_ERR", hwndDlg);
  783 
  784             XmlQuoteTextW (!favorite.VolumePathId.empty() ? favorite.VolumePathId.c_str() : favorite.Path.c_str(), tq, ARRAYSIZE (tq));
  785 
  786             wstring s = L"\n\t\t<volume mountpoint=\"" + favorite.MountPoint + L"\"";
  787 
  788             if (!IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)))
  789                 s += L" ID=\"" + ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)) + L"\"";
  790 
  791             if (!favorite.Label.empty())
  792                 s += L" label=\"" + favorite.Label + L"\"";
  793 
  794             if ((favorite.Pim >= 0) && (favorite.TrueCryptMode <= 0))
  795                 s += L" pim=\"" + IntToWideString(favorite.Pim) + L"\"";
  796 
  797             if (favorite.Pkcs5 > 0)
  798                 s += L" pkcs5=\"" + IntToWideString(favorite.Pkcs5) + L"\"";
  799 
  800             if (favorite.TrueCryptMode > 0)
  801                 s += L" TrueCryptMode=\"1\"";
  802             else if (favorite.TrueCryptMode == 0)
  803                 s += L" TrueCryptMode=\"0\"";
  804 
  805             if (favorite.ReadOnly)
  806                 s += L" readonly=\"1\"";
  807 
  808             if (favorite.Removable)
  809                 s += L" removable=\"1\"";
  810 
  811             if (favorite.SystemEncryption)
  812                 s += L" system=\"1\"";
  813 
  814             if (favorite.MountOnArrival)
  815                 s += L" mountOnArrival=\"1\"";
  816 
  817             if (favorite.MountOnLogOn)
  818                 s += L" mountOnLogOn=\"1\"";
  819 
  820             if (favorite.DisableHotkeyMount)
  821                 s += L" noHotKeyMount=\"1\"";
  822 
  823             if (favorite.OpenExplorerWindow)
  824                 s += L" openExplorerWindow=\"1\"";
  825 
  826             if (favorite.UseLabelInExplorer && !favorite.ReadOnly)
  827                 s += L" useLabelInExplorer=\"1\"";
  828 
  829             if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)))
  830                 s += L" useVolumeID=\"1\"";
  831 
  832             s += L">" + wstring (tq) + L"</volume>";
  833 
  834             fwprintf (f, L"%ws", s.c_str());
  835             cnt++;
  836         }
  837 
  838         fputws (L"\n\t</favorites>", f);
  839         XmlWriteFooter (f);
  840 
  841         if (!CheckFileStreamWriteErrors (hwndDlg, f, systemFavorites ? TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES : TC_APPD_FILENAME_FAVORITE_VOLUMES))
  842         {
  843             fclose (f);
  844             return false;
  845         }
  846 
  847         fclose (f);
  848 
  849         BootEncryption bootEnc (MainDlg);
  850 
  851         if (systemFavorites)
  852         {
  853             finally_do ({ _wremove (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES)); });
  854 
  855             try
  856             {
  857                 bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).c_str());
  858             }
  859             catch (UserAbort&) { return false; }
  860             catch (...) { }
  861 
  862             try
  863             {
  864                 if (cnt != 0)
  865                 {
  866                     bootEnc.CopyFileAdmin (GetConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES), GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).c_str());
  867 
  868                     if (!(ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES))
  869                         Info ("SYS_FAVORITE_VOLUMES_SAVED", hwndDlg);
  870                 }
  871             }
  872             catch (Exception &e)
  873             {
  874                 e.Show (NULL);
  875             }
  876         }
  877 
  878         if (cnt == 0)
  879         {
  880             if (systemFavorites)
  881             {
  882                 try
  883                 {
  884                     bootEnc.DeleteFileAdmin (GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false).c_str());
  885                 }
  886                 catch (...) { }
  887             }
  888             else
  889                 _wremove (GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES));
  890         }
  891 
  892         return true;
  893     }
  894 
  895 
  896     static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable)
  897     {
  898         BOOL bIsDevice = favorite.DisconnectedDevice || IsVolumeDeviceHosted (favorite.Path.c_str()) || !enable;
  899         if (favorite.Pim > 0)
  900         {
  901             wchar_t szTmp[MAX_PIM + 1];
  902             StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", favorite.Pim);
  903             SetDlgItemText (hwndDlg, IDC_PIM, szTmp);
  904         }
  905         else
  906             SetDlgItemText (hwndDlg, IDC_PIM, L"");
  907         SetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, favorite.Label.c_str());
  908         SetCheckBox (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER, favorite.UseLabelInExplorer);
  909         SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON, favorite.MountOnLogOn);
  910         SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL, favorite.MountOnArrival);
  911         SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_READONLY, favorite.ReadOnly);
  912         SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE, favorite.Removable);
  913         SetCheckBox (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID, favorite.UseVolumeID && bIsDevice);
  914         SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, (favorite.TrueCryptMode > 0)? TRUE : FALSE);
  915 
  916         /* Populate the PRF algorithms list */
  917         int nIndex, i, nSelected = 0;
  918         HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
  919         SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
  920 
  921         nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
  922         SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
  923 
  924         for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
  925         {
  926             if (!favorite.SystemEncryption || (favorite.TrueCryptMode != 1) || (i == RIPEMD160))
  927             {
  928                 nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
  929                 SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
  930                 if (favorite.Pkcs5 == i)
  931                     nSelected = nIndex;
  932             }
  933         }
  934 
  935         if (favorite.Pkcs5 >= 0)
  936             SendMessage (hComboBox, CB_SETCURSEL, nSelected, 0);
  937 
  938         if (IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)) || !bIsDevice)
  939         {
  940             SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, L"");
  941         }
  942         else
  943             SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)).c_str());
  944 
  945         if (systemFavoritesMode)
  946         {
  947             uint32 driverConfig = ReadDriverConfigurationFlags();
  948 
  949             // MOUNT_SYSTEM_FAVORITES_ON_BOOT
  950             CheckDlgButton (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, (driverConfig & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES) ? BST_CHECKED : BST_UNCHECKED);
  951 
  952             // DISABLE_NONADMIN_SYS_FAVORITES_ACCESS
  953             CheckDlgButton (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY, (driverConfig & TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS) ? BST_CHECKED : BST_UNCHECKED);
  954         }
  955         else
  956         {
  957             SetCheckBox (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, favorite.OpenExplorerWindow);
  958             SetCheckBox (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY, favorite.DisableHotkeyMount);
  959         }
  960 
  961         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOVE_UP), enable);
  962         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOVE_DOWN), enable);
  963         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_REMOVE), enable);
  964         EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), enable && !favorite.SystemEncryption);
  965         EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), enable && !favorite.SystemEncryption);
  966         EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), enable && !favorite.SystemEncryption);                      
  967         EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), enable);
  968         EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), enable);
  969         EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PIM), enable);
  970         EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), enable);
  971         EnableWindow (GetDlgItem (hwndDlg, IDT_FAVORITE_LABEL), enable);
  972         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_LABEL), enable);
  973         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER), enable);
  974         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON), enable && !systemFavoritesMode);
  975         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL), enable && !systemFavoritesMode);
  976         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_READONLY), enable);
  977         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE), enable);
  978         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), enable || systemFavoritesMode);
  979         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), enable || systemFavoritesMode);
  980         EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), enable && bIsDevice);
  981         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), enable && bIsDevice);
  982         EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), enable && bIsDevice && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)));
  983 
  984         ShowWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
  985         ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
  986         ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE);
  987 
  988         // Group box
  989         RECT boxRect, checkRect, labelRect;
  990 
  991         GetWindowRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &boxRect);
  992         GetWindowRect (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), &checkRect);
  993         GetWindowRect (GetDlgItem (hwndDlg, IDT_VOLUME_ID), &labelRect);
  994 
  995         if (!bIsDevice && (boxRect.top < checkRect.top))
  996         {
  997             POINT pt = {boxRect.left, checkRect.bottom};
  998             ScreenToClient (hwndDlg, &pt);
  999             SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y,
 1000                 boxRect.right - boxRect.left,
 1001                 boxRect.bottom - checkRect.bottom,
 1002                 SWP_NOZORDER);
 1003 
 1004             InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
 1005         }
 1006 
 1007         if (bIsDevice && (boxRect.top >= checkRect.top))
 1008         {
 1009             POINT pt = {boxRect.left, labelRect.top - CompensateYDPI (10)};
 1010             ScreenToClient (hwndDlg, &pt);
 1011             SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y,
 1012                 boxRect.right - boxRect.left,
 1013                 boxRect.bottom - labelRect.top + CompensateYDPI (10),
 1014                 SWP_NOZORDER);
 1015 
 1016             InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE);
 1017         }
 1018     }
 1019 
 1020 
 1021     static void SetFavoriteVolume (HWND hwndDlg, FavoriteVolume &favorite, bool systemFavoritesMode)
 1022     {
 1023         wchar_t label[1024];
 1024         if (GetDlgItemTextW (hwndDlg, IDC_FAVORITE_LABEL, label, ARRAYSIZE (label)) != 0)
 1025         {
 1026             favorite.Label = label;
 1027 
 1028             for (size_t i = 0; i < favorite.Label.size(); ++i)
 1029             {
 1030                 if (favorite.Label[i] == L'"')
 1031                     favorite.Label.at (i) = L'\'';
 1032             }
 1033         }
 1034         else
 1035             favorite.Label.clear();
 1036 
 1037         favorite.Pim = GetPim (hwndDlg, IDC_PIM, -1);
 1038         favorite.UseLabelInExplorer = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER) != 0);
 1039         favorite.UseVolumeID = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID) != 0);
 1040         int nSelected = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0);
 1041         if (nSelected != CB_ERR)
 1042             favorite.Pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, nSelected, 0);
 1043         else
 1044             favorite.Pkcs5 = -1;
 1045         BOOL selectedTrueCryptMode = (IsDlgButtonChecked (hwndDlg, IDC_TRUECRYPT_MODE) != 0)? 1 : 0;
 1046         if ((favorite.TrueCryptMode >= 0) || selectedTrueCryptMode)
 1047             favorite.TrueCryptMode = selectedTrueCryptMode;
 1048 
 1049         if (favorite.TrueCryptMode == 1)
 1050         {
 1051             if ((favorite.Pkcs5 > 0) && !is_pkcs5_prf_supported (favorite.Pkcs5, TRUE, favorite.SystemEncryption? PRF_BOOT_MBR : PRF_BOOT_NO))
 1052             {
 1053                 Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
 1054                 favorite.Pkcs5 = 0;
 1055             }
 1056 
 1057             if (favorite.Pim > 0)
 1058             {
 1059                 Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
 1060                 favorite.Pim = 0;
 1061             }
 1062         }
 1063 
 1064         favorite.ReadOnly = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_READONLY) != 0);
 1065         favorite.Removable = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE) != 0);
 1066 
 1067         if (!systemFavoritesMode)
 1068         {
 1069             favorite.MountOnLogOn = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_ON_LOGON) != 0);
 1070             favorite.MountOnArrival = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL) != 0);
 1071             favorite.DisableHotkeyMount = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY) != 0);
 1072             favorite.OpenExplorerWindow = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT) != 0);
 1073         }
 1074 
 1075         if (favorite.VolumePathId.empty()
 1076             && IsVolumeDeviceHosted (favorite.Path.c_str())
 1077             && favorite.Path.find (L"\\\\?\\Volume{") != 0)
 1078         {
 1079             bool partition = (favorite.Path.find (L"\\Partition0") == wstring::npos);
 1080 
 1081             if (!favorite.Label.empty())
 1082             {
 1083                 ErrorDirect ((GetString (partition ? "FAVORITE_LABEL_PARTITION_TYPE_ERR" : "FAVORITE_LABEL_DEVICE_PATH_ERR") + wstring (L"\n\n") + favorite.Path).c_str(), hwndDlg);
 1084                 favorite.Label.clear();
 1085             }
 1086 
 1087             if (favorite.MountOnArrival)
 1088             {
 1089                 ErrorDirect ((GetString (partition ? "FAVORITE_ARRIVAL_MOUNT_PARTITION_TYPE_ERR" : "FAVORITE_ARRIVAL_MOUNT_DEVICE_PATH_ERR") + wstring (L"\n\n") + favorite.Path).c_str(), hwndDlg);
 1090                 favorite.MountOnArrival = false;
 1091             }
 1092         }
 1093 
 1094         if (favorite.MountOnArrival && favorite.Path.find (L"\\\\") == 0 && favorite.Path.find (L"Volume{") == wstring::npos)
 1095         {
 1096             Error ("FAVORITE_ARRIVAL_MOUNT_NETWORK_PATH_ERR", hwndDlg);
 1097             favorite.MountOnArrival = false;
 1098         }
 1099     }
 1100 
 1101 
 1102     void UpdateDeviceHostedFavoriteVolumes ()
 1103     {
 1104         try
 1105         {
 1106             LoadFavoriteVolumes();
 1107         }
 1108         catch (Exception &e)
 1109         {
 1110             e.Show (MainDlg);
 1111         }
 1112     }
 1113 }