"Fossies" - the Fresh Open Source Software Archive

Member "src/Mount/Mount.c" (10 Oct 2018, 352836 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 "Mount.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.22_Source_vs_1.23_Source.

    1 /*
    2  Legal Notice: Some portions of the source code contained in this file were
    3  derived from the source code of TrueCrypt 7.1a, which is
    4  Copyright (c) 2003-2012 TrueCrypt Developers Association and which is
    5  governed by the TrueCrypt License 3.0, also from the source code of
    6  Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux
    7  and which is governed by the 'License Agreement for Encryption for the Masses'
    8  Modifications and additions to the original source code (contained in this file)
    9  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
   10  and are governed by the Apache License 2.0 the full text of which is
   11  contained in the file License.txt included in VeraCrypt binary and source
   12  code distribution packages. */
   13 
   14 #include "Tcdefs.h"
   15 #include "cpu.h"
   16 
   17 #include <time.h>
   18 #include <math.h>
   19 #include <dbt.h>
   20 #include <fcntl.h>
   21 #include <io.h>
   22 #include <shlobj.h>
   23 #include <sys/stat.h>
   24 #include <windowsx.h>
   25 
   26 #include "Apidrvr.h"
   27 #include "BootEncryption.h"
   28 #include "Cmdline.h"
   29 #include "Crypto.h"
   30 #include "Dlgcode.h"
   31 #include "Combo.h"
   32 #include "Favorites.h"
   33 #include "Hotkeys.h"
   34 #include "Keyfiles.h"
   35 #include "Language.h"
   36 #include "MainCom.h"
   37 #include "Mount.h"
   38 #include "Pkcs5.h"
   39 #include "Random.h"
   40 #include "Registry.h"
   41 #include "Resource.h"
   42 #include "Password.h"
   43 #include "Xml.h"
   44 #include "../Boot/Windows/BootCommon.h"
   45 #include "../Common/Dictionary.h"
   46 #include "../Common/Common.h"
   47 #include "../Common/Resource.h"
   48 #include "../Common/SecurityToken.h"
   49 #include "../Platform/Finally.h"
   50 #include "../Platform/ForEach.h"
   51 #include "../Setup/SelfExtract.h"
   52 
   53 #include <Strsafe.h>
   54 
   55 #import <msxml6.dll> no_auto_exclude
   56 
   57 #include <wtsapi32.h>
   58 
   59 typedef BOOL (WINAPI *WTSREGISTERSESSIONNOTIFICATION)(HWND, DWORD);
   60 typedef BOOL (WINAPI *WTSUNREGISTERSESSIONNOTIFICATION)(HWND);
   61 
   62 using namespace VeraCrypt;
   63 
   64 enum timer_ids
   65 {
   66     TIMER_ID_MAIN = 0xff,
   67     TIMER_ID_KEYB_LAYOUT_GUARD,
   68     TIMER_ID_UPDATE_DEVICE_LIST,
   69     TIMER_ID_CHECK_FOREGROUND
   70 };
   71 
   72 enum hidden_os_read_only_notif_mode
   73 {
   74     TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE = 0,
   75     TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT,
   76     TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED
   77 };
   78 
   79 #define TIMER_INTERVAL_MAIN                 500
   80 #define TIMER_INTERVAL_KEYB_LAYOUT_GUARD    10
   81 #define TIMER_INTERVAL_UPDATE_DEVICE_LIST   1000
   82 #define TIMER_INTERVAL_CHECK_FOREGROUND     500
   83 
   84 BootEncryption          *BootEncObj = NULL;
   85 BootEncryptionStatus    BootEncStatus;
   86 BootEncryptionStatus    RecentBootEncStatus;
   87 
   88 BOOL bExplore = FALSE;              /* Display explorer window after mount */
   89 BOOL bBeep = FALSE;                 /* Donot beep after mount */
   90 wchar_t szFileName[TC_MAX_PATH+1];      /* Volume to mount */
   91 wchar_t szDriveLetter[3];               /* Drive Letter to mount */
   92 wchar_t commandLineDrive = 0;
   93 BOOL bCacheInDriver = FALSE;        /* Cache any passwords we see */
   94 BOOL bCacheInDriverDefault = FALSE;
   95 BOOL bCacheDuringMultipleMount = FALSE;
   96 BOOL bCmdCacheDuringMultipleMount = FALSE;
   97 BOOL bIncludePimInCache = FALSE;
   98 BOOL bTryEmptyPasswordWhenKeyfileUsed = FALSE;
   99 BOOL bCmdTryEmptyPasswordWhenKeyfileUsed = FALSE;
  100 BOOL bCmdTryEmptyPasswordWhenKeyfileUsedValid = FALSE;
  101 BOOL bHistoryCmdLine = FALSE;       /* History control is always disabled */
  102 BOOL bUseDifferentTrayIconIfVolMounted = TRUE;
  103 BOOL bCloseDismountedWindows=TRUE;  /* Close all open explorer windows of dismounted volume */
  104 BOOL bWipeCacheOnExit = FALSE;      /* Wipe password from chace on exit */
  105 BOOL bWipeCacheOnAutoDismount = TRUE;
  106 BOOL bEnableBkgTask = FALSE;
  107 BOOL bCloseBkgTaskWhenNoVolumes = FALSE;
  108 BOOL bDismountOnLogOff = TRUE;
  109 BOOL bDismountOnSessionLocked = TRUE;
  110 BOOL bDismountOnScreenSaver = TRUE;
  111 BOOL bDismountOnPowerSaving = FALSE;
  112 BOOL bForceAutoDismount = TRUE;
  113 BOOL bForceMount = FALSE;           /* Mount volume even if host file/device already in use */
  114 BOOL bForceUnmount = FALSE;         /* Unmount volume even if it cannot be locked */
  115 BOOL bWipe = FALSE;                 /* Wipe driver passwords */
  116 BOOL bAuto = FALSE;                 /* Do everything without user input */
  117 BOOL LogOn = FALSE;
  118 BOOL bAutoMountDevices = FALSE;     /* Auto-mount devices */
  119 BOOL bAutoMountFavorites = FALSE;
  120 BOOL bPlaySoundOnSuccessfulHkDismount = TRUE;
  121 BOOL bDisplayBalloonOnSuccessfulHkDismount = TRUE;
  122 BOOL bHibernationPreventionNotified = FALSE;    /* TRUE if the user has been notified that hibernation was prevented (system encryption) during the session. */
  123 BOOL bHiddenSysLeakProtNotifiedDuringSession = FALSE;   /* TRUE if the user has been notified during the session that unencrypted filesystems and non-hidden TrueCrypt volumes are mounted as read-only under hidden OS. */
  124 BOOL CloseSecurityTokenSessionsAfterMount = FALSE;
  125 
  126 BOOL Quit = FALSE;                  /* Exit after processing command line */
  127 BOOL ComServerMode = FALSE;
  128 BOOL ServiceMode = FALSE;
  129 BOOL UsePreferences = TRUE;
  130 
  131 BOOL bSystemIsGPT = FALSE;
  132 wchar_t szDefaultRescueDiskName[TC_MAX_PATH+1];
  133 wchar_t szRescueDiskExtension[4];
  134 
  135 int HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE;
  136 int MaxVolumeIdleTime = -120;
  137 int nCurrentShowType = 0;           /* current display mode, mount, unmount etc */
  138 int nSelectedDriveIndex = -1;       /* Item number of selected drive */
  139 
  140 int cmdUnmountDrive = -2;           /* Volume drive letter to unmount (-1 = all) */
  141 Password VolumePassword;            /* Password used for mounting volumes */
  142 Password CmdVolumePassword;         /* Password passed from command line */
  143 int VolumePkcs5 = 0;
  144 int CmdVolumePkcs5 = 0;
  145 int VolumePim = -1;
  146 int CmdVolumePim = -1;
  147 int DefaultVolumePkcs5 = 0;
  148 BOOL VolumeTrueCryptMode = FALSE;
  149 BOOL CmdVolumeTrueCryptMode = FALSE;
  150 BOOL DefaultVolumeTrueCryptMode = FALSE;
  151 BOOL CmdVolumePasswordValid = FALSE;
  152 MountOptions CmdMountOptions;
  153 BOOL CmdMountOptionsValid = FALSE;
  154 MountOptions mountOptions;
  155 MountOptions defaultMountOptions;
  156 KeyFile *FirstCmdKeyFile;
  157 
  158 HBITMAP hbmLogoBitmapRescaled = NULL;
  159 wchar_t OrigKeyboardLayout [8+1] = L"00000409";
  160 BOOL bKeyboardLayoutChanged = FALSE;        /* TRUE if the keyboard layout was changed to the standard US keyboard layout (from any other layout). */
  161 BOOL bKeybLayoutAltKeyWarningShown = FALSE; /* TRUE if the user has been informed that it is not possible to type characters by pressing keys while the right Alt key is held down. */
  162 
  163 static KeyFilesDlgParam             hidVolProtKeyFilesParam;
  164 
  165 static MOUNT_LIST_STRUCT    LastKnownMountList = {0};
  166 VOLUME_NOTIFICATIONS_LIST   VolumeNotificationsList;
  167 static DWORD                LastKnownLogicalDrives;
  168 
  169 static HANDLE TaskBarIconMutex = NULL;
  170 static BOOL MainWindowHidden = FALSE;
  171 static int pwdChangeDlgMode = PCDM_CHANGE_PASSWORD;
  172 static int bSysEncPwdChangeDlgMode = FALSE;
  173 static int bPrebootPasswordDlgMode = FALSE;
  174 static int NoCmdLineArgs;
  175 static BOOL CmdLineVolumeSpecified;
  176 static int LastDriveListVolumeColumnWidth;
  177 // WTS handling
  178 static HMODULE hWtsLib = NULL;
  179 static WTSREGISTERSESSIONNOTIFICATION   fnWtsRegisterSessionNotification = NULL;
  180 static WTSUNREGISTERSESSIONNOTIFICATION fnWtsUnRegisterSessionNotification = NULL;
  181 
  182 static void RegisterWtsNotification(HWND hWnd)
  183 {
  184     if (!hWtsLib)
  185     {
  186         wchar_t dllPath[MAX_PATH];
  187         if (GetSystemDirectory(dllPath, MAX_PATH))
  188             StringCbCatW(dllPath, sizeof(dllPath), L"\\wtsapi32.dll");
  189         else
  190             StringCbCopyW(dllPath, sizeof(dllPath), L"c:\\Windows\\System32\\wtsapi32.dll");
  191 
  192         hWtsLib = LoadLibrary(dllPath);
  193         if (hWtsLib)
  194         {
  195             fnWtsRegisterSessionNotification = (WTSREGISTERSESSIONNOTIFICATION) GetProcAddress(hWtsLib, "WTSRegisterSessionNotification" );
  196             fnWtsUnRegisterSessionNotification = (WTSUNREGISTERSESSIONNOTIFICATION) GetProcAddress(hWtsLib, "WTSUnRegisterSessionNotification" );
  197             if (    !fnWtsRegisterSessionNotification
  198                 ||  !fnWtsUnRegisterSessionNotification
  199                 ||  !fnWtsRegisterSessionNotification( hWnd, NOTIFY_FOR_THIS_SESSION )
  200                 )
  201             {
  202                 fnWtsRegisterSessionNotification = NULL;
  203                 fnWtsUnRegisterSessionNotification = NULL;
  204                 FreeLibrary(hWtsLib);
  205                 hWtsLib = NULL;
  206             }
  207         }
  208     }
  209 }
  210 
  211 static void UnregisterWtsNotification(HWND hWnd)
  212 {
  213     if (hWtsLib && fnWtsUnRegisterSessionNotification)
  214     {
  215         fnWtsUnRegisterSessionNotification(hWnd);
  216         FreeLibrary(hWtsLib);
  217         hWtsLib = NULL;
  218         fnWtsRegisterSessionNotification = NULL;
  219         fnWtsUnRegisterSessionNotification = NULL;
  220     }
  221 }
  222 
  223 static std::vector<MSXML2::IXMLDOMNodePtr> GetReadChildNodes (MSXML2::IXMLDOMNodeListPtr childs)
  224 {
  225     std::vector<MSXML2::IXMLDOMNodePtr> list;   
  226     if (childs && childs->Getlength())
  227     {
  228         for (long i = 0; i < childs->Getlength(); i++)
  229         {
  230             MSXML2::IXMLDOMNodePtr node = childs->Getitem(i);
  231             if (node)
  232             {
  233                 //skip comments
  234                 if (node->GetnodeType() == NODE_COMMENT)
  235                     continue;
  236                 // skip root xml node
  237                 if (node->GetbaseName().GetBSTR() && (0 == strcmp ("xml", (const char*) node->GetbaseName())))
  238                     continue;
  239 
  240                 list.push_back (node);
  241             }
  242         }
  243     }
  244 
  245     return list;
  246 }
  247 
  248 static bool validateDcsPropXml(const char* xmlData)
  249 {
  250     bool bValid = false;    
  251     HRESULT hr = CoInitialize(NULL);
  252     if(FAILED(hr))
  253         return false;
  254     else
  255     {
  256         MSXML2::IXMLDOMDocumentPtr pXMLDom;
  257         hr= pXMLDom.CreateInstance(__uuidof(MSXML2::DOMDocument60), NULL, CLSCTX_INPROC_SERVER);
  258         if (SUCCEEDED(hr)) 
  259         {
  260             try
  261             {
  262                 pXMLDom->async = VARIANT_FALSE;
  263                 pXMLDom->validateOnParse = VARIANT_FALSE;
  264                 pXMLDom->resolveExternals = VARIANT_FALSE;
  265 
  266                 if(pXMLDom->loadXML(xmlData) == VARIANT_TRUE && pXMLDom->hasChildNodes())
  267                 {
  268                     MSXML2::IXMLDOMNodePtr veracryptNode, configurationNode, configNode;
  269                     std::vector<MSXML2::IXMLDOMNodePtr> nodes = GetReadChildNodes (pXMLDom->GetchildNodes());
  270                     size_t nodesCount = nodes.size();
  271                     if (nodesCount == 1 
  272                         && ((veracryptNode = nodes[0])->GetnodeType() == NODE_ELEMENT)
  273                         && veracryptNode->GetnodeName().GetBSTR()
  274                         && (0 == strcmp ((const char*) veracryptNode->GetnodeName(), "VeraCrypt")) 
  275                         && veracryptNode->hasChildNodes()
  276                         
  277                         )
  278                     {
  279                         nodes = GetReadChildNodes (veracryptNode->GetchildNodes());
  280                         nodesCount = nodes.size();
  281                         if ((nodesCount == 1)
  282                             && ((configurationNode = nodes[0])->GetnodeType() == NODE_ELEMENT)
  283                             && configurationNode->GetnodeName().GetBSTR()
  284                             &&  (0 == strcmp ((const char*) configurationNode->GetnodeName(), "configuration"))
  285                             &&  (configurationNode->hasChildNodes())
  286                             )
  287                         {
  288                             nodes = GetReadChildNodes (configurationNode->GetchildNodes());
  289                             nodesCount = nodes.size();
  290 
  291                             if (nodesCount > 1)
  292                             {
  293                                 bValid = true;
  294                                 for (size_t i = 0; bValid && (i < nodesCount); i++)
  295                                 {
  296                                     configNode = nodes[i];
  297                                     if (configNode->GetnodeType() == NODE_COMMENT)
  298                                         continue;                                   
  299                                     else if (   (configNode->GetnodeType() == NODE_ELEMENT)
  300                                         &&  (configNode->GetnodeName().GetBSTR())
  301                                         && (0 == strcmp ((const char*) configNode->GetnodeName(), "config"))    
  302                                         )
  303                                     {
  304                                         nodes = GetReadChildNodes (configNode->GetchildNodes());
  305                                         nodesCount = nodes.size();
  306                                         if ((nodesCount == 0 || (nodesCount == 1 && nodes[0]->GetnodeType() == NODE_TEXT)) 
  307                                             && configNode->Getattributes() 
  308                                             && (configNode->Getattributes()->Getlength() == 1)
  309                                             && (configNode->Getattributes()->Getitem(0))
  310                                             )
  311                                         {
  312                                             std::string val;
  313                                             bstr_t bstr = configNode->Getattributes()->Getitem(0)->GetnodeName ();
  314                                             if (bstr.GetBSTR())
  315                                                 val = (const char*) bstr;
  316                                             if (val != "key")
  317                                                 bValid = false;
  318                                         }
  319                                         else
  320                                             bValid = false;
  321                                     }
  322                                     else
  323                                         bValid = false;
  324                                 }
  325                             }
  326                         }
  327                     }
  328                 }
  329             }
  330             catch(_com_error errorObject)
  331             {
  332                 bValid = false;
  333             }
  334         }
  335     }
  336 
  337     CoUninitialize();
  338     return bValid;
  339 }
  340 
  341 
  342 static void localcleanup (void)
  343 {
  344     // Wipe command line
  345     char *c = GetCommandLineA ();
  346     wchar_t *wc = GetCommandLineW ();
  347     burn(c, strlen (c));
  348     burn(wc, wcslen (wc) * sizeof (wchar_t));
  349 
  350     /* Delete buffered bitmaps (if any) */
  351     if (hbmLogoBitmapRescaled != NULL)
  352     {
  353         DeleteObject ((HGDIOBJ) hbmLogoBitmapRescaled);
  354         hbmLogoBitmapRescaled = NULL;
  355     }
  356 
  357     /* These items should have already been cleared by the functions that used them, but we're going to
  358     clear them for extra security. */
  359     burn (&VolumePassword, sizeof (VolumePassword));
  360     burn (&CmdVolumePassword, sizeof (CmdVolumePassword));
  361     burn (&VolumePkcs5, sizeof (VolumePkcs5));
  362     burn (&CmdVolumePkcs5, sizeof (CmdVolumePkcs5));
  363     burn (&VolumePim, sizeof (VolumePim));
  364     burn (&CmdVolumePim, sizeof (CmdVolumePim));
  365     burn (&VolumeTrueCryptMode, sizeof (VolumeTrueCryptMode));
  366     burn (&CmdVolumeTrueCryptMode, sizeof (CmdVolumeTrueCryptMode));
  367     burn (&mountOptions, sizeof (mountOptions));
  368     burn (&defaultMountOptions, sizeof (defaultMountOptions));
  369     burn (szFileName, sizeof(szFileName));
  370 
  371     /* Cleanup common code resources */
  372     cleanup ();
  373 
  374     if (BootEncObj != NULL)
  375     {
  376         delete BootEncObj;
  377         BootEncObj = NULL;
  378     }
  379 
  380     RandStop (TRUE);
  381 }
  382 
  383 void RefreshMainDlg (HWND hwndDlg)
  384 {
  385     if (Silent)
  386         LoadDriveLetters (hwndDlg, NULL, 0);
  387     else
  388     {
  389         int drive = (wchar_t) (HIWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST))));
  390 
  391         MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory);
  392         LoadDriveLetters (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST), drive);
  393         EnableDisableButtons (hwndDlg);
  394     }
  395 }
  396 
  397 void EndMainDlg (HWND hwndDlg)
  398 {
  399     MoveEditToCombo (GetDlgItem (hwndDlg, IDC_VOLUME), bHistory);
  400 
  401     if (UsePreferences)
  402         SaveSettings (hwndDlg);
  403 
  404     if (bWipeCacheOnExit)
  405     {
  406         DWORD dwResult;
  407         DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
  408     }
  409 
  410     if (!bHistory)
  411     {
  412         SetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), L"");
  413         ClearHistory (GetDlgItem (hwndDlg, IDC_VOLUME));
  414     }
  415 
  416     if (TaskBarIconMutex != NULL)
  417     {
  418         MainWindowHidden = TRUE;
  419         ShowWindow (hwndDlg, SW_HIDE);
  420     }
  421     else
  422     {
  423         KillTimer (hwndDlg, TIMER_ID_MAIN);
  424         KillTimer (hwndDlg, TIMER_ID_UPDATE_DEVICE_LIST);
  425         TaskBarIconRemove (hwndDlg);
  426         UnregisterWtsNotification(hwndDlg);
  427         EndDialog (hwndDlg, 0);
  428     }
  429 }
  430 
  431 static void InitMainDialog (HWND hwndDlg)
  432 {
  433     MENUITEMINFOW info;
  434     char *popupTexts[] = {"MENU_VOLUMES", "MENU_SYSTEM_ENCRYPTION", "MENU_FAVORITES", "MENU_TOOLS", "MENU_SETTINGS", "MENU_HELP", "MENU_WEBSITE", 0};
  435     wchar_t *str;
  436     int i;
  437 
  438     if (!Silent)
  439     {
  440         /* Call the common dialog init code */
  441         InitDialog (hwndDlg);
  442         LocalizeDialog (hwndDlg, NULL);
  443 
  444         SetWindowLongPtrW (hwndDlg, DWLP_USER, (LONG_PTR) (IsAdmin() ? TC_MAIN_WINDOW_FLAG_ADMIN_PRIVILEGES : 0));
  445 
  446         DragAcceptFiles (hwndDlg, TRUE);
  447 
  448         SendMessageW (GetDlgItem (hwndDlg, IDC_VOLUME), CB_LIMITTEXT, TC_MAX_PATH, 0);
  449         SetWindowTextW (hwndDlg, (IsAdmin() && !IsBuiltInAdmin() && IsUacSupported() && !IsNonInstallMode()) ? (wstring (lpszTitle) + L" [" + GetString ("ADMINISTRATOR") + L"]").c_str() : lpszTitle);
  450 
  451         // Help file name
  452         InitHelpFileName();
  453 
  454         // Localize menu strings
  455         for (i = 40001; str = (wchar_t *)GetDictionaryValueByInt (i); i++)
  456         {
  457             info.cbSize = sizeof (info);
  458             info.fMask = MIIM_TYPE;
  459             info.fType = MFT_STRING;
  460             info.dwTypeData = str;
  461             info.cch = (UINT) wcslen (str);
  462 
  463             SetMenuItemInfoW (GetMenu (hwndDlg), i, FALSE,  &info);
  464         }
  465 
  466         for (i = 0; popupTexts[i] != 0; i++)
  467         {
  468             str = GetString (popupTexts[i]);
  469 
  470             info.cbSize = sizeof (info);
  471             info.fMask = MIIM_TYPE;
  472 
  473             if (strcmp (popupTexts[i], "MENU_WEBSITE") == 0)
  474                 info.fType = MFT_STRING | MFT_RIGHTJUSTIFY;
  475             else
  476                 info.fType = MFT_STRING;
  477 
  478             if (strcmp (popupTexts[i], "MENU_FAVORITES") == 0)
  479                 FavoriteVolumesMenu = GetSubMenu (GetMenu (hwndDlg), i);
  480 
  481             info.dwTypeData = str;
  482             info.cch = (UINT) wcslen (str);
  483 
  484             SetMenuItemInfoW (GetMenu (hwndDlg), i, TRUE,  &info);
  485         }
  486 
  487         {
  488             // disable hidden OS creation for GPT system encryption
  489             if (bSystemIsGPT)
  490             {
  491                 EnableMenuItem (GetMenu (hwndDlg), IDM_CREATE_HIDDEN_OS, MF_GRAYED);
  492             }
  493         }
  494 
  495         // Disable menu item for changing system header key derivation algorithm until it's implemented
  496         EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO, MF_GRAYED);
  497     }
  498 
  499     try
  500     {
  501         LoadFavoriteVolumes();
  502     }
  503     catch (Exception &e)
  504     {
  505         e.Show (NULL);
  506     }
  507 
  508     // initialize the list of devices available for mounting as early as possible
  509     UpdateMountableHostDeviceList ();
  510 
  511     if (Silent)
  512         LoadDriveLetters (hwndDlg, NULL, 0);
  513     else
  514     {
  515         // Resize the logo bitmap if the user has a non-default DPI
  516         if (ScreenDPI != USER_DEFAULT_SCREEN_DPI
  517             && hbmLogoBitmapRescaled == NULL)   // If not re-called (e.g. after language pack change)
  518         {
  519             hbmLogoBitmapRescaled = RenderBitmap (MAKEINTRESOURCE (IDB_LOGO_288DPI),
  520                 GetDlgItem (hwndDlg, IDC_LOGO),
  521                 0, 0, 0, 0, FALSE, TRUE);
  522         }
  523 
  524         BuildTree (hwndDlg, GetDlgItem (hwndDlg, IDC_DRIVELIST));
  525 
  526         if (*szDriveLetter != 0)
  527         {
  528             SelectItem (GetDlgItem (hwndDlg, IDC_DRIVELIST), *szDriveLetter);
  529 
  530             if(nSelectedDriveIndex > SendMessage (GetDlgItem (hwndDlg, IDC_DRIVELIST), LVM_GETITEMCOUNT, 0, 0)/2)
  531                 SendMessage(GetDlgItem (hwndDlg, IDC_DRIVELIST), LVM_SCROLL, 0, 10000);
  532         }
  533         else
  534         {
  535             SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_DRIVELIST), 1L);
  536         }
  537 
  538         SendMessage (GetDlgItem (hwndDlg, IDC_NO_HISTORY), BM_SETCHECK, bHistory ? BST_UNCHECKED : BST_CHECKED, 0);
  539         EnableDisableButtons (hwndDlg);
  540 
  541         // Ensure bottom buttons are visible if the user sets a large font size
  542         RECT mainRectScreen, boxRectScreen;
  543         ULONG mainHeigth, mainWidth, correctHeigth;
  544         GetWindowRect (hwndDlg, &mainRectScreen);
  545         GetWindowRect (GetDlgItem (hwndDlg, IDC_LOWER_BOX), &boxRectScreen);
  546 
  547         mainHeigth = mainRectScreen.bottom - mainRectScreen.top;
  548         mainWidth = mainRectScreen.right - mainRectScreen.left;
  549         correctHeigth =  boxRectScreen.bottom - mainRectScreen.top + CompensateYDPI (5);
  550 
  551         if (mainHeigth < correctHeigth)
  552         {
  553             SetWindowPos (hwndDlg, NULL, 0, 0, mainWidth, correctHeigth , SWP_NOACTIVATE | SWP_NOZORDER  | SWP_NOMOVE);
  554         }
  555     }
  556 }
  557 
  558 void EnableDisableButtons (HWND hwndDlg)
  559 {
  560     HWND hOKButton = GetDlgItem (hwndDlg, IDOK);
  561     WORD x;
  562 
  563     x = LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)));
  564 
  565     EnableMenuItem (GetMenu (hwndDlg), IDM_MOUNT_VOLUME, MF_ENABLED);
  566     EnableMenuItem (GetMenu (hwndDlg), IDM_MOUNT_VOLUME_OPTIONS, MF_ENABLED);
  567     EnableMenuItem (GetMenu (hwndDlg), IDM_BACKUP_VOL_HEADER, MF_ENABLED);
  568     EnableMenuItem (GetMenu (hwndDlg), IDM_RESTORE_VOL_HEADER, MF_ENABLED);
  569     EnableMenuItem (GetMenu (hwndDlg), IDM_CHANGE_PASSWORD, MF_ENABLED);
  570     EnableWindow (hOKButton, TRUE);
  571 
  572     switch (x)
  573     {
  574     case TC_MLIST_ITEM_NONSYS_VOL:
  575         {
  576             SetWindowTextW (hOKButton, GetString ("UNMOUNT_BUTTON"));
  577             EnableWindow (hOKButton, TRUE);
  578             EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_ENABLED);
  579 
  580             EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), TRUE);
  581             EnableMenuItem (GetMenu (hwndDlg), IDM_VOLUME_PROPERTIES, MF_ENABLED);
  582         }
  583         break;
  584 
  585     case TC_MLIST_ITEM_SYS_PARTITION:
  586     case TC_MLIST_ITEM_SYS_DRIVE:
  587         EnableWindow (hOKButton, FALSE);
  588         SetWindowTextW (hOKButton, GetString ("MOUNT_BUTTON"));
  589         EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), TRUE);
  590         EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_GRAYED);
  591         break;
  592 
  593     case TC_MLIST_ITEM_FREE:
  594     default:
  595         SetWindowTextW (hOKButton, GetString ("MOUNT_BUTTON"));
  596         EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES), FALSE);
  597         EnableMenuItem (GetMenu (hwndDlg), IDM_VOLUME_PROPERTIES, MF_GRAYED);
  598         EnableMenuItem (GetMenu (hwndDlg), IDM_UNMOUNT_VOLUME, MF_GRAYED);
  599     }
  600 
  601     EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty());
  602     EnableMenuItem (GetMenu (hwndDlg), IDM_WIPE_CACHE, IsPasswordCacheEmpty() ? MF_GRAYED:MF_ENABLED);
  603     EnableMenuItem (GetMenu (hwndDlg), IDM_CLEAR_HISTORY, IsComboEmpty (GetDlgItem (hwndDlg, IDC_VOLUME)) ? MF_GRAYED:MF_ENABLED);
  604 }
  605 
  606 BOOL VolumeSelected (HWND hwndDlg)
  607 {
  608     return (GetWindowTextLength (GetDlgItem (hwndDlg, IDC_VOLUME)) > 0);
  609 }
  610 
  611 void GetVolumePath (HWND hwndDlg, LPWSTR szPath, int nMaxCount)
  612 {
  613     GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), szPath, nMaxCount);
  614     CorrectFileName (szPath);
  615 }
  616 
  617 /* Returns TRUE if the last partition/drive selected via the Select Device dialog box was the system
  618 partition/drive and if it is encrypted.
  619          WARNING: This function is very fast but not always reliable (for example, if the user manually types
  620          a device path before Select Device is invoked during the session; after the Select Device dialog
  621          has been invoked at least once, the correct system device paths are cached). Therefore, it must NOT
  622          be used before performing any dangerous operations (such as header backup restore or formatting a
  623          supposedly non-system device) -- instead use IsSystemDevicePath(path, hwndDlg, TRUE) for such
  624          purposes. This function can be used only for preliminary GUI checks requiring very fast responses. */
  625 BOOL ActiveSysEncDeviceSelected (void)
  626 {
  627     try
  628     {
  629         BootEncStatus = BootEncObj->GetStatus();
  630 
  631         if (BootEncStatus.DriveEncrypted)
  632         {
  633             int retCode = 0;
  634 
  635             GetVolumePath (MainDlg, szFileName, ARRAYSIZE (szFileName));
  636 
  637             retCode = IsSystemDevicePath (szFileName, MainDlg, FALSE);
  638 
  639             return (WholeSysDriveEncryption(FALSE) ? (retCode == 2 || retCode == 1) : (retCode == 1));
  640         }
  641     }
  642     catch (Exception &e)
  643     {
  644         e.Show (MainDlg);
  645     }
  646 
  647     return FALSE;
  648 }
  649 
  650 // When a function does not require the affected volume to be dismounted, there may be cases where we have two valid
  651 // paths selected in the main window and we cannot be sure which of them the user really intends to apply the function to.
  652 // This function asks the user to explicitly select either the volume path specified in the input field below the main
  653 // drive list (whether mounted or not), or the path to the volume selected in the main drive list. If, however, both
  654 // of the GUI elements contain the same volume (or one of them does not contain any path), this function does not
  655 // ask the user and returns the volume path directly (no selection ambiguity).
  656 // If driveNoPtr is not NULL, and the volume is mounted, its drive letter is returned in *driveNoPtr (if no valid drive
  657 // letter is resolved, -1 is stored instead).
  658 static wstring ResolveAmbiguousSelection (HWND hwndDlg, int *driveNoPtr)
  659 {
  660     LPARAM selectedDrive = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST));
  661 
  662     wchar_t volPathInputField [TC_MAX_PATH];
  663 
  664     wchar_t volPathDriveListW [TC_MAX_PATH];
  665     wstring volPathDriveListStr;
  666 
  667     wstring retPath;
  668 
  669     VOLUME_PROPERTIES_STRUCT prop;
  670     DWORD dwResult;
  671 
  672     BOOL useInputField = TRUE;
  673 
  674     memset (&prop, 0, sizeof(prop));
  675 
  676     BOOL ambig = (LOWORD (selectedDrive) != TC_MLIST_ITEM_FREE && LOWORD (selectedDrive) != 0xffff && HIWORD (selectedDrive) != 0xffff
  677         && VolumeSelected (MainDlg));
  678 
  679     if (VolumeSelected (MainDlg))
  680     {
  681         // volPathInputField will contain the volume path (if any) from the input field below the drive list
  682         GetVolumePath (MainDlg, volPathInputField, ARRAYSIZE (volPathInputField));
  683 
  684         if (!ambig)
  685             retPath = (wstring) volPathInputField;
  686     }
  687 
  688     if (LOWORD (selectedDrive) != TC_MLIST_ITEM_FREE && LOWORD (selectedDrive) != 0xffff && HIWORD (selectedDrive) != 0xffff)
  689     {
  690         // A volume is selected in the main drive list.
  691 
  692         switch (LOWORD (selectedDrive))
  693         {
  694         case TC_MLIST_ITEM_NONSYS_VOL:
  695             prop.driveNo = HIWORD (selectedDrive) - L'A';
  696 
  697             if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0)
  698             {
  699                 // The driver did not return any path for this drive letter (the volume may have been dismounted).
  700 
  701                 // Return whatever is in the input field below the drive list (even if empty)
  702                 return ((wstring) volPathInputField);
  703             }
  704 
  705             // volPathDriveListWStr will contain the volume path selected in the main drive list
  706             volPathDriveListStr = (wstring) prop.wszVolume;
  707             break;
  708 
  709         case TC_MLIST_ITEM_SYS_PARTITION:
  710 
  711             GetSysDevicePaths (MainDlg);
  712 
  713             if (bCachedSysDevicePathsValid)
  714             {
  715                 volPathDriveListStr = (wstring) SysPartitionDevicePath;
  716             }
  717 
  718             break;
  719 
  720         case TC_MLIST_ITEM_SYS_DRIVE:
  721 
  722             GetSysDevicePaths (MainDlg);
  723 
  724             if (bCachedSysDevicePathsValid)
  725             {
  726                 volPathDriveListStr = (wstring) SysDriveDevicePath;
  727             }
  728 
  729             break;
  730         }
  731 
  732         if (!ambig)
  733         {
  734             useInputField = FALSE;
  735             retPath = volPathDriveListStr;
  736         }
  737     }
  738 
  739     if (ambig)
  740     {
  741         /* We have two paths. Compare them and if they don't match, ask the user to select one of them. Otherwise, return the path without asking. */
  742 
  743         if (wmemcmp (volPathDriveListStr.c_str (), L"\\??\\", 4) == 0)
  744         {
  745             // The volume path starts with "\\??\\" which is used for file-hosted containers. We're going to strip this prefix.
  746 
  747             volPathDriveListStr = (wstring) (volPathDriveListStr.c_str () + 4);
  748         }
  749 
  750         StringCbCopyW (volPathDriveListW, sizeof(volPathDriveListW), volPathDriveListStr.c_str ());
  751 
  752         if (wcscmp (((wmemcmp (volPathDriveListW, L"\\??\\", 4) == 0) ? volPathDriveListW + 4 : volPathDriveListW), volPathInputField) != 0)
  753         {
  754             // The path selected in the input field is different from the path to the volume selected
  755             // in the drive lettter list. We have to resolve possible ambiguity.
  756 
  757             wchar_t *tmp[] = {L"", L"", L"", L"", L"", 0};
  758             const int maxVolPathLen = 80;
  759 
  760             if (volPathDriveListStr.length () > maxVolPathLen)
  761             {
  762                 // Ellipsis (path too long)
  763                 volPathDriveListStr = wstring (L"...") + volPathDriveListStr.substr (volPathDriveListStr.length () - maxVolPathLen, maxVolPathLen);
  764             }
  765 
  766             wstring volPathInputFieldWStr (volPathInputField);
  767 
  768             if (volPathInputFieldWStr.length () > maxVolPathLen)
  769             {
  770                 // Ellipsis (path too long)
  771                 volPathInputFieldWStr = wstring (L"...") + volPathInputFieldWStr.substr (volPathInputFieldWStr.length () - maxVolPathLen, maxVolPathLen);
  772             }
  773 
  774             tmp[1] = GetString ("AMBIGUOUS_VOL_SELECTION");
  775             tmp[2] = (wchar_t *) volPathDriveListStr.c_str();
  776             tmp[3] = (wchar_t *) volPathInputFieldWStr.c_str();
  777             tmp[4] = GetString ("IDCANCEL");
  778 
  779             switch (AskMultiChoice ((void **) tmp, FALSE, hwndDlg))
  780             {
  781             case 1:
  782                 retPath = volPathDriveListStr;
  783                 break;
  784 
  785             case 2:
  786                 retPath = (wstring) volPathInputField;
  787                 break;
  788 
  789             default:
  790                 if (driveNoPtr != NULL)
  791                     *driveNoPtr = -1;
  792 
  793                 return wstring (L"");
  794             }
  795         }
  796         else
  797         {
  798             // Both selected paths are the same
  799             retPath = (wstring) volPathInputField;
  800         }
  801     }
  802 
  803     if (driveNoPtr != NULL)
  804         *driveNoPtr = GetMountedVolumeDriveNo ((wchar_t *) retPath.c_str ());
  805 
  806 
  807     if (wmemcmp (retPath.c_str (), L"\\??\\", 4) == 0)
  808     {
  809         // The selected volume path starts with "\\??\\" which is used for file-hosted containers. We're going to strip this prefix.
  810 
  811         retPath = (wstring) (retPath.c_str () + 4);
  812     }
  813 
  814     return retPath;
  815 }
  816 
  817 void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL* pbSettingsModified, BOOL* pbHistoryModified)
  818 {
  819     char langid[6] = {0};
  820     if (!bOnlyCheckModified)
  821        EnableHwEncryption ((ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE);
  822 
  823     WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE;
  824 
  825     if (!bOnlyCheckModified)
  826         LoadSysEncSettings ();
  827 
  828     if (!bOnlyCheckModified && LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0)
  829         bInPlaceEncNonSysPending = TRUE;
  830 
  831     // If the config file has already been loaded during this session
  832     if (ConfigBuffer != NULL)
  833     {
  834         free (ConfigBuffer);
  835         ConfigBuffer = NULL;
  836     }
  837 
  838     // Options
  839     ConfigReadCompareInt ("OpenExplorerWindowAfterMount", FALSE, &bExplore, bOnlyCheckModified, pbSettingsModified);
  840     ConfigReadCompareInt ("UseDifferentTrayIconIfVolumesMounted", TRUE, &bUseDifferentTrayIconIfVolMounted, bOnlyCheckModified, pbSettingsModified);
  841 
  842     ConfigReadCompareInt ("SaveVolumeHistory", FALSE, &bHistory, bOnlyCheckModified, pbSettingsModified);
  843 
  844     ConfigReadCompareInt ("CachePasswords", FALSE, &bCacheInDriverDefault, bOnlyCheckModified, pbSettingsModified);
  845     if (!bOnlyCheckModified)
  846         bCacheInDriver = bCacheInDriverDefault;
  847 
  848     ConfigReadCompareInt ("CachePasswordDuringMultipleMount", FALSE, &bCacheDuringMultipleMount, bOnlyCheckModified, pbSettingsModified);
  849     ConfigReadCompareInt ("WipePasswordCacheOnExit", FALSE, &bWipeCacheOnExit, bOnlyCheckModified, pbSettingsModified);
  850     ConfigReadCompareInt ("WipeCacheOnAutoDismount", TRUE, &bWipeCacheOnAutoDismount, bOnlyCheckModified, pbSettingsModified);
  851 
  852     ConfigReadCompareInt ("IncludePimInCache", FALSE, &bIncludePimInCache, bOnlyCheckModified, pbSettingsModified);
  853 
  854     ConfigReadCompareInt ("TryEmptyPasswordWhenKeyfileUsed",FALSE, &bTryEmptyPasswordWhenKeyfileUsed, bOnlyCheckModified, pbSettingsModified);
  855 
  856     ConfigReadCompareInt ("StartOnLogon", FALSE, &bStartOnLogon, bOnlyCheckModified, pbSettingsModified);
  857     ConfigReadCompareInt ("MountDevicesOnLogon", FALSE, &bMountDevicesOnLogon, bOnlyCheckModified, pbSettingsModified);
  858     ConfigReadCompareInt ("MountFavoritesOnLogon", FALSE, &bMountFavoritesOnLogon, bOnlyCheckModified, pbSettingsModified);
  859 
  860     ConfigReadCompareInt ("EnableBackgroundTask", TRUE, &bEnableBkgTask, bOnlyCheckModified, pbSettingsModified);
  861     ConfigReadCompareInt ("CloseBackgroundTaskOnNoVolumes", FALSE, &bCloseBkgTaskWhenNoVolumes, bOnlyCheckModified, pbSettingsModified);
  862 
  863     ConfigReadCompareInt ("DismountOnLogOff", !(IsServerOS() && IsAdmin()), &bDismountOnLogOff, bOnlyCheckModified, pbSettingsModified);
  864     ConfigReadCompareInt ("DismountOnSessionLocked", FALSE, &bDismountOnSessionLocked, bOnlyCheckModified, pbSettingsModified);
  865     ConfigReadCompareInt ("DismountOnPowerSaving", FALSE, &bDismountOnPowerSaving, bOnlyCheckModified, pbSettingsModified);
  866     ConfigReadCompareInt ("DismountOnScreenSaver", FALSE, &bDismountOnScreenSaver, bOnlyCheckModified, pbSettingsModified);
  867     ConfigReadCompareInt ("ForceAutoDismount", TRUE, &bForceAutoDismount, bOnlyCheckModified, pbSettingsModified);
  868     ConfigReadCompareInt ("MaxVolumeIdleTime", -60, &MaxVolumeIdleTime, bOnlyCheckModified, pbSettingsModified);
  869 
  870     ConfigReadCompareInt ("HiddenSectorDetectionStatus", 0, &HiddenSectorDetectionStatus, bOnlyCheckModified, pbSettingsModified);
  871 
  872     ConfigReadCompareInt ("UseKeyfiles", FALSE, &defaultKeyFilesParam.EnableKeyFiles, bOnlyCheckModified, pbSettingsModified);
  873 
  874     ConfigReadCompareInt ("PreserveTimestamps", TRUE, &defaultMountOptions.PreserveTimestamp, bOnlyCheckModified, pbSettingsModified);
  875     if (!bOnlyCheckModified)
  876         bPreserveTimestamp = defaultMountOptions.PreserveTimestamp;
  877 
  878     ConfigReadCompareInt ("ShowDisconnectedNetworkDrives", FALSE, &bShowDisconnectedNetworkDrives, bOnlyCheckModified, pbSettingsModified);
  879 
  880     ConfigReadCompareInt ("HideWaitingDialog", FALSE, &bHideWaitingDialog, bOnlyCheckModified, pbSettingsModified);
  881 
  882     ConfigReadCompareInt ("UseSecureDesktop", FALSE, &bUseSecureDesktop, bOnlyCheckModified, pbSettingsModified);
  883 
  884     ConfigReadCompareInt ("MountVolumesRemovable", FALSE, &defaultMountOptions.Removable, bOnlyCheckModified, pbSettingsModified);
  885     ConfigReadCompareInt ("MountVolumesReadOnly", FALSE, &defaultMountOptions.ReadOnly, bOnlyCheckModified, pbSettingsModified);
  886 
  887     if (!bOnlyCheckModified)
  888     {
  889         defaultMountOptions.ProtectHiddenVolume = FALSE;
  890         defaultMountOptions.ProtectedHidVolPkcs5Prf = 0;
  891         defaultMountOptions.ProtectedHidVolPim = 0;
  892         defaultMountOptions.PartitionInInactiveSysEncScope = FALSE;
  893         defaultMountOptions.RecoveryMode = FALSE;
  894         defaultMountOptions.UseBackupHeader =  FALSE;
  895 
  896         mountOptions = defaultMountOptions;
  897     }
  898 
  899     ConfigReadCompareInt ("CloseSecurityTokenSessionsAfterMount", 0, &CloseSecurityTokenSessionsAfterMount, bOnlyCheckModified, pbSettingsModified);
  900 
  901     if (IsHiddenOSRunning())
  902         ConfigReadCompareInt ("HiddenSystemLeakProtNotifStatus", TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE, &HiddenSysLeakProtectionNotificationStatus, bOnlyCheckModified, pbSettingsModified);
  903 
  904     // Drive letter - command line arg overrides registry
  905     if (!bOnlyCheckModified && bHistory && szDriveLetter[0] == 0)
  906     {
  907         char szTmp[3] = {0};
  908         ConfigReadString ("LastSelectedDrive", "", szTmp, sizeof (szTmp));
  909         MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, szDriveLetter, ARRAYSIZE (szDriveLetter));
  910     }
  911     if (bHistory && pbSettingsModified)
  912     {
  913         // only check for last drive modification if history enabled
  914         char szTmp[32] = {0};
  915         LPARAM lLetter;
  916         lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST));
  917         if (LOWORD (lLetter) != 0xffff)
  918             StringCbPrintfA (szTmp, sizeof(szTmp), "%lc:", (wchar_t) HIWORD (lLetter));
  919 
  920         ConfigReadCompareString ("LastSelectedDrive", "", szTmp, sizeof (szTmp), bOnlyCheckModified, pbSettingsModified);
  921     }
  922 
  923     {
  924         char szTmp[MAX_PATH];
  925         WideCharToMultiByte (CP_UTF8, 0, SecurityTokenLibraryPath, -1, szTmp, MAX_PATH, NULL, NULL);
  926         ConfigReadCompareString ("SecurityTokenLibrary", "", szTmp, sizeof (szTmp) - 1, bOnlyCheckModified, pbSettingsModified);
  927         MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, SecurityTokenLibraryPath, ARRAYSIZE (SecurityTokenLibraryPath));
  928         if (!bOnlyCheckModified && SecurityTokenLibraryPath[0])
  929         {
  930             InitSecurityTokenLibrary(hwndDlg);
  931         }
  932     }
  933 
  934     // Hotkeys
  935     ConfigReadCompareInt ("PlaySoundOnHotkeyMountDismount", TRUE, &bPlaySoundOnSuccessfulHkDismount, bOnlyCheckModified, pbSettingsModified);
  936     ConfigReadCompareInt ("DisplayMsgBoxOnHotkeyDismount", TRUE, &bDisplayBalloonOnSuccessfulHkDismount, bOnlyCheckModified, pbSettingsModified);
  937     ConfigReadCompareInt ("HotkeyModAutoMountDevices", 0, (int*) &Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  938     ConfigReadCompareInt ("HotkeyCodeAutoMountDevices", 0, (int*) &Hotkeys [HK_AUTOMOUNT_DEVICES].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  939     ConfigReadCompareInt ("HotkeyModDismountAll", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  940     ConfigReadCompareInt ("HotkeyCodeDismountAll", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  941     ConfigReadCompareInt ("HotkeyModWipeCache", 0, (int*) &Hotkeys [HK_WIPE_CACHE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  942     ConfigReadCompareInt ("HotkeyCodeWipeCache", 0, (int*) &Hotkeys [HK_WIPE_CACHE].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  943     ConfigReadCompareInt ("HotkeyModDismountAllWipe", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  944     ConfigReadCompareInt ("HotkeyCodeDismountAllWipe", 0, (int*) &Hotkeys [HK_DISMOUNT_ALL_AND_WIPE].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  945     ConfigReadCompareInt ("HotkeyModForceDismountAllWipe", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  946     ConfigReadCompareInt ("HotkeyCodeForceDismountAllWipe", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  947     ConfigReadCompareInt ("HotkeyModForceDismountAllWipeExit", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  948     ConfigReadCompareInt ("HotkeyCodeForceDismountAllWipeExit", 0, (int*) &Hotkeys [HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  949     ConfigReadCompareInt ("HotkeyModMountFavoriteVolumes", 0, (int*) &Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  950     ConfigReadCompareInt ("HotkeyCodeMountFavoriteVolumes", 0, (int*) &Hotkeys [HK_MOUNT_FAVORITE_VOLUMES].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  951     ConfigReadCompareInt ("HotkeyModShowHideMainWindow", 0, (int*) &Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  952     ConfigReadCompareInt ("HotkeyCodeShowHideMainWindow", 0, (int*) &Hotkeys [HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  953     ConfigReadCompareInt ("HotkeyModCloseSecurityTokenSessions", 0, (int*) &Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers, bOnlyCheckModified, pbSettingsModified);
  954     ConfigReadCompareInt ("HotkeyCodeCloseSecurityTokenSessions", 0, (int*) &Hotkeys [HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode, bOnlyCheckModified, pbSettingsModified);
  955 
  956     // History
  957     if (bHistoryCmdLine != TRUE)
  958     {
  959         LoadCombo (GetDlgItem (MainDlg, IDC_VOLUME), bHistory, bOnlyCheckModified, pbHistoryModified);
  960         if (!bOnlyCheckModified && CmdLineVolumeSpecified)
  961             SetWindowText (GetDlgItem (MainDlg, IDC_VOLUME), szFileName);
  962     }
  963 
  964     // Mount Options
  965     ConfigReadCompareInt ("DefaultPRF", 0, &DefaultVolumePkcs5, bOnlyCheckModified, pbSettingsModified);
  966     ConfigReadCompareInt ("DefaultTrueCryptMode", FALSE, &DefaultVolumeTrueCryptMode, bOnlyCheckModified, pbSettingsModified);
  967 
  968     if (bOnlyCheckModified)
  969     {
  970         if (!IsNonInstallMode ())
  971         {
  972             ConfigReadString ("Language", "", langid, sizeof (langid));
  973             // when installed, if no preferred language set by user, English is set default
  974             //
  975             if (langid [0] == 0)
  976                 StringCbCopyA (langid, sizeof(langid), "en");
  977 
  978             if (pbSettingsModified && strcmp (langid, GetPreferredLangId ()))
  979                 *pbSettingsModified = TRUE;
  980         }
  981         else
  982         {
  983             StringCbCopyA (langid, sizeof(langid), GetPreferredLangId ());
  984             ConfigReadCompareString ("Language", "", langid, sizeof (langid), TRUE, pbSettingsModified);
  985         }
  986     }
  987 
  988     if (DefaultVolumePkcs5 < 0 || DefaultVolumePkcs5 > LAST_PRF_ID)
  989         DefaultVolumePkcs5 = 0;
  990     if (DefaultVolumeTrueCryptMode != TRUE && DefaultVolumeTrueCryptMode != FALSE)
  991         DefaultVolumeTrueCryptMode = FALSE;
  992 
  993 }
  994 
  995 void LoadSettings ( HWND hwndDlg )
  996 {
  997     LoadSettingsAndCheckModified (hwndDlg, FALSE, NULL, NULL);
  998 }
  999 
 1000 void SaveSettings (HWND hwndDlg)
 1001 {
 1002     WaitCursor ();
 1003 
 1004     // Check first if modifications ocurred before writing to the settings and history files
 1005     // This avoids leaking information about VeraCrypt usage when user only mount volumes without changing setttings or history
 1006     BOOL bSettingsChanged = FALSE;
 1007     BOOL bHistoryChanged = FALSE;
 1008 
 1009     LoadSettingsAndCheckModified (hwndDlg, TRUE, &bSettingsChanged, &bHistoryChanged);
 1010 
 1011     if (bSettingsChanged)
 1012     {
 1013         char szTmp[32] = {0};
 1014         LPARAM lLetter;
 1015 
 1016         // Options
 1017         ConfigWriteBegin ();
 1018 
 1019         ConfigWriteInt ("OpenExplorerWindowAfterMount",     bExplore);
 1020         ConfigWriteInt ("UseDifferentTrayIconIfVolumesMounted", bUseDifferentTrayIconIfVolMounted);
 1021         ConfigWriteInt ("SaveVolumeHistory",                bHistory);
 1022 
 1023         ConfigWriteInt ("CachePasswords",                   bCacheInDriverDefault);
 1024         ConfigWriteInt ("CachePasswordDuringMultipleMount", bCacheDuringMultipleMount);
 1025         ConfigWriteInt ("WipePasswordCacheOnExit",          bWipeCacheOnExit);
 1026         ConfigWriteInt ("WipeCacheOnAutoDismount",          bWipeCacheOnAutoDismount);
 1027 
 1028         ConfigWriteInt ("IncludePimInCache",                bIncludePimInCache);
 1029 
 1030         ConfigWriteInt ("TryEmptyPasswordWhenKeyfileUsed",  bTryEmptyPasswordWhenKeyfileUsed);
 1031 
 1032         ConfigWriteInt ("StartOnLogon",                     bStartOnLogon);
 1033         ConfigWriteInt ("MountDevicesOnLogon",              bMountDevicesOnLogon);
 1034         ConfigWriteInt ("MountFavoritesOnLogon",            bMountFavoritesOnLogon);
 1035 
 1036         ConfigWriteInt ("MountVolumesReadOnly",             defaultMountOptions.ReadOnly);
 1037         ConfigWriteInt ("MountVolumesRemovable",            defaultMountOptions.Removable);
 1038         ConfigWriteInt ("PreserveTimestamps",               defaultMountOptions.PreserveTimestamp);
 1039         ConfigWriteInt ("ShowDisconnectedNetworkDrives",bShowDisconnectedNetworkDrives);
 1040         ConfigWriteInt ("HideWaitingDialog",                bHideWaitingDialog);
 1041         ConfigWriteInt ("UseSecureDesktop",                 bUseSecureDesktop);
 1042 
 1043         ConfigWriteInt ("EnableBackgroundTask",             bEnableBkgTask);
 1044         ConfigWriteInt ("CloseBackgroundTaskOnNoVolumes",   bCloseBkgTaskWhenNoVolumes);
 1045 
 1046         ConfigWriteInt ("DismountOnLogOff",                 bDismountOnLogOff);
 1047         ConfigWriteInt ("DismountOnSessionLocked",          bDismountOnSessionLocked);
 1048         ConfigWriteInt ("DismountOnPowerSaving",            bDismountOnPowerSaving);
 1049         ConfigWriteInt ("DismountOnScreenSaver",            bDismountOnScreenSaver);
 1050         ConfigWriteInt ("ForceAutoDismount",                bForceAutoDismount);
 1051         ConfigWriteInt ("MaxVolumeIdleTime",                MaxVolumeIdleTime);
 1052 
 1053         ConfigWriteInt ("HiddenSectorDetectionStatus",              HiddenSectorDetectionStatus);
 1054 
 1055         ConfigWriteInt ("UseKeyfiles",                      defaultKeyFilesParam.EnableKeyFiles);
 1056 
 1057         if (IsHiddenOSRunning())
 1058             ConfigWriteInt ("HiddenSystemLeakProtNotifStatus", HiddenSysLeakProtectionNotificationStatus);
 1059 
 1060         // save last selected drive only when history enabled
 1061         if (bHistory)
 1062         {
 1063             // Drive Letter
 1064             lLetter = GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST));
 1065             if (LOWORD (lLetter) != 0xffff)
 1066                 StringCbPrintfA (szTmp, sizeof(szTmp), "%lc:", (wchar_t) HIWORD (lLetter));
 1067             ConfigWriteString ("LastSelectedDrive", szTmp);
 1068         }
 1069 
 1070         ConfigWriteInt ("CloseSecurityTokenSessionsAfterMount", CloseSecurityTokenSessionsAfterMount);
 1071 
 1072         // Hotkeys
 1073         ConfigWriteInt ("HotkeyModAutoMountDevices",                Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyModifiers);
 1074         ConfigWriteInt ("HotkeyCodeAutoMountDevices",               Hotkeys[HK_AUTOMOUNT_DEVICES].vKeyCode);
 1075         ConfigWriteInt ("HotkeyModDismountAll",                     Hotkeys[HK_DISMOUNT_ALL].vKeyModifiers);
 1076         ConfigWriteInt ("HotkeyCodeDismountAll",                    Hotkeys[HK_DISMOUNT_ALL].vKeyCode);
 1077         ConfigWriteInt ("HotkeyModWipeCache",                       Hotkeys[HK_WIPE_CACHE].vKeyModifiers);
 1078         ConfigWriteInt ("HotkeyCodeWipeCache",                      Hotkeys[HK_WIPE_CACHE].vKeyCode);
 1079         ConfigWriteInt ("HotkeyModDismountAllWipe",                 Hotkeys[HK_DISMOUNT_ALL_AND_WIPE].vKeyModifiers);
 1080         ConfigWriteInt ("HotkeyCodeDismountAllWipe",                Hotkeys[HK_DISMOUNT_ALL_AND_WIPE].vKeyCode);
 1081         ConfigWriteInt ("HotkeyModForceDismountAllWipe",            Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyModifiers);
 1082         ConfigWriteInt ("HotkeyCodeForceDismountAllWipe",           Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE].vKeyCode);
 1083         ConfigWriteInt ("HotkeyModForceDismountAllWipeExit",        Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyModifiers);
 1084         ConfigWriteInt ("HotkeyCodeForceDismountAllWipeExit",       Hotkeys[HK_FORCE_DISMOUNT_ALL_AND_WIPE_AND_EXIT].vKeyCode);
 1085         ConfigWriteInt ("HotkeyModMountFavoriteVolumes",            Hotkeys[HK_MOUNT_FAVORITE_VOLUMES].vKeyModifiers);
 1086         ConfigWriteInt ("HotkeyCodeMountFavoriteVolumes",           Hotkeys[HK_MOUNT_FAVORITE_VOLUMES].vKeyCode);
 1087         ConfigWriteInt ("HotkeyModShowHideMainWindow",              Hotkeys[HK_SHOW_HIDE_MAIN_WINDOW].vKeyModifiers);
 1088         ConfigWriteInt ("HotkeyCodeShowHideMainWindow",             Hotkeys[HK_SHOW_HIDE_MAIN_WINDOW].vKeyCode);
 1089         ConfigWriteInt ("HotkeyModCloseSecurityTokenSessions",      Hotkeys[HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyModifiers);
 1090         ConfigWriteInt ("HotkeyCodeCloseSecurityTokenSessions",     Hotkeys[HK_CLOSE_SECURITY_TOKEN_SESSIONS].vKeyCode);
 1091         ConfigWriteInt ("PlaySoundOnHotkeyMountDismount",           bPlaySoundOnSuccessfulHkDismount);
 1092         ConfigWriteInt ("DisplayMsgBoxOnHotkeyDismount",            bDisplayBalloonOnSuccessfulHkDismount);
 1093 
 1094         // Language
 1095         ConfigWriteString ("Language", GetPreferredLangId ());
 1096 
 1097         // PKCS#11 Library Path
 1098         ConfigWriteStringW ("SecurityTokenLibrary", SecurityTokenLibraryPath[0] ? SecurityTokenLibraryPath : L"");
 1099 
 1100         // Mount Options
 1101         ConfigWriteInt ("DefaultPRF", DefaultVolumePkcs5);
 1102         ConfigWriteInt ("DefaultTrueCryptMode", DefaultVolumeTrueCryptMode);
 1103 
 1104         ConfigWriteEnd (hwndDlg);
 1105     }
 1106 
 1107     if (bHistoryChanged)
 1108     {
 1109         // History
 1110         DumpCombo (GetDlgItem (MainDlg, IDC_VOLUME), IsButtonChecked (GetDlgItem (MainDlg, IDC_NO_HISTORY)));
 1111     }
 1112 
 1113     NormalCursor ();
 1114 }
 1115 
 1116 // Returns TRUE if system encryption or decryption had been or is in progress and has not been completed
 1117 static BOOL SysEncryptionOrDecryptionRequired (void)
 1118 {
 1119     /* If you update this function, revise SysEncryptionOrDecryptionRequired() in Tcformat.c as well. */
 1120 
 1121     try
 1122     {
 1123         BootEncStatus = BootEncObj->GetStatus();
 1124     }
 1125     catch (Exception &e)
 1126     {
 1127         e.Show (MainDlg);
 1128     }
 1129 
 1130     return (SystemEncryptionStatus == SYSENC_STATUS_ENCRYPTING
 1131         || SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING
 1132         ||
 1133         (
 1134             BootEncStatus.DriveMounted
 1135             &&
 1136             (
 1137                 BootEncStatus.ConfiguredEncryptedAreaStart != BootEncStatus.EncryptedAreaStart
 1138                 || BootEncStatus.ConfiguredEncryptedAreaEnd != BootEncStatus.EncryptedAreaEnd
 1139             )
 1140         )
 1141     );
 1142 }
 1143 
 1144 // Returns TRUE if the system partition/drive is completely encrypted
 1145 static BOOL SysDriveOrPartitionFullyEncrypted (BOOL bSilent)
 1146 {
 1147     /* If you update this function, revise SysDriveOrPartitionFullyEncrypted() in Tcformat.c as well. */
 1148 
 1149     try
 1150     {
 1151         BootEncStatus = BootEncObj->GetStatus();
 1152     }
 1153     catch (Exception &e)
 1154     {
 1155         if (!bSilent)
 1156             e.Show (MainDlg);
 1157     }
 1158 
 1159     return (!BootEncStatus.SetupInProgress
 1160         && BootEncStatus.ConfiguredEncryptedAreaEnd != 0
 1161         && BootEncStatus.ConfiguredEncryptedAreaEnd != -1
 1162         && BootEncStatus.ConfiguredEncryptedAreaStart == BootEncStatus.EncryptedAreaStart
 1163         && BootEncStatus.ConfiguredEncryptedAreaEnd == BootEncStatus.EncryptedAreaEnd);
 1164 }
 1165 
 1166 // Returns TRUE if the system partition/drive is being filtered by the TrueCrypt driver and the key data
 1167 // was successfully decrypted (the device is fully ready to be encrypted or decrypted). Note that this
 1168 // function does not examine whether the system device is encrypted or not (or to what extent).
 1169 static BOOL SysEncDeviceActive (BOOL bSilent)
 1170 {
 1171     try
 1172     {
 1173         BootEncStatus = BootEncObj->GetStatus();
 1174     }
 1175     catch (Exception &e)
 1176     {
 1177         if (!bSilent)
 1178             e.Show (MainDlg);
 1179 
 1180         return FALSE;
 1181     }
 1182 
 1183     return (BootEncStatus.DriveMounted);
 1184 }
 1185 
 1186 // Returns TRUE if the entire system drive (as opposed to the system partition only) of the currently running OS is (or is to be) encrypted
 1187 BOOL WholeSysDriveEncryption (BOOL bSilent)
 1188 {
 1189     try
 1190     {
 1191         BootEncStatus = BootEncObj->GetStatus();
 1192 
 1193         if (BootEncStatus.BootDriveLength.QuadPart < 1) // paranoid check
 1194             return FALSE;
 1195         else
 1196             return (BootEncStatus.ConfiguredEncryptedAreaStart == TC_BOOT_LOADER_AREA_SIZE
 1197                 && BootEncStatus.ConfiguredEncryptedAreaEnd >= BootEncStatus.BootDriveLength.QuadPart - 1);
 1198     }
 1199     catch (Exception &e)
 1200     {
 1201         if (!bSilent)
 1202             e.Show (MainDlg);
 1203 
 1204         return FALSE;
 1205     }
 1206 }
 1207 
 1208 // Returns the size of the system drive/partition (if encrypted) in bytes
 1209 unsigned __int64 GetSysEncDeviceSize (BOOL bSilent)
 1210 {
 1211     try
 1212     {
 1213         BootEncStatus = BootEncObj->GetStatus();
 1214     }
 1215     catch (Exception &e)
 1216     {
 1217         if (!bSilent)
 1218             e.Show (MainDlg);
 1219         return 1;
 1220     }
 1221 
 1222     if (    BootEncStatus.ConfiguredEncryptedAreaEnd < 0
 1223         ||  BootEncStatus.ConfiguredEncryptedAreaStart < 0
 1224         ||  BootEncStatus.ConfiguredEncryptedAreaEnd < BootEncStatus.ConfiguredEncryptedAreaStart
 1225         )
 1226         return 1; // we return 1 to avoid devision by zero
 1227     else
 1228         return ((unsigned __int64)(BootEncStatus.ConfiguredEncryptedAreaEnd - BootEncStatus.ConfiguredEncryptedAreaStart)) + 1;
 1229 }
 1230 
 1231 // Returns the current size of the encrypted area of the system drive/partition in bytes
 1232 unsigned __int64 GetSysEncDeviceEncryptedPartSize (BOOL bSilent)
 1233 {
 1234     try
 1235     {
 1236         BootEncStatus = BootEncObj->GetStatus();
 1237     }
 1238     catch (Exception &e)
 1239     {
 1240         if (!bSilent)
 1241             e.Show (MainDlg);
 1242         return 0;
 1243     }
 1244 
 1245     if (    BootEncStatus.EncryptedAreaEnd < 0
 1246         || BootEncStatus.EncryptedAreaStart < 0
 1247         || BootEncStatus.EncryptedAreaEnd < BootEncStatus.EncryptedAreaStart
 1248         )
 1249         return 0;
 1250     else
 1251         return ((unsigned __int64)(BootEncStatus.EncryptedAreaEnd - BootEncStatus.EncryptedAreaStart)) + 1;
 1252 }
 1253 
 1254 
 1255 static void PopulateSysEncContextMenu (HMENU popup, BOOL bToolsOnly)
 1256 {
 1257     SystemDriveConfiguration config;
 1258     try
 1259     {
 1260         BootEncStatus = BootEncObj->GetStatus();
 1261         config = BootEncObj->GetSystemDriveConfiguration();
 1262     }
 1263     catch (Exception &e)
 1264     {
 1265         e.Show (MainDlg);
 1266     }
 1267 
 1268     if (!bToolsOnly && !IsHiddenOSRunning())
 1269     {
 1270         if (SysEncryptionOrDecryptionRequired ())
 1271         {
 1272             if (!BootEncStatus.SetupInProgress)
 1273                 AppendMenuW (popup, MF_STRING, IDM_SYSENC_RESUME, GetString ("IDM_SYSENC_RESUME"));
 1274 
 1275             if (SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING)
 1276                 AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT"));
 1277 
 1278             AppendMenuW (popup, MF_STRING, IDM_ENCRYPT_SYSTEM_DEVICE, GetString ("ENCRYPT"));
 1279             AppendMenu (popup, MF_SEPARATOR, 0, L"");
 1280         }
 1281     }
 1282 
 1283     AppendMenuW (popup, MF_STRING, IDM_CHANGE_SYS_PASSWORD, GetString ("IDM_CHANGE_SYS_PASSWORD"));
 1284     // AppendMenuW (popup, MF_STRING, IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO, GetString ("IDM_CHANGE_SYS_HEADER_KEY_DERIV_ALGO"));
 1285 
 1286     AppendMenu (popup, MF_SEPARATOR, 0, L"");
 1287     AppendMenuW (popup, MF_STRING, IDM_SYS_ENC_SETTINGS, GetString ("IDM_SYS_ENC_SETTINGS"));
 1288 
 1289     if (!IsHiddenOSRunning())
 1290     {
 1291         AppendMenu (popup, MF_SEPARATOR, 0, L"");
 1292         AppendMenuW (popup, MF_STRING, IDM_CREATE_RESCUE_DISK, GetString ("IDM_CREATE_RESCUE_DISK"));
 1293         AppendMenuW (popup, MF_STRING, IDM_VERIFY_RESCUE_DISK, GetString ("IDM_VERIFY_RESCUE_DISK"));
 1294         AppendMenuW (popup, MF_STRING, IDM_VERIFY_RESCUE_DISK_ISO, GetString ("IDM_VERIFY_RESCUE_DISK_ISO"));
 1295     }
 1296 
 1297     if (!bToolsOnly)
 1298     {
 1299         if (SysDriveOrPartitionFullyEncrypted (FALSE) && !IsHiddenOSRunning())
 1300         {
 1301             AppendMenu (popup, MF_SEPARATOR, 0, L"");
 1302             AppendMenuW (popup, MF_STRING, IDM_PERMANENTLY_DECRYPT_SYS, GetString ("PERMANENTLY_DECRYPT"));
 1303         }
 1304         AppendMenu (popup, MF_SEPARATOR, 0, L"");
 1305         AppendMenuW (popup, MF_STRING, IDM_VOLUME_PROPERTIES, GetString ("IDPM_PROPERTIES"));
 1306     }
 1307 }
 1308 
 1309 
 1310 // WARNING: This function may take a long time to complete. To prevent data corruption, it MUST be called before
 1311 // mounting a partition (as a regular volume) that is within key scope of system encryption.
 1312 // Returns TRUE if the partition can be mounted as a partition within key scope of inactive system encryption.
 1313 // If devicePath is empty, the currently selected partition in the GUI is checked.
 1314 BOOL CheckSysEncMountWithoutPBA (HWND hwndDlg, const wchar_t *devicePath, BOOL quiet)
 1315 {
 1316     BOOL tmpbDevice;
 1317     wchar_t szDevicePath [TC_MAX_PATH+1];
 1318     wchar_t szDiskFile [TC_MAX_PATH+1];
 1319 
 1320     if (wcslen (devicePath) < 2)
 1321     {
 1322         GetVolumePath (MainDlg, szDevicePath, ARRAYSIZE (szDevicePath));
 1323         CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), szDevicePath, &tmpbDevice);
 1324 
 1325         if (!tmpbDevice)
 1326         {
 1327             if (!quiet)
 1328                 Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg);
 1329 
 1330             return FALSE;
 1331         }
 1332 
 1333         if (LOWORD (GetSelectedLong (GetDlgItem (MainDlg, IDC_DRIVELIST))) != TC_MLIST_ITEM_FREE)
 1334         {
 1335             if (!quiet)
 1336                 Warning ("SELECT_FREE_DRIVE", hwndDlg);
 1337 
 1338             return FALSE;
 1339         }
 1340     }
 1341     else
 1342         StringCbCopyW (szDevicePath, sizeof(szDevicePath), devicePath);
 1343 
 1344     wchar_t *partionPortion = wcsrchr (szDevicePath, L'\\');
 1345 
 1346     if (!partionPortion
 1347         || !_wcsicmp (partionPortion, L"\\Partition0"))
 1348     {
 1349         // Only partitions are supported (not whole drives)
 1350         if (!quiet)
 1351             Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg);
 1352 
 1353         return FALSE;
 1354     }
 1355 
 1356     try
 1357     {
 1358         BootEncStatus = BootEncObj->GetStatus();
 1359 
 1360         if (BootEncStatus.DriveMounted)
 1361         {
 1362             int retCode = 0;
 1363             int driveNo;
 1364             wchar_t parentDrivePath [TC_MAX_PATH+1];
 1365 
 1366             if (swscanf (szDevicePath, L"\\Device\\Harddisk%d\\Partition", &driveNo) != 1)
 1367             {
 1368                 if (!quiet)
 1369                     Error ("INVALID_PATH", hwndDlg);
 1370 
 1371                 return FALSE;
 1372             }
 1373 
 1374             StringCbPrintfW (parentDrivePath,
 1375                 sizeof (parentDrivePath),
 1376                 L"\\Device\\Harddisk%d\\Partition0",
 1377                 driveNo);
 1378 
 1379             WaitCursor ();
 1380 
 1381             // This is critical (re-mounting a mounted system volume as a normal volume could cause data corruption)
 1382             // so we force the slower but reliable method
 1383             retCode = IsSystemDevicePath (parentDrivePath, MainDlg, TRUE);
 1384 
 1385             NormalCursor();
 1386 
 1387             if (retCode != 2)
 1388                 return TRUE;
 1389             else
 1390             {
 1391                 // The partition is located on active system drive
 1392 
 1393                 if (!quiet)
 1394                     Warning ("MOUNT_WITHOUT_PBA_VOL_ON_ACTIVE_SYSENC_DRIVE", hwndDlg);
 1395 
 1396                 return FALSE;
 1397             }
 1398         }
 1399         else
 1400             return TRUE;
 1401     }
 1402     catch (Exception &e)
 1403     {
 1404         NormalCursor();
 1405         e.Show (hwndDlg);
 1406     }
 1407 
 1408     return FALSE;
 1409 }
 1410 
 1411 
 1412 // Returns TRUE if the host drive of the specified partition contains a portion of the TrueCrypt Boot Loader
 1413 // and if the drive is not within key scope of active system encryption (e.g. the system drive of the running OS).
 1414 // If bPrebootPasswordDlgMode is TRUE, this function returns FALSE (because the check would be redundant).
 1415 BOOL TCBootLoaderOnInactiveSysEncDrive (wchar_t *szDevicePath)
 1416 {
 1417     try
 1418     {
 1419         int driveNo;
 1420         wchar_t parentDrivePath [TC_MAX_PATH+1];
 1421 
 1422         if (bPrebootPasswordDlgMode)
 1423             return FALSE;
 1424 
 1425 
 1426         if (swscanf (szDevicePath, L"\\Device\\Harddisk%d\\Partition", &driveNo) != 1)
 1427             return FALSE;
 1428 
 1429         StringCbPrintfW (parentDrivePath,
 1430             sizeof (parentDrivePath),
 1431             L"\\Device\\Harddisk%d\\Partition0",
 1432             driveNo);
 1433 
 1434         BootEncStatus = BootEncObj->GetStatus();
 1435 
 1436         if (BootEncStatus.DriveMounted
 1437             && IsSystemDevicePath (parentDrivePath, MainDlg, FALSE) == 2)
 1438         {
 1439             // The partition is within key scope of active system encryption
 1440             return FALSE;
 1441         }
 1442 
 1443         return ((BOOL) BootEncObj->IsBootLoaderOnDrive (parentDrivePath));
 1444     }
 1445     catch (...)
 1446     {
 1447         return FALSE;
 1448     }
 1449 
 1450 }
 1451 
 1452 
 1453 BOOL SelectItem (HWND hTree, wchar_t nLetter)
 1454 {
 1455     if (nLetter == 0)
 1456     {
 1457         // The caller specified an invalid drive letter (typically because it is unknown).
 1458         // Find out which drive letter is currently selected in the list and use it.
 1459         nLetter = (wchar_t) (HIWORD (GetSelectedLong (hTree)));
 1460     }
 1461 
 1462     int i;
 1463     LVITEM item;
 1464 
 1465     for (i = 0; i < ListView_GetItemCount(hTree); i++)
 1466     {
 1467         memset(&item, 0, sizeof(LVITEM));
 1468         item.mask = LVIF_PARAM;
 1469         item.iItem = i;
 1470 
 1471         if (ListView_GetItem (hTree, &item) == FALSE)
 1472             return FALSE;
 1473         else
 1474         {
 1475             if (HIWORD (item.lParam) == nLetter)
 1476             {
 1477                 memset(&item, 0, sizeof(LVITEM));
 1478                 item.state = LVIS_FOCUSED|LVIS_SELECTED;
 1479                 item.stateMask = LVIS_FOCUSED|LVIS_SELECTED;
 1480                 item.mask = LVIF_STATE;
 1481                 item.iItem = i;
 1482                 SendMessage(hTree, LVM_SETITEMSTATE, i, (LPARAM) &item);
 1483                 return TRUE;
 1484             }
 1485         }
 1486     }
 1487 
 1488     return TRUE;
 1489 }
 1490 
 1491 
 1492 static void LaunchVolCreationWizard (HWND hwndDlg, const wchar_t *arg, BOOL bElevation)
 1493 {
 1494     wchar_t t[TC_MAX_PATH + 1024] = {L'"',0};
 1495     wchar_t *tmp;
 1496 
 1497     GetModuleFileName (NULL, t+1, ARRAYSIZE(t)-1);
 1498 
 1499     tmp = wcsrchr (t, L'\\');
 1500     if (tmp)
 1501     {
 1502         STARTUPINFO si;
 1503         PROCESS_INFORMATION pi;
 1504         wchar_t formatExeName[64];
 1505         wchar_t* suffix = NULL;
 1506         ZeroMemory (&si, sizeof (si));
 1507 
 1508         StringCbCopyW (formatExeName, sizeof (formatExeName), L"\\VeraCrypt Format");
 1509 
 1510         // check if there is a suffix in VeraCrypt file name
 1511         // in order to use the same for "VeraCrypt Format"
 1512         suffix = wcsrchr (tmp + 1, L'-');
 1513         if (suffix)
 1514         {
 1515             StringCbCatW (formatExeName, sizeof (formatExeName), suffix);
 1516             StringCbCatW (formatExeName, sizeof (formatExeName), L"\"");
 1517         }
 1518         else
 1519             StringCbCatW (formatExeName, sizeof (formatExeName), L".exe\"");
 1520 
 1521         *tmp = 0;
 1522         StringCbCatW (t, sizeof(t), formatExeName);
 1523 
 1524         if (!FileExists(t))
 1525             Error ("VOL_CREATION_WIZARD_NOT_FOUND", hwndDlg);   // Display a user-friendly error message and advise what to do
 1526         else if (!VerifyModuleSignature (t))
 1527         {
 1528             Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 1529         }
 1530         else
 1531         {
 1532 
 1533             if (bElevation && !IsAdmin() && IsUacSupported())
 1534             {
 1535                 LaunchElevatedProcess (hwndDlg, t, arg);
 1536             }
 1537             else
 1538             {
 1539                 if (wcslen (arg) > 0)
 1540                 {
 1541                     StringCbCatW (t, sizeof(t), L" ");
 1542                     StringCbCatW (t, sizeof(t), arg);
 1543                 }
 1544                 if (!CreateProcess (NULL, (LPWSTR) t, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
 1545                 {
 1546                     handleWin32Error (hwndDlg, SRC_POS);
 1547                 }
 1548                 else
 1549                 {
 1550                     CloseHandle (pi.hProcess);
 1551                     CloseHandle (pi.hThread);
 1552                 }
 1553             }
 1554         }
 1555     }
 1556 }
 1557 
 1558 static void LaunchVolExpander (HWND hwndDlg)
 1559 {
 1560     wchar_t t[TC_MAX_PATH + TC_MAX_PATH] = {L'"',0};
 1561     wchar_t *tmp;
 1562 
 1563     GetModuleFileName (NULL, t+1, ARRAYSIZE(t)-1);
 1564 
 1565     tmp = wcsrchr (t, L'\\');
 1566     if (tmp)
 1567     {
 1568         wchar_t expanderExeName[64];
 1569         wchar_t* suffix = NULL;
 1570 
 1571         StringCbCopyW (expanderExeName, sizeof (expanderExeName), L"\\VeraCryptExpander");
 1572 
 1573         // check if there is a suffix in VeraCrypt file name
 1574         // in order to use the same for "VeraCrypt Format"
 1575         suffix = wcsrchr (tmp + 1, L'-');
 1576         if (suffix)
 1577         {
 1578             StringCbCatW (expanderExeName, sizeof (expanderExeName), suffix);
 1579             StringCbCatW (expanderExeName, sizeof (expanderExeName), L"\"");
 1580         }
 1581         else
 1582             StringCbCatW (expanderExeName, sizeof (expanderExeName), L".exe\"");
 1583 
 1584         *tmp = 0;
 1585         StringCbCatW (t, sizeof(t), expanderExeName);
 1586 
 1587         if (!FileExists(t))
 1588             Error ("VOL_EXPANDER_NOT_FOUND", hwndDlg);  // Display a user-friendly error message and advise what to do
 1589         else if (((int)ShellExecuteW (NULL, (!IsAdmin() && IsUacSupported()) ? L"runas" : L"open", t, NULL, NULL, SW_SHOW)) <= 32)
 1590         {
 1591             handleWin32Error (hwndDlg, SRC_POS);
 1592         }
 1593     }
 1594 }
 1595 
 1596 
 1597 // Fills drive list
 1598 // drive>0 = update only the corresponding drive subitems
 1599 void LoadDriveLetters (HWND hwndDlg, HWND hTree, int drive)
 1600 {
 1601     // Remember the top-most visible item
 1602     int lastTopMostVisibleItem = (!Silent && hTree)? ListView_GetTopIndex (hTree) : 0;
 1603 
 1604     wchar_t *szDriveLetters[]=
 1605     {L"A:", L"B:", L"C:", L"D:",
 1606      L"E:", L"F:", L"G:", L"H:", L"I:", L"J:", L"K:",
 1607      L"L:", L"M:", L"N:", L"O:", L"P:", L"Q:", L"R:",
 1608      L"S:", L"T:", L"U:", L"V:", L"W:", L"X:", L"Y:",
 1609      L"Z:"};
 1610 
 1611     DWORD dwResult;
 1612     BOOL bResult;
 1613     DWORD dwUsedDrives;
 1614     MOUNT_LIST_STRUCT driver;
 1615     VOLUME_PROPERTIES_STRUCT propSysEnc;
 1616     wchar_t sysDriveLetter = 0;
 1617 
 1618     BOOL bSysEnc = FALSE;
 1619     BOOL bWholeSysDriveEncryption = FALSE;
 1620 
 1621     LVITEM listItem;
 1622     int item = 0;
 1623     char i;
 1624 
 1625     try
 1626     {
 1627         BootEncStatus = BootEncObj->GetStatus();
 1628         if (bSysEnc = BootEncStatus.DriveMounted)
 1629         {
 1630             BootEncObj->GetVolumeProperties (&propSysEnc);
 1631         }
 1632     }
 1633     catch (...)
 1634     {
 1635         bSysEnc = FALSE;
 1636     }
 1637 
 1638     ZeroMemory (&driver, sizeof (driver));
 1639     bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &driver,
 1640         sizeof (driver), &driver, sizeof (driver), &dwResult,
 1641         NULL);
 1642     memcpy (&LastKnownMountList, &driver, sizeof (driver));
 1643 
 1644     if ((bResult == FALSE) || (driver.ulMountedDrives >= (1 << 26)))
 1645     {
 1646         KillTimer (MainDlg, TIMER_ID_MAIN);
 1647         KillTimer (hwndDlg, TIMER_ID_UPDATE_DEVICE_LIST);
 1648         handleWin32Error (hTree, SRC_POS);
 1649         AbortProcessSilent();
 1650     }
 1651 
 1652     LastKnownLogicalDrives = dwUsedDrives = GetUsedLogicalDrives ();
 1653     if (dwUsedDrives == 0)
 1654             Warning ("DRIVELETTERS", hwndDlg);
 1655 
 1656     if (Silent)
 1657         return;
 1658 
 1659     if(drive == 0)
 1660         ListView_DeleteAllItems(hTree);
 1661 
 1662     if (bSysEnc)
 1663     {
 1664         bWholeSysDriveEncryption = WholeSysDriveEncryption (TRUE);
 1665 
 1666         sysDriveLetter = GetSystemDriveLetter ();
 1667     }
 1668 
 1669     /* System drive */
 1670 
 1671     if (bWholeSysDriveEncryption)
 1672     {
 1673         int curDrive = 0;
 1674 
 1675         if (drive > 0)
 1676         {
 1677             LVITEM tmp;
 1678             memset(&tmp, 0, sizeof(LVITEM));
 1679             tmp.mask = LVIF_PARAM;
 1680             tmp.iItem = item;
 1681             if (ListView_GetItem (hTree, &tmp))
 1682                 curDrive = HIWORD(tmp.lParam);
 1683         }
 1684 
 1685         {
 1686             wchar_t szTmp[1024];
 1687             wchar_t szTmpW[1024];
 1688 
 1689             memset(&listItem, 0, sizeof(listItem));
 1690 
 1691             listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
 1692             listItem.iImage = 2;
 1693             listItem.iItem = item++;
 1694 
 1695             listItem.pszText = szTmp;
 1696             szTmp[0] = L' ';
 1697             szTmp[1] = 0;
 1698 
 1699             listItem.lParam = MAKELONG (TC_MLIST_ITEM_SYS_DRIVE, ENC_SYSDRIVE_PSEUDO_DRIVE_LETTER);
 1700 
 1701             if(drive == 0)
 1702                 ListView_InsertItem (hTree, &listItem);
 1703             else
 1704                 ListView_SetItem (hTree, &listItem);
 1705 
 1706             listItem.mask=LVIF_TEXT;
 1707 
 1708             // Fully encrypted
 1709             if (SysDriveOrPartitionFullyEncrypted (TRUE))
 1710             {
 1711                 StringCbCopyW (szTmpW, sizeof(szTmpW), GetString ("SYSTEM_DRIVE"));
 1712             }
 1713             else
 1714             {
 1715                 // Partially encrypted
 1716 
 1717                 if (BootEncStatus.SetupInProgress)
 1718                 {
 1719                     // Currently encrypting/decrypting
 1720 
 1721                     if (BootEncStatus.SetupMode != SetupDecryption)
 1722                     {
 1723                         StringCbPrintfW (szTmpW,
 1724                             sizeof szTmpW,
 1725                             GetString ("SYSTEM_DRIVE_ENCRYPTING"),
 1726                             (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0);
 1727                     }
 1728                     else
 1729                     {
 1730                         StringCbPrintfW (szTmpW,
 1731                             sizeof szTmpW,
 1732                             GetString ("SYSTEM_DRIVE_DECRYPTING"),
 1733                             100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0));
 1734                     }
 1735                 }
 1736                 else
 1737                 {
 1738                     StringCbPrintfW (szTmpW,
 1739                         sizeof szTmpW,
 1740                         GetString ("SYSTEM_DRIVE_PARTIALLY_ENCRYPTED"),
 1741                         (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0);
 1742                 }
 1743             }
 1744 
 1745             ListSubItemSet (hTree, listItem.iItem, 1, szTmpW);
 1746 
 1747             GetSizeString (GetSysEncDeviceSize(TRUE), szTmpW, sizeof(szTmpW));
 1748             ListSubItemSet (hTree, listItem.iItem, 2, szTmpW);
 1749 
 1750             if (propSysEnc.ea >= EAGetFirst() && propSysEnc.ea <= EAGetCount())
 1751             {
 1752                 EAGetName (szTmp, propSysEnc.ea, 1);
 1753             }
 1754             else
 1755             {
 1756                 szTmp[0] = L'?';
 1757                 szTmp[1] = 0;
 1758             }
 1759             listItem.iSubItem = 3;
 1760             ListView_SetItem (hTree, &listItem);
 1761 
 1762             ListSubItemSet (hTree, listItem.iItem, 4, GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE"));
 1763         }
 1764     }
 1765 
 1766     /* Drive letters */
 1767 
 1768     for (i = 0; i < 26; i++)
 1769     {
 1770         int curDrive = 0;
 1771 
 1772         BOOL bSysEncPartition = (bSysEnc && !bWholeSysDriveEncryption && sysDriveLetter == *((wchar_t *) szDriveLetters[i]));
 1773 
 1774         if (drive > 0)
 1775         {
 1776             LVITEM tmp;
 1777             memset(&tmp, 0, sizeof(LVITEM));
 1778             tmp.mask = LVIF_PARAM;
 1779             tmp.iItem = item;
 1780             if (ListView_GetItem (hTree, &tmp))
 1781                 curDrive = HIWORD(tmp.lParam);
 1782         }
 1783 
 1784         if (((driver.ulMountedDrives & (1 << i)) && (IsNullTerminateString (driver.wszVolume[i], TC_MAX_PATH)))
 1785             || bSysEncPartition)
 1786         {
 1787             wchar_t szTmp[1024];
 1788             wchar_t szTmpW[1024];
 1789             wchar_t *ws;
 1790 
 1791             memset(&listItem, 0, sizeof(listItem));
 1792 
 1793             listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
 1794             listItem.iImage = bSysEncPartition ? 2 : 1;
 1795             listItem.iItem = item++;
 1796 
 1797             if (drive > 0 && drive != curDrive)
 1798                 continue;
 1799 
 1800             listItem.lParam = MAKELONG (
 1801                 bSysEncPartition ? TC_MLIST_ITEM_SYS_PARTITION : TC_MLIST_ITEM_NONSYS_VOL,
 1802                 i + L'A');
 1803 
 1804             listItem.pszText = szDriveLetters[i];
 1805 
 1806             if (drive == 0)
 1807                 ListView_InsertItem (hTree, &listItem);
 1808             else
 1809                 ListView_SetItem (hTree, &listItem);
 1810 
 1811             listItem.mask=LVIF_TEXT;
 1812             listItem.pszText = szTmp;
 1813 
 1814             if (bSysEncPartition)
 1815             {
 1816                 // Fully encrypted
 1817                 if (SysDriveOrPartitionFullyEncrypted (TRUE))
 1818                 {
 1819                     StringCbCopyW (szTmpW, sizeof(szTmpW), GetString (IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION"));
 1820                 }
 1821                 else
 1822                 {
 1823                     // Partially encrypted
 1824 
 1825                     if (BootEncStatus.SetupInProgress)
 1826                     {
 1827                         // Currently encrypting/decrypting
 1828 
 1829                         if (BootEncStatus.SetupMode != SetupDecryption)
 1830                         {
 1831                             StringCbPrintfW (szTmpW,
 1832                                 sizeof szTmpW,
 1833                                 GetString ("SYSTEM_PARTITION_ENCRYPTING"),
 1834                                 (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0);
 1835                         }
 1836                         else
 1837                         {
 1838                             StringCbPrintfW (szTmpW,
 1839                                 sizeof szTmpW,
 1840                                 GetString ("SYSTEM_PARTITION_DECRYPTING"),
 1841                                 100.0 - ((double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0));
 1842                         }
 1843                     }
 1844                     else
 1845                     {
 1846                         StringCbPrintfW (szTmpW,
 1847                             sizeof szTmpW,
 1848                             GetString ("SYSTEM_PARTITION_PARTIALLY_ENCRYPTED"),
 1849                             (double) GetSysEncDeviceEncryptedPartSize (TRUE) / (double) GetSysEncDeviceSize (TRUE) * 100.0);
 1850                     }
 1851                 }
 1852 
 1853                 ListSubItemSet (hTree, listItem.iItem, 1, szTmpW);
 1854             }
 1855             else
 1856             {
 1857                 wchar_t *path = driver.wszVolume[i];
 1858 
 1859                 if (wmemcmp (path, L"\\??\\", 4) == 0)
 1860                     path += 4;
 1861 
 1862                 listItem.iSubItem = 1;
 1863 
 1864                 // first check label used for mounting. If empty, look for it in favorites.
 1865                 bool useInExplorer = false;
 1866                 wstring label = (wchar_t *) driver.wszLabel[i];
 1867                 if (label.empty())
 1868                     label = GetFavoriteVolumeLabel (path, useInExplorer);
 1869                 if (!label.empty())
 1870                     ListSubItemSet (hTree, listItem.iItem, 1, (wchar_t *) label.c_str());
 1871                 else
 1872                     ListSubItemSet (hTree, listItem.iItem, 1, (wchar_t *) FitPathInGfxWidth (hTree, hUserFont, ListView_GetColumnWidth (hTree, 1) - GetTextGfxWidth (hTree, L"___", hUserFont), path).c_str());
 1873             }
 1874 
 1875             GetSizeString (bSysEncPartition ? GetSysEncDeviceSize(TRUE) : driver.diskLength[i], szTmpW, sizeof(szTmpW));
 1876             ListSubItemSet (hTree, listItem.iItem, 2, szTmpW);
 1877 
 1878             EAGetName (szTmp, bSysEncPartition ? propSysEnc.ea : driver.ea[i], 1);
 1879             listItem.iSubItem = 3;
 1880             ListView_SetItem (hTree, &listItem);
 1881 
 1882             if (bSysEncPartition)
 1883             {
 1884                 ws = GetString (IsHiddenOSRunning() ? "HIDDEN" : "SYSTEM_VOLUME_TYPE_ADJECTIVE");
 1885                 VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE;
 1886                 ListSubItemSet (hTree, listItem.iItem, 4, ws);
 1887             }
 1888             else
 1889             {
 1890                 switch (driver.volumeType[i])
 1891                 {
 1892                 case PROP_VOL_TYPE_NORMAL:
 1893                     ws = GetString ("NORMAL");
 1894                     break;
 1895                 case PROP_VOL_TYPE_HIDDEN:
 1896                     ws = GetString ("HIDDEN");
 1897                     break;
 1898                 case PROP_VOL_TYPE_OUTER:
 1899                     ws = GetString ("OUTER");       // Normal/outer volume (hidden volume protected)
 1900                     break;
 1901                 case PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED:
 1902                     ws = GetString ("OUTER_VOL_WRITE_PREVENTED");   // Normal/outer volume (hidden volume protected AND write denied)
 1903                     break;
 1904                 default:
 1905                     ws = L"?";
 1906                 }
 1907 
 1908                 if (driver.truecryptMode[i])
 1909                 {
 1910                     StringCbPrintfW (szTmpW, sizeof(szTmpW), L"TrueCrypt-%s", ws);
 1911                     ListSubItemSet (hTree, listItem.iItem, 4, szTmpW);
 1912                 }
 1913                 else
 1914                     ListSubItemSet (hTree, listItem.iItem, 4, ws);
 1915 
 1916                 if (driver.volumeType[i] == PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED)    // Normal/outer volume (hidden volume protected AND write denied)
 1917                 {
 1918                     if (!VolumeNotificationsList.bHidVolDamagePrevReported[i])
 1919                     {
 1920                         wchar_t szTmp[4096];
 1921 
 1922                         VolumeNotificationsList.bHidVolDamagePrevReported[i] = TRUE;
 1923                         StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), i+L'A');
 1924                         SetForegroundWindow (GetParent(hTree));
 1925                         MessageBoxW (GetParent(hTree), szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
 1926                     }
 1927                 }
 1928                 else
 1929                 {
 1930                     VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE;
 1931                 }
 1932             }
 1933         }
 1934         else
 1935         {
 1936             VolumeNotificationsList.bHidVolDamagePrevReported[i] = FALSE;
 1937 
 1938             if (!(dwUsedDrives & 1 << i))
 1939             {
 1940                 if(drive > 0 && drive != HIWORD (GetSelectedLong (hTree)))
 1941                 {
 1942                     item++;
 1943                     continue;
 1944                 }
 1945 
 1946                 memset(&listItem,0,sizeof(listItem));
 1947 
 1948                 listItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
 1949                 listItem.iImage = 0;
 1950                 listItem.iItem = item++;
 1951                 listItem.pszText = szDriveLetters[i];
 1952                 listItem.lParam = MAKELONG (TC_MLIST_ITEM_FREE, i + 'A');
 1953 
 1954                 if(drive == 0)
 1955                     ListView_InsertItem (hTree, &listItem);
 1956                 else
 1957                     ListView_SetItem (hTree, &listItem);
 1958 
 1959                 listItem.mask=LVIF_TEXT;
 1960                 listItem.pszText = L"";
 1961                 listItem.iSubItem = 1;
 1962                 ListView_SetItem (hTree, &listItem);
 1963                 listItem.iSubItem = 2;
 1964                 ListView_SetItem (hTree, &listItem);
 1965                 listItem.iSubItem = 3;
 1966                 ListView_SetItem (hTree, &listItem);
 1967                 listItem.iSubItem = 4;
 1968                 ListView_SetItem (hTree, &listItem);
 1969 
 1970             }
 1971         }
 1972     }
 1973 
 1974     // Restore the original scroll position (the topmost item that was visible when we were called) and the
 1975     // last selected item.
 1976     SetListScrollHPos (hTree, lastTopMostVisibleItem);
 1977     SelectItem (hTree, 0);
 1978 }
 1979 
 1980 static void PasswordChangeEnable (HWND hwndDlg, int button, int passwordId, BOOL keyFilesEnabled,
 1981                                   int newPasswordId, int newVerifyId, BOOL newKeyFilesEnabled)
 1982 {
 1983     char password[MAX_PASSWORD + 1];
 1984     char newPassword[MAX_PASSWORD + 1];
 1985     char newVerify[MAX_PASSWORD + 1];
 1986     wchar_t tmp[MAX_PASSWORD + 1];
 1987     BOOL bEnable = TRUE;
 1988     int passwordUtf8Len, newPasswordUtf8Len, newVerifyUtf8Len;
 1989 
 1990     GetWindowText (GetDlgItem (hwndDlg, passwordId), tmp, ARRAYSIZE (tmp));
 1991     passwordUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, password, sizeof (password), NULL, NULL);
 1992 
 1993     if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF)
 1994         newKeyFilesEnabled = keyFilesEnabled;
 1995 
 1996     switch (pwdChangeDlgMode)
 1997     {
 1998     case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL:
 1999     case PCDM_ADD_REMOVE_VOL_KEYFILES:
 2000     case PCDM_CHANGE_PKCS5_PRF:
 2001         memcpy (newPassword, password, sizeof (newPassword));
 2002         memcpy (newVerify, password, sizeof (newVerify));
 2003         newPasswordUtf8Len = passwordUtf8Len;
 2004         newVerifyUtf8Len = passwordUtf8Len;
 2005         break;
 2006 
 2007     default:
 2008         GetWindowText (GetDlgItem (hwndDlg, newPasswordId), tmp, ARRAYSIZE (tmp));
 2009         newPasswordUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, newPassword, sizeof (newPassword), NULL, NULL);
 2010         GetWindowText (GetDlgItem (hwndDlg, newVerifyId), tmp, ARRAYSIZE (tmp));
 2011         newVerifyUtf8Len = WideCharToMultiByte (CP_UTF8, 0, tmp, -1, newVerify, sizeof (newVerify), NULL, NULL);
 2012 
 2013     }
 2014 
 2015     if (passwordUtf8Len <= 0 || (!keyFilesEnabled && ((passwordUtf8Len - 1) < MIN_PASSWORD)))
 2016         bEnable = FALSE;
 2017     else if (strcmp (newPassword, newVerify) != 0)
 2018         bEnable = FALSE;
 2019     else if ((newPasswordUtf8Len <= 0) || (!newKeyFilesEnabled && ((newPasswordUtf8Len - 1) < MIN_PASSWORD)))
 2020         bEnable = FALSE;
 2021 
 2022     burn (password, sizeof (password));
 2023     burn (newPassword, sizeof (newPassword));
 2024     burn (newVerify, sizeof (newVerify));
 2025     burn (tmp, sizeof (tmp));
 2026 
 2027     EnableWindow (GetDlgItem (hwndDlg, button), bEnable);
 2028 }
 2029 
 2030 // implementation for support of change password operation in wait dialog mechanism
 2031 
 2032 typedef struct
 2033 {
 2034     Password *oldPassword;
 2035     int old_pkcs5;
 2036     int old_pim;
 2037     Password *newPassword;
 2038     int pkcs5;
 2039     int pim;
 2040     int wipePassCount;
 2041     BOOL truecryptMode;
 2042     int* pnStatus;
 2043 } ChangePwdThreadParam;
 2044 
 2045 void CALLBACK ChangePwdWaitThreadProc(void* pArg, HWND hwndDlg)
 2046 {
 2047     ChangePwdThreadParam* pThreadParam = (ChangePwdThreadParam*) pArg;
 2048 
 2049     if (bSysEncPwdChangeDlgMode)
 2050     {
 2051         // System
 2052 
 2053         try
 2054         {
 2055             VOLUME_PROPERTIES_STRUCT properties;
 2056             BootEncObj->GetVolumeProperties(&properties);
 2057             pThreadParam->old_pkcs5 = properties.pkcs5;
 2058         }
 2059         catch(...)
 2060         {}
 2061 
 2062         pThreadParam->pkcs5 = 0;    // PKCS-5 PRF unchanged (currently we can't change PRF of system encryption)
 2063 
 2064         try
 2065         {
 2066             *pThreadParam->pnStatus = BootEncObj->ChangePassword (pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg);
 2067         }
 2068         catch (Exception &e)
 2069         {
 2070             e.Show (hwndDlg);
 2071             *(pThreadParam->pnStatus) = ERR_OS_ERROR;
 2072         }
 2073     }
 2074     else
 2075     {
 2076         // Non-system
 2077 
 2078         *pThreadParam->pnStatus = ChangePwd (szFileName, pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->truecryptMode, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg);
 2079 
 2080         if (*pThreadParam->pnStatus == ERR_OS_ERROR
 2081             && GetLastError () == ERROR_ACCESS_DENIED
 2082             && IsUacSupported ()
 2083             && IsVolumeDeviceHosted (szFileName))
 2084         {
 2085             *pThreadParam->pnStatus = UacChangePwd (szFileName, pThreadParam->oldPassword, pThreadParam->old_pkcs5, pThreadParam->old_pim, pThreadParam->truecryptMode, pThreadParam->newPassword, pThreadParam->pkcs5, pThreadParam->pim, pThreadParam->wipePassCount, hwndDlg);
 2086         }
 2087     }
 2088 }
 2089 
 2090 // implementation for support of backup header operation in wait dialog mechanism
 2091 
 2092 typedef struct
 2093 {
 2094     BOOL bRequireConfirmation;
 2095     wchar_t *lpszVolume;
 2096     size_t cchVolume;
 2097     int* iResult;
 2098 } BackupHeaderThreadParam;
 2099 
 2100 void CALLBACK BackupHeaderWaitThreadProc(void* pArg, HWND hwndDlg)
 2101 {
 2102     BackupHeaderThreadParam* pThreadParam = (BackupHeaderThreadParam*) pArg;
 2103 
 2104     if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume))
 2105     {
 2106         if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume))
 2107             *(pThreadParam->iResult) = UacBackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume);
 2108         else
 2109             *(pThreadParam->iResult) = BackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume);
 2110     }
 2111     else
 2112         *(pThreadParam->iResult) = ERR_OS_ERROR;
 2113 }
 2114 
 2115 // implementation for support of restoring header operation in wait dialog mechanism
 2116 
 2117 typedef struct
 2118 {
 2119     wchar_t *lpszVolume;
 2120     size_t cchVolume;
 2121     int* iResult;
 2122 } RestoreHeaderThreadParam;
 2123 
 2124 void CALLBACK RestoreHeaderWaitThreadProc(void* pArg, HWND hwndDlg)
 2125 {
 2126     RestoreHeaderThreadParam* pThreadParam = (RestoreHeaderThreadParam*) pArg;
 2127 
 2128     if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume))
 2129     {
 2130         if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume))
 2131             *(pThreadParam->iResult) = UacRestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume);
 2132         else
 2133             *(pThreadParam->iResult) = RestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume);
 2134     }
 2135     else
 2136         *(pThreadParam->iResult) = ERR_OS_ERROR;
 2137 }
 2138 
 2139 /* Except in response to the WM_INITDIALOG message, the dialog box procedure
 2140    should return nonzero if it processes the message, and zero if it does
 2141    not. - see DialogProc */
 2142 BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 2143 {
 2144     static KeyFilesDlgParam newKeyFilesParam;
 2145     static BOOL PimValueChangedWarning = FALSE;
 2146     static int* NewPimValuePtr = NULL;
 2147 
 2148     WORD lw = LOWORD (wParam);
 2149     WORD hw = HIWORD (wParam);
 2150 
 2151     switch (msg)
 2152     {
 2153     case WM_INITDIALOG:
 2154         {
 2155             LPARAM nIndex, nSelectedIndex = 0;
 2156             HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID);
 2157             int i;
 2158             WipeAlgorithmId headerWipeMode = TC_WIPE_3_DOD_5220;
 2159             int EffectiveVolumePkcs5 = CmdVolumePkcs5;
 2160             BOOL EffectiveVolumeTrueCryptMode = CmdVolumeTrueCryptMode;
 2161             int EffectiveVolumePim = CmdVolumePim;
 2162 
 2163             /* Priority is given to command line parameters
 2164              * Default values used only when nothing specified in command line
 2165              */
 2166             if (EffectiveVolumePkcs5 == 0)
 2167                 EffectiveVolumePkcs5 = DefaultVolumePkcs5;
 2168             if (!EffectiveVolumeTrueCryptMode)
 2169                 EffectiveVolumeTrueCryptMode = DefaultVolumeTrueCryptMode;
 2170 
 2171             NewPimValuePtr = (int*) lParam;
 2172 
 2173             PimValueChangedWarning = FALSE;
 2174 
 2175             ZeroMemory (&newKeyFilesParam, sizeof (newKeyFilesParam));
 2176             if (NewPimValuePtr)
 2177             {
 2178                 /* we are in the case of a volume. Store its name to use it in the key file dialog
 2179                  * this will help avoid using the current container file as a key file
 2180                  */
 2181                 StringCbCopyW (newKeyFilesParam.VolumeFileName, sizeof (newKeyFilesParam.VolumeFileName), szFileName);
 2182             }
 2183 
 2184             SetWindowTextW (hwndDlg, GetString ("IDD_PASSWORDCHANGE_DLG"));
 2185             LocalizeDialog (hwndDlg, "IDD_PASSWORDCHANGE_DLG");
 2186 
 2187             ToNormalPwdField (hwndDlg, IDC_OLD_PASSWORD);
 2188             ToNormalPwdField (hwndDlg, IDC_PASSWORD);
 2189             ToNormalPwdField (hwndDlg, IDC_VERIFY);
 2190             SendMessage (GetDlgItem (hwndDlg, IDC_OLD_PIM), EM_LIMITTEXT, MAX_PIM, 0);
 2191             SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0);
 2192             EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE);
 2193 
 2194             SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable);
 2195             EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE);
 2196             EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), TRUE);
 2197 
 2198             /* Add PRF algorithm list for current password */
 2199             SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
 2200 
 2201             nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
 2202             SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
 2203 
 2204             for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
 2205             {
 2206                 nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
 2207                 SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
 2208                 if (i == EffectiveVolumePkcs5)
 2209                 {
 2210                     nSelectedIndex = nIndex;
 2211                 }
 2212             }
 2213 
 2214             SendMessage (hComboBox, CB_SETCURSEL, nSelectedIndex, 0);
 2215 
 2216             /* check TrueCrypt Mode if it was set as default*/
 2217             SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, EffectiveVolumeTrueCryptMode);
 2218 
 2219             /* set default PIM if set in the command line*/
 2220             if (EffectiveVolumePim > 0)
 2221             {
 2222                 SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE);
 2223                 ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE);
 2224                 ShowWindow (GetDlgItem( hwndDlg, IDT_OLD_PIM), SW_SHOW);
 2225                 ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW);
 2226                 ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW);
 2227                 SetPim (hwndDlg, IDC_OLD_PIM, EffectiveVolumePim);
 2228             }
 2229 
 2230             /* Add PRF algorithm list for new password */
 2231             hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
 2232             SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
 2233 
 2234             nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("UNCHANGED"));
 2235             SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
 2236 
 2237             for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
 2238             {
 2239                 if (!HashIsDeprecated (i))
 2240                 {
 2241                     nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
 2242                     SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
 2243                 }
 2244             }
 2245 
 2246             SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
 2247 
 2248             PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, FALSE, TRUE);
 2249             SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &headerWipeMode);
 2250 
 2251             switch (pwdChangeDlgMode)
 2252             {
 2253             case PCDM_CHANGE_PKCS5_PRF:
 2254                 SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_CHANGE_PKCS5_PRF"));
 2255                 LocalizeDialog (hwndDlg, "IDD_PCDM_CHANGE_PKCS5_PRF");
 2256                 EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE);
 2257                 EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE);
 2258                 EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE);
 2259                 EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE);
 2260                 EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE);
 2261                 EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE);
 2262                 EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE);
 2263                 EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE);
 2264                 EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE);
 2265                 EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE);
 2266                 EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE);
 2267                 break;
 2268 
 2269             case PCDM_ADD_REMOVE_VOL_KEYFILES:
 2270                 SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_ADD_REMOVE_VOL_KEYFILES"));
 2271                 LocalizeDialog (hwndDlg, "IDD_PCDM_ADD_REMOVE_VOL_KEYFILES");
 2272                 newKeyFilesParam.EnableKeyFiles = TRUE;
 2273                 EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE);
 2274                 EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE);
 2275                 EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE);
 2276                 EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE);
 2277                 EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE);
 2278                 EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE);
 2279                 EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE);
 2280                 EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE);
 2281                 EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE);
 2282                 EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE);
 2283                 EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE);
 2284                 break;
 2285 
 2286             case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL:
 2287                 newKeyFilesParam.EnableKeyFiles = FALSE;
 2288                 SetWindowTextW (hwndDlg, GetString ("IDD_PCDM_REMOVE_ALL_KEYFILES_FROM_VOL"));
 2289                 LocalizeDialog (hwndDlg, "IDD_PCDM_REMOVE_ALL_KEYFILES_FROM_VOL");
 2290                 KeyFilesEnable = TRUE;
 2291                 SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, TRUE);
 2292                 EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES), TRUE);
 2293                 EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_KEYFILES), TRUE);
 2294                 EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD), FALSE);
 2295                 EnableWindow (GetDlgItem (hwndDlg, IDC_VERIFY), FALSE);
 2296                 EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), FALSE);
 2297                 EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), FALSE);
 2298                 EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), FALSE);
 2299                 EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), FALSE);
 2300                 EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE);
 2301                 EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW), FALSE);
 2302                 EnableWindow (GetDlgItem (hwndDlg, IDC_NEW_KEYFILES), FALSE);
 2303                 EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PASSWORD), FALSE);
 2304                 EnableWindow (GetDlgItem (hwndDlg, IDT_CONFIRM_PASSWORD), FALSE);
 2305                 EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE);
 2306                 EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE);
 2307                 break;
 2308 
 2309             case PCDM_CHANGE_PASSWORD:
 2310             default:
 2311                 // NOP
 2312                 break;
 2313             };
 2314 
 2315             if (bSysEncPwdChangeDlgMode)
 2316             {
 2317                 /* No support for changing the password of TrueCrypt system partition */
 2318                 SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE);
 2319                 EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE);
 2320 
 2321                 ToBootPwdField (hwndDlg, IDC_PASSWORD);
 2322                 ToBootPwdField (hwndDlg, IDC_VERIFY);
 2323                 ToBootPwdField (hwndDlg, IDC_OLD_PASSWORD);
 2324 
 2325                 if ((DWORD) GetKeyboardLayout (NULL) != 0x00000409 && (DWORD) GetKeyboardLayout (NULL) != 0x04090409)
 2326                 {
 2327                     DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE);
 2328 
 2329                     if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 2330                     {
 2331                         Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg);
 2332                         EndDialog (hwndDlg, IDCANCEL);
 2333                         return 0;
 2334                     }
 2335 
 2336                     bKeyboardLayoutChanged = TRUE;
 2337                 }
 2338 
 2339 
 2340                 /* for system encryption, we can't change the PRF */
 2341                 EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), FALSE);
 2342                 EnableWindow (GetDlgItem (hwndDlg, IDT_NEW_PKCS5_PRF), FALSE);
 2343                 EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), FALSE);
 2344                 EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), FALSE);
 2345 
 2346                 if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0)
 2347                 {
 2348                     Error ("CANNOT_SET_TIMER", hwndDlg);
 2349                     EndDialog (hwndDlg, IDCANCEL);
 2350                     return 0;
 2351                 }
 2352 
 2353                 newKeyFilesParam.EnableKeyFiles = FALSE;
 2354                 KeyFilesEnable = FALSE;
 2355                 SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, FALSE);
 2356                 EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_KEYFILES), FALSE);
 2357                 EnableWindow (GetDlgItem (hwndDlg, IDC_ENABLE_NEW_KEYFILES), FALSE);
 2358             }
 2359 
 2360             CheckCapsLock (hwndDlg, FALSE);
 2361 
 2362             return 0;
 2363         }
 2364 
 2365     case WM_TIMER:
 2366         switch (wParam)
 2367         {
 2368         case TIMER_ID_KEYB_LAYOUT_GUARD:
 2369             if (bSysEncPwdChangeDlgMode)
 2370             {
 2371                 DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL);
 2372 
 2373                 /* Watch the keyboard layout */
 2374 
 2375                 if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 2376                 {
 2377                     // Keyboard layout is not standard US
 2378 
 2379                     // Attempt to wipe passwords stored in the input field buffers
 2380                     wchar_t tmp[MAX_PASSWORD+1];
 2381                     wmemset (tmp, L'X', MAX_PASSWORD);
 2382                     tmp [MAX_PASSWORD] = 0;
 2383                     SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp);
 2384                     SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
 2385                     SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp);
 2386 
 2387                     SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), L"");
 2388                     SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L"");
 2389                     SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), L"");
 2390 
 2391                     keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE);
 2392 
 2393                     if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 2394                     {
 2395                         KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD);
 2396                         Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg);
 2397                         EndDialog (hwndDlg, IDCANCEL);
 2398                         return 1;
 2399                     }
 2400 
 2401                     bKeyboardLayoutChanged = TRUE;
 2402 
 2403                     wchar_t szTmp [4096];
 2404                     StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED"));
 2405                     StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
 2406                     StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
 2407                     MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
 2408                 }
 2409 
 2410 
 2411                 /* Watch the right Alt key (which is used to enter various characters on non-US keyboards) */
 2412 
 2413                 if (bKeyboardLayoutChanged && !bKeybLayoutAltKeyWarningShown)
 2414                 {
 2415                     if (GetAsyncKeyState (VK_RMENU) < 0)
 2416                     {
 2417                         bKeybLayoutAltKeyWarningShown = TRUE;
 2418 
 2419                         wchar_t szTmp [4096];
 2420                         StringCbCopyW (szTmp, sizeof(szTmp), GetString ("ALT_KEY_CHARS_NOT_FOR_SYS_ENCRYPTION"));
 2421                         StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
 2422                         StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
 2423                         MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONINFORMATION  | MB_SETFOREGROUND | MB_TOPMOST);
 2424                     }
 2425                 }
 2426             }
 2427             return 1;
 2428         }
 2429         return 0;
 2430 
 2431     case WM_CTLCOLORSTATIC:
 2432         {
 2433             if (PimValueChangedWarning && ((HWND)lParam == GetDlgItem(hwndDlg, IDC_PIM_HELP)) )
 2434             {
 2435                 // we're about to draw the static
 2436                 // set the text colour in (HDC)lParam
 2437                 SetBkMode((HDC)wParam,TRANSPARENT);
 2438                 SetTextColor((HDC)wParam, RGB(255,0,0));
 2439                 // NOTE: per documentation as pointed out by selbie, GetSolidBrush would leak a GDI handle.
 2440                 return (BOOL)GetSysColorBrush(COLOR_MENU);
 2441             }
 2442         }
 2443         return 0;
 2444 
 2445     case WM_COMMAND:
 2446         if (lw == IDCANCEL)
 2447         {
 2448             // Attempt to wipe passwords stored in the input field buffers
 2449             wchar_t tmp[MAX_PASSWORD+1];
 2450             wmemset (tmp, L'X', MAX_PASSWORD);
 2451             tmp[MAX_PASSWORD] = 0;
 2452             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
 2453             SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp);
 2454             SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp);
 2455             RestoreDefaultKeyFilesParam ();
 2456 
 2457             EndDialog (hwndDlg, IDCANCEL);
 2458             return 1;
 2459         }
 2460 
 2461         if (hw == EN_CHANGE)
 2462         {
 2463             PasswordChangeEnable (hwndDlg, IDOK,
 2464                 IDC_OLD_PASSWORD,
 2465                 KeyFilesEnable && FirstKeyFile != NULL,
 2466                 IDC_PASSWORD, IDC_VERIFY,
 2467                 newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
 2468 
 2469             if ((lw == IDC_OLD_PIM) && IsWindowEnabled (GetDlgItem (hwndDlg, IDC_PIM)))
 2470             {
 2471                 wchar_t tmp[MAX_PIM+1] = {0};
 2472                 GetDlgItemText (hwndDlg, IDC_OLD_PIM, tmp, MAX_PIM + 1);
 2473                 SetDlgItemText (hwndDlg, IDC_PIM, tmp);
 2474             }
 2475 
 2476             if (lw == IDC_PIM)
 2477             {
 2478                 if(GetPim (hwndDlg, IDC_OLD_PIM, 0) != GetPim (hwndDlg, IDC_PIM, 0))
 2479                 {
 2480                     PimValueChangedWarning = TRUE;
 2481                     SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, GetString (bSysEncPwdChangeDlgMode? "PIM_SYSENC_CHANGE_WARNING" : "PIM_CHANGE_WARNING"));
 2482                 }
 2483                 else
 2484                 {
 2485                     PimValueChangedWarning = FALSE;
 2486                     SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, (wchar_t *) GetDictionaryValueByInt (IDC_PIM_HELP));
 2487                 }
 2488             }
 2489 
 2490             return 1;
 2491         }
 2492 
 2493         if (lw == IDC_PIM_ENABLE)
 2494         {
 2495             ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE);
 2496             ShowWindow (GetDlgItem( hwndDlg, IDT_OLD_PIM), SW_SHOW);
 2497             ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM), SW_SHOW);
 2498             ShowWindow (GetDlgItem( hwndDlg, IDC_OLD_PIM_HELP), SW_SHOW);
 2499 
 2500             // check also the "Use PIM" for the new password if it is enabled
 2501             if (IsWindowEnabled (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE)))
 2502             {
 2503                 SetCheckBox (hwndDlg, IDC_NEW_PIM_ENABLE, TRUE);
 2504 
 2505                 ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE);
 2506                 ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
 2507                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
 2508                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW);
 2509             }
 2510 
 2511             SetFocus (GetDlgItem (hwndDlg, IDC_OLD_PIM));
 2512 
 2513             return 1;
 2514         }
 2515 
 2516         if (lw == IDC_NEW_PIM_ENABLE)
 2517         {
 2518             ShowWindow (GetDlgItem (hwndDlg, IDC_NEW_PIM_ENABLE), SW_HIDE);
 2519             ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
 2520             ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
 2521             ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW);
 2522 
 2523             SetFocus (GetDlgItem (hwndDlg, IDC_PIM));
 2524 
 2525             return 1;
 2526         }
 2527 
 2528         if (lw == IDC_KEYFILES)
 2529         {
 2530             if (bSysEncPwdChangeDlgMode)
 2531             {
 2532                 Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg);
 2533                 return 1;
 2534             }
 2535 
 2536             KeyFilesDlgParam param;
 2537             param.EnableKeyFiles = KeyFilesEnable;
 2538             param.FirstKeyFile = FirstKeyFile;
 2539 
 2540             if (IDOK == DialogBoxParamW (hInst,
 2541                 MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg,
 2542                 (DLGPROC) KeyFilesDlgProc, (LPARAM) &param))
 2543             {
 2544                 KeyFilesEnable = param.EnableKeyFiles;
 2545                 FirstKeyFile = param.FirstKeyFile;
 2546 
 2547                 SetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES, KeyFilesEnable);
 2548             }
 2549 
 2550             PasswordChangeEnable (hwndDlg, IDOK,
 2551                 IDC_OLD_PASSWORD,
 2552                 KeyFilesEnable && FirstKeyFile != NULL,
 2553                 IDC_PASSWORD, IDC_VERIFY,
 2554                 newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
 2555 
 2556             return 1;
 2557         }
 2558 
 2559 
 2560         if (lw == IDC_NEW_KEYFILES)
 2561         {
 2562             if (bSysEncPwdChangeDlgMode)
 2563             {
 2564                 Warning ("KEYFILES_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg);
 2565                 return 1;
 2566             }
 2567 
 2568             if (IDOK == DialogBoxParamW (hInst,
 2569                 MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg,
 2570                 (DLGPROC) KeyFilesDlgProc, (LPARAM) &newKeyFilesParam))
 2571             {
 2572                 SetCheckBox (hwndDlg, IDC_ENABLE_NEW_KEYFILES, newKeyFilesParam.EnableKeyFiles);
 2573 
 2574                 VerifyPasswordAndUpdate (hwndDlg, GetDlgItem (hwndDlg, IDOK), GetDlgItem (hwndDlg, IDC_PASSWORD),
 2575                     GetDlgItem (hwndDlg, IDC_VERIFY), NULL, NULL,
 2576                     newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
 2577             }
 2578 
 2579             PasswordChangeEnable (hwndDlg, IDOK,
 2580                 IDC_OLD_PASSWORD,
 2581                 KeyFilesEnable && FirstKeyFile != NULL,
 2582                 IDC_PASSWORD, IDC_VERIFY,
 2583                 newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
 2584 
 2585             return 1;
 2586         }
 2587 
 2588         if (lw == IDC_ENABLE_KEYFILES)
 2589         {
 2590             KeyFilesEnable = GetCheckBox (hwndDlg, IDC_ENABLE_KEYFILES);
 2591 
 2592             PasswordChangeEnable (hwndDlg, IDOK,
 2593                 IDC_OLD_PASSWORD,
 2594                 KeyFilesEnable && FirstKeyFile != NULL,
 2595                 IDC_PASSWORD, IDC_VERIFY,
 2596                 newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
 2597 
 2598             return 1;
 2599         }
 2600 
 2601         if (lw == IDC_ENABLE_NEW_KEYFILES)
 2602         {
 2603             newKeyFilesParam.EnableKeyFiles = GetCheckBox (hwndDlg, IDC_ENABLE_NEW_KEYFILES);
 2604 
 2605             PasswordChangeEnable (hwndDlg, IDOK,
 2606                 IDC_OLD_PASSWORD,
 2607                 KeyFilesEnable && FirstKeyFile != NULL,
 2608                 IDC_PASSWORD, IDC_VERIFY,
 2609                 newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL);
 2610 
 2611             return 1;
 2612         }
 2613 
 2614         if (hw == CBN_SELCHANGE)
 2615         {
 2616             switch (lw)
 2617             {
 2618             case IDC_PKCS5_PRF_ID:
 2619                 if (bSysEncPwdChangeDlgMode)
 2620                 {
 2621                     int new_hash_algo_id = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, 
 2622                         SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0);
 2623 
 2624                     if (new_hash_algo_id != 0 && !bSystemIsGPT && !HashForSystemEncryption(new_hash_algo_id))
 2625                     {
 2626                         int new_hash_algo_id = DEFAULT_HASH_ALGORITHM_BOOT;
 2627                         Info ("ALGO_NOT_SUPPORTED_FOR_SYS_ENCRYPTION", hwndDlg);
 2628                         SelectAlgo (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), &new_hash_algo_id);
 2629                     }
 2630                 }
 2631                 break;
 2632             }
 2633             return 1;
 2634 
 2635         }
 2636 
 2637         if (lw == IDC_TRUECRYPT_MODE)
 2638         {
 2639             BOOL bEnablePim = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE) ? FALSE: TRUE;
 2640             EnableWindow (GetDlgItem (hwndDlg, IDT_OLD_PIM), bEnablePim);
 2641             EnableWindow (GetDlgItem (hwndDlg, IDC_OLD_PIM), bEnablePim);
 2642             EnableWindow (GetDlgItem (hwndDlg, IDC_OLD_PIM_HELP), bEnablePim);
 2643         }
 2644 
 2645         if (lw == IDC_SHOW_PASSWORD_CHPWD_ORI)
 2646         {
 2647             HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_ORI, IDC_OLD_PASSWORD, IDC_OLD_PIM);
 2648             return 1;
 2649         }
 2650 
 2651         if (lw == IDC_SHOW_PASSWORD_CHPWD_NEW)
 2652         {
 2653             HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PASSWORD, IDC_VERIFY);
 2654             HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_CHPWD_NEW, IDC_PIM, 0);
 2655             return 1;
 2656         }
 2657 
 2658         if (lw == IDOK)
 2659         {
 2660             HWND hParent = GetParent (hwndDlg);
 2661             Password oldPassword;
 2662             Password newPassword;
 2663             WipeAlgorithmId headerWiperMode = (WipeAlgorithmId) SendMessage (
 2664                 GetDlgItem (hwndDlg, IDC_WIPE_MODE),
 2665                 CB_GETITEMDATA,
 2666                 SendMessage (GetDlgItem (hwndDlg, IDC_WIPE_MODE), CB_GETCURSEL, 0, 0),
 2667                 0);
 2668             int nStatus;
 2669             int old_pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETITEMDATA,
 2670                     SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_OLD_PRF_ID), CB_GETCURSEL, 0, 0), 0);
 2671             int pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA,
 2672                     SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0);
 2673             BOOL truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE);
 2674 
 2675             int old_pim = GetPim (hwndDlg, IDC_OLD_PIM, 0);
 2676             int pim = GetPim (hwndDlg, IDC_PIM, 0);
 2677 
 2678             if (truecryptMode && !is_pkcs5_prf_supported (old_pkcs5, TRUE, PRF_BOOT_NO))
 2679             {
 2680                 Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
 2681                 return 1;
 2682             }
 2683             else if (truecryptMode && (old_pim != 0))
 2684             {
 2685                 Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
 2686                 return 1;
 2687             }
 2688 
 2689             if (bSysEncPwdChangeDlgMode && !CheckPasswordCharEncoding (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL))
 2690             {
 2691                 Error ("UNSUPPORTED_CHARS_IN_PWD", hwndDlg);
 2692                 return 1;
 2693             }
 2694 
 2695             if (bSysEncPwdChangeDlgMode && (pim > MAX_BOOT_PIM_VALUE))
 2696             {
 2697                 SetFocus (GetDlgItem(hwndDlg, IDC_PIM));
 2698                 Error ("PIM_SYSENC_TOO_BIG", hwndDlg);
 2699                 return 1;
 2700             }
 2701 
 2702             if (!bSysEncPwdChangeDlgMode && (pim > MAX_PIM_VALUE))
 2703             {
 2704                 SetFocus (GetDlgItem(hwndDlg, IDC_PIM));
 2705                 Error ("PIM_TOO_BIG", hwndDlg);
 2706                 return 1;
 2707             }
 2708 
 2709             if (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF)
 2710             {
 2711                 newKeyFilesParam.EnableKeyFiles = KeyFilesEnable;
 2712             }
 2713             else if (!(newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL)
 2714                 && pwdChangeDlgMode == PCDM_CHANGE_PASSWORD)
 2715             {
 2716                 int bootPRF = 0;
 2717                 if (bSysEncPwdChangeDlgMode)
 2718                 {
 2719                     try
 2720                     {
 2721                         VOLUME_PROPERTIES_STRUCT properties;
 2722                         BootEncObj->GetVolumeProperties(&properties);
 2723                         bootPRF = properties.pkcs5;
 2724                     }
 2725                     catch(...)
 2726                     {}
 2727                 }
 2728                 if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pim, bSysEncPwdChangeDlgMode, bootPRF, FALSE, FALSE))
 2729                     return 1;
 2730             }
 2731 
 2732             GetVolumePath (hParent, szFileName, ARRAYSIZE (szFileName));
 2733 
 2734             if (GetPassword (hwndDlg, IDC_OLD_PASSWORD, (LPSTR) oldPassword.Text, sizeof (oldPassword.Text), TRUE))
 2735                 oldPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text);
 2736             else
 2737             {
 2738                 return 1;
 2739             }
 2740 
 2741             switch (pwdChangeDlgMode)
 2742             {
 2743             case PCDM_REMOVE_ALL_KEYFILES_FROM_VOL:
 2744             case PCDM_ADD_REMOVE_VOL_KEYFILES:
 2745             case PCDM_CHANGE_PKCS5_PRF:
 2746                 memcpy (newPassword.Text, oldPassword.Text, sizeof (newPassword.Text));
 2747                 newPassword.Length = (unsigned __int32) strlen ((char *) oldPassword.Text);
 2748                 pim = old_pim;
 2749                 break;
 2750 
 2751             default:
 2752                 if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) newPassword.Text, sizeof (newPassword.Text), TRUE))
 2753                     newPassword.Length = (unsigned __int32) strlen ((char *) newPassword.Text);
 2754                 else
 2755                     return 1;
 2756             }
 2757 
 2758             WaitCursor ();
 2759 
 2760             if (KeyFilesEnable)
 2761                 KeyFilesApply (hwndDlg, &oldPassword, FirstKeyFile, szFileName);
 2762 
 2763             if (newKeyFilesParam.EnableKeyFiles)
 2764             {
 2765                 if (!KeyFilesApply (hwndDlg, &newPassword, pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? FirstKeyFile : newKeyFilesParam.FirstKeyFile, szFileName))
 2766                 {
 2767                     nStatus = ERR_DONT_REPORT;
 2768                     goto err;
 2769                 }
 2770             }
 2771 
 2772             ChangePwdThreadParam changePwdParam;
 2773             changePwdParam.oldPassword = &oldPassword;
 2774             changePwdParam.old_pkcs5 = old_pkcs5;
 2775             changePwdParam.old_pim = old_pim;
 2776             changePwdParam.newPassword = &newPassword;
 2777             changePwdParam.pkcs5 = pkcs5;
 2778             changePwdParam.pim = pim;
 2779             changePwdParam.wipePassCount = GetWipePassCount(headerWiperMode);
 2780             changePwdParam.pnStatus = &nStatus;
 2781             changePwdParam.truecryptMode = truecryptMode;
 2782 
 2783             ShowWaitDialog(hwndDlg, TRUE, ChangePwdWaitThreadProc, &changePwdParam);
 2784 
 2785 err:
 2786             // notify the caller in case the PIM has changed
 2787             if (NewPimValuePtr)
 2788             {
 2789                 if (pim != old_pim)
 2790                     *NewPimValuePtr = pim;
 2791                 else
 2792                     *NewPimValuePtr = -1;
 2793             }
 2794 
 2795             burn (&oldPassword, sizeof (oldPassword));
 2796             burn (&newPassword, sizeof (newPassword));
 2797             burn (&old_pim, sizeof(old_pim));
 2798             burn (&pim, sizeof(pim));
 2799 
 2800             NormalCursor ();
 2801 
 2802             if (nStatus == 0)
 2803             {
 2804                 // Attempt to wipe passwords stored in the input field buffers
 2805                 wchar_t tmp[MAX_PASSWORD+1];
 2806                 wmemset (tmp, L'X', MAX_PASSWORD);
 2807                 tmp[MAX_PASSWORD] = 0;
 2808                 SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
 2809                 SetWindowText (GetDlgItem (hwndDlg, IDC_OLD_PASSWORD), tmp);
 2810                 SetWindowText (GetDlgItem (hwndDlg, IDC_VERIFY), tmp);
 2811 
 2812                 KeyFileRemoveAll (&newKeyFilesParam.FirstKeyFile);
 2813                 RestoreDefaultKeyFilesParam ();
 2814 
 2815                 if (bSysEncPwdChangeDlgMode)
 2816                 {
 2817                     KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD);
 2818                 }
 2819 
 2820                 EndDialog (hwndDlg, IDOK);
 2821             }
 2822             return 1;
 2823         }
 2824         return 0;
 2825     }
 2826 
 2827     return 0;
 2828 }
 2829 
 2830 static wchar_t PasswordDlgVolume[MAX_PATH + 1];
 2831 static BOOL PasswordDialogDisableMountOptions;
 2832 static char *PasswordDialogTitleStringId;
 2833 
 2834 /* Except in response to the WM_INITDIALOG message, the dialog box procedure
 2835    should return nonzero if it processes the message, and zero if it does
 2836    not. - see DialogProc */
 2837 BOOL CALLBACK PasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 2838 {
 2839     WORD lw = LOWORD (wParam);
 2840     static Password *szXPwd;
 2841     static int *pkcs5;
 2842     static int *pim;
 2843     static BOOL* truecryptMode;
 2844 
 2845     switch (msg)
 2846     {
 2847     case WM_INITDIALOG:
 2848         {
 2849             int i, nIndex, defaultPrfIndex = 0;
 2850             szXPwd = ((PasswordDlgParam *) lParam) -> password;
 2851             pkcs5 = ((PasswordDlgParam *) lParam) -> pkcs5;
 2852             pim = ((PasswordDlgParam *) lParam) -> pim;
 2853             truecryptMode = ((PasswordDlgParam *) lParam) -> truecryptMode;
 2854             LocalizeDialog (hwndDlg, "IDD_PASSWORD_DLG");
 2855             DragAcceptFiles (hwndDlg, TRUE);
 2856 
 2857             if (PasswordDialogTitleStringId)
 2858             {
 2859                 SetWindowTextW (hwndDlg, GetString (PasswordDialogTitleStringId));
 2860             }
 2861             else if (wcslen (PasswordDlgVolume) > 0)
 2862             {
 2863                 wchar_t s[1024];
 2864                 RECT rect;
 2865                 GetWindowRect (hwndDlg, &rect);
 2866 
 2867                 bool useInExplorer = false;
 2868                 wstring label = GetFavoriteVolumeLabel (PasswordDlgVolume, useInExplorer);
 2869                 if (!label.empty())
 2870                 {
 2871                     StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR_LABEL"), label.c_str());
 2872                     if (useInExplorer)
 2873                         StringCbCopyW (mountOptions.Label, sizeof (mountOptions.Label), label.c_str());
 2874                 }
 2875                 else
 2876                 {
 2877                     StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), L"___");
 2878                     StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), FitPathInGfxWidth (hwndDlg, WindowTitleBarFont, rect.right - rect.left - GetTextGfxWidth (hwndDlg, s, WindowTitleBarFont), PasswordDlgVolume).c_str());
 2879                 }
 2880 
 2881                 SetWindowTextW (hwndDlg, s);
 2882             }
 2883 
 2884             /* Populate the PRF algorithms list */
 2885             HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
 2886             SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
 2887 
 2888             nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
 2889             SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
 2890 
 2891             for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
 2892             {
 2893                 nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
 2894                 SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
 2895                 if (*pkcs5 && (*pkcs5 == i))
 2896                     defaultPrfIndex = nIndex;
 2897             }
 2898 
 2899             /* make autodetection the default unless a specific PRF was specified in the command line */
 2900             SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0);
 2901 
 2902             ToNormalPwdField (hwndDlg, IDC_PASSWORD);
 2903             SendMessage (GetDlgItem (hwndDlg, IDC_CACHE), BM_SETCHECK, bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0);
 2904             SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0);
 2905 
 2906             SetPim (hwndDlg, IDC_PIM, *pim);
 2907 
 2908             /* make PIM field visible if a PIM value has been explicitely specified */
 2909             if (*pim > 0)
 2910             {
 2911                 SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE);
 2912                 ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE);
 2913                 ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
 2914                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
 2915                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW);
 2916             }
 2917 
 2918             SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
 2919 
 2920             mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode;
 2921 
 2922             if (bPrebootPasswordDlgMode)
 2923             {
 2924                 SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0);
 2925             }
 2926 
 2927             if (PasswordDialogDisableMountOptions)
 2928             {
 2929                 EnableWindow (GetDlgItem (hwndDlg, IDC_CACHE), FALSE);
 2930                 EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_OPTIONS), FALSE);
 2931                 /* Disable TrueCrypt mode option in case of backup/restore header operation */
 2932                 SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE);
 2933                 EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE);
 2934             }
 2935             else if (*truecryptMode)
 2936             {
 2937                 /* Check TrueCryptMode if it is enabled on the command line */
 2938                 SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, TRUE);
 2939             }
 2940 
 2941             if (!SetForegroundWindow (hwndDlg) && (FavoriteMountOnArrivalInProgress || LogOn))
 2942             {
 2943                 SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
 2944 
 2945                 FLASHWINFO flash;
 2946                 flash.cbSize = sizeof (flash);
 2947                 flash.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
 2948                 flash.dwTimeout = 0;
 2949                 flash.hwnd = hwndDlg;
 2950                 flash.uCount = 0;
 2951 
 2952                 FlashWindowEx (&flash);
 2953 
 2954                 SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
 2955             }
 2956             SetFocus (GetDlgItem (hwndDlg, IDC_PASSWORD));
 2957             SetTimer (hwndDlg, TIMER_ID_CHECK_FOREGROUND, TIMER_INTERVAL_CHECK_FOREGROUND, NULL);
 2958         }
 2959         return 0;
 2960 
 2961     case TC_APPMSG_PREBOOT_PASSWORD_MODE:
 2962         {
 2963             /* Repopulate the PRF algorithms list with algorithms that support system encryption */
 2964             HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
 2965             SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
 2966 
 2967             int i, defaultPrfIndex = 0, nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
 2968             SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
 2969 
 2970             for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
 2971             {
 2972                 if (bSystemIsGPT || HashForSystemEncryption(i))
 2973                 {
 2974                     nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
 2975                     SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
 2976                     if (*pkcs5 && (*pkcs5 == i))
 2977                         defaultPrfIndex = nIndex;
 2978                 }
 2979             }
 2980 
 2981             /* make autodetection the default unless a specific PRF was specified in the command line */
 2982             SendMessage (hComboBox, CB_SETCURSEL, defaultPrfIndex, 0);
 2983 
 2984             ToBootPwdField (hwndDlg, IDC_PASSWORD);
 2985 
 2986             // Attempt to wipe the password stored in the input field buffer
 2987             wchar_t tmp[MAX_PASSWORD+1];
 2988             wmemset (tmp, L'X', MAX_PASSWORD);
 2989             tmp [MAX_PASSWORD] = 0;
 2990             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
 2991             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L"");
 2992 
 2993             StringCbPrintfW (OrigKeyboardLayout, sizeof(OrigKeyboardLayout),L"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF);
 2994 
 2995             DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE);
 2996 
 2997             if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 2998             {
 2999                 Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg);
 3000                 EndDialog (hwndDlg, IDCANCEL);
 3001                 return 1;
 3002             }
 3003 
 3004             if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0)
 3005             {
 3006                 Error ("CANNOT_SET_TIMER", hwndDlg);
 3007                 EndDialog (hwndDlg, IDCANCEL);
 3008                 return 1;
 3009             }
 3010 
 3011             if (GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD))
 3012             {
 3013                 // simulate hiding password
 3014                 SetCheckBox (hwndDlg, IDC_SHOW_PASSWORD, FALSE);
 3015 
 3016                 HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD, IDC_PASSWORD, IDC_PIM);
 3017             }
 3018 
 3019             SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, FALSE);
 3020             EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE), FALSE);
 3021             EnableWindow (GetDlgItem (hwndDlg, IDC_KEY_FILES), FALSE);
 3022 
 3023             SetPim (hwndDlg, IDC_PIM, *pim);
 3024 
 3025             bPrebootPasswordDlgMode = TRUE;
 3026         }
 3027         return 1;
 3028 
 3029     case WM_TIMER:
 3030         switch (wParam)
 3031         {
 3032         case TIMER_ID_CHECK_FOREGROUND:
 3033             if (hwndDlg != ::GetForegroundWindow ())
 3034             {
 3035                 // we are not foreground after 500ms of creating the dialog
 3036                 // try to force it for be foreground
 3037                 BringToForeground (hwndDlg);
 3038                 SetFocus (GetDlgItem (hwndDlg, IDC_PASSWORD));
 3039             }
 3040             // one shot timer: stop it
 3041             KillTimer (hwndDlg, TIMER_ID_CHECK_FOREGROUND);
 3042             return 0;
 3043         case TIMER_ID_KEYB_LAYOUT_GUARD:
 3044             if (bPrebootPasswordDlgMode)
 3045             {
 3046                 DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL);
 3047 
 3048                 if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 3049                 {
 3050                     // Keyboard layout is not standard US
 3051 
 3052                     // Attempt to wipe the password stored in the input field buffer
 3053                     wchar_t tmp[MAX_PASSWORD+1];
 3054                     wmemset (tmp, L'X', MAX_PASSWORD);
 3055                     tmp [MAX_PASSWORD] = 0;
 3056                     SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
 3057                     SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), L"");
 3058 
 3059                     keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE);
 3060 
 3061                     if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 3062                     {
 3063                         KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD);
 3064                         Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg);
 3065                         EndDialog (hwndDlg, IDCANCEL);
 3066                         return 1;
 3067                     }
 3068 
 3069                     wchar_t szTmp [4096];
 3070                     StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED"));
 3071                     StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
 3072                     StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
 3073                     MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
 3074                 }
 3075             }
 3076             return 1;
 3077         }
 3078         return 0;
 3079 
 3080     case WM_COMMAND:
 3081 
 3082         if (lw == IDC_MOUNT_OPTIONS)
 3083         {
 3084             /* Use default PRF specified by the user if any */
 3085             if (mountOptions.ProtectedHidVolPkcs5Prf == 0)
 3086                 mountOptions.ProtectedHidVolPkcs5Prf = *pkcs5;
 3087             if (mountOptions.ProtectedHidVolPim == 0)
 3088                 mountOptions.ProtectedHidVolPim = *pim;
 3089             DialogBoxParamW (hInst,
 3090                 MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg,
 3091                 (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions);
 3092 
 3093             if (!bPrebootPasswordDlgMode && mountOptions.PartitionInInactiveSysEncScope)
 3094                 SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0);
 3095 
 3096             return 1;
 3097         }
 3098 
 3099         if (lw == IDC_PIM_ENABLE)
 3100         {
 3101             ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE);
 3102             ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
 3103             ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
 3104             ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW);
 3105 
 3106             SetFocus (GetDlgItem (hwndDlg, IDC_PIM));
 3107             return 1;
 3108         }
 3109 
 3110         if (lw == IDC_SHOW_PASSWORD)
 3111         {
 3112             HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD, IDC_PASSWORD, IDC_PIM);
 3113             return 1;
 3114         }
 3115 
 3116         if (lw == IDC_TRUECRYPT_MODE)
 3117         {
 3118             BOOL bEnablePim = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE) ? FALSE: TRUE;
 3119             EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), bEnablePim);
 3120             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), bEnablePim);
 3121             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), bEnablePim);
 3122         }
 3123 
 3124         if (lw == IDC_KEY_FILES)
 3125         {
 3126             KeyFilesDlgParam param;
 3127             param.EnableKeyFiles = KeyFilesEnable;
 3128             param.FirstKeyFile = FirstKeyFile;
 3129 
 3130             if (IDOK == DialogBoxParamW (hInst,
 3131                 MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg,
 3132                 (DLGPROC) KeyFilesDlgProc, (LPARAM) &param))
 3133             {
 3134                 KeyFilesEnable = param.EnableKeyFiles;
 3135                 FirstKeyFile = param.FirstKeyFile;
 3136 
 3137                 SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
 3138             }
 3139 
 3140             return 1;
 3141         }
 3142 
 3143         if (lw == IDC_KEYFILES_ENABLE)
 3144         {
 3145             KeyFilesEnable = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE);
 3146 
 3147             return 1;
 3148         }
 3149 
 3150         if (lw == IDCANCEL || lw == IDOK)
 3151         {
 3152             wchar_t tmp[MAX_PASSWORD+1];
 3153 
 3154             if (lw == IDOK)
 3155             {
 3156                 if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles)
 3157                     KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile, wcslen (PasswordDlgVolume) > 0 ? PasswordDlgVolume : NULL);
 3158 
 3159                 if (GetPassword (hwndDlg, IDC_PASSWORD, (LPSTR) szXPwd->Text, MAX_PASSWORD + 1, TRUE))
 3160                     szXPwd->Length = (unsigned __int32) strlen ((char *) szXPwd->Text);
 3161                 else
 3162                     return 1;
 3163 
 3164                 bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_CACHE));
 3165                 *pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0);
 3166                 *truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE);
 3167 
 3168                 *pim = GetPim (hwndDlg, IDC_PIM, 0);
 3169 
 3170                 /* check that PRF is supported in TrueCrypt Mode */
 3171                 if (    (*truecryptMode)
 3172                     && ((!is_pkcs5_prf_supported (*pkcs5, TRUE, PRF_BOOT_NO)) || (mountOptions.ProtectHiddenVolume && !is_pkcs5_prf_supported (mountOptions.ProtectedHidVolPkcs5Prf, TRUE, PRF_BOOT_NO)))
 3173                     )
 3174                 {
 3175                     Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
 3176                     return 1;
 3177                 }
 3178 
 3179                 if (    (*truecryptMode)
 3180                     &&  (*pim != 0)
 3181                     )
 3182                 {
 3183                     Error ("PIM_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
 3184                     return 1;
 3185                 }
 3186             }
 3187 
 3188             // Attempt to wipe password stored in the input field buffer
 3189             wmemset (tmp, L'X', MAX_PASSWORD);
 3190             tmp[MAX_PASSWORD] = 0;
 3191             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
 3192             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp);
 3193 
 3194             if (hidVolProtKeyFilesParam.FirstKeyFile != NULL)
 3195             {
 3196                 KeyFileRemoveAll (&hidVolProtKeyFilesParam.FirstKeyFile);
 3197                 hidVolProtKeyFilesParam.EnableKeyFiles = FALSE;
 3198             }
 3199 
 3200             if (bPrebootPasswordDlgMode)
 3201             {
 3202                 KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD);
 3203 
 3204                 // Restore the original keyboard layout
 3205                 if (LoadKeyboardLayout (OrigKeyboardLayout, KLF_ACTIVATE | KLF_SUBSTITUTE_OK) == NULL)
 3206                     Warning ("CANNOT_RESTORE_KEYBOARD_LAYOUT", hwndDlg);
 3207             }
 3208 
 3209             EndDialog (hwndDlg, lw);
 3210             return 1;
 3211         }
 3212         return 0;
 3213 
 3214     case WM_CONTEXTMENU:
 3215         {
 3216             RECT buttonRect;
 3217             GetWindowRect (GetDlgItem (hwndDlg, IDC_KEY_FILES), &buttonRect);
 3218 
 3219             if (LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right
 3220                 && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom)
 3221             {
 3222                 // The "Keyfiles" button has been right-clicked
 3223 
 3224                 KeyFilesDlgParam param;
 3225                 param.EnableKeyFiles = KeyFilesEnable;
 3226                 param.FirstKeyFile = FirstKeyFile;
 3227 
 3228                 POINT popupPos;
 3229                 popupPos.x = buttonRect.left + 2;
 3230                 popupPos.y = buttonRect.top + 2;
 3231 
 3232                 if (KeyfilesPopupMenu (hwndDlg, popupPos, &param))
 3233                 {
 3234                     KeyFilesEnable = param.EnableKeyFiles;
 3235                     FirstKeyFile = param.FirstKeyFile;
 3236                     SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
 3237                 }
 3238             }
 3239         }
 3240         break;
 3241 
 3242     case WM_DROPFILES:
 3243         {
 3244             HDROP hdrop = (HDROP) wParam;
 3245             int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
 3246 
 3247             while (count-- > 0)
 3248             {
 3249                 KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
 3250                 if (kf)
 3251                 {
 3252                     DragQueryFile (hdrop, i++, kf->FileName, ARRAYSIZE (kf->FileName));
 3253                     FirstKeyFile = KeyFileAdd (FirstKeyFile, kf);
 3254                     KeyFilesEnable = TRUE;
 3255                 }
 3256             }
 3257 
 3258             SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
 3259             DragFinish (hdrop);
 3260         }
 3261         return 1;
 3262     }
 3263 
 3264     return 0;
 3265 }
 3266 
 3267 static void PreferencesDlgEnableButtons (HWND hwndDlg)
 3268 {
 3269     BOOL back = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE));
 3270     BOOL idle = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE));
 3271     BOOL installed = !IsNonInstallMode();
 3272     BOOL wtsEnabled = (hWtsLib != NULL) ? TRUE : FALSE;
 3273 
 3274     EnableWindow (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL), back && installed);
 3275     EnableWindow (GetDlgItem (hwndDlg, IDT_LOGON), installed);
 3276     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START), back && installed);
 3277     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES), installed);
 3278     EnableWindow (GetDlgItem (hwndDlg, IDT_AUTO_DISMOUNT), back);
 3279     EnableWindow (GetDlgItem (hwndDlg, IDT_AUTO_DISMOUNT_ON), back);
 3280     EnableWindow (GetDlgItem (hwndDlg, IDT_MINUTES), back);
 3281     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF), back);
 3282     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED), back && wtsEnabled);
 3283     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING), back);
 3284     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER), back);
 3285     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE), back);
 3286     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME), back && idle);
 3287     EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT), back);
 3288 }
 3289 
 3290 BOOL CALLBACK PreferencesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 3291 {
 3292     static BOOL PreferencesDialogActive = FALSE;
 3293     static HWND ActivePreferencesDialogWindow;
 3294 
 3295     WORD lw = LOWORD (wParam);
 3296 
 3297     switch (msg)
 3298     {
 3299     case WM_INITDIALOG:
 3300         {
 3301             if (PreferencesDialogActive)
 3302             {
 3303                 ShowWindow (ActivePreferencesDialogWindow, SW_SHOW);
 3304                 SetForegroundWindow (ActivePreferencesDialogWindow);
 3305                 EndDialog (hwndDlg, IDCANCEL);
 3306                 return 1;
 3307             }
 3308 
 3309             ActivePreferencesDialogWindow = hwndDlg;
 3310             PreferencesDialogActive = TRUE;
 3311 
 3312             LocalizeDialog (hwndDlg, "IDD_PREFERENCES_DLG");
 3313 
 3314             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_OPEN_EXPLORER), BM_SETCHECK,
 3315                         bExplore ? BST_CHECKED:BST_UNCHECKED, 0);
 3316 
 3317             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED), BM_SETCHECK,
 3318                         bUseDifferentTrayIconIfVolMounted ? BST_CHECKED:BST_UNCHECKED, 0);
 3319 
 3320             SendMessage (GetDlgItem (hwndDlg, IDC_PRESERVE_TIMESTAMPS), BM_SETCHECK,
 3321                         defaultMountOptions.PreserveTimestamp ? BST_CHECKED:BST_UNCHECKED, 0);
 3322 
 3323             SendMessage (GetDlgItem (hwndDlg, IDC_SHOW_DISCONNECTED_NETWORK_DRIVES), BM_SETCHECK,
 3324                 bShowDisconnectedNetworkDrives ? BST_CHECKED:BST_UNCHECKED, 0);
 3325 
 3326             SendMessage (GetDlgItem (hwndDlg, IDC_HIDE_WAITING_DIALOG), BM_SETCHECK,
 3327                 bHideWaitingDialog ? BST_CHECKED:BST_UNCHECKED, 0);
 3328 
 3329             SendMessage (GetDlgItem (hwndDlg, IDC_SECURE_DESKTOP_PASSWORD_ENTRY), BM_SETCHECK,
 3330                 bUseSecureDesktop ? BST_CHECKED:BST_UNCHECKED, 0);
 3331 
 3332             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_TEMP_CACHE_ON_MULTIPLE_MOUNT), BM_SETCHECK,
 3333                         bCacheDuringMultipleMount ? BST_CHECKED:BST_UNCHECKED, 0);
 3334 
 3335             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_EXIT), BM_SETCHECK,
 3336                         bWipeCacheOnExit ? BST_CHECKED:BST_UNCHECKED, 0);
 3337 
 3338             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT), BM_SETCHECK,
 3339                         bWipeCacheOnAutoDismount ? BST_CHECKED:BST_UNCHECKED, 0);
 3340 
 3341             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PASSWORDS), BM_SETCHECK,
 3342                         bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0);
 3343 
 3344             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM), BM_SETCHECK,
 3345                         bIncludePimInCache? BST_CHECKED:BST_UNCHECKED, 0);
 3346 
 3347             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_READONLY), BM_SETCHECK,
 3348                         defaultMountOptions.ReadOnly ? BST_CHECKED:BST_UNCHECKED, 0);
 3349 
 3350             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_REMOVABLE), BM_SETCHECK,
 3351                         defaultMountOptions.Removable ? BST_CHECKED:BST_UNCHECKED, 0);
 3352 
 3353             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START), BM_SETCHECK,
 3354                         bStartOnLogon ? BST_CHECKED:BST_UNCHECKED, 0);
 3355 
 3356             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES), BM_SETCHECK,
 3357                         bMountDevicesOnLogon ? BST_CHECKED:BST_UNCHECKED, 0);
 3358 
 3359             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE), BM_SETCHECK,
 3360                         bEnableBkgTask ? BST_CHECKED:BST_UNCHECKED, 0);
 3361 
 3362             SendMessage (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL), BM_SETCHECK,
 3363                         bCloseBkgTaskWhenNoVolumes || IsNonInstallMode() ? BST_CHECKED:BST_UNCHECKED, 0);
 3364 
 3365             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF), BM_SETCHECK,
 3366                         bDismountOnLogOff ? BST_CHECKED:BST_UNCHECKED, 0);
 3367 
 3368             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED), BM_SETCHECK,
 3369                         bDismountOnSessionLocked ? BST_CHECKED:BST_UNCHECKED, 0);
 3370 
 3371             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING), BM_SETCHECK,
 3372                         bDismountOnPowerSaving ? BST_CHECKED:BST_UNCHECKED, 0);
 3373 
 3374             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER), BM_SETCHECK,
 3375                         bDismountOnScreenSaver ? BST_CHECKED:BST_UNCHECKED, 0);
 3376 
 3377             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT), BM_SETCHECK,
 3378                         bForceAutoDismount ? BST_CHECKED:BST_UNCHECKED, 0);
 3379 
 3380             SendMessage (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE), BM_SETCHECK,
 3381                         MaxVolumeIdleTime > 0 ? BST_CHECKED:BST_UNCHECKED, 0);
 3382 
 3383             SetDlgItemInt (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME, abs (MaxVolumeIdleTime), FALSE);
 3384 
 3385             PreferencesDlgEnableButtons (hwndDlg);
 3386         }
 3387         return 0;
 3388 
 3389     case WM_COMMAND:
 3390 
 3391         if (lw == IDC_PREF_BKG_TASK_ENABLE && !IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE)))
 3392         {
 3393             if (AskWarnNoYes ("CONFIRM_BACKGROUND_TASK_DISABLED", hwndDlg) == IDNO)
 3394                 SetCheckBox (hwndDlg, IDC_PREF_BKG_TASK_ENABLE, TRUE);
 3395         }
 3396 
 3397         // Forced dismount disabled warning
 3398         if (lw == IDC_PREF_DISMOUNT_INACTIVE
 3399             || lw == IDC_PREF_DISMOUNT_LOGOFF
 3400             || lw == IDC_PREF_DISMOUNT_SESSION_LOCKED
 3401             || lw == IDC_PREF_DISMOUNT_POWERSAVING
 3402             || lw == IDC_PREF_DISMOUNT_SCREENSAVER
 3403             || lw == IDC_PREF_FORCE_AUTO_DISMOUNT)
 3404         {
 3405             BOOL i = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE));
 3406             BOOL l = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF));
 3407             BOOL sl = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED));
 3408             BOOL p = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING));
 3409             BOOL s = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER));
 3410             BOOL q = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT));
 3411 
 3412             if (!q)
 3413             {
 3414                 if (lw == IDC_PREF_FORCE_AUTO_DISMOUNT && (i || l || sl || p || s))
 3415                 {
 3416                     if (AskWarnNoYes ("CONFIRM_NO_FORCED_AUTODISMOUNT", hwndDlg) == IDNO)
 3417                         SetCheckBox (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT, TRUE);
 3418                 }
 3419                 else if ((lw == IDC_PREF_DISMOUNT_INACTIVE && i
 3420                     || lw == IDC_PREF_DISMOUNT_LOGOFF && l
 3421                     || lw == IDC_PREF_DISMOUNT_SESSION_LOCKED && sl
 3422                     || lw == IDC_PREF_DISMOUNT_POWERSAVING && p
 3423                     || lw == IDC_PREF_DISMOUNT_SCREENSAVER && s))
 3424                     Warning ("WARN_PREF_AUTO_DISMOUNT", hwndDlg);
 3425             }
 3426 
 3427             if (p && lw == IDC_PREF_DISMOUNT_POWERSAVING)
 3428                 Warning ("WARN_PREF_AUTO_DISMOUNT_ON_POWER", hwndDlg);
 3429         }
 3430 
 3431         if (lw == IDCANCEL)
 3432         {
 3433             PreferencesDialogActive = FALSE;
 3434             EndDialog (hwndDlg, lw);
 3435             return 1;
 3436         }
 3437 
 3438         if (lw == IDOK)
 3439         {
 3440             WaitCursor ();
 3441 
 3442             bExplore                        = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_OPEN_EXPLORER));
 3443             bUseDifferentTrayIconIfVolMounted = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_USE_DIFF_TRAY_ICON_IF_VOL_MOUNTED));
 3444             bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PRESERVE_TIMESTAMPS));
 3445             bShowDisconnectedNetworkDrives = IsButtonChecked (GetDlgItem (hwndDlg, IDC_SHOW_DISCONNECTED_NETWORK_DRIVES));
 3446             bHideWaitingDialog = IsButtonChecked (GetDlgItem (hwndDlg, IDC_HIDE_WAITING_DIALOG));
 3447             bUseSecureDesktop = IsButtonChecked (GetDlgItem (hwndDlg, IDC_SECURE_DESKTOP_PASSWORD_ENTRY));
 3448             bCacheDuringMultipleMount   = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_TEMP_CACHE_ON_MULTIPLE_MOUNT));
 3449             bWipeCacheOnExit                = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_EXIT));
 3450             bWipeCacheOnAutoDismount        = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_WIPE_CACHE_ON_AUTODISMOUNT));
 3451             bCacheInDriverDefault = bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PASSWORDS));
 3452             bIncludePimInCache = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM));
 3453             defaultMountOptions.ReadOnly    = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_READONLY));
 3454             defaultMountOptions.Removable   = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_MOUNT_REMOVABLE));
 3455             bEnableBkgTask              = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_BKG_TASK_ENABLE));
 3456             bCloseBkgTaskWhenNoVolumes  = IsNonInstallMode() ? bCloseBkgTaskWhenNoVolumes : IsButtonChecked (GetDlgItem (hwndDlg, IDC_CLOSE_BKG_TASK_WHEN_NOVOL));
 3457             bDismountOnLogOff               = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_LOGOFF));
 3458             bDismountOnSessionLocked        = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SESSION_LOCKED));
 3459             bDismountOnPowerSaving          = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_POWERSAVING));
 3460             bDismountOnScreenSaver          = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_SCREENSAVER));
 3461             bForceAutoDismount              = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_FORCE_AUTO_DISMOUNT));
 3462             MaxVolumeIdleTime               = GetDlgItemInt (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE_TIME, NULL, FALSE)
 3463                                                 * (IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_DISMOUNT_INACTIVE)) ? 1 : -1);
 3464             bStartOnLogon                   = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_LOGON_START));
 3465             bMountDevicesOnLogon            = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_LOGON_MOUNT_DEVICES));
 3466 
 3467             ManageStartupSeq ();
 3468 
 3469             SaveSettings (hwndDlg);
 3470 
 3471             NormalCursor ();
 3472 
 3473             PreferencesDialogActive = FALSE;
 3474             EndDialog (hwndDlg, lw);
 3475             return 1;
 3476         }
 3477 
 3478         if (lw == IDC_MORE_SETTINGS)
 3479         {
 3480             HMENU popup = CreatePopupMenu ();
 3481             if (popup)
 3482             {
 3483                 AppendMenuW (popup, MF_STRING, IDM_LANGUAGE, GetString ("IDM_LANGUAGE"));
 3484                 AppendMenuW (popup, MF_STRING, IDM_HOTKEY_SETTINGS, GetString ("IDM_HOTKEY_SETTINGS"));
 3485                 AppendMenuW (popup, MF_STRING, IDM_PERFORMANCE_SETTINGS, GetString ("IDM_PERFORMANCE_SETTINGS"));
 3486                 AppendMenuW (popup, MF_STRING, IDM_SYSENC_SETTINGS, GetString ("IDM_SYSENC_SETTINGS"));
 3487                 AppendMenuW (popup, MF_STRING, IDM_SYS_FAVORITES_SETTINGS, GetString ("IDM_SYS_FAVORITES_SETTINGS"));
 3488                 AppendMenuW (popup, MF_STRING, IDM_DEFAULT_KEYFILES, GetString ("IDM_DEFAULT_KEYFILES"));
 3489                 AppendMenuW (popup, MF_STRING, IDM_DEFAULT_MOUNT_PARAMETERS, GetString ("IDM_DEFAULT_MOUNT_PARAMETERS"));
 3490                 AppendMenuW (popup, MF_STRING, IDM_TOKEN_PREFERENCES, GetString ("IDM_TOKEN_PREFERENCES"));
 3491 
 3492                 RECT rect;
 3493                 GetWindowRect (GetDlgItem (hwndDlg, IDC_MORE_SETTINGS), &rect);
 3494 
 3495                 int menuItem = TrackPopupMenu (popup, TPM_RETURNCMD | TPM_LEFTBUTTON, rect.left + 2, rect.top + 2, 0, hwndDlg, NULL);
 3496                 DestroyMenu (popup);
 3497 
 3498                 SendMessage (MainDlg, WM_COMMAND, menuItem, (LPARAM) hwndDlg);
 3499                 return 1;
 3500             }
 3501             else
 3502                 return 0;
 3503         }
 3504 
 3505         if (HIWORD (wParam) == BN_CLICKED)
 3506         {
 3507             PreferencesDlgEnableButtons (hwndDlg);
 3508             return 1;
 3509         }
 3510 
 3511         return 0;
 3512     }
 3513 
 3514     return 0;
 3515 }
 3516 
 3517 
 3518 BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 3519 {
 3520     static MountOptions *mountOptions;
 3521 
 3522     WORD lw = LOWORD (wParam);
 3523 
 3524     switch (msg)
 3525     {
 3526     case WM_INITDIALOG:
 3527         {
 3528             BOOL protect;
 3529 
 3530             mountOptions = (MountOptions *) lParam;
 3531 
 3532             LocalizeDialog (hwndDlg, "IDD_MOUNT_OPTIONS");
 3533 
 3534             SendDlgItemMessage (hwndDlg, IDC_MOUNT_READONLY, BM_SETCHECK,
 3535                 mountOptions->ReadOnly ? BST_CHECKED : BST_UNCHECKED, 0);
 3536             SendDlgItemMessage (hwndDlg, IDC_MOUNT_REMOVABLE, BM_SETCHECK,
 3537                 mountOptions->Removable ? BST_CHECKED : BST_UNCHECKED, 0);
 3538             SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK,
 3539                 mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0);
 3540 
 3541             SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK,
 3542                 mountOptions->ProtectHiddenVolume ? BST_CHECKED : BST_UNCHECKED, 0);
 3543 
 3544             mountOptions->PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode;
 3545 
 3546             SendDlgItemMessage (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA, BM_SETCHECK,
 3547                 bPrebootPasswordDlgMode ? BST_CHECKED : BST_UNCHECKED, 0);
 3548 
 3549             SendDlgItemMessage (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK, BM_SETCHECK,
 3550                 mountOptions->UseBackupHeader ? BST_CHECKED : BST_UNCHECKED, 0);
 3551 
 3552             EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA), !bPrebootPasswordDlgMode);
 3553 
 3554             SetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label);
 3555             SendDlgItemMessage (hwndDlg, IDC_VOLUME_LABEL, EM_LIMITTEXT, 32, 0); // 32 is the maximum possible length for a drive label in Windows
 3556 
 3557             /* Add PRF algorithm list for hidden volume password */
 3558             HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
 3559             SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
 3560 
 3561             int i, nSelectedIndex = 0, nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
 3562             SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
 3563 
 3564             for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
 3565             {
 3566                 nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
 3567                 SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
 3568                 /* if a PRF was selected previously, select it */
 3569                 if (i == mountOptions->ProtectedHidVolPkcs5Prf)
 3570                     nSelectedIndex = nIndex;
 3571             }
 3572 
 3573             SendMessage (hComboBox, CB_SETCURSEL, nSelectedIndex, 0);
 3574 
 3575             protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
 3576 
 3577             EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
 3578             EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
 3579             EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect);
 3580             EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect);
 3581             EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect);
 3582             EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), protect);
 3583             EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT), protect);
 3584             EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), protect);
 3585             EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), protect);
 3586             EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), protect);
 3587             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), protect);
 3588             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), protect);
 3589             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), protect);
 3590 
 3591             SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles);
 3592 
 3593             ToNormalPwdField (hwndDlg, IDC_PASSWORD_PROT_HIDVOL);
 3594             SendDlgItemMessage (hwndDlg, IDC_PIM, EM_LIMITTEXT, MAX_PIM, 0);
 3595 
 3596             if (mountOptions->ProtectedHidVolPassword.Length > 0)
 3597             {
 3598                 wchar_t szTmp[MAX_PASSWORD + 1];
 3599                 if (0 == MultiByteToWideChar (CP_UTF8, 0, (LPSTR) mountOptions->ProtectedHidVolPassword.Text, -1, szTmp, MAX_PASSWORD + 1))
 3600                     szTmp [0] = 0;
 3601                 SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), szTmp);
 3602                 burn (szTmp, sizeof (szTmp));
 3603             }
 3604 
 3605             SetPim (hwndDlg, IDC_PIM, mountOptions->ProtectedHidVolPim);
 3606 
 3607             /* make PIM field visible if a PIM value has been explicitely specified */
 3608             if (mountOptions->ProtectedHidVolPim > 0)
 3609             {
 3610                 SetCheckBox (hwndDlg, IDC_PIM_ENABLE, TRUE);
 3611                 ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE);
 3612                 ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
 3613                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
 3614                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW);
 3615             }
 3616 
 3617             ToHyperlink (hwndDlg, IDC_LINK_HIDVOL_PROTECTION_INFO);
 3618 
 3619         }
 3620         return 0;
 3621 
 3622     case WM_CONTEXTMENU:
 3623         {
 3624             RECT buttonRect;
 3625             GetWindowRect (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), &buttonRect);
 3626 
 3627             if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL))
 3628                 && LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right
 3629                 && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom)
 3630             {
 3631                 // The "Keyfiles" button has been right-clicked
 3632 
 3633                 POINT popupPos;
 3634                 popupPos.x = buttonRect.left + 2;
 3635                 popupPos.y = buttonRect.top + 2;
 3636 
 3637                 if (KeyfilesPopupMenu (hwndDlg, popupPos, &hidVolProtKeyFilesParam))
 3638                     SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles);
 3639             }
 3640         }
 3641         break;
 3642 
 3643     case WM_COMMAND:
 3644 
 3645         if (lw == IDC_KEYFILES_HIDVOL_PROT)
 3646         {
 3647             if (IDOK == DialogBoxParamW (hInst,
 3648                 MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg,
 3649                 (DLGPROC) KeyFilesDlgProc, (LPARAM) &hidVolProtKeyFilesParam))
 3650             {
 3651                 SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT, hidVolProtKeyFilesParam.EnableKeyFiles);
 3652             }
 3653         }
 3654 
 3655         if (lw == IDC_KEYFILES_ENABLE_HIDVOL_PROT)
 3656         {
 3657             hidVolProtKeyFilesParam.EnableKeyFiles = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT);
 3658 
 3659             return 0;
 3660         }
 3661 
 3662         if (lw == IDC_SHOW_PASSWORD_MO)
 3663         {
 3664             HandleShowPasswordFieldAction (hwndDlg, IDC_SHOW_PASSWORD_MO, IDC_PASSWORD_PROT_HIDVOL, IDC_PIM);
 3665             return 1;
 3666         }
 3667 
 3668         if (lw == IDC_PIM_ENABLE)
 3669         {
 3670             ShowWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), SW_HIDE);
 3671             ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), SW_SHOW);
 3672             ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), SW_SHOW);
 3673             ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), SW_SHOW);
 3674 
 3675             SetFocus (GetDlgItem (hwndDlg, IDC_PIM));
 3676             return 1;
 3677         }
 3678 
 3679         if (lw == IDC_LINK_HIDVOL_PROTECTION_INFO)
 3680         {
 3681             Applink ("hiddenvolprotection");
 3682         }
 3683 
 3684         if (lw == IDCANCEL)
 3685         {
 3686             wchar_t tmp[MAX_PASSWORD+1];
 3687 
 3688             // Cleanup
 3689             wmemset (tmp, L'X', MAX_PASSWORD);
 3690             tmp[MAX_PASSWORD] = 0;
 3691             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp);
 3692 
 3693             EndDialog (hwndDlg, lw);
 3694             return 1;
 3695         }
 3696 
 3697         if (lw == IDOK)
 3698         {
 3699             wchar_t tmp[MAX_PASSWORD+1];
 3700 
 3701             mountOptions->ReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY));
 3702             mountOptions->Removable = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_REMOVABLE));
 3703             mountOptions->ProtectHiddenVolume = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
 3704             mountOptions->PartitionInInactiveSysEncScope = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_SYSENC_PART_WITHOUT_PBA));
 3705             mountOptions->UseBackupHeader = IsButtonChecked (GetDlgItem (hwndDlg, IDC_USE_EMBEDDED_HEADER_BAK));
 3706 
 3707             GetDlgItemTextW (hwndDlg, IDC_VOLUME_LABEL, mountOptions->Label, sizeof (mountOptions->Label) /sizeof (wchar_t));
 3708 
 3709             if (mountOptions->ProtectHiddenVolume)
 3710             {
 3711                 GetPassword (hwndDlg, IDC_PASSWORD_PROT_HIDVOL,
 3712                     (LPSTR) mountOptions->ProtectedHidVolPassword.Text, MAX_PASSWORD + 1,
 3713                     FALSE);
 3714 
 3715                 mountOptions->ProtectedHidVolPassword.Length = (unsigned __int32) strlen ((char *) mountOptions->ProtectedHidVolPassword.Text);
 3716 
 3717                 mountOptions->ProtectedHidVolPkcs5Prf = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA,
 3718                     SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0);
 3719 
 3720                 mountOptions->ProtectedHidVolPim = GetPim (hwndDlg, IDC_PIM, 0);
 3721             }
 3722 
 3723             // Cleanup
 3724             wmemset (tmp, L'X', MAX_PASSWORD);
 3725             tmp[MAX_PASSWORD] = 0;
 3726             SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp);
 3727 
 3728             if ((mountOptions->ProtectHiddenVolume && !bEnableBkgTask)
 3729                 && (AskWarnYesNo ("HIDVOL_PROT_BKG_TASK_WARNING", hwndDlg) == IDYES))
 3730             {
 3731                 bEnableBkgTask = TRUE;
 3732                 TaskBarIconAdd (MainDlg);
 3733             }
 3734 
 3735             EndDialog (hwndDlg, lw);
 3736             return 1;
 3737         }
 3738 
 3739         if (lw == IDC_MOUNT_READONLY || lw == IDC_PROTECT_HIDDEN_VOL)
 3740         {
 3741             BOOL protect;
 3742 
 3743             if (lw == IDC_MOUNT_READONLY)
 3744             {
 3745                 SendDlgItemMessage (hwndDlg, IDC_PROTECT_HIDDEN_VOL, BM_SETCHECK, BST_UNCHECKED, 0);
 3746                 EnableWindow (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
 3747                 EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_VOL_PROTECTION), !IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY)));
 3748             }
 3749 
 3750             protect = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PROTECT_HIDDEN_VOL));
 3751 
 3752             EnableWindow (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), protect);
 3753             EnableWindow (GetDlgItem (hwndDlg, IDT_HIDDEN_PROT_PASSWD), protect);
 3754             EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD_MO), protect);
 3755             EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_HIDVOL_PROT), protect);
 3756             EnableWindow (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE_HIDVOL_PROT), protect);
 3757             EnableWindow (GetDlgItem (hwndDlg, IDT_PKCS5_PRF), protect);
 3758             EnableWindow (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), protect);
 3759             EnableWindow (GetDlgItem (hwndDlg, IDT_PIM), protect);
 3760             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM), protect);
 3761             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_HELP), protect);
 3762             EnableWindow (GetDlgItem (hwndDlg, IDC_PIM_ENABLE), protect);
 3763 
 3764             return 1;
 3765         }
 3766 
 3767         return 0;
 3768     }
 3769 
 3770     return 0;
 3771 }
 3772 
 3773 
 3774 // Returns the block size (in bits) of the cipher with which the volume mounted as the
 3775 // specified drive letter is encrypted. In case of a cascade of ciphers with different
 3776 // block sizes the function returns the smallest block size.
 3777 int GetCipherBlockSizeByDriveNo (int nDosDriveNo)
 3778 {
 3779     VOLUME_PROPERTIES_STRUCT prop;
 3780     DWORD dwResult;
 3781 
 3782     int blockSize = 0, cipherID;
 3783 
 3784     memset (&prop, 0, sizeof(prop));
 3785     prop.driveNo = nDosDriveNo;
 3786 
 3787     if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL))
 3788     {
 3789         if (    (prop.driveNo == nDosDriveNo)
 3790             &&  (prop.ea >= EAGetFirst() && prop.ea <= EAGetCount())
 3791             )
 3792         {
 3793             for (cipherID = EAGetLastCipher (prop.ea);
 3794                 cipherID != 0;
 3795                 cipherID = EAGetPreviousCipher (prop.ea, cipherID))
 3796             {
 3797                 if (blockSize > 0)
 3798                     blockSize = min (blockSize, CipherGetBlockSize (cipherID) * 8);
 3799                 else
 3800                     blockSize = CipherGetBlockSize (cipherID) * 8;
 3801             }
 3802         }
 3803     }
 3804 
 3805     return blockSize;
 3806 }
 3807 
 3808 
 3809 // Returns the mode of operation in which the volume mounted as the specified drive letter is encrypted.
 3810 int GetModeOfOperationByDriveNo (int nDosDriveNo)
 3811 {
 3812     VOLUME_PROPERTIES_STRUCT prop;
 3813     DWORD dwResult;
 3814 
 3815     memset (&prop, 0, sizeof(prop));
 3816     prop.driveNo = nDosDriveNo;
 3817 
 3818     if (DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL))
 3819     {
 3820         if (    (prop.driveNo == nDosDriveNo)
 3821             &&  (prop.ea >= EAGetFirst() && prop.ea <= EAGetCount())
 3822             &&  (prop.mode >= FIRST_MODE_OF_OPERATION_ID && prop.mode < MODE_ENUM_END_ID)
 3823             )
 3824         {
 3825             return prop.mode;
 3826         }
 3827     }
 3828 
 3829     return 0;
 3830 }
 3831 
 3832 void DisplayVolumePropertiesListContextMenu (HWND hwndDlg, LPARAM lParam)
 3833 {
 3834     /* Volume Properties list context menu */
 3835     DWORD mPos;
 3836     int menuItem;
 3837     HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST);
 3838     int hItem = ListView_GetSelectionMark (hList);
 3839 
 3840     SetFocus (hList);
 3841 
 3842     if (hItem >= 0)
 3843     {
 3844         HMENU popup = CreatePopupMenu ();
 3845         AppendMenuW (popup, MF_STRING, IDPM_COPY_VALUE_TO_CLIPBOARD, GetString ("IDPM_COPY_VALUE_TO_CLIPBOARD"));
 3846 
 3847         if (lParam)
 3848         {
 3849             mPos=GetMessagePos();
 3850         }
 3851         else
 3852         {
 3853             POINT pt = {0};
 3854             if (ListView_GetItemPosition (hList, hItem, &pt))
 3855             {
 3856                 pt.x += 2 + ::GetSystemMetrics(SM_CXICON);
 3857                 pt.y += 2;
 3858             }
 3859             ClientToScreen (hList, &pt);
 3860             mPos  = MAKELONG (pt.x, pt.y);
 3861         }
 3862 
 3863         menuItem = TrackPopupMenu (popup,
 3864             TPM_RETURNCMD | TPM_LEFTBUTTON,
 3865             GET_X_LPARAM(mPos),
 3866             GET_Y_LPARAM(mPos),
 3867             0,
 3868             hwndDlg,
 3869             NULL);
 3870 
 3871         DestroyMenu (popup);
 3872 
 3873         switch (menuItem)
 3874         {
 3875         case IDPM_COPY_VALUE_TO_CLIPBOARD:
 3876             {
 3877                 wchar_t valueText[256] = {0};
 3878                 ListView_GetItemText (hList, hItem, 1, valueText, ARRAYSIZE (valueText));
 3879                 CopyTextToClipboard (valueText);
 3880             }
 3881             break;
 3882         }
 3883     }
 3884 }
 3885 
 3886 
 3887 BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 3888 {
 3889     BOOL bSysEnc = (BOOL) lParam;
 3890     BOOL bSysEncWholeDrive = FALSE;
 3891     WORD lw = LOWORD (wParam);
 3892     int i = 0;
 3893 
 3894     switch (msg)
 3895     {
 3896     case WM_INITDIALOG:
 3897         {
 3898             VOLUME_PROPERTIES_STRUCT prop;
 3899             DWORD dwResult;
 3900 
 3901             LVCOLUMNW lvCol;
 3902             HWND list = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST);
 3903             wchar_t szTmp[1024];
 3904             wchar_t sw[1024];
 3905             wchar_t *s;
 3906 
 3907             if (bSysEnc)
 3908             {
 3909                 try
 3910                 {
 3911                     BootEncStatus = BootEncObj->GetStatus();
 3912                     bSysEncWholeDrive = WholeSysDriveEncryption(FALSE);
 3913                 }
 3914                 catch (Exception &e)
 3915                 {
 3916                     e.Show (MainDlg);
 3917                     return 0;
 3918                 }
 3919 
 3920                 if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted)
 3921                     return 0;
 3922             }
 3923             else
 3924             {
 3925                 switch (LOWORD (GetSelectedLong (GetDlgItem (GetParent(hwndDlg), IDC_DRIVELIST))))
 3926                 {
 3927                 case TC_MLIST_ITEM_FREE:
 3928 
 3929                     // No mounted volume
 3930                     EndDialog (hwndDlg, IDOK);
 3931                     return 0;
 3932 
 3933                 case TC_MLIST_ITEM_NONSYS_VOL:
 3934                     // NOP
 3935                     break;
 3936 
 3937                 case TC_MLIST_ITEM_SYS_DRIVE:
 3938                     // Encrypted system drive
 3939                     bSysEnc = TRUE;
 3940                     bSysEncWholeDrive = TRUE;
 3941                     break;
 3942 
 3943                 case TC_MLIST_ITEM_SYS_PARTITION:
 3944                     // Encrypted system partition
 3945                     bSysEnc = TRUE;
 3946                     bSysEncWholeDrive = FALSE;
 3947                     break;
 3948                 }
 3949             }
 3950 
 3951             LocalizeDialog (hwndDlg, "IDD_VOLUME_PROPERTIES");
 3952 
 3953             SendMessage (list,LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
 3954                 LVS_EX_FULLROWSELECT
 3955                 |LVS_EX_HEADERDRAGDROP
 3956                 |LVS_EX_LABELTIP
 3957                 );
 3958 
 3959             memset (&lvCol,0,sizeof(lvCol));
 3960             lvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
 3961             lvCol.pszText = GetString ("VALUE");
 3962             lvCol.cx = CompensateXDPI (208);
 3963             lvCol.fmt = LVCFMT_LEFT;
 3964             SendMessage (list,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol);
 3965 
 3966             lvCol.pszText = GetString ("PROPERTY");
 3967             lvCol.cx = CompensateXDPI (192);
 3968             lvCol.fmt = LVCFMT_LEFT;
 3969             SendMessage (list,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol);
 3970 
 3971             memset (&prop, 0, sizeof(prop));
 3972             prop.driveNo = HIWORD (GetSelectedLong (GetDlgItem (GetParent(hwndDlg), IDC_DRIVELIST))) - L'A';
 3973 
 3974             if (bSysEnc)
 3975             {
 3976                 try
 3977                 {
 3978                     BootEncStatus = BootEncObj->GetStatus();
 3979                     if (!BootEncStatus.DriveEncrypted && !BootEncStatus.DriveMounted)
 3980                         return 0;
 3981 
 3982                     BootEncObj->GetVolumeProperties (&prop);
 3983                 }
 3984                 catch (Exception &e)
 3985                 {
 3986                     e.Show (MainDlg);
 3987                     return 0;
 3988                 }
 3989             }
 3990             else
 3991             {
 3992                 if (!DeviceIoControl (hDriver, TC_IOCTL_GET_VOLUME_PROPERTIES, &prop, sizeof (prop), &prop, sizeof (prop), &dwResult, NULL) || dwResult == 0)
 3993                     return 0;
 3994             }
 3995 
 3996             // Location
 3997             ListItemAdd (list, i, GetString ("LOCATION"));
 3998             if (bSysEnc)
 3999                 ListSubItemSet (list, i++, 1, GetString (bSysEncWholeDrive ? "SYSTEM_DRIVE" : IsHiddenOSRunning() ? "HIDDEN_SYSTEM_PARTITION" : "SYSTEM_PARTITION"));
 4000             else
 4001                 ListSubItemSet (list, i++, 1, (wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4));
 4002 
 4003             if (!bSysEnc && IsVolumeDeviceHosted ((wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4)))
 4004             {
 4005                 // Volume ID
 4006                 std::wstring hexID = ArrayToHexWideString (prop.volumeID, sizeof (prop.volumeID));
 4007                 ListItemAdd (list, i, GetString ("VOLUME_ID"));
 4008 
 4009                 ListSubItemSet (list, i++, 1, hexID.c_str());
 4010             }
 4011 
 4012 
 4013             // Size
 4014             ListItemAdd (list, i, GetString ("SIZE"));
 4015             StringCbPrintfW (sw, sizeof(sw), L"%I64u %s", prop.diskLength, GetString ("BYTES"));
 4016             ListSubItemSet (list, i++, 1, sw);
 4017 
 4018             // Type
 4019             ListItemAdd (list, i, GetString ("TYPE"));
 4020             if (bSysEnc)
 4021                 ListSubItemSet (list, i++, 1, GetString (IsHiddenOSRunning() ? "TYPE_HIDDEN_SYSTEM_ADJECTIVE" : "SYSTEM_VOLUME_TYPE_ADJECTIVE"));
 4022             else
 4023             {
 4024                 bool truecryptMode = prop.pkcs5Iterations == get_pkcs5_iteration_count(prop.pkcs5, 0, TRUE, prop.partitionInInactiveSysEncScope);
 4025                 s = prop.hiddenVolume ? GetString ("HIDDEN") :
 4026                     (prop.hiddenVolProtection != HIDVOL_PROT_STATUS_NONE ? GetString ("OUTER") : GetString ("NORMAL"));
 4027 
 4028                 if (truecryptMode)
 4029                 {
 4030                     StringCbPrintfW (sw, sizeof(sw), L"TrueCrypt - %s", s);
 4031                     ListSubItemSet (list, i++, 1, sw);
 4032                 }
 4033                 else
 4034                     ListSubItemSet (list, i++, 1, s);
 4035             }
 4036 
 4037             if (!bSysEnc)
 4038             {
 4039                 // Write protection
 4040                 ListItemAdd (list, i, GetString ("READ_ONLY"));
 4041 
 4042                 if (prop.readOnly || prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN)
 4043                     s = GetString ("UISTR_YES");
 4044                 else
 4045                     s = GetString ("UISTR_NO");
 4046 
 4047                 ListSubItemSet (list, i++, 1, s);
 4048 
 4049                 // Hidden Volume Protection
 4050                 ListItemAdd (list, i, GetString ("HIDDEN_VOL_PROTECTION"));
 4051                 if (prop.hiddenVolume)
 4052                     s = GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE");
 4053                 else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_NONE)
 4054                     s = GetString ("UISTR_NO");
 4055                 else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTIVE)
 4056                     s = GetString ("UISTR_YES");
 4057                 else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN)
 4058                     s = GetString ("HID_VOL_DAMAGE_PREVENTED");
 4059 
 4060                 ListSubItemSet (list, i++, 1, s);
 4061             }
 4062 
 4063             // Encryption algorithm
 4064             ListItemAdd (list, i, GetString ("ENCRYPTION_ALGORITHM"));
 4065 
 4066             if (prop.ea < EAGetFirst() || prop.ea > EAGetCount ())
 4067             {
 4068                 ListSubItemSet (list, i, 1, L"?");
 4069                 return 1;
 4070             }
 4071 
 4072             EAGetName (szTmp, prop.ea, 1);
 4073             ListSubItemSet (list, i++, 1, szTmp);
 4074 
 4075             // Key size(s)
 4076             {
 4077                 wchar_t name[128];
 4078                 int size = EAGetKeySize (prop.ea);
 4079                 EAGetName (name, prop.ea, 1);
 4080 
 4081                 // Primary key
 4082                 ListItemAdd (list, i, GetString ("KEY_SIZE"));
 4083                 StringCbPrintfW (sw, sizeof(sw), L"%d %s", size * 8, GetString ("BITS"));
 4084                 ListSubItemSet (list, i++, 1, sw);
 4085 
 4086                 if (wcscmp (EAGetModeName (prop.ea, prop.mode, TRUE), L"XTS") == 0)
 4087                 {
 4088                     // Secondary key (XTS)
 4089 
 4090                     ListItemAdd (list, i, GetString ("SECONDARY_KEY_SIZE_XTS"));
 4091                     ListSubItemSet (list, i++, 1, sw);
 4092                 }
 4093             }
 4094 
 4095             // Block size
 4096             ListItemAdd (list, i, GetString ("BLOCK_SIZE"));
 4097 
 4098             StringCbPrintfW (sw, sizeof(sw), L"%d ", CipherGetBlockSize (EAGetFirstCipher(prop.ea))*8);
 4099             StringCbCatW (sw, sizeof(sw), GetString ("BITS"));
 4100             ListSubItemSet (list, i++, 1, sw);
 4101 
 4102             // Mode
 4103             ListItemAdd (list, i, GetString ("MODE_OF_OPERATION"));
 4104             ListSubItemSet (list, i++, 1, EAGetModeName (prop.ea, prop.mode, TRUE));
 4105 
 4106             // PKCS 5 PRF
 4107             ListItemAdd (list, i, GetString ("PKCS5_PRF"));
 4108             if (prop.volumePim == 0)
 4109                 ListSubItemSet (list, i++, 1, get_pkcs5_prf_name (prop.pkcs5));
 4110             else
 4111             {
 4112                 StringCbPrintfW (szTmp, sizeof(szTmp), L"%s (Dynamic)", get_pkcs5_prf_name (prop.pkcs5));
 4113                 ListSubItemSet (list, i++, 1, szTmp);
 4114             }
 4115 
 4116 #if 0
 4117             // PCKS 5 iterations
 4118             ListItemAdd (list, i, GetString ("PKCS5_ITERATIONS"));
 4119             sprintf (szTmp, "%d", prop.pkcs5Iterations);
 4120             ListSubItemSet (list, i++, 1, szTmp);
 4121 #endif
 4122 
 4123 #if 0
 4124             {
 4125                 // Legacy
 4126 
 4127                 FILETIME ft, curFt;
 4128                 LARGE_INTEGER ft64, curFt64;
 4129                 SYSTEMTIME st;
 4130                 wchar_t date[128];
 4131                 memset (date, 0, sizeof (date));
 4132 
 4133                 // Volume date
 4134                 ListItemAdd (list, i, GetString ("VOLUME_CREATE_DATE"));
 4135                 *(unsigned __int64 *)(&ft) = prop.volumeCreationTime;
 4136                 FileTimeToSystemTime (&ft, &st);
 4137                 GetDateFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2);
 4138                 swprintf (date, L"%s ", sw);
 4139                 GetTimeFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2);
 4140                 wcscat (date, sw);
 4141                 ListSubItemSet (list, i++, 1, date);
 4142 
 4143                 // Header date
 4144                 ListItemAdd (list, i, GetString ("VOLUME_HEADER_DATE"));
 4145                 *(unsigned __int64 *)(&ft) = prop.headerCreationTime;
 4146                 FileTimeToSystemTime (&ft, &st);
 4147                 GetDateFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2);
 4148                 swprintf (date, L"%s ", sw);
 4149                 GetTimeFormatW (LOCALE_USER_DEFAULT, 0, &st, 0, sw, sizeof (sw)/2);
 4150                 wcscat (date, sw);
 4151 
 4152                 GetLocalTime (&st);
 4153                 SystemTimeToFileTime (&st, &curFt);
 4154                 curFt64.HighPart = curFt.dwHighDateTime;
 4155                 curFt64.LowPart = curFt.dwLowDateTime;
 4156                 ft64.HighPart = ft.dwHighDateTime;
 4157                 ft64.LowPart = ft.dwLowDateTime;
 4158                 swprintf (date + wcslen (date),  GetString ("VOLUME_HEADER_DAYS")
 4159                     , (curFt64.QuadPart - ft64.QuadPart)/(24LL*3600*10000000));
 4160                 ListSubItemSet (list, i++, 1, date);
 4161             }
 4162 #endif // 0
 4163 
 4164             if (!bSysEnc || IsHiddenOSRunning())
 4165             {
 4166                 // Volume format version
 4167                 ListItemAdd (list, i, GetString ("VOLUME_FORMAT_VERSION"));
 4168                 StringCbPrintfW (szTmp, sizeof(szTmp), L"%d", prop.volFormatVersion);
 4169                 ListSubItemSet (list, i++, 1, szTmp);
 4170 
 4171                 // Backup header
 4172                 ListItemAdd (list, i, GetString ("BACKUP_HEADER"));
 4173                 ListSubItemSet (list, i++, 1, GetString (prop.volFormatVersion > 1 ? "UISTR_YES" : "UISTR_NO"));
 4174             }
 4175 
 4176             // Total data read
 4177             ListItemAdd (list, i, GetString ("TOTAL_DATA_READ"));
 4178             GetSizeString (prop.totalBytesRead, sw, sizeof(sw));
 4179             ListSubItemSet (list, i++, 1, sw);
 4180 
 4181             // Total data written
 4182             ListItemAdd (list, i, GetString ("TOTAL_DATA_WRITTEN"));
 4183             GetSizeString (prop.totalBytesWritten, sw, sizeof(sw));
 4184             ListSubItemSet (list, i++, 1, sw);
 4185 
 4186             if (bSysEnc)
 4187             {
 4188                 // TrueCrypt Boot Loader version
 4189                 ListItemAdd (list, i, GetString ("VC_BOOT_LOADER_VERSION"));
 4190                 ListSubItemSet (list, i++, 1, GetUserFriendlyVersionString (BootEncStatus.BootLoaderVersion).c_str());
 4191 
 4192                 // Encrypted portion
 4193                 ListItemAdd (list, i, GetString ("ENCRYPTED_PORTION"));
 4194                 if (GetSysEncDeviceEncryptedPartSize (FALSE) == GetSysEncDeviceSize (FALSE))
 4195                     ListSubItemSet (list, i++, 1, GetString ("ENCRYPTED_PORTION_FULLY_ENCRYPTED"));
 4196                 else if (GetSysEncDeviceEncryptedPartSize (FALSE) <= 1)
 4197                     ListSubItemSet (list, i++, 1, GetString ("ENCRYPTED_PORTION_NOT_ENCRYPTED"));
 4198                 else
 4199                 {
 4200 
 4201                     StringCbPrintfW (sw,
 4202                         sizeof sw,
 4203                         GetString ("PROCESSED_PORTION_X_PERCENT"),
 4204                         (double) GetSysEncDeviceEncryptedPartSize (FALSE) / (double) GetSysEncDeviceSize (FALSE) * 100.0);
 4205 
 4206                     ListSubItemSet (list, i++, 1, sw);
 4207                 }
 4208             }
 4209 
 4210             return 0;
 4211         }
 4212 
 4213     case WM_NOTIFY:
 4214 
 4215         if(wParam == IDC_VOLUME_PROPERTIES_LIST)
 4216         {
 4217             /* Right click */
 4218 
 4219             switch (((NM_LISTVIEW *) lParam)->hdr.code)
 4220             {
 4221             case NM_RCLICK:
 4222             case LVN_BEGINRDRAG:
 4223                 /* If the mouse was moving while the right mouse button is pressed, popup menu would
 4224                 not open, because drag&drop operation would be initiated. Therefore, we're handling
 4225                 RMB drag-and-drop operations as well. */
 4226                 {
 4227 
 4228                     DisplayVolumePropertiesListContextMenu (hwndDlg, lParam);
 4229 
 4230                     return 1;
 4231                 }
 4232             }
 4233         }
 4234         return 0;
 4235 
 4236     case WM_CONTEXTMENU:
 4237         {
 4238             HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST);
 4239             // only handle if it is coming from keyboard and if the drive
 4240             // list has focus. The other cases are handled elsewhere
 4241             if (   (-1 == GET_X_LPARAM(lParam))
 4242                 && (-1 == GET_Y_LPARAM(lParam))
 4243                 && (GetFocus () == hList)
 4244                 )
 4245             {
 4246                 DisplayVolumePropertiesListContextMenu (hwndDlg, NULL);
 4247             }
 4248         }
 4249         return 0;
 4250 
 4251     case WM_COMMAND:
 4252         if (lw == IDOK)
 4253         {
 4254             EndDialog (hwndDlg, lw);
 4255             return 1;
 4256         }
 4257         return 0;
 4258 
 4259     case WM_CLOSE:
 4260         EndDialog (hwndDlg, lw);
 4261         return 1;
 4262     }
 4263 
 4264     return 0;
 4265 }
 4266 
 4267 
 4268 BOOL CALLBACK TravelerDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 4269 {
 4270     WORD lw = LOWORD (wParam);
 4271     static BOOL bAutoRunWarningDisplayed = FALSE;
 4272 
 4273     switch (msg)
 4274     {
 4275     case WM_INITDIALOG:
 4276         {
 4277             WCHAR i;
 4278             int index;
 4279             WCHAR drive[] = { 0, L':', 0 };
 4280 
 4281             LocalizeDialog (hwndDlg, "IDD_TRAVELER_DLG");
 4282 
 4283             SendDlgItemMessage (hwndDlg, IDC_COPY_WIZARD, BM_SETCHECK,
 4284                         BST_CHECKED, 0);
 4285 
 4286             SendDlgItemMessage (hwndDlg, IDC_COPY_EXPANDER, BM_SETCHECK,
 4287                         BST_CHECKED, 0);
 4288 
 4289             SendDlgItemMessage (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER, BM_SETCHECK,
 4290                         BST_CHECKED, 0);
 4291 
 4292             SendDlgItemMessage (hwndDlg, IDC_AUTORUN_DISABLE, BM_SETCHECK,
 4293                         BST_CHECKED, 0);
 4294 
 4295             SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_RESETCONTENT, 0, 0);
 4296 
 4297             index = (int) SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) GetString ("FIRST_AVAILABLE"));
 4298             SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) 0);
 4299 
 4300             for (i = L'A'; i <= L'Z'; i++)
 4301             {
 4302                 if (i == L'C')
 4303                     continue;
 4304                 drive[0] = i;
 4305                 index = (int) SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_ADDSTRING, 0, (LPARAM) drive);
 4306                 SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_SETITEMDATA, index, (LPARAM) i);
 4307             }
 4308 
 4309             SendDlgItemMessageW (hwndDlg, IDC_DRIVELIST, CB_SETCURSEL, 0, 0);
 4310 
 4311             return 0;
 4312         }
 4313 
 4314     case WM_CTLCOLORSTATIC:
 4315         {
 4316             HDC hdc = (HDC) wParam;
 4317             HWND hw = (HWND) lParam;
 4318             if (hw == GetDlgItem(hwndDlg, IDC_DIRECTORY))
 4319             {
 4320                 // This the directory field. Make its background like normal edit
 4321                 HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW);
 4322                 ::SelectObject(hdc, hbr);
 4323                 return (BOOL) hbr;
 4324             }
 4325         }
 4326         return 0;
 4327 
 4328     case WM_COMMAND:
 4329 
 4330         if (HIWORD (wParam) == BN_CLICKED
 4331             && (lw == IDC_AUTORUN_DISABLE || lw == IDC_AUTORUN_MOUNT || lw == IDC_AUTORUN_START ))
 4332         {
 4333             BOOL enabled = IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_MOUNT));
 4334 
 4335             EnableWindow (GetDlgItem (hwndDlg, IDC_BROWSE_FILES), enabled);
 4336             EnableWindow (GetDlgItem (hwndDlg, IDC_VOLUME_NAME), enabled);
 4337             EnableWindow (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER), enabled);
 4338             EnableWindow (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS), enabled);
 4339             EnableWindow (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM), enabled);
 4340             EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY), enabled);
 4341             EnableWindow (GetDlgItem (hwndDlg, IDC_DRIVELIST), enabled);
 4342             EnableWindow (GetDlgItem (hwndDlg, IDT_TRAVELER_MOUNT), enabled);
 4343             EnableWindow (GetDlgItem (hwndDlg, IDT_MOUNT_LETTER), enabled);
 4344             EnableWindow (GetDlgItem (hwndDlg, IDT_MOUNT_SETTINGS), enabled);
 4345 
 4346             if (!bAutoRunWarningDisplayed
 4347                 && (lw == IDC_AUTORUN_MOUNT || lw == IDC_AUTORUN_START))
 4348             {
 4349                 bAutoRunWarningDisplayed = TRUE;
 4350                 Warning ("AUTORUN_MAY_NOT_ALWAYS_WORK", hwndDlg);
 4351             }
 4352 
 4353             return 1;
 4354         }
 4355 
 4356         if (lw == IDC_BROWSE_FILES)
 4357         {
 4358             wchar_t dstDir[MAX_PATH];
 4359             wchar_t volName[MAX_PATH] = { 0 };
 4360 
 4361             GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstDir, ARRAYSIZE (dstDir));
 4362 
 4363             if (BrowseFilesInDir (hwndDlg, "OPEN_TITLE", dstDir, volName, bHistory, FALSE, NULL))
 4364                 SetDlgItemText (hwndDlg, IDC_VOLUME_NAME, wcschr (volName, L'\\') + 1);
 4365 
 4366             return 1;
 4367         }
 4368 
 4369         if (lw == IDC_BROWSE_DIRS)
 4370         {
 4371             wchar_t dstPath[MAX_PATH * 2];
 4372             GetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath, ARRAYSIZE (dstPath));
 4373 
 4374             if (BrowseDirectories (hwndDlg, "SELECT_DEST_DIR", dstPath))
 4375                 SetDlgItemText (hwndDlg, IDC_DIRECTORY, dstPath);
 4376 
 4377             return 1;
 4378         }
 4379 
 4380         if (lw == IDCANCEL || lw == IDCLOSE)
 4381         {
 4382             EndDialog (hwndDlg, lw);
 4383             return 1;
 4384         }
 4385 
 4386         if (lw == IDC_CREATE)
 4387         {
 4388 
 4389             BOOL copyWizard, copyExpander, bExplore, bCacheInDriver, bIncludePimInCache, bAutoRun, bAutoMount, bMountReadOnly;
 4390             WCHAR dstDir[MAX_PATH + 1];
 4391             WCHAR srcPath[1024 + MAX_PATH + 1];
 4392             WCHAR dstPath[2*MAX_PATH + 1];
 4393             WCHAR appDir[1024];
 4394             WCHAR volName[MAX_PATH + 2];
 4395             int drive;
 4396             WCHAR* ptr;
 4397 
 4398             GetDlgItemTextW (hwndDlg, IDC_DIRECTORY, dstDir, array_capacity (dstDir));
 4399             volName[0] = 0;
 4400             GetDlgItemTextW (hwndDlg, IDC_VOLUME_NAME, volName + 1, (array_capacity (volName)) - 1);
 4401 
 4402             drive = (int) SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETCURSEL, 0, 0);
 4403             drive = (int) SendDlgItemMessage (hwndDlg, IDC_DRIVELIST, CB_GETITEMDATA, drive, 0);
 4404 
 4405             copyWizard = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_WIZARD));
 4406             copyExpander = IsButtonChecked (GetDlgItem (hwndDlg, IDC_COPY_EXPANDER));
 4407             bExplore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAVEL_OPEN_EXPLORER));
 4408             bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_TRAV_CACHE_PASSWORDS));
 4409             bIncludePimInCache = IsButtonChecked (GetDlgItem (hwndDlg, IDC_PREF_CACHE_PIM));
 4410             bMountReadOnly = IsButtonChecked (GetDlgItem (hwndDlg, IDC_MOUNT_READONLY));
 4411             bAutoRun = !IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_DISABLE));
 4412             bAutoMount = IsButtonChecked (GetDlgItem (hwndDlg, IDC_AUTORUN_MOUNT));
 4413 
 4414             if (dstDir[0] == 0)
 4415             {
 4416                 SetFocus (GetDlgItem (hwndDlg, IDC_DIRECTORY));
 4417                 MessageBoxW (hwndDlg, GetString ("NO_PATH_SELECTED"), lpszTitle, MB_ICONEXCLAMATION);
 4418                 return 1;
 4419             }
 4420 
 4421 
 4422             if (bAutoMount && volName[1] == 0)
 4423             {
 4424                 SetFocus (GetDlgItem (hwndDlg, IDC_VOLUME_NAME));
 4425                 MessageBoxW (hwndDlg, GetString ("NO_FILE_SELECTED"), lpszTitle, MB_ICONEXCLAMATION);
 4426                 return 1;
 4427             }
 4428 
 4429             if (volName[1] != 0)
 4430             {
 4431                 volName[0] = L'"';
 4432                 StringCbCatW (volName, sizeof(volName), L"\"");
 4433             }
 4434 
 4435             GetModuleFileNameW (NULL, appDir, array_capacity (appDir));
 4436             if (ptr = wcsrchr (appDir, L'\\'))
 4437                 ptr[0] = 0;
 4438 
 4439             WaitCursor ();
 4440 
 4441             StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt", dstDir);
 4442             if (!CreateDirectoryW (dstPath, NULL))
 4443             {
 4444                 handleWin32Error (hwndDlg, SRC_POS);
 4445                 goto stop;
 4446             }
 4447 
 4448             if (IsNonInstallMode ())
 4449             {
 4450                 // Main app 32-bit
 4451                 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt.exe", appDir);
 4452                 StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt.exe", dstDir);
 4453                 if (!VerifyModuleSignature (srcPath))
 4454                 {
 4455                     Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4456                     goto stop;
 4457                 }
 4458                 else if (!TCCopyFile (srcPath, dstPath))
 4459                 {
 4460                     handleWin32Error (hwndDlg, SRC_POS);
 4461                     goto stop;
 4462                 }
 4463 
 4464                 // Main app 64-bit
 4465                 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt-x64.exe", appDir);
 4466                 StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt-x64.exe", dstDir);
 4467                 if (!VerifyModuleSignature (srcPath))
 4468                 {
 4469                     Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4470                     goto stop;
 4471                 }
 4472                 else if (!TCCopyFile (srcPath, dstPath))
 4473                 {
 4474                     handleWin32Error (hwndDlg, SRC_POS);
 4475                     goto stop;
 4476                 }
 4477 
 4478                 // Wizard
 4479                 if (copyWizard)
 4480                 {
 4481                     // Wizard 32-bit
 4482                     StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format.exe", appDir);
 4483                     StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format.exe", dstDir);
 4484                     if (!VerifyModuleSignature (srcPath))
 4485                     {
 4486                         Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4487                         goto stop;
 4488                     }
 4489                     else if (!TCCopyFile (srcPath, dstPath))
 4490                     {
 4491                         handleWin32Error (hwndDlg, SRC_POS);
 4492                         goto stop;
 4493                     }
 4494 
 4495                     // Wizard 64-bit
 4496                     StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Format-x64.exe", appDir);
 4497                     StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format-x64.exe", dstDir);
 4498                     if (!VerifyModuleSignature (srcPath))
 4499                     {
 4500                         Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4501                         goto stop;
 4502                     }
 4503                     else if (!TCCopyFile (srcPath, dstPath))
 4504                     {
 4505                         handleWin32Error (hwndDlg, SRC_POS);
 4506                         goto stop;
 4507                     }
 4508                 }
 4509 
 4510                 // Expander
 4511                 if (copyExpander)
 4512                 {
 4513                     // Expander 32-bit
 4514                     StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander.exe", appDir);
 4515                     StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander.exe", dstDir);
 4516                     if (!VerifyModuleSignature (srcPath))
 4517                     {
 4518                         Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4519                         goto stop;
 4520                     }
 4521                     else if (!TCCopyFile (srcPath, dstPath))
 4522                     {
 4523                         handleWin32Error (hwndDlg, SRC_POS);
 4524                         goto stop;
 4525                     }
 4526 
 4527                     // Expander 64-bit
 4528                     StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCryptExpander-x64.exe", appDir);
 4529                     StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander-x64.exe", dstDir);
 4530                     if (!VerifyModuleSignature (srcPath))
 4531                     {
 4532                         Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4533                         goto stop;
 4534                     }
 4535                     else if (!TCCopyFile (srcPath, dstPath))
 4536                     {
 4537                         handleWin32Error (hwndDlg, SRC_POS);
 4538                         goto stop;
 4539                     }
 4540                 }
 4541 
 4542                 // Driver
 4543                 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt.sys", appDir);
 4544                 StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt.sys", dstDir);
 4545                 if (!VerifyModuleSignature (srcPath))
 4546                 {
 4547                     Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4548                     goto stop;
 4549                 }
 4550                 else if (!TCCopyFile (srcPath, dstPath))
 4551                 {
 4552                     handleWin32Error (hwndDlg, SRC_POS);
 4553                     goto stop;
 4554                 }
 4555 
 4556                 // Driver x64
 4557                 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\veracrypt-x64.sys", appDir);
 4558                 StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-x64.sys", dstDir);
 4559                 if (!VerifyModuleSignature (srcPath))
 4560                 {
 4561                     Error ("DIST_PACKAGE_CORRUPTED", hwndDlg);
 4562                     goto stop;
 4563                 }
 4564                 else if (!TCCopyFile (srcPath, dstPath))
 4565                 {
 4566                     handleWin32Error (hwndDlg, SRC_POS);
 4567                     goto stop;
 4568                 }
 4569             }
 4570             else
 4571             {
 4572                 int fileNo = 0;
 4573                 // get file from the Setup binary after checking its signature and its version
 4574                 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\VeraCrypt Setup.exe", appDir);
 4575 
 4576                 FreeAllFileBuffers ();
 4577 
 4578                 if (!VerifyPackageIntegrity (srcPath) || !SelfExtractInMemory (srcPath))
 4579                 {
 4580                     MessageBoxW (hwndDlg, GetString ("DIST_PACKAGE_CORRUPTED"), lpszTitle, MB_ICONEXCLAMATION);
 4581                     goto stop;
 4582                 }
 4583 
 4584                 for (fileNo = 0; fileNo < NBR_COMPRESSED_FILES; fileNo++)
 4585                 {
 4586                     wchar_t fileName [TC_MAX_PATH] = {0};
 4587 
 4588                     // Filename
 4589                     StringCchCopyNW (fileName, ARRAYSIZE(fileName), Decompressed_Files[fileNo].fileName, Decompressed_Files[fileNo].fileNameLength);
 4590 
 4591                     if (wcscmp (fileName, L"VeraCrypt.exe") == 0)
 4592                     {
 4593                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt.exe", dstDir);
 4594                     }
 4595                     else if (wcscmp (fileName, L"VeraCrypt-x64.exe") == 0)
 4596                     {
 4597                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt-x64.exe", dstDir);
 4598                     }
 4599                     else if (wcscmp (fileName, L"veracrypt.sys") == 0)
 4600                     {
 4601                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt.sys", dstDir);
 4602                     }
 4603                     else if (wcscmp (fileName, L"veracrypt-x64.sys") == 0)
 4604                     {
 4605                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\veracrypt-x64.sys", dstDir);
 4606                     }
 4607                     else if (copyWizard && (wcscmp (fileName, L"VeraCrypt Format.exe") == 0))
 4608                     {
 4609                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format.exe", dstDir);
 4610                     }
 4611                     else if (copyWizard && (wcscmp (fileName, L"VeraCrypt Format-x64.exe") == 0))
 4612                     {
 4613                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCrypt Format-x64.exe", dstDir);
 4614                     }
 4615                     else if (copyExpander && (wcscmp (fileName, L"VeraCryptExpander.exe") == 0))
 4616                     {
 4617                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander.exe", dstDir);
 4618                     }
 4619                     else if (copyExpander && (wcscmp (fileName, L"VeraCryptExpander-x64.exe") == 0))
 4620                     {
 4621                         StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\VeraCryptExpander-x64.exe", dstDir);
 4622                     }
 4623                     else
 4624                         continue;
 4625 
 4626                     if (!SaveBufferToFile (
 4627                         (char *) Decompressed_Files[fileNo].fileContent,
 4628                         dstPath,
 4629                         Decompressed_Files[fileNo].fileLength,
 4630                         FALSE, FALSE))
 4631                     {
 4632                         wchar_t szTmp[512];
 4633 
 4634                         StringCbPrintfW (szTmp, sizeof (szTmp), GetString ("CANNOT_WRITE_FILE_X"), dstPath);
 4635                         MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
 4636                         goto stop;
 4637                     }
 4638                 }
 4639             }
 4640 
 4641             if (strcmp (GetPreferredLangId (), "en") != 0)
 4642             {
 4643                 // Language pack
 4644                 StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\Languages", dstDir);
 4645                 if (!CreateDirectoryW (dstPath, NULL))
 4646                 {
 4647                     handleWin32Error (hwndDlg, SRC_POS);
 4648                     goto stop;
 4649                 }
 4650                 StringCbPrintfW (srcPath, sizeof(srcPath), L"%s\\Languages\\Language.%hs.xml", appDir, GetPreferredLangId ());
 4651                 StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\VeraCrypt\\Languages\\Language.%hs.xml", dstDir, GetPreferredLangId ());
 4652                 if (!TCCopyFile (srcPath, dstPath))
 4653                 {
 4654                     handleWin32Error (hwndDlg, SRC_POS);
 4655                     goto stop;
 4656                 }
 4657             }
 4658 
 4659             // AutoRun
 4660             StringCbPrintfW (dstPath, sizeof(dstPath), L"%s\\autorun.inf", dstDir);
 4661             DeleteFileW (dstPath);
 4662             if (bAutoRun)
 4663             {
 4664                 FILE *af;
 4665                 wchar_t autoMount[2*MAX_PATH + 2];
 4666                 wchar_t driveLetter[] = { L' ', L'/', L'l', L' ', (wchar_t) drive, 0 };
 4667 
 4668                 af = _wfopen (dstPath, L"w,ccs=UNICODE");
 4669 
 4670                 if (af == NULL)
 4671                 {
 4672                     MessageBoxW (hwndDlg, GetString ("CANT_CREATE_AUTORUN"), lpszTitle, MB_ICONERROR);
 4673                     goto stop;
 4674                 }
 4675 
 4676                 StringCbPrintfW (autoMount, sizeof(autoMount), L"VeraCrypt\\VeraCrypt.exe /q background%s%s%s%s /m rm /v %s",
 4677                     drive > 0 ? driveLetter : L"",
 4678                     bExplore ? L" /e" : L"",
 4679                     bCacheInDriver ? (bIncludePimInCache? L" /c p" : L" /c y") : L"",
 4680                     bMountReadOnly ? L" /m ro" : L"",
 4681                     volName);
 4682 
 4683                 fwprintf (af, L"[autorun]\nlabel=%s\nicon=VeraCrypt\\VeraCrypt.exe\n", GetString ("TC_TRAVELER_DISK"));
 4684                 fwprintf (af, L"action=%s\n", bAutoMount ? GetString ("MOUNT_TC_VOLUME") : GetString ("IDC_PREF_LOGON_START"));
 4685                 fwprintf (af, L"open=%s\n", bAutoMount ? autoMount : L"VeraCrypt\\VeraCrypt.exe");
 4686                 fwprintf (af, L"shell\\start=%s\nshell\\start\\command=VeraCrypt\\VeraCrypt.exe\n", GetString ("IDC_PREF_LOGON_START"));
 4687                 fwprintf (af, L"shell\\dismount=%s\nshell\\dismount\\command=VeraCrypt\\VeraCrypt.exe /q /d\n", GetString ("DISMOUNT_ALL_TC_VOLUMES"));
 4688 
 4689                 CheckFileStreamWriteErrors (hwndDlg, af, dstPath);
 4690                 fclose (af);
 4691             }
 4692             MessageBoxW (hwndDlg, GetString ("TRAVELER_DISK_CREATED"), lpszTitle, MB_ICONINFORMATION);
 4693 
 4694 stop:
 4695             FreeAllFileBuffers ();
 4696             NormalCursor ();
 4697             return 1;
 4698         }
 4699         return 0;
 4700     }
 4701 
 4702     return 0;
 4703 }
 4704 
 4705 void BuildTree (HWND hwndDlg, HWND hTree)
 4706 {
 4707     HIMAGELIST hList;
 4708     HBITMAP hBitmap, hBitmapMask;
 4709     LVCOLUMNW lvCol;
 4710 
 4711     ListView_DeleteColumn (hTree,0);
 4712     ListView_DeleteColumn (hTree,0);
 4713     ListView_DeleteColumn (hTree,0);
 4714     ListView_DeleteColumn (hTree,0);
 4715     ListView_DeleteColumn (hTree,0);
 4716     ListView_DeleteColumn (hTree,0);
 4717 
 4718     SendMessage(hTree,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
 4719         LVS_EX_FULLROWSELECT
 4720         |LVS_EX_HEADERDRAGDROP
 4721         );
 4722 
 4723     memset(&lvCol,0,sizeof(lvCol));
 4724 
 4725     lvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
 4726     lvCol.pszText = GetString ("DRIVE");
 4727     lvCol.cx = CompensateXDPI (38);
 4728     lvCol.fmt = LVCFMT_COL_HAS_IMAGES|LVCFMT_LEFT ;
 4729     SendMessage (hTree,LVM_INSERTCOLUMNW,0,(LPARAM)&lvCol);
 4730 
 4731     lvCol.pszText = GetString ("VOLUME");
 4732     lvCol.cx = CompensateXDPI (200);
 4733     lvCol.fmt = LVCFMT_LEFT;
 4734     SendMessage (hTree,LVM_INSERTCOLUMNW,1,(LPARAM)&lvCol);
 4735     LastDriveListVolumeColumnWidth = ListView_GetColumnWidth (hTree, 1);
 4736 
 4737     lvCol.pszText = GetString ("SIZE");
 4738     lvCol.cx = CompensateXDPI (55);
 4739     lvCol.fmt = LVCFMT_RIGHT;
 4740     SendMessage (hTree,LVM_INSERTCOLUMNW,2,(LPARAM)&lvCol);
 4741 
 4742     lvCol.pszText = GetString ("ENCRYPTION_ALGORITHM_LV");
 4743     lvCol.cx = CompensateXDPI (123);
 4744     lvCol.fmt = LVCFMT_LEFT;
 4745     SendMessage (hTree,LVM_INSERTCOLUMNW,3,(LPARAM)&lvCol);
 4746 
 4747     lvCol.pszText = GetString ("TYPE");
 4748     lvCol.cx = CompensateXDPI (100);
 4749     lvCol.fmt = LVCFMT_LEFT;
 4750     SendMessage (hTree,LVM_INSERTCOLUMNW,4,(LPARAM)&lvCol);
 4751 
 4752     // Regular drive icon
 4753 
 4754     hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_DRIVEICON));
 4755     if (hBitmap == NULL)
 4756         return;
 4757     hBitmapMask = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_DRIVEICON_MASK));
 4758 
 4759     hList = CreateImageList (16, 12, ILC_COLOR8|ILC_MASK, 2, 2);
 4760     if (AddBitmapToImageList (hList, hBitmap, hBitmapMask) == -1)
 4761     {
 4762         DeleteObject (hBitmap);
 4763         DeleteObject (hBitmapMask);
 4764         return;
 4765     }
 4766     else
 4767     {
 4768         DeleteObject (hBitmap);
 4769         DeleteObject (hBitmapMask);
 4770     }
 4771 
 4772     // System drive icon
 4773 
 4774     hBitmap = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_SYS_DRIVEICON));
 4775     if (hBitmap == NULL)
 4776         return;
 4777     hBitmapMask = LoadBitmap (hInst, MAKEINTRESOURCE (IDB_SYS_DRIVEICON_MASK));
 4778 
 4779     if (AddBitmapToImageList (hList, hBitmap, hBitmapMask) == -1)
 4780     {
 4781         DeleteObject (hBitmap);
 4782         DeleteObject (hBitmapMask);
 4783         return;
 4784     }
 4785     else
 4786     {
 4787         DeleteObject (hBitmap);
 4788         DeleteObject (hBitmapMask);
 4789     }
 4790 
 4791     ListView_SetImageList (hTree, hList, LVSIL_NORMAL);
 4792     ListView_SetImageList (hTree, hList, LVSIL_SMALL);
 4793 
 4794     LoadDriveLetters (hwndDlg, hTree, 0);
 4795 }
 4796 
 4797 LPARAM GetSelectedLong (HWND hTree)
 4798 {
 4799     int hItem = ListView_GetSelectionMark (hTree);
 4800     LVITEM item;
 4801 
 4802