"Fossies" - the Fresh Open Source Software Archive

Member "src/Format/Tcformat.c" (10 Oct 2018, 317254 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 "Tcformat.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 
   16 #include <stdlib.h>
   17 #include <limits.h>
   18 #include <time.h>
   19 #include <errno.h>
   20 #include <io.h>
   21 #include <sys/stat.h>
   22 #include <shlobj.h>
   23 
   24 #include "Crypto.h"
   25 #include "cpu.h"
   26 #include "Apidrvr.h"
   27 #include "Dlgcode.h"
   28 #include "Language.h"
   29 #include "Combo.h"
   30 #include "Registry.h"
   31 #include "Boot/Windows/BootDefs.h"
   32 #include "Common/Common.h"
   33 #include "Common/BootEncryption.h"
   34 #include "Common/Dictionary.h"
   35 #include "Common/Endian.h"
   36 #include "Common/resource.h"
   37 #include "Common/Pkcs5.h"
   38 #include "Platform/Finally.h"
   39 #include "Platform/ForEach.h"
   40 #include "Random.h"
   41 #include "Fat.h"
   42 #include "InPlace.h"
   43 #include "Resource.h"
   44 #include "TcFormat.h"
   45 #include "Format.h"
   46 #include "FormatCom.h"
   47 #include "Password.h"
   48 #include "Progress.h"
   49 #include "Tests.h"
   50 #include "Cmdline.h"
   51 #include "Volumes.h"
   52 #include "Wipe.h"
   53 #include "Xml.h"
   54 #include "SecurityToken.h"
   55 
   56 #include <Strsafe.h>
   57 
   58 using namespace VeraCrypt;
   59 
   60 enum wizard_pages
   61 {
   62     /* IMPORTANT: IF YOU ADD/REMOVE/MOVE ANY PAGES THAT ARE RELATED TO SYSTEM ENCRYPTION,
   63     REVISE THE 'DECOY_OS_INSTRUCTIONS_PORTION_??' STRINGS! */
   64 
   65     INTRO_PAGE,
   66             SYSENC_TYPE_PAGE,
   67                     SYSENC_HIDDEN_OS_REQ_CHECK_PAGE,
   68             SYSENC_SPAN_PAGE,
   69             SYSENC_PRE_DRIVE_ANALYSIS_PAGE,
   70             SYSENC_DRIVE_ANALYSIS_PAGE,
   71             SYSENC_MULTI_BOOT_MODE_PAGE,
   72             SYSENC_MULTI_BOOT_SYS_EQ_BOOT_PAGE,
   73             SYSENC_MULTI_BOOT_NBR_SYS_DRIVES_PAGE,
   74             SYSENC_MULTI_BOOT_ADJACENT_SYS_PAGE,
   75             SYSENC_MULTI_BOOT_NONWIN_BOOT_LOADER_PAGE,
   76             SYSENC_MULTI_BOOT_OUTCOME_PAGE,
   77     VOLUME_TYPE_PAGE,
   78                 HIDDEN_VOL_WIZARD_MODE_PAGE,
   79     VOLUME_LOCATION_PAGE,
   80         DEVICE_TRANSFORM_MODE_PAGE,
   81                 HIDDEN_VOL_HOST_PRE_CIPHER_PAGE,
   82                 HIDDEN_VOL_PRE_CIPHER_PAGE,
   83     CIPHER_PAGE,
   84     SIZE_PAGE,
   85                 HIDDEN_VOL_HOST_PASSWORD_PAGE,
   86     PASSWORD_PAGE,
   87     PIM_PAGE,
   88         FILESYS_PAGE,
   89             SYSENC_COLLECTING_RANDOM_DATA_PAGE,
   90             SYSENC_KEYS_GEN_PAGE,
   91             SYSENC_RESCUE_DISK_CREATION_PAGE,
   92             SYSENC_RESCUE_DISK_BURN_PAGE,
   93             SYSENC_RESCUE_DISK_VERIFIED_PAGE,
   94             SYSENC_WIPE_MODE_PAGE,
   95             SYSENC_PRETEST_INFO_PAGE,
   96             SYSENC_PRETEST_RESULT_PAGE,
   97             SYSENC_ENCRYPTION_PAGE,
   98         NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE,
   99         NONSYS_INPLACE_ENC_RESUME_PARTITION_SEL_PAGE,
  100         NONSYS_INPLACE_ENC_RAND_DATA_PAGE,
  101         NONSYS_INPLACE_ENC_WIPE_MODE_PAGE,
  102         NONSYS_INPLACE_ENC_TRANSFORM_PAGE,
  103         NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE,
  104         NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE,
  105     FORMAT_PAGE,
  106     FORMAT_FINISHED_PAGE,
  107                     SYSENC_HIDDEN_OS_INITIAL_INFO_PAGE,
  108                     SYSENC_HIDDEN_OS_WIPE_INFO_PAGE,
  109                         DEVICE_WIPE_MODE_PAGE,
  110                         DEVICE_WIPE_PAGE
  111 };
  112 
  113 #define TIMER_INTERVAL_RANDVIEW                         30
  114 #define TIMER_INTERVAL_SYSENC_PROGRESS                  30
  115 #define TIMER_INTERVAL_NONSYS_INPLACE_ENC_PROGRESS      30
  116 #define TIMER_INTERVAL_SYSENC_DRIVE_ANALYSIS_PROGRESS   100
  117 #define TIMER_INTERVAL_WIPE_PROGRESS                    30
  118 #define TIMER_INTERVAL_KEYB_LAYOUT_GUARD                10
  119 
  120 enum sys_encryption_cmd_line_switches
  121 {
  122     SYSENC_COMMAND_NONE = 0,
  123     SYSENC_COMMAND_RESUME,
  124     SYSENC_COMMAND_STARTUP_SEQ_RESUME,
  125     SYSENC_COMMAND_ENCRYPT,
  126     SYSENC_COMMAND_DECRYPT,
  127     SYSENC_COMMAND_CREATE_HIDDEN_OS,
  128     SYSENC_COMMAND_CREATE_HIDDEN_OS_ELEV
  129 };
  130 
  131 typedef struct
  132 {
  133     int NumberOfSysDrives;          // Number of drives that contain an operating system. -1: unknown, 1: one, 2: two or more
  134     int MultipleSystemsOnDrive;     // Multiple systems are installed on the drive where the currently running system resides.  -1: unknown, 0: no, 1: yes
  135     int BootLoaderLocation;         // Boot loader (boot manager) installed in: 1: MBR/1st cylinder, 0: partition/bootsector: -1: unknown
  136     int BootLoaderBrand;            // -1: unknown, 0: Microsoft Windows, 1: any non-Windows boot manager/loader
  137     int SystemOnBootDrive;          // If the currently running operating system is installed on the boot drive. -1: unknown, 0: no, 1: yes
  138 } SYSENC_MULTIBOOT_CFG;
  139 
  140 #define SYSENC_PAUSE_RETRY_INTERVAL     100
  141 #define SYSENC_PAUSE_RETRIES            200
  142 
  143 // Expected duration of system drive analysis, in ms
  144 #define SYSENC_DRIVE_ANALYSIS_ETA       (4*60000)
  145 
  146 BootEncryption          *BootEncObj = NULL;
  147 BootEncryptionStatus    BootEncStatus;
  148 
  149 HWND hCurPage = NULL;       /* Handle to current wizard page */
  150 int nCurPageNo = -1;        /* The current wizard page */
  151 int nLastPageNo = -1;
  152 volatile int WizardMode = DEFAULT_VOL_CREATION_WIZARD_MODE; /* IMPORTANT: Never change this value directly -- always use ChangeWizardMode() instead. */
  153 volatile BOOL bHiddenOS = FALSE;        /* If TRUE, we are performing or (or supposed to perform) actions relating to an operating system installed in a hidden volume (i.e., encrypting a decoy OS partition or creating the outer/hidden volume for the hidden OS). To determine or set the phase of the process, call ChangeHiddenOSCreationPhase() and DetermineHiddenOSCreationPhase()) */
  154 BOOL bDirectSysEncMode = FALSE;
  155 BOOL bDirectSysEncModeCommand = SYSENC_COMMAND_NONE;
  156 BOOL DirectDeviceEncMode = FALSE;
  157 BOOL DirectNonSysInplaceDecStartMode = FALSE;
  158 BOOL DirectNonSysInplaceEncResumeMode = FALSE;
  159 BOOL DirectNonSysInplaceDecResumeMode = FALSE;
  160 BOOL DirectPromptNonSysInplaceEncResumeMode = FALSE;
  161 BOOL DirectCreationMode = FALSE;
  162 
  163 volatile BOOL bInPlaceEncNonSys = FALSE;        /* If TRUE, existing data on a non-system partition/volume are to be encrypted (or decrypted if bInPlaceDecNonSys is TRUE) in place (for system encryption, this flag is ignored) */
  164 volatile BOOL bInPlaceDecNonSys = FALSE;        /* If TRUE, existing data on a non-system partition/volume are to be decrypted in place (for system encryption, this flag is ignored) */
  165 volatile BOOL bInPlaceEncNonSysResumed = FALSE; /* If TRUE, the wizard is supposed to resume (or has resumed) process of non-system in-place encryption/decryption. */
  166 volatile BOOL bFirstNonSysInPlaceEncResumeDone = FALSE;
  167 __int64 NonSysInplaceEncBytesDone = 0;
  168 __int64 NonSysInplaceEncTotalSize = 0;
  169 BOOL bDeviceTransformModeChoiceMade = FALSE;        /* TRUE if the user has at least once manually selected the 'in-place' or 'format' option (on the 'device transform mode' page). */
  170 int nNeedToStoreFilesOver4GB = 0;       /* Whether the user wants to be able to store files larger than 4GB on the volume: -1 = Undecided or error, 0 = No, 1 = Yes */
  171 int nVolumeEA = 1;          /* Default encryption algorithm */
  172 BOOL bSystemEncryptionInProgress = FALSE;       /* TRUE when encrypting/decrypting the system partition/drive (FALSE when paused). */
  173 BOOL bWholeSysDrive = FALSE;    /* Whether to encrypt the entire system drive or just the system partition. */
  174 static BOOL bSystemEncryptionStatusChanged = FALSE;   /* TRUE if this instance changed the value of SystemEncryptionStatus (it's set to FALSE each time the system encryption settings are saved to the config file). This value is to be treated as protected -- only the wizard can change this value (others may only read it). */
  175 volatile BOOL bSysEncDriveAnalysisInProgress = FALSE;
  176 volatile BOOL bSysEncDriveAnalysisTimeOutOccurred = FALSE;
  177 int SysEncDetectHiddenSectors = -1;     /* Whether the user wants us to detect and encrypt the Host Protect Area (if any): -1 = Undecided or error, 0 = No, 1 = Yes */
  178 int SysEncDriveAnalysisStart;
  179 BOOL bDontVerifyRescueDisk = FALSE;
  180 BOOL bFirstSysEncResumeDone = FALSE;
  181 BOOL bDontCheckFileContainerSize = FALSE; /* If true, we don't check if the given size of file container is smaller than the available size on the hosting disk */
  182 int nMultiBoot = 0;         /* The number of operating systems installed on the computer, according to the user. 0: undetermined, 1: one, 2: two or more */
  183 volatile BOOL bHiddenVol = FALSE;   /* If true, we are (or will be) creating a hidden volume. */
  184 volatile BOOL bHiddenVolHost = FALSE;   /* If true, we are (or will be) creating the host volume (called "outer") for a hidden volume. */
  185 volatile BOOL bHiddenVolDirect = FALSE; /* If true, the wizard omits creating a host volume in the course of the process of hidden volume creation. */
  186 volatile BOOL bHiddenVolFinished = FALSE;
  187 int hiddenVolHostDriveNo = -1;  /* Drive letter for the volume intended to host a hidden volume. */
  188 BOOL bRemovableHostDevice = FALSE;  /* TRUE when creating a device/partition-hosted volume on a removable device. State undefined when creating file-hosted volumes. */
  189 int realClusterSize;        /* Parameter used when determining the maximum possible size of a hidden volume. */
  190 int hash_algo = DEFAULT_HASH_ALGORITHM; /* Which PRF to use in header key derivation (PKCS #5) and in the RNG. */
  191 unsigned __int64 nUIVolumeSize = 0;     /* The volume size. Important: This value is not in bytes. It has to be multiplied by nMultiplier. Do not use this value when actually creating the volume (it may chop off sector size, if it is not a multiple of 1024 bytes). */
  192 unsigned __int64 nVolumeSize = 0;       /* The volume size, in bytes. */
  193 unsigned __int64 nHiddenVolHostSize = 0;    /* Size of the hidden volume host, in bytes */
  194 __int64 nMaximumHiddenVolSize = 0;      /* Maximum possible size of the hidden volume, in bytes */
  195 __int64 nbrFreeClusters = 0;
  196 __int64 nMultiplier = BYTES_PER_MB;     /* Size selection multiplier. */
  197 wchar_t szFileName[TC_MAX_PATH+1];  /* The file selected by the user */
  198 wchar_t szDiskFile[TC_MAX_PATH+1];  /* Fully qualified name derived from szFileName */
  199 wchar_t szRescueDiskISO[TC_MAX_PATH+1]; /* The filename and path to the Rescue Disk ISO file to be burned (for boot encryption) */
  200 BOOL bDeviceWipeInProgress = FALSE;
  201 volatile BOOL bTryToCorrectReadErrors = FALSE;
  202 volatile BOOL DiscardUnreadableEncryptedSectors = FALSE;
  203 
  204 volatile BOOL bVolTransformThreadCancel = FALSE;    /* TRUE if the user cancels/pauses volume encryption/format */
  205 volatile BOOL bVolTransformThreadRunning = FALSE;   /* Is the volume encryption/format thread running */
  206 volatile BOOL bVolTransformThreadToRun = FALSE;     /* TRUE if the Format/Encrypt button has been clicked and we are proceeding towards launching the thread. */
  207 
  208 volatile BOOL bConfirmQuit = FALSE;     /* If TRUE, the user is asked to confirm exit when he clicks the X icon, Exit, etc. */
  209 volatile BOOL bConfirmQuitSysEncPretest = FALSE;
  210 
  211 BOOL bDevice = FALSE;       /* Is this a partition volume ? */
  212 
  213 BOOL showKeys = FALSE;
  214 volatile HWND hMasterKey = NULL;        /* Text box showing hex dump of the master key */
  215 volatile HWND hHeaderKey = NULL;        /* Text box showing hex dump of the header key */
  216 volatile HWND hRandPool = NULL;     /* Text box showing hex dump of the random pool */
  217 volatile HWND hRandPoolSys = NULL;  /* Text box showing hex dump of the random pool for system encryption */
  218 volatile HWND hPasswordInputField = NULL;   /* Password input field */
  219 volatile HWND hVerifyPasswordInputField = NULL;     /* Verify-password input field */
  220 
  221 HBITMAP hbmWizardBitmapRescaled = NULL;
  222 
  223 wchar_t OrigKeyboardLayout [8+1] = L"00000409";
  224 BOOL bKeyboardLayoutChanged = FALSE;        /* TRUE if the keyboard layout was changed to the standard US keyboard layout (from any other layout). */
  225 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. */
  226 
  227 #ifndef _DEBUG
  228     BOOL bWarnDeviceFormatAdvanced = TRUE;
  229 #else
  230     BOOL bWarnDeviceFormatAdvanced = FALSE;
  231 #endif
  232 
  233 BOOL bWarnOuterVolSuitableFileSys = TRUE;
  234 
  235 Password volumePassword;            /* User password */
  236 char szVerify[MAX_PASSWORD + 1];    /* Tmp password buffer */
  237 char szRawPassword[MAX_PASSWORD + 1];   /* Password before keyfile was applied to it */
  238 
  239 int volumePim = 0;
  240 
  241 BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */
  242 BOOL ComServerMode = FALSE;
  243 
  244 
  245 Password CmdVolumePassword = {0}; /* Password passed from command line */
  246 int CmdVolumeEA = 0;
  247 int CmdVolumePkcs5 = 0;
  248 int CmdVolumePim = 0;
  249 int CmdVolumeFilesystem = FILESYS_NONE;
  250 unsigned __int64 CmdVolumeFileSize = 0;
  251 BOOL CmdSparseFileSwitch = FALSE;
  252 BOOL CmdQuickFormat = FALSE;
  253 
  254 BOOL bForceOperation = FALSE;
  255 
  256 BOOL bOperationSuccess = FALSE;
  257 
  258 BOOL bGuiMode = TRUE;
  259 
  260 BOOL bSystemIsGPT = FALSE;
  261 
  262 int nPbar = 0;          /* Control ID of progress bar:- for format code */
  263 
  264 wchar_t HeaderKeyGUIView [KEY_GUI_VIEW_SIZE];
  265 wchar_t MasterKeyGUIView [KEY_GUI_VIEW_SIZE];
  266 
  267 #define RANDPOOL_DISPLAY_COLUMNS    15
  268 #define RANDPOOL_DISPLAY_ROWS       8
  269 #define RANDPOOL_DISPLAY_BYTE_PORTION   (RANDPOOL_DISPLAY_COLUMNS * RANDPOOL_DISPLAY_ROWS)
  270 #define RANDPOOL_DISPLAY_SIZE   (RANDPOOL_DISPLAY_BYTE_PORTION * 3 + RANDPOOL_DISPLAY_ROWS + 2)
  271 unsigned char randPool [RANDPOOL_DISPLAY_BYTE_PORTION];
  272 unsigned char lastRandPool [RANDPOOL_DISPLAY_BYTE_PORTION];
  273 static unsigned char maskRandPool [RANDPOOL_DISPLAY_BYTE_PORTION];
  274 static BOOL bUseMask = FALSE;
  275 static DWORD mouseEntropyGathered = 0xFFFFFFFF;
  276 static DWORD mouseEventsInitialCount = 0;
  277 /* max value of entropy needed to fill all random pool = 8 * RNG_POOL_SIZE = 2560 bits */
  278 static const DWORD maxEntropyLevel = RNG_POOL_SIZE * 8;
  279 static HWND hEntropyBar = NULL;
  280 wchar_t outRandPoolDispBuffer [RANDPOOL_DISPLAY_SIZE];
  281 BOOL bDisplayPoolContents = TRUE;
  282 
  283 volatile BOOL bSparseFileSwitch = FALSE;
  284 volatile BOOL quickFormat = FALSE;  /* WARNING: Meaning of this variable depends on bSparseFileSwitch. If bSparseFileSwitch is TRUE, this variable represents the sparse file flag. */
  285 volatile int fileSystem = FILESYS_NONE;
  286 volatile int clusterSize = 0;
  287 
  288 SYSENC_MULTIBOOT_CFG    SysEncMultiBootCfg;
  289 wchar_t SysEncMultiBootCfgOutcome [4096] = {L'N',L'/',L'A',0};
  290 volatile int NonSysInplaceEncStatus = NONSYS_INPLACE_ENC_STATUS_NONE;
  291 
  292 LONGLONG nAvailableFreeSpace = -1;
  293 BOOL bIsSparseFilesSupportedByHost = FALSE;
  294 
  295 vector <HostDevice> DeferredNonSysInPlaceEncDevices;
  296 
  297 // specific definitions and implementation for support of resume operation
  298 // in wait dialog mechanism
  299 
  300 void CALLBACK ResumeInPlaceEncWaitThreadProc(void* pArg, HWND hwndDlg)
  301 {
  302     wchar_t szDevicePath[MAX_PATH] = {0};
  303     RawDevicesDlgParam param;
  304     param.devices = GetAvailableHostDevices (false, true, false);
  305     param.pszFileName = szDevicePath;
  306 
  307     DeferredNonSysInPlaceEncDevices.clear();
  308 
  309     if ((IDOK == DialogBoxParamW (hInst,
  310         MAKEINTRESOURCEW (IDD_RAWDEVICES_DLG), hwndDlg,
  311         (DLGPROC) RawDevicesDlgProc, (LPARAM) &param)) && wcslen(szDevicePath))
  312     {
  313         foreach (const HostDevice &device, param.devices)
  314         {
  315             if (device.Path == szDevicePath)
  316             {
  317                 OpenVolumeContext volume;
  318                 int status = OpenVolume (&volume, device.Path.c_str(), &volumePassword, hash_algo, volumePim, FALSE, FALSE, FALSE, TRUE);
  319 
  320                 if ( status == ERR_SUCCESS)
  321                 {
  322                     if ((volume.CryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
  323                         && volume.CryptoInfo->EncryptedAreaLength.Value != volume.CryptoInfo->VolumeSize.Value)
  324                     {
  325                         DeferredNonSysInPlaceEncDevices.push_back (device);
  326                     }
  327                     else if (volume.CryptoInfo->EncryptedAreaLength.Value == volume.CryptoInfo->VolumeSize.Value)
  328                     {
  329                         WCHAR szMsg[1024];
  330                         StringCbPrintfW(szMsg, sizeof(szMsg), GetString ("SELECTED_PARTITION_ALREADY_INPLACE_ENC"),
  331                             volume.CryptoInfo->HeaderFlags);
  332                         ErrorDirect(szMsg, hwndDlg);
  333                     }
  334                     else
  335                     {
  336                         WCHAR szMsg[1024];
  337                         StringCbPrintfW(szMsg, sizeof(szMsg), GetString ("SELECTED_PARTITION_NOT_INPLACE_ENC"),
  338                             volume.CryptoInfo->HeaderFlags);
  339                         ErrorDirect(szMsg, hwndDlg);
  340                     }
  341 
  342                     CloseVolume (&volume);
  343                 }
  344                 else
  345                 {
  346                     handleError(hwndDlg, status, SRC_POS);
  347                 }
  348 
  349                 break;
  350             }
  351         }
  352     }
  353     else
  354     {
  355         foreach (const HostDevice &device, param.devices)
  356         {
  357             if (    !device.ContainsSystem
  358                 &&  (device.IsPartition || device.DynamicVolume || device.IsVirtualPartition || device.Partitions.empty())
  359                 )
  360             {
  361 
  362                 OpenVolumeContext volume;
  363 
  364                 if (OpenVolume (&volume, device.Path.c_str(), &volumePassword, hash_algo, volumePim, FALSE, FALSE, FALSE, TRUE) == ERR_SUCCESS)
  365                 {
  366                     if ((volume.CryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
  367                         && volume.CryptoInfo->EncryptedAreaLength.Value != volume.CryptoInfo->VolumeSize.Value)
  368                     {
  369                         DeferredNonSysInPlaceEncDevices.push_back (device);
  370                     }
  371 
  372                     CloseVolume (&volume);
  373                 }
  374             }
  375         }
  376     }
  377 }
  378 
  379 
  380 static BOOL ElevateWholeWizardProcess (wstring arguments)
  381 {
  382     wchar_t modPath[MAX_PATH];
  383 
  384     if (IsAdmin())
  385         return TRUE;
  386 
  387     if (!IsUacSupported())
  388         return IsAdmin();
  389 
  390     GetModuleFileName (NULL, modPath, ARRAYSIZE (modPath));
  391 
  392     while (true)
  393     {
  394         if ((int)ShellExecute (MainDlg, L"runas", modPath, (wstring(L"/q UAC ") + arguments).c_str(), NULL, SW_SHOWNORMAL) > 32)
  395         {
  396             exit (0);
  397         }
  398         else
  399         {
  400             if (IDRETRY == ErrorRetryCancel ("UAC_INIT_ERROR", MainDlg))
  401                 continue;
  402             return FALSE;
  403         }
  404     }
  405 }
  406 
  407 static void WipePasswordsAndKeyfiles (void)
  408 {
  409     wchar_t tmp[MAX_PASSWORD+1];
  410 
  411     // Attempt to wipe passwords stored in the input field buffers
  412     wmemset (tmp, L'X', MAX_PASSWORD);
  413     tmp [MAX_PASSWORD] = 0;
  414     SetWindowText (hPasswordInputField, tmp);
  415     SetWindowText (hVerifyPasswordInputField, tmp);
  416 
  417     burn (&szVerify[0], sizeof (szVerify));
  418     burn (&volumePassword, sizeof (volumePassword));
  419     burn (&szRawPassword[0], sizeof (szRawPassword));
  420     burn (&volumePim, sizeof (volumePim));
  421     burn (&CmdVolumePassword, sizeof (CmdVolumePassword));
  422     burn (&CmdVolumePim, sizeof (CmdVolumePim));
  423 
  424     SetWindowText (hPasswordInputField, L"");
  425     SetWindowText (hVerifyPasswordInputField, L"");
  426 
  427     KeyFileRemoveAll (&FirstKeyFile);
  428     KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile);
  429 }
  430 
  431 static void localcleanup (void)
  432 {
  433     wchar_t tmp[RANDPOOL_DISPLAY_SIZE+1];
  434 
  435     // System encryption
  436 
  437     if (WizardMode == WIZARD_MODE_SYS_DEVICE
  438         && InstanceHasSysEncMutex ())
  439     {
  440         try
  441         {
  442             BootEncStatus = BootEncObj->GetStatus();
  443 
  444             if (BootEncStatus.SetupInProgress)
  445             {
  446                 BootEncObj->AbortSetup ();
  447             }
  448         }
  449         catch (...)
  450         {
  451             // NOP
  452         }
  453     }
  454 
  455     // Mon-system in-place encryption
  456 
  457     if (bInPlaceEncNonSys && (bVolTransformThreadRunning || bVolTransformThreadToRun))
  458     {
  459         NonSysInplaceEncPause ();
  460     }
  461 
  462     CloseNonSysInplaceEncMutex ();
  463 
  464 
  465     // Device wipe
  466 
  467     if (bDeviceWipeInProgress)
  468         WipeAbort();
  469 
  470 
  471     WipePasswordsAndKeyfiles ();
  472 
  473     RandStop (TRUE);
  474 
  475     burn (HeaderKeyGUIView, sizeof(HeaderKeyGUIView));
  476     burn (MasterKeyGUIView, sizeof(MasterKeyGUIView));
  477     burn (randPool, sizeof(randPool));
  478     burn (lastRandPool, sizeof(lastRandPool));
  479     burn (outRandPoolDispBuffer, sizeof(outRandPoolDispBuffer));
  480     burn (&mouseEntropyGathered, sizeof(mouseEntropyGathered));
  481     burn (&mouseEventsInitialCount, sizeof(mouseEventsInitialCount));
  482     burn (maskRandPool, sizeof(maskRandPool));
  483     burn (szFileName, sizeof(szFileName));
  484     burn (szDiskFile, sizeof(szDiskFile));
  485 
  486     // Attempt to wipe the GUI fields showing portions of randpool, of the master and header keys
  487     wmemset (tmp, L'X', ARRAYSIZE(tmp));
  488     tmp [ARRAYSIZE(tmp)-1] = 0;
  489     SetWindowText (hRandPool, tmp);
  490     SetWindowText (hRandPoolSys, tmp);
  491     SetWindowText (hMasterKey, tmp);
  492     SetWindowText (hHeaderKey, tmp);
  493 
  494     UnregisterRedTick (hInst);
  495 
  496     // Delete buffered bitmaps (if any)
  497     if (hbmWizardBitmapRescaled != NULL)
  498     {
  499         DeleteObject ((HGDIOBJ) hbmWizardBitmapRescaled);
  500         hbmWizardBitmapRescaled = NULL;
  501     }
  502 
  503     // Cleanup common code resources
  504     cleanup ();
  505 
  506     if (BootEncObj != NULL)
  507     {
  508         delete BootEncObj;
  509         BootEncObj = NULL;
  510     }
  511 }
  512 
  513 static BOOL CALLBACK BroadcastSysEncCfgUpdateCallb (HWND hwnd, LPARAM lParam)
  514 {
  515     LONG_PTR userDataVal = GetWindowLongPtrW (hwnd, GWLP_USERDATA);
  516     if ((userDataVal == (LONG_PTR) 'VERA') || (userDataVal == (LONG_PTR) 'TRUE')) // Prior to 1.0e, 'TRUE' was used for VeraCrypt dialogs
  517     {
  518         wchar_t name[1024] = { 0 };
  519         GetWindowText (hwnd, name, ARRAYSIZE (name) - 1);
  520         if (hwnd != MainDlg && wcsstr (name, L"VeraCrypt"))
  521         {
  522             PostMessage (hwnd, TC_APPMSG_SYSENC_CONFIG_UPDATE, 0, 0);
  523         }
  524     }
  525     return TRUE;
  526 }
  527 
  528 static BOOL BroadcastSysEncCfgUpdate (void)
  529 {
  530     BOOL bSuccess = FALSE;
  531     EnumWindows (BroadcastSysEncCfgUpdateCallb, (LPARAM) &bSuccess);
  532     return bSuccess;
  533 }
  534 
  535 // IMPORTANT: This function may be called only by Format (other modules can only _read_ the system encryption config).
  536 // Returns TRUE if successful (otherwise FALSE)
  537 static BOOL SaveSysEncSettings (HWND hwndDlg)
  538 {
  539     FILE *f;
  540 
  541     if (!bSystemEncryptionStatusChanged)
  542         return TRUE;
  543 
  544     if (hwndDlg == NULL && MainDlg != NULL)
  545         hwndDlg = MainDlg;
  546 
  547     if (!CreateSysEncMutex ())
  548         return FALSE;       // Only one instance that has the mutex can modify the system encryption settings
  549 
  550     if (SystemEncryptionStatus == SYSENC_STATUS_NONE)
  551     {
  552         if (_wremove (GetConfigPath (TC_APPD_FILENAME_SYSTEM_ENCRYPTION)) != 0)
  553         {
  554             Error ("CANNOT_SAVE_SYS_ENCRYPTION_SETTINGS", hwndDlg);
  555             return FALSE;
  556         }
  557 
  558         bSystemEncryptionStatusChanged = FALSE;
  559         BroadcastSysEncCfgUpdate ();
  560         return TRUE;
  561     }
  562 
  563     f = _wfopen (GetConfigPath (TC_APPD_FILENAME_SYSTEM_ENCRYPTION), L"w,ccs=UTF-8");
  564     if (f == NULL)
  565     {
  566         Error ("CANNOT_SAVE_SYS_ENCRYPTION_SETTINGS", hwndDlg);
  567         handleWin32Error (hwndDlg, SRC_POS);
  568         return FALSE;
  569     }
  570 
  571     if (XmlWriteHeader (f) < 0
  572 
  573     || fputws (L"\n\t<sysencryption>", f) < 0
  574 
  575     || fwprintf (f, L"\n\t\t<config key=\"SystemEncryptionStatus\">%d</config>", SystemEncryptionStatus) < 0
  576 
  577     || fwprintf (f, L"\n\t\t<config key=\"WipeMode\">%d</config>", (int) nWipeMode) < 0
  578 
  579     || fputws (L"\n\t</sysencryption>", f) < 0
  580 
  581     || XmlWriteFooter (f) < 0)
  582     {
  583         handleWin32Error (hwndDlg, SRC_POS);
  584         fclose (f);
  585         Error ("CANNOT_SAVE_SYS_ENCRYPTION_SETTINGS", hwndDlg);
  586         return FALSE;
  587     }
  588 
  589     TCFlushFile (f);
  590 
  591     fclose (f);
  592 
  593     bSystemEncryptionStatusChanged = FALSE;
  594     BroadcastSysEncCfgUpdate ();
  595 
  596     return TRUE;
  597 }
  598 
  599 // WARNING: This function may take a long time to finish
  600 static unsigned int DetermineHiddenOSCreationPhase (void)
  601 {
  602     unsigned int phase = TC_HIDDEN_OS_CREATION_PHASE_NONE;
  603 
  604     try
  605     {
  606         phase = BootEncObj->GetHiddenOSCreationPhase();
  607     }
  608     catch (Exception &e)
  609     {
  610         e.Show (MainDlg);
  611         AbortProcess("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS");
  612     }
  613 
  614     return phase;
  615 }
  616 
  617 // IMPORTANT: This function may be called only by Format (other modules can only _read_ the status).
  618 // Returns TRUE if successful (otherwise FALSE)
  619 static BOOL ChangeHiddenOSCreationPhase (int newPhase)
  620 {
  621     if (!CreateSysEncMutex ())
  622     {
  623         Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
  624         return FALSE;
  625     }
  626 
  627     try
  628     {
  629         BootEncObj->SetHiddenOSCreationPhase (newPhase);
  630     }
  631     catch (Exception &e)
  632     {
  633         e.Show (MainDlg);
  634         return FALSE;
  635     }
  636 
  637     //// The contents of the following items might be inappropriate after a change of the phase
  638     //szFileName[0] = 0;
  639     //szDiskFile[0] = 0;
  640     //nUIVolumeSize = 0;
  641     //nVolumeSize = 0;
  642 
  643     return TRUE;
  644 }
  645 
  646 // IMPORTANT: This function may be called only by Format (other modules can only _read_ the system encryption status).
  647 // Returns TRUE if successful (otherwise FALSE)
  648 static BOOL ChangeSystemEncryptionStatus (int newStatus)
  649 {
  650     if (!CreateSysEncMutex ())
  651     {
  652         Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
  653         return FALSE;       // Only one instance that has the mutex can modify the system encryption settings
  654     }
  655 
  656     SystemEncryptionStatus = newStatus;
  657     bSystemEncryptionStatusChanged = TRUE;
  658 
  659     if (newStatus == SYSENC_STATUS_ENCRYPTING)
  660     {
  661         // If the user has created a hidden OS and now is creating a decoy OS, we must wipe the hidden OS
  662         // config area in the MBR.
  663         WipeHiddenOSCreationConfig();
  664     }
  665 
  666     if (newStatus == SYSENC_STATUS_NONE && !IsHiddenOSRunning())
  667     {
  668         if (DetermineHiddenOSCreationPhase() != TC_HIDDEN_OS_CREATION_PHASE_NONE
  669             && !ChangeHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE))
  670             return FALSE;
  671 
  672         WipeHiddenOSCreationConfig();
  673     }
  674 
  675     if (!SaveSysEncSettings (MainDlg))
  676     {
  677         return FALSE;
  678     }
  679 
  680     return TRUE;
  681 }
  682 
  683 // If the return code of this function is ignored and newWizardMode == WIZARD_MODE_SYS_DEVICE, then this function
  684 // may be called only after CreateSysEncMutex() returns TRUE. It returns TRUE if successful (otherwise FALSE).
  685 static BOOL ChangeWizardMode (int newWizardMode)
  686 {
  687     if (WizardMode != newWizardMode)
  688     {
  689         if (WizardMode == WIZARD_MODE_SYS_DEVICE || newWizardMode == WIZARD_MODE_SYS_DEVICE)
  690         {
  691             if (newWizardMode == WIZARD_MODE_SYS_DEVICE)
  692             {
  693                 if (!CreateSysEncMutex ())
  694                 {
  695                     Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
  696                     return FALSE;
  697                 }
  698             }
  699 
  700             // If the previous mode was different, the password may have been typed using a different
  701             // keyboard layout (which might confuse the user and cause other problems if system encryption
  702             // was or will be involved).
  703             WipePasswordsAndKeyfiles();
  704         }
  705 
  706         if (newWizardMode != WIZARD_MODE_NONSYS_DEVICE)
  707         {
  708             bInPlaceEncNonSys = FALSE;
  709             bInPlaceDecNonSys = FALSE;
  710         }
  711 
  712         if (newWizardMode == WIZARD_MODE_NONSYS_DEVICE && !IsAdmin() && IsUacSupported())
  713         {
  714             if (!ElevateWholeWizardProcess (L"/e"))
  715                 return FALSE;
  716         }
  717 
  718         // The contents of the following items may be inappropriate after a change of mode
  719         if (! (bInPlaceDecNonSys && !bInPlaceEncNonSysResumed)) // If we are starting (but not resuming) decryption of non-system volume, we actually need szFileName as it contains the command line param.
  720             szFileName[0] = 0;
  721         szDiskFile[0] = 0;
  722         nUIVolumeSize = 0;
  723         nVolumeSize = 0;
  724 
  725         WizardMode = newWizardMode;
  726     }
  727 
  728     bDevice = (WizardMode != WIZARD_MODE_FILE_CONTAINER);
  729 
  730     if (newWizardMode != WIZARD_MODE_SYS_DEVICE
  731         && !bHiddenOS)
  732     {
  733         CloseSysEncMutex ();
  734     }
  735 
  736     return TRUE;
  737 }
  738 
  739 // Determines whether the wizard directly affects system encryption in any way.
  740 // Note, for example, that when the user enters a password for a hidden volume that is to host a hidden OS,
  741 // WizardMode is NOT set to WIZARD_MODE_SYS_DEVICE. The keyboard layout, however, has to be US. That's why
  742 // this function has to be called instead of checking the value of WizardMode.
  743 static BOOL SysEncInEffect (void)
  744 {
  745     return (WizardMode == WIZARD_MODE_SYS_DEVICE
  746         || CreatingHiddenSysVol());
  747 }
  748 
  749 static BOOL CreatingHiddenSysVol (void)
  750 {
  751     return (bHiddenOS
  752         && bHiddenVol && !bHiddenVolHost);
  753 }
  754 
  755 static void LoadSettingsAndCheckModified (HWND hwndDlg, BOOL bOnlyCheckModified, BOOL* pbSettingsModified, BOOL* pbHistoryModified)
  756 {
  757     if (!bOnlyCheckModified)
  758         EnableHwEncryption ((ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? FALSE : TRUE);
  759 
  760     WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE;
  761 
  762     if (!bOnlyCheckModified)
  763         LoadSysEncSettings ();
  764 
  765     if (!bOnlyCheckModified && LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0)
  766         bInPlaceEncNonSysPending = TRUE;
  767 
  768     if (!bOnlyCheckModified)
  769         defaultKeyFilesParam.EnableKeyFiles = FALSE;
  770 
  771     ConfigReadCompareInt ("StartOnLogon", FALSE, &bStartOnLogon, bOnlyCheckModified, pbSettingsModified);
  772 
  773     ConfigReadCompareInt ("HiddenSectorDetectionStatus", 0, &HiddenSectorDetectionStatus, bOnlyCheckModified, pbSettingsModified);
  774 
  775     ConfigReadCompareInt ("ShowDisconnectedNetworkDrives", FALSE, &bShowDisconnectedNetworkDrives, bOnlyCheckModified, pbSettingsModified);
  776 
  777     ConfigReadCompareInt ("HideWaitingDialog", FALSE, &bHideWaitingDialog, bOnlyCheckModified, pbSettingsModified);
  778 
  779     ConfigReadCompareInt ("SaveVolumeHistory", FALSE, &bHistory, bOnlyCheckModified, pbSettingsModified);
  780 
  781     {
  782         char szTmp[MAX_PATH] = {0};
  783         WideCharToMultiByte (CP_UTF8, 0, SecurityTokenLibraryPath, -1, szTmp, MAX_PATH, NULL, NULL);
  784         ConfigReadCompareString ("SecurityTokenLibrary", "", szTmp, sizeof (szTmp) - 1, bOnlyCheckModified, pbSettingsModified);
  785         MultiByteToWideChar (CP_UTF8, 0, szTmp, -1, SecurityTokenLibraryPath, ARRAYSIZE (SecurityTokenLibraryPath));
  786 
  787         if (!bOnlyCheckModified && SecurityTokenLibraryPath[0])
  788             InitSecurityTokenLibrary(hwndDlg);
  789     }
  790 
  791     if (bOnlyCheckModified)
  792     {
  793         char langid[6] = {0};
  794         if (!IsNonInstallMode ())
  795         {
  796             ConfigReadString ("Language", "", langid, sizeof (langid));
  797             // when installed, if no preferred language set by user, English is selected default
  798             if (langid [0] == 0)
  799                 StringCbCopyA (langid, sizeof(langid), "en");
  800 
  801             if (pbSettingsModified && strcmp (langid, GetPreferredLangId ()))
  802                 *pbSettingsModified = TRUE;
  803         }
  804         else
  805         {
  806             StringCbCopyA (langid, sizeof(langid), GetPreferredLangId ());
  807             ConfigReadCompareString ("Language", "", langid, sizeof (langid), TRUE, pbSettingsModified);
  808         }
  809     }
  810 
  811     if (hwndDlg != NULL)
  812     {
  813         LoadCombo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), bHistory, bOnlyCheckModified, pbHistoryModified);
  814         return;
  815     }
  816 
  817     if (bHistoryCmdLine)
  818         return;
  819 }
  820 
  821 static void LoadSettings (HWND hwndDlg)
  822 {
  823     LoadSettingsAndCheckModified (hwndDlg, FALSE, NULL, NULL);
  824 }
  825 
  826 void SaveSettings (HWND hwndDlg)
  827 {
  828     WaitCursor ();
  829 
  830     // Check first if modifications ocurred before writing to the settings and history files
  831     // This avoids leaking information about VeraCrypt usage when user only mount volumes without changing setttings or history
  832     BOOL bSettingsChanged = FALSE;
  833     BOOL bHistoryChanged = FALSE;
  834 
  835     LoadSettingsAndCheckModified (hwndDlg, TRUE, &bSettingsChanged, &bHistoryChanged);
  836 
  837     if (bHistoryChanged && hwndDlg != NULL)
  838         DumpCombo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), !bHistory);
  839 
  840     if (bSettingsChanged)
  841     {
  842         ConfigWriteBegin ();
  843 
  844         ConfigWriteInt ("StartOnLogon", bStartOnLogon);
  845         ConfigWriteInt ("HiddenSectorDetectionStatus", HiddenSectorDetectionStatus);
  846         ConfigWriteInt ("SaveVolumeHistory", bHistory);
  847         ConfigWriteStringW ("SecurityTokenLibrary", SecurityTokenLibraryPath[0] ? SecurityTokenLibraryPath : L"");
  848 
  849         ConfigWriteString ("Language", GetPreferredLangId ());
  850 
  851         ConfigWriteEnd (hwndDlg);
  852     }
  853 
  854     NormalCursor ();
  855 }
  856 
  857 // WARNING: This function does NOT cause immediate application exit (use e.g. return 1 after calling it
  858 // from a DialogProc function).
  859 static void EndMainDlg (HWND hwndDlg)
  860 {
  861     if (nCurPageNo == VOLUME_LOCATION_PAGE)
  862     {
  863         if (IsWindow(GetDlgItem(hCurPage, IDC_NO_HISTORY)))
  864             bHistory = !IsButtonChecked (GetDlgItem (hCurPage, IDC_NO_HISTORY));
  865 
  866         MoveEditToCombo (GetDlgItem (hCurPage, IDC_COMBO_BOX), bHistory);
  867         SaveSettings (hCurPage);
  868     }
  869     else
  870     {
  871         SaveSettings (NULL);
  872     }
  873 
  874     SaveSysEncSettings (hwndDlg);
  875 
  876     if (!bHistory)
  877         CleanLastVisitedMRU ();
  878 
  879     EndDialog (hwndDlg, 0);
  880 }
  881 
  882 // Returns TRUE if system encryption or decryption had been or is in progress and has not been completed
  883 static BOOL SysEncryptionOrDecryptionRequired (void)
  884 {
  885     /* If you update this function, revise SysEncryptionOrDecryptionRequired() in Mount.c as well. */
  886 
  887     static BootEncryptionStatus locBootEncStatus;
  888 
  889     try
  890     {
  891         locBootEncStatus = BootEncObj->GetStatus();
  892     }
  893     catch (Exception &e)
  894     {
  895         e.Show (MainDlg);
  896     }
  897 
  898     return (SystemEncryptionStatus == SYSENC_STATUS_ENCRYPTING
  899         || SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING
  900         ||
  901         (
  902             locBootEncStatus.DriveMounted
  903             &&
  904             (
  905                 locBootEncStatus.ConfiguredEncryptedAreaStart != locBootEncStatus.EncryptedAreaStart
  906                 || locBootEncStatus.ConfiguredEncryptedAreaEnd != locBootEncStatus.EncryptedAreaEnd
  907             )
  908         )
  909     );
  910 }
  911 
  912 // Returns TRUE if the system partition/drive is completely encrypted
  913 static BOOL SysDriveOrPartitionFullyEncrypted (BOOL bSilent)
  914 {
  915     /* If you update this function, revise SysDriveOrPartitionFullyEncrypted() in Mount.c as well. */
  916 
  917     static BootEncryptionStatus locBootEncStatus;
  918 
  919     try
  920     {
  921         locBootEncStatus = BootEncObj->GetStatus();
  922     }
  923     catch (Exception &e)
  924     {
  925         if (!bSilent)
  926             e.Show (MainDlg);
  927     }
  928 
  929     return (!locBootEncStatus.SetupInProgress
  930         && locBootEncStatus.ConfiguredEncryptedAreaEnd != 0
  931         && locBootEncStatus.ConfiguredEncryptedAreaEnd != -1
  932         && locBootEncStatus.ConfiguredEncryptedAreaStart == locBootEncStatus.EncryptedAreaStart
  933         && locBootEncStatus.ConfiguredEncryptedAreaEnd == locBootEncStatus.EncryptedAreaEnd);
  934 }
  935 
  936 // This functions is to be used when the wizard mode needs to be changed to WIZARD_MODE_SYS_DEVICE.
  937 // If the function fails to switch the mode, it returns FALSE (otherwise TRUE).
  938 BOOL SwitchWizardToSysEncMode (void)
  939 {
  940     WaitCursor ();
  941     SystemDriveConfiguration config;
  942 
  943     try
  944     {
  945         BootEncStatus = BootEncObj->GetStatus();
  946         bWholeSysDrive = BootEncObj->SystemPartitionCoversWholeDrive();
  947         config = BootEncObj->GetSystemDriveConfiguration ();
  948     }
  949     catch (Exception &e)
  950     {
  951         e.Show (MainDlg);
  952         Error ("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS", MainDlg);
  953         NormalCursor ();
  954         return FALSE;
  955     }
  956 
  957     // From now on, we should be the only instance of the TC wizard allowed to deal with system encryption
  958     if (!CreateSysEncMutex ())
  959     {
  960         Warning ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
  961         NormalCursor ();
  962         return FALSE;
  963     }
  964 
  965     // User-mode app may have crashed and its mutex may have gotten lost, so we need to check the driver status too
  966     if (BootEncStatus.SetupInProgress)
  967     {
  968         if (AskWarnYesNo ("SYSTEM_ENCRYPTION_RESUME_PROMPT", MainDlg) == IDYES)
  969         {
  970             if (SystemEncryptionStatus != SYSENC_STATUS_ENCRYPTING
  971                 && SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING)
  972             {
  973                 // The config file with status was lost or not written correctly
  974                 if (!ResolveUnknownSysEncDirection ())
  975                 {
  976                     CloseSysEncMutex ();
  977                     NormalCursor ();
  978                     return FALSE;
  979                 }
  980             }
  981 
  982             bDirectSysEncMode = TRUE;
  983             ChangeWizardMode (WIZARD_MODE_SYS_DEVICE);
  984             LoadPage (MainDlg, SYSENC_ENCRYPTION_PAGE);
  985             NormalCursor ();
  986             return TRUE;
  987         }
  988         else
  989         {
  990             CloseSysEncMutex ();
  991             Error ("SYS_ENCRYPTION_OR_DECRYPTION_IN_PROGRESS", MainDlg);
  992             NormalCursor ();
  993             return FALSE;
  994         }
  995     }
  996 
  997     if (BootEncStatus.DriveMounted
  998         || BootEncStatus.DriveEncrypted
  999         || SysEncryptionOrDecryptionRequired ())
 1000     {
 1001 
 1002         if (!SysDriveOrPartitionFullyEncrypted (FALSE)
 1003             && AskWarnYesNo ("SYSTEM_ENCRYPTION_RESUME_PROMPT", MainDlg) == IDYES)
 1004         {
 1005             if (SystemEncryptionStatus == SYSENC_STATUS_NONE)
 1006             {
 1007                 // If the config file with status was lost or not written correctly, we
 1008                 // don't know whether to encrypt or decrypt (but we know that encryption or
 1009                 // decryption is required). Ask the user to select encryption, decryption,
 1010                 // or cancel
 1011                 if (!ResolveUnknownSysEncDirection ())
 1012                 {
 1013                     CloseSysEncMutex ();
 1014                     NormalCursor ();
 1015                     return FALSE;
 1016                 }
 1017             }
 1018 
 1019             bDirectSysEncMode = TRUE;
 1020             ChangeWizardMode (WIZARD_MODE_SYS_DEVICE);
 1021             LoadPage (MainDlg, SYSENC_ENCRYPTION_PAGE);
 1022             NormalCursor ();
 1023             return TRUE;
 1024         }
 1025         else
 1026         {
 1027             CloseSysEncMutex ();
 1028             Error ("SETUP_FAILED_BOOT_DRIVE_ENCRYPTED", MainDlg);
 1029             NormalCursor ();
 1030             return FALSE;
 1031         }
 1032     }
 1033     else
 1034     {
 1035         // Check compliance with requirements for boot encryption
 1036 
 1037         if (!IsAdmin())
 1038         {
 1039             if (!IsUacSupported())
 1040             {
 1041                 Warning ("ADMIN_PRIVILEGES_WARN_DEVICES", MainDlg);
 1042             }
 1043         }
 1044 
 1045         try
 1046         {
 1047             BootEncObj->CheckRequirements ();
 1048         }
 1049         catch (Exception &e)
 1050         {
 1051             CloseSysEncMutex ();
 1052             e.Show (MainDlg);
 1053             NormalCursor ();
 1054             return FALSE;
 1055         }
 1056 
 1057         if (!ChangeWizardMode (WIZARD_MODE_SYS_DEVICE))
 1058         {
 1059             NormalCursor ();
 1060             return FALSE;
 1061         }
 1062 
 1063         if (bSysDriveSelected || bSysPartitionSelected)
 1064         {
 1065             // The user selected the non-sys-device wizard mode but then selected a system device
 1066 
 1067             bWholeSysDrive = (bSysDriveSelected && !bSysPartitionSelected);
 1068 
 1069             bSysDriveSelected = FALSE;
 1070             bSysPartitionSelected = FALSE;
 1071 
 1072             try
 1073             {
 1074                 if (!bHiddenVol)
 1075                 {
 1076                     if (bWholeSysDrive && !BootEncObj->SystemPartitionCoversWholeDrive())
 1077                     {
 1078                         if (BootEncObj->SystemDriveContainsNonStandardPartitions())
 1079                         {
 1080                             if (AskWarnYesNoString ((wstring (GetString ("SYSDRIVE_NON_STANDARD_PARTITIONS")) + L"\n\n" + GetString ("ASK_ENCRYPT_PARTITION_INSTEAD_OF_DRIVE")).c_str(), MainDlg) == IDYES)
 1081                                 bWholeSysDrive = FALSE;
 1082                         }
 1083 
 1084                         if (!IsOSAtLeast (WIN_VISTA) && bWholeSysDrive)
 1085                         {
 1086                             if (BootEncObj->SystemDriveContainsExtendedPartition())
 1087                             {
 1088                                 bWholeSysDrive = FALSE;
 1089 
 1090                                 Error ("WDE_UNSUPPORTED_FOR_EXTENDED_PARTITIONS", MainDlg);
 1091 
 1092                                 if (AskYesNo ("ASK_ENCRYPT_PARTITION_INSTEAD_OF_DRIVE", MainDlg) == IDNO)
 1093                                 {
 1094                                     ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE);
 1095                                     return FALSE;
 1096                                 }
 1097                             }
 1098                             else
 1099                                 Warning ("WDE_EXTENDED_PARTITIONS_WARNING", MainDlg);
 1100                         }
 1101                     }
 1102                     else if (BootEncObj->SystemPartitionCoversWholeDrive()
 1103                         && !bWholeSysDrive)
 1104                         bWholeSysDrive = (AskYesNo ("WHOLE_SYC_DEVICE_RECOM", MainDlg) == IDYES);
 1105                 }
 1106 
 1107             }
 1108             catch (Exception &e)
 1109             {
 1110                 e.Show (MainDlg);
 1111                 return FALSE;
 1112             }
 1113 
 1114             if (!bHiddenVol)
 1115             {
 1116                 // Skip SYSENC_SPAN_PAGE and SYSENC_TYPE_PAGE as the user already made the choice
 1117                 LoadPage (MainDlg, bWholeSysDrive ? SYSENC_PRE_DRIVE_ANALYSIS_PAGE : SYSENC_MULTI_BOOT_MODE_PAGE);
 1118             }
 1119             else
 1120             {
 1121                 // The user selected the non-sys-device wizard mode but then selected a system device.
 1122                 // In addition, he selected the hidden volume mode.
 1123 
 1124                 if (bWholeSysDrive)
 1125                     Warning ("HIDDEN_OS_PRECLUDES_SINGLE_KEY_WDE", MainDlg);
 1126 
 1127                 bWholeSysDrive = FALSE;
 1128 
 1129                 LoadPage (MainDlg, SYSENC_TYPE_PAGE);
 1130             }
 1131         }
 1132         else
 1133             LoadPage (MainDlg, SYSENC_TYPE_PAGE);
 1134 
 1135         NormalCursor ();
 1136         return TRUE;
 1137     }
 1138 }
 1139 
 1140 void SwitchWizardToFileContainerMode (void)
 1141 {
 1142     ChangeWizardMode (WIZARD_MODE_FILE_CONTAINER);
 1143 
 1144     LoadPage (MainDlg, VOLUME_LOCATION_PAGE);
 1145 
 1146     NormalCursor ();
 1147 }
 1148 
 1149 void SwitchWizardToNonSysDeviceMode (void)
 1150 {
 1151     ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE);
 1152 
 1153     LoadPage (MainDlg, VOLUME_TYPE_PAGE);
 1154 
 1155     NormalCursor ();
 1156 }
 1157 
 1158 BOOL SwitchWizardToHiddenOSMode (void)
 1159 {
 1160     if (SwitchWizardToSysEncMode())
 1161     {
 1162         if (nCurPageNo != SYSENC_ENCRYPTION_PAGE)   // If the user did not manually choose to resume encryption or decryption of the system partition/drive
 1163         {
 1164             bHiddenOS = TRUE;
 1165             bHiddenVol = TRUE;
 1166             bHiddenVolHost = TRUE;
 1167             bHiddenVolDirect = FALSE;
 1168             bWholeSysDrive = FALSE;
 1169             bInPlaceEncNonSys = FALSE;
 1170             bInPlaceDecNonSys = FALSE;
 1171 
 1172             if (bDirectSysEncModeCommand == SYSENC_COMMAND_CREATE_HIDDEN_OS_ELEV)
 1173             {
 1174                 // Some of the requirements for hidden OS should have already been checked by the wizard process
 1175                 // that launched us (in order to elevate), but we must recheck them. Otherwise, an advanced user
 1176                 // could bypass the checks by using the undocumented CLI switch. Moreover, some requirements
 1177                 // can be checked only at this point (when we are elevated).
 1178                 try
 1179                 {
 1180                     BootEncObj->CheckRequirementsHiddenOS ();
 1181 
 1182                     BootEncObj->InitialSecurityChecksForHiddenOS ();
 1183                 }
 1184                 catch (Exception &e)
 1185                 {
 1186                     e.Show (MainDlg);
 1187                     return FALSE;
 1188                 }
 1189 
 1190                 LoadPage (MainDlg, SYSENC_MULTI_BOOT_MODE_PAGE);
 1191             }
 1192             else
 1193                 LoadPage (MainDlg, SYSENC_HIDDEN_OS_REQ_CHECK_PAGE);
 1194 
 1195             NormalCursor ();
 1196         }
 1197         else
 1198             return TRUE;
 1199     }
 1200     else
 1201         return FALSE;
 1202 
 1203     return TRUE;
 1204 }
 1205 
 1206 void SwitchWizardToNonSysInplaceEncResumeMode (BOOL bDecrypt)
 1207 {
 1208     if (!IsAdmin() && IsUacSupported())
 1209     {
 1210         if (!ElevateWholeWizardProcess (bDecrypt ? L"/resumeinplacedec" : L"/zinplace"))
 1211             AbortProcessSilent ();
 1212     }
 1213 
 1214     if (!IsAdmin())
 1215         AbortProcess("ADMIN_PRIVILEGES_WARN_DEVICES");
 1216 
 1217     CreateNonSysInplaceEncMutex ();
 1218 
 1219     bInPlaceEncNonSys = TRUE;
 1220     bInPlaceDecNonSys = bDecrypt;
 1221     bInPlaceEncNonSysResumed = TRUE;
 1222 
 1223     ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE);
 1224 
 1225     LoadPage (MainDlg, NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE);
 1226 }
 1227 
 1228 void SwitchWizardToNonSysInplaceDecStartMode (wchar_t *volPath)
 1229 {
 1230     if (!IsAdmin() && IsUacSupported())
 1231     {
 1232         if (!ElevateWholeWizardProcess ((wstring (L"/inplacedec \"") + volPath + L"\"").c_str()))
 1233             AbortProcessSilent ();
 1234     }
 1235 
 1236     if (!IsAdmin())
 1237         AbortProcess("ADMIN_PRIVILEGES_WARN_DEVICES");
 1238 
 1239     if (!CheckRequirementsForNonSysInPlaceDec (MainDlg, volPath, FALSE))
 1240         AbortProcessSilent ();
 1241 
 1242     CreateNonSysInplaceEncMutex ();
 1243 
 1244     bInPlaceEncNonSys = TRUE;
 1245     bInPlaceDecNonSys = TRUE;
 1246     bInPlaceEncNonSysResumed = FALSE;
 1247 
 1248     ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE);
 1249 
 1250     LoadPage (MainDlg, NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE);
 1251 }
 1252 
 1253 // Use this function e.g. if the config file with the system encryption settings was lost or not written
 1254 // correctly, and we don't know whether to encrypt or decrypt (but we know that encryption or decryption
 1255 // is required). Returns FALSE if failed or cancelled.
 1256 static BOOL ResolveUnknownSysEncDirection (void)
 1257 {
 1258     if (CreateSysEncMutex ())
 1259     {
 1260         if (SystemEncryptionStatus != SYSENC_STATUS_ENCRYPTING
 1261             && SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING)
 1262         {
 1263             try
 1264             {
 1265                 BootEncStatus = BootEncObj->GetStatus();
 1266             }
 1267             catch (Exception &e)
 1268             {
 1269                 e.Show (MainDlg);
 1270                 Error ("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS", MainDlg);
 1271                 return FALSE;
 1272             }
 1273 
 1274             if (BootEncStatus.SetupInProgress)
 1275             {
 1276                 return ChangeSystemEncryptionStatus (
 1277                     (BootEncStatus.SetupMode != SetupDecryption) ? SYSENC_STATUS_ENCRYPTING : SYSENC_STATUS_DECRYPTING);
 1278             }
 1279             else
 1280             {
 1281                 // Ask the user to select encryption, decryption, or cancel
 1282 
 1283                 char *tmpStr[] = {0,
 1284                     !BootEncStatus.DriveEncrypted ? "CHOOSE_ENCRYPT_OR_DECRYPT_FINALIZE_DECRYPT_NOTE" : "CHOOSE_ENCRYPT_OR_DECRYPT",
 1285                     "ENCRYPT",
 1286                     "DECRYPT",
 1287                     "IDCANCEL",
 1288                     0};
 1289 
 1290                 switch (AskMultiChoice ((void **) tmpStr, FALSE, MainDlg))
 1291                 {
 1292                 case 1:
 1293                     return ChangeSystemEncryptionStatus (SYSENC_STATUS_ENCRYPTING);
 1294                 case 2:
 1295                     return ChangeSystemEncryptionStatus (SYSENC_STATUS_DECRYPTING);
 1296                 default:
 1297                     return FALSE;
 1298                 }
 1299             }
 1300         }
 1301         else
 1302             return TRUE;
 1303     }
 1304     else
 1305     {
 1306         Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
 1307         return FALSE;
 1308     }
 1309 }
 1310 
 1311 // This function should be used to resolve inconsistencies that might lead to a deadlock (inability to encrypt or
 1312 // decrypt the system partition/drive and to uninstall TrueCrypt). The function removes the system encryption key
 1313 // data ("volume header"), the TrueCrypt boot loader, restores the original system loader (if available),
 1314 // unregisters the boot driver, etc. Note that if the system partition/drive is encrypted, it will start decrypting
 1315 // it in the background (therefore, it should be used when the system partition/drive is not encrypted, ideally).
 1316 // Exceptions are handled and errors are reported within the function. Returns TRUE if successful.
 1317 static BOOL ForceRemoveSysEnc (void)
 1318 {
 1319     if (CreateSysEncMutex ())   // If no other instance is currently taking care of system encryption
 1320     {
 1321         BootEncryptionStatus locBootEncStatus;
 1322 
 1323         try
 1324         {
 1325             locBootEncStatus = BootEncObj->GetStatus();
 1326 
 1327             if (locBootEncStatus.SetupInProgress)
 1328                 BootEncObj->AbortSetupWait ();
 1329 
 1330             locBootEncStatus = BootEncObj->GetStatus();
 1331 
 1332             if (locBootEncStatus.DriveMounted)
 1333             {
 1334                 // Remove the header
 1335                 BootEncObj->StartDecryption (DiscardUnreadableEncryptedSectors);
 1336                 locBootEncStatus = BootEncObj->GetStatus();
 1337 
 1338                 while (locBootEncStatus.SetupInProgress)
 1339                 {
 1340                     Sleep (100);
 1341                     locBootEncStatus = BootEncObj->GetStatus();
 1342                 }
 1343 
 1344                 BootEncObj->CheckEncryptionSetupResult ();
 1345             }
 1346 
 1347             Sleep (50);
 1348         }
 1349         catch (Exception &e)
 1350         {
 1351             e.Show (MainDlg);
 1352             return FALSE;
 1353         }
 1354 
 1355         try
 1356         {
 1357             locBootEncStatus = BootEncObj->GetStatus();
 1358 
 1359             if (!locBootEncStatus.DriveMounted)
 1360                 BootEncObj->Deinstall (true);
 1361         }
 1362         catch (Exception &e)
 1363         {
 1364             e.Show (MainDlg);
 1365             return FALSE;
 1366         }
 1367 
 1368         return TRUE;
 1369     }
 1370     else
 1371         return FALSE;
 1372 }
 1373 
 1374 // Returns 0 if there's an error.
 1375 __int64 GetSystemPartitionSize (void)
 1376 {
 1377     try
 1378     {
 1379         return BootEncObj->GetSystemDriveConfiguration().SystemPartition.Info.PartitionLength.QuadPart;
 1380     }
 1381     catch (Exception &e)
 1382     {
 1383         e.Show (MainDlg);
 1384         return 0;
 1385     }
 1386 }
 1387 
 1388 void ComboSelChangeEA (HWND hwndDlg)
 1389 {
 1390     int nIndex = (int) SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_GETCURSEL, 0, 0);
 1391 
 1392     if (nIndex == CB_ERR)
 1393     {
 1394         SetWindowText (GetDlgItem (hwndDlg, IDC_BOX_HELP), L"");
 1395     }
 1396     else
 1397     {
 1398         wchar_t name[100];
 1399         wchar_t auxLine[4096];
 1400         wchar_t hyperLink[256] = { 0 };
 1401         int cipherIDs[5];
 1402         int i, cnt = 0;
 1403 
 1404         nIndex = (int) SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_GETITEMDATA, nIndex, 0);
 1405         EAGetName (name, nIndex, 0);
 1406 
 1407         if (wcscmp (name, L"AES") == 0)
 1408         {
 1409             StringCbPrintfW (hyperLink, sizeof(hyperLink) / 2, GetString ("MORE_INFO_ABOUT"), name);
 1410 
 1411             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("AES_HELP"));
 1412         }
 1413         else if (wcscmp (name, L"Serpent") == 0)
 1414         {
 1415             StringCbPrintfW (hyperLink, sizeof(hyperLink) / 2, GetString ("MORE_INFO_ABOUT"), name);
 1416 
 1417             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SERPENT_HELP"));
 1418         }
 1419         else if (wcscmp (name, L"Twofish") == 0)
 1420         {
 1421             StringCbPrintfW (hyperLink, sizeof(hyperLink) / 2, GetString ("MORE_INFO_ABOUT"), name);
 1422 
 1423             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("TWOFISH_HELP"));
 1424         }
 1425         else if (wcscmp (name, L"Kuznyechik") == 0)
 1426         {
 1427             StringCbPrintfW (hyperLink, sizeof(hyperLink) / 2, GetString ("MORE_INFO_ABOUT"), name);
 1428 
 1429             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("KUZNYECHIK_HELP"));
 1430         }
 1431         else if (wcscmp (name, L"Camellia") == 0)
 1432         {
 1433             StringCbPrintfW (hyperLink, sizeof(hyperLink) / 2, GetString ("MORE_INFO_ABOUT"), name);
 1434 
 1435             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("CAMELLIA_HELP"));
 1436         }
 1437         else if (EAGetCipherCount (nIndex) > 1)
 1438         {
 1439             // Cascade
 1440             cipherIDs[cnt++] = i = EAGetLastCipher(nIndex);
 1441             while (i = EAGetPreviousCipher(nIndex, i))
 1442             {
 1443                 cipherIDs[cnt] = i;
 1444                 cnt++;
 1445             }
 1446 
 1447             switch (cnt)    // Number of ciphers in the cascade
 1448             {
 1449             case 2:
 1450                 StringCbPrintfW (auxLine, sizeof(auxLine), GetString ("TWO_LAYER_CASCADE_HELP"),
 1451                     CipherGetName (cipherIDs[1]),
 1452                     CipherGetKeySize (cipherIDs[1])*8,
 1453                     CipherGetName (cipherIDs[0]),
 1454                     CipherGetKeySize (cipherIDs[0])*8);
 1455                 break;
 1456 
 1457             case 3:
 1458                 StringCbPrintfW (auxLine, sizeof(auxLine), GetString ("THREE_LAYER_CASCADE_HELP"),
 1459                     CipherGetName (cipherIDs[2]),
 1460                     CipherGetKeySize (cipherIDs[2])*8,
 1461                     CipherGetName (cipherIDs[1]),
 1462                     CipherGetKeySize (cipherIDs[1])*8,
 1463                     CipherGetName (cipherIDs[0]),
 1464                     CipherGetKeySize (cipherIDs[0])*8);
 1465                 break;
 1466             }
 1467 
 1468             StringCbCopyW (hyperLink, sizeof(hyperLink), GetString ("IDC_LINK_MORE_INFO_ABOUT_CIPHER"));
 1469 
 1470             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), auxLine);
 1471         }
 1472         else
 1473         {
 1474             // No info available for this encryption algorithm
 1475             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), L"");
 1476         }
 1477 
 1478 
 1479         // Update hyperlink
 1480         SetWindowTextW (GetDlgItem (hwndDlg, IDC_LINK_MORE_INFO_ABOUT_CIPHER), hyperLink);
 1481         AccommodateTextField (hwndDlg, IDC_LINK_MORE_INFO_ABOUT_CIPHER, FALSE, hUserUnderlineFont);
 1482     }
 1483 }
 1484 
 1485 static void VerifySizeAndUpdate (HWND hwndDlg, BOOL bUpdate)
 1486 {
 1487     BOOL bEnable = TRUE;
 1488     wchar_t szTmp[50];
 1489     __int64 lTmp;
 1490     __int64 i;
 1491     static unsigned __int64 nLastVolumeSize = 0;
 1492 
 1493     GetWindowText (GetDlgItem (hwndDlg, IDC_SIZEBOX), szTmp, ARRAYSIZE (szTmp));
 1494 
 1495     for (i = 0; i < (__int64) wcslen (szTmp); i++)
 1496     {
 1497         if (szTmp[i] >= L'0' && szTmp[i] <= L'9')
 1498             continue;
 1499         else
 1500         {
 1501             bEnable = FALSE;
 1502             break;
 1503         }
 1504     }
 1505 
 1506     if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_KB)))
 1507         nMultiplier = BYTES_PER_KB;
 1508     else if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_MB)))
 1509         nMultiplier = BYTES_PER_MB;
 1510     else if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_GB)))
 1511         nMultiplier = BYTES_PER_GB;
 1512     else
 1513         nMultiplier = BYTES_PER_TB;
 1514 
 1515     if (bDevice && !(bHiddenVol && !bHiddenVolHost))    // If raw device but not a hidden volume
 1516     {
 1517         lTmp = nVolumeSize;
 1518         i = 1;
 1519     }
 1520     else
 1521     {
 1522         i = nMultiplier;
 1523         lTmp = _wtoi64 (szTmp);
 1524 
 1525         DWORD sectorSize = GetFormatSectorSize();
 1526         uint32 sectorSizeRem = (lTmp * nMultiplier) % sectorSize;
 1527 
 1528         if (sectorSizeRem != 0)
 1529             lTmp = (lTmp * nMultiplier + (sectorSize - sectorSizeRem)) / nMultiplier;
 1530     }
 1531 
 1532     if (bEnable)
 1533     {
 1534         if (lTmp * i < (bHiddenVolHost ? TC_MIN_HIDDEN_VOLUME_HOST_SIZE : (bHiddenVol ? TC_MIN_HIDDEN_VOLUME_SIZE : TC_MIN_VOLUME_SIZE)))
 1535             bEnable = FALSE;
 1536 
 1537         if (!bHiddenVolHost && bHiddenVol)
 1538         {
 1539             if (lTmp * i > nMaximumHiddenVolSize)
 1540                 bEnable = FALSE;
 1541         }
 1542         else
 1543         {
 1544             if (lTmp * i > (bHiddenVolHost ? TC_MAX_HIDDEN_VOLUME_HOST_SIZE : TC_MAX_VOLUME_SIZE))
 1545                 bEnable = FALSE;
 1546             else if (!bDevice && (lTmp * i > nAvailableFreeSpace) && !bDontCheckFileContainerSize && (!bIsSparseFilesSupportedByHost || bHiddenVolHost))
 1547             {
 1548                 // we check container size against available free space only when creating dynamic volume is not possible
 1549                 // which is the case if filesystem doesn't allow sparce file or if we are creating outer volume of a hidden volume
 1550                 bEnable = FALSE;
 1551             }
 1552         }
 1553     }
 1554 
 1555     if (bUpdate)
 1556     {
 1557         nUIVolumeSize = lTmp;
 1558 
 1559         if (!bDevice || (bHiddenVol && !bHiddenVolHost))    // Update only if it's not a raw device or if it's a hidden volume
 1560             nVolumeSize = i * lTmp;
 1561     }
 1562 
 1563     EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), bEnable);
 1564 
 1565     if (nVolumeSize != nLastVolumeSize)
 1566     {
 1567         // Change of volume size may make some file systems allowed or disallowed, so the default filesystem must
 1568         // be reselected.
 1569         fileSystem = FILESYS_NONE;
 1570         nLastVolumeSize = nVolumeSize;
 1571     }
 1572 }
 1573 
 1574 static void UpdateWizardModeControls (HWND hwndDlg, int setWizardMode)
 1575 {
 1576     SendMessage (GetDlgItem (hwndDlg, IDC_FILE_CONTAINER),
 1577         BM_SETCHECK,
 1578         setWizardMode == WIZARD_MODE_FILE_CONTAINER ? BST_CHECKED : BST_UNCHECKED,
 1579         0);
 1580 
 1581     SendMessage (GetDlgItem (hwndDlg, IDC_NONSYS_DEVICE),
 1582         BM_SETCHECK,
 1583         setWizardMode == WIZARD_MODE_NONSYS_DEVICE ? BST_CHECKED : BST_UNCHECKED,
 1584         0);
 1585 
 1586     SendMessage (GetDlgItem (hwndDlg, IDC_SYS_DEVICE),
 1587         BM_SETCHECK,
 1588         setWizardMode == WIZARD_MODE_SYS_DEVICE ? BST_CHECKED : BST_UNCHECKED,
 1589         0);
 1590 }
 1591 
 1592 static int GetSelectedWizardMode (HWND hwndDlg)
 1593 {
 1594     if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_FILE_CONTAINER)))
 1595         return WIZARD_MODE_FILE_CONTAINER;
 1596 
 1597     if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_NONSYS_DEVICE)))
 1598         return WIZARD_MODE_NONSYS_DEVICE;
 1599 
 1600     if (IsButtonChecked (GetDlgItem (hwndDlg, IDC_SYS_DEVICE)))
 1601         return WIZARD_MODE_SYS_DEVICE;
 1602 
 1603     return DEFAULT_VOL_CREATION_WIZARD_MODE;
 1604 }
 1605 
 1606 static void RefreshMultiBootControls (HWND hwndDlg)
 1607 {
 1608 #ifdef DEBUG
 1609     if (nMultiBoot == 0)
 1610         nMultiBoot = 1;
 1611 #endif
 1612 
 1613     // For now, we force single configuration in wizard
 1614     if (bSystemIsGPT && nMultiBoot == 0)
 1615         nMultiBoot = 1;
 1616 
 1617     SendMessage (GetDlgItem (hwndDlg, IDC_SINGLE_BOOT),
 1618         BM_SETCHECK,
 1619         nMultiBoot == 1 ? BST_CHECKED : BST_UNCHECKED,
 1620         0);
 1621 
 1622     SendMessage (GetDlgItem (hwndDlg, IDC_MULTI_BOOT),
 1623         BM_SETCHECK,
 1624         nMultiBoot > 1 ? BST_CHECKED : BST_UNCHECKED,
 1625         0);
 1626 }
 1627 
 1628 // -1 = Undecided or error, 0 = No, 1 = Yes
 1629 static int Get2RadButtonPageAnswer (void)
 1630 {
 1631     if (IsButtonChecked (GetDlgItem (hCurPage, IDC_CHOICE1)))
 1632         return 1;
 1633 
 1634     if (IsButtonChecked (GetDlgItem (hCurPage, IDC_CHOICE2)))
 1635         return 0;
 1636 
 1637     return -1;
 1638 }
 1639 
 1640 // 0 = No, 1 = Yes
 1641 static void Update2RadButtonPage (int answer)
 1642 {
 1643     SendMessage (GetDlgItem (hCurPage, IDC_CHOICE1),
 1644         BM_SETCHECK,
 1645         answer == 1 ? BST_CHECKED : BST_UNCHECKED,
 1646         0);
 1647 
 1648     SendMessage (GetDlgItem (hCurPage, IDC_CHOICE2),
 1649         BM_SETCHECK,
 1650         answer == 0 ? BST_CHECKED : BST_UNCHECKED,
 1651         0);
 1652 }
 1653 
 1654 // -1 = Undecided, 0 = No, 1 = Yes
 1655 static void Init2RadButtonPageYesNo (int answer)
 1656 {
 1657     SetWindowTextW (GetDlgItem (hCurPage, IDC_CHOICE1), GetString ("UISTR_YES"));
 1658     SetWindowTextW (GetDlgItem (hCurPage, IDC_CHOICE2), GetString ("UISTR_NO"));
 1659 
 1660     SetWindowTextW (GetDlgItem (MainDlg, IDC_NEXT), GetString ("NEXT"));
 1661     SetWindowTextW (GetDlgItem (MainDlg, IDC_PREV), GetString ("PREV"));
 1662     SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
 1663 
 1664     EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), answer >= 0);
 1665     EnableWindow (GetDlgItem (MainDlg, IDC_PREV), TRUE);
 1666 
 1667     Update2RadButtonPage (answer);
 1668 }
 1669 
 1670 static void UpdateSysEncProgressBar (void)
 1671 {
 1672     BootEncryptionStatus locBootEncStatus;
 1673 
 1674     try
 1675     {
 1676         locBootEncStatus = BootEncObj->GetStatus();
 1677     }
 1678     catch (...)
 1679     {
 1680         return;
 1681     }
 1682 
 1683     if (locBootEncStatus.EncryptedAreaEnd == -1
 1684         || locBootEncStatus.EncryptedAreaStart == -1)
 1685     {
 1686         UpdateProgressBarProc (0);
 1687     }
 1688     else
 1689     {
 1690         UpdateProgressBarProc (locBootEncStatus.EncryptedAreaEnd - locBootEncStatus.EncryptedAreaStart + 1);
 1691 
 1692         if (locBootEncStatus.SetupInProgress)
 1693         {
 1694             wchar_t tmpStr[100];
 1695 
 1696             // Status
 1697 
 1698             if (locBootEncStatus.TransformWaitingForIdle)
 1699                 StringCbCopyW (tmpStr, sizeof(tmpStr), GetString ("PROGRESS_STATUS_WAITING"));
 1700             else
 1701                 StringCbCopyW (tmpStr, sizeof(tmpStr), GetString (SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING ? "PROGRESS_STATUS_DECRYPTING" : "PROGRESS_STATUS_ENCRYPTING"));
 1702 
 1703             StringCbCatW (tmpStr, sizeof(tmpStr), L" ");
 1704 
 1705             SetWindowTextW (GetDlgItem (hCurPage, IDC_WRITESPEED), tmpStr);
 1706         }
 1707     }
 1708 }
 1709 
 1710 static void InitSysEncProgressBar (void)
 1711 {
 1712     BootEncryptionStatus locBootEncStatus;
 1713 
 1714     try
 1715     {
 1716         locBootEncStatus = BootEncObj->GetStatus();
 1717     }
 1718     catch (...)
 1719     {
 1720         return;
 1721     }
 1722 
 1723     if (locBootEncStatus.ConfiguredEncryptedAreaEnd == -1
 1724         || locBootEncStatus.ConfiguredEncryptedAreaStart == -1)
 1725         return;
 1726 
 1727     InitProgressBar (locBootEncStatus.ConfiguredEncryptedAreaEnd
 1728         - locBootEncStatus.ConfiguredEncryptedAreaStart + 1,
 1729         (locBootEncStatus.EncryptedAreaEnd == locBootEncStatus.EncryptedAreaStart || locBootEncStatus.EncryptedAreaEnd == -1) ?
 1730         0 : locBootEncStatus.EncryptedAreaEnd - locBootEncStatus.EncryptedAreaStart + 1,
 1731         SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING,
 1732         TRUE,
 1733         TRUE,
 1734         TRUE);
 1735 }
 1736 
 1737 static void UpdateSysEncControls (void)
 1738 {
 1739     BootEncryptionStatus locBootEncStatus;
 1740 
 1741     try
 1742     {
 1743         locBootEncStatus = BootEncObj->GetStatus();
 1744     }
 1745     catch (...)
 1746     {
 1747         return;
 1748     }
 1749 
 1750     EnableWindow (GetDlgItem (hCurPage, IDC_WIPE_MODE),
 1751         !locBootEncStatus.SetupInProgress
 1752         && SystemEncryptionStatus == SYSENC_STATUS_ENCRYPTING);
 1753 
 1754     SetWindowTextW (GetDlgItem (hCurPage, IDC_PAUSE),
 1755         GetString (locBootEncStatus.SetupInProgress ? "IDC_PAUSE" : "RESUME"));
 1756 
 1757     EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), !locBootEncStatus.SetupInProgress && !bFirstSysEncResumeDone);
 1758 
 1759     if (!locBootEncStatus.SetupInProgress)
 1760     {
 1761         wchar_t tmpStr[100];
 1762 
 1763         StringCbCopyW (tmpStr, sizeof(tmpStr), GetString ((SysDriveOrPartitionFullyEncrypted (TRUE) || !locBootEncStatus.DriveMounted) ?
 1764             "PROGRESS_STATUS_FINISHED" : "PROGRESS_STATUS_PAUSED"));
 1765         StringCbCatW (tmpStr, sizeof(tmpStr), L" ");
 1766 
 1767         // Status
 1768         SetWindowTextW (GetDlgItem (hCurPage, IDC_WRITESPEED), tmpStr);
 1769 
 1770         if (SysDriveOrPartitionFullyEncrypted (TRUE) || SystemEncryptionStatus == SYSENC_STATUS_NONE)
 1771         {
 1772             StringCbCopyW (tmpStr, sizeof(tmpStr), GetString ("PROCESSED_PORTION_100_PERCENT"));
 1773             StringCbCatW (tmpStr, sizeof(tmpStr), L" ");
 1774 
 1775             SetWindowTextW (GetDlgItem (hCurPage, IDC_BYTESWRITTEN), tmpStr);
 1776         }
 1777 
 1778         SetWindowText (GetDlgItem (hCurPage, IDC_TIMEREMAIN), L" ");
 1779     }
 1780 }
 1781 
 1782 static void SysEncPause (void)
 1783 {
 1784     BootEncryptionStatus locBootEncStatus;
 1785 
 1786     if (CreateSysEncMutex ())
 1787     {
 1788         EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), FALSE);
 1789 
 1790         try
 1791         {
 1792             locBootEncStatus = BootEncObj->GetStatus();
 1793         }
 1794         catch (Exception &e)
 1795         {
 1796             e.Show (MainDlg);
 1797             Error ("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS", MainDlg);
 1798             EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1799             return;
 1800         }
 1801 
 1802         if (!locBootEncStatus.SetupInProgress)
 1803         {
 1804             EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1805             return;
 1806         }
 1807 
 1808         WaitCursor ();
 1809 
 1810         try
 1811         {
 1812             int attempts = SYSENC_PAUSE_RETRIES;
 1813 
 1814             BootEncObj->AbortSetup ();
 1815 
 1816             locBootEncStatus = BootEncObj->GetStatus();
 1817 
 1818             while (locBootEncStatus.SetupInProgress && attempts > 0)
 1819             {
 1820                 Sleep (SYSENC_PAUSE_RETRY_INTERVAL);
 1821                 attempts--;
 1822                 locBootEncStatus = BootEncObj->GetStatus();
 1823             }
 1824 
 1825             if (!locBootEncStatus.SetupInProgress)
 1826                 BootEncObj->CheckEncryptionSetupResult ();
 1827 
 1828         }
 1829         catch (Exception &e)
 1830         {
 1831             e.Show (MainDlg);
 1832         }
 1833 
 1834         NormalCursor ();
 1835 
 1836         if (locBootEncStatus.SetupInProgress)
 1837         {
 1838             SetTimer (MainDlg, TIMER_ID_SYSENC_PROGRESS, TIMER_INTERVAL_SYSENC_PROGRESS, NULL);
 1839             EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1840             Error ("FAILED_TO_INTERRUPT_SYSTEM_ENCRYPTION", MainDlg);
 1841             return;
 1842         }
 1843 
 1844         UpdateSysEncControls ();
 1845         EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1846     }
 1847     else
 1848         Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
 1849 }
 1850 
 1851 
 1852 static void SysEncResume (void)
 1853 {
 1854     BootEncryptionStatus locBootEncStatus;
 1855 
 1856     if (CreateSysEncMutex ())
 1857     {
 1858         EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), FALSE);
 1859 
 1860         try
 1861         {
 1862             locBootEncStatus = BootEncObj->GetStatus();
 1863         }
 1864         catch (Exception &e)
 1865         {
 1866             e.Show (MainDlg);
 1867             Error ("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS", MainDlg);
 1868             EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1869             return;
 1870         }
 1871 
 1872         if (locBootEncStatus.SetupInProgress)
 1873         {
 1874             // Prevent the OS from entering Sleep mode when idle
 1875             SetThreadExecutionState (ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
 1876 
 1877             bSystemEncryptionInProgress = TRUE;
 1878             UpdateSysEncControls ();
 1879             SetTimer (MainDlg, TIMER_ID_SYSENC_PROGRESS, TIMER_INTERVAL_SYSENC_PROGRESS, NULL);
 1880             EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1881             return;
 1882         }
 1883 
 1884         bVolTransformThreadCancel = FALSE;
 1885         bSystemEncryptionInProgress = FALSE;
 1886         WaitCursor ();
 1887 
 1888         try
 1889         {
 1890             switch (SystemEncryptionStatus)
 1891             {
 1892             case SYSENC_STATUS_ENCRYPTING:
 1893 
 1894                 BootEncObj->StartEncryption (nWipeMode, bTryToCorrectReadErrors ? true : false);
 1895                 break;
 1896 
 1897             case SYSENC_STATUS_DECRYPTING:
 1898 
 1899                 if (locBootEncStatus.DriveMounted)  // If the drive is not encrypted we will just deinstall
 1900                     BootEncObj->StartDecryption (DiscardUnreadableEncryptedSectors);
 1901 
 1902                 break;
 1903             }
 1904 
 1905             bSystemEncryptionInProgress = TRUE;
 1906         }
 1907         catch (Exception &e)
 1908         {
 1909             e.Show (MainDlg);
 1910         }
 1911 
 1912         NormalCursor ();
 1913 
 1914         if (!bSystemEncryptionInProgress)
 1915         {
 1916             // Allow the OS to enter Sleep mode when idle
 1917             SetThreadExecutionState (ES_CONTINUOUS);
 1918 
 1919             EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1920             Error ("FAILED_TO_RESUME_SYSTEM_ENCRYPTION", MainDlg);
 1921             return;
 1922         }
 1923 
 1924         // Prevent the OS from entering Sleep mode when idle
 1925         SetThreadExecutionState (ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
 1926 
 1927         bFirstSysEncResumeDone = TRUE;
 1928         InitSysEncProgressBar ();
 1929         UpdateSysEncProgressBar ();
 1930         UpdateSysEncControls ();
 1931         EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), TRUE);
 1932         SetTimer (MainDlg, TIMER_ID_SYSENC_PROGRESS, TIMER_INTERVAL_SYSENC_PROGRESS, NULL);
 1933     }
 1934     else
 1935         Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
 1936 }
 1937 
 1938 
 1939 static BOOL GetDevicePathForHiddenOS (void)
 1940 {
 1941     BOOL tmpbDevice = FALSE;
 1942 
 1943     try
 1944     {
 1945         StringCbCopyW (szFileName, sizeof(szFileName), BootEncObj->GetPartitionForHiddenOS().DevicePath.c_str());
 1946 
 1947         CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), szFileName, &tmpbDevice);
 1948     }
 1949     catch (Exception &e)
 1950     {
 1951         e.Show (MainDlg);
 1952         return FALSE;
 1953     }
 1954 
 1955     return (szFileName[0] != 0
 1956         && szDiskFile[0] != 0
 1957         && tmpbDevice);
 1958 }
 1959 
 1960 
 1961 // Returns TRUE if there is unallocated space greater than 64 MB (max possible slack space size) between the
 1962 // boot partition and the first partition behind it. If there's none or if an error occurs, returns FALSE.
 1963 static BOOL CheckGapBetweenSysAndHiddenOS (void)
 1964 {
 1965     try
 1966     {
 1967         SystemDriveConfiguration sysDriveCfg = BootEncObj->GetSystemDriveConfiguration();
 1968 
 1969         return (sysDriveCfg.SystemPartition.Info.StartingOffset.QuadPart
 1970             + sysDriveCfg.SystemPartition.Info.PartitionLength.QuadPart
 1971             + 64 * BYTES_PER_MB
 1972             + 128 * BYTES_PER_KB
 1973             <= BootEncObj->GetPartitionForHiddenOS().Info.StartingOffset.QuadPart);
 1974     }
 1975     catch (Exception &e)
 1976     {
 1977         e.Show (MainDlg);
 1978     }
 1979 
 1980     return FALSE;
 1981 }
 1982 
 1983 
 1984 static void NonSysInplaceEncPause (void)
 1985 {
 1986     bVolTransformThreadCancel = TRUE;
 1987 
 1988     WaitCursor ();
 1989 
 1990     int waitThreshold = 100;    // Do not block GUI events for more than 10 seconds. IMPORTANT: This prevents deadlocks when the thread calls us back e.g. to update GUI!
 1991 
 1992     while (bVolTransformThreadRunning || bVolTransformThreadToRun)
 1993     {
 1994         MSG guiMsg;
 1995 
 1996         bVolTransformThreadCancel = TRUE;
 1997 
 1998         if (waitThreshold <= 0)
 1999         {
 2000             while (PeekMessageW (&guiMsg, NULL, 0, 0, PM_REMOVE) != 0)
 2001             {
 2002                 DispatchMessageW (&guiMsg);
 2003             }
 2004         }
 2005         else
 2006             waitThreshold--;
 2007 
 2008         Sleep (100);
 2009     }
 2010 }
 2011 
 2012 
 2013 static void NonSysInplaceEncResume (void)
 2014 {
 2015     if (bVolTransformThreadRunning || bVolTransformThreadToRun || bVolTransformThreadCancel)
 2016         return;
 2017 
 2018     if (!bInPlaceEncNonSysResumed
 2019         && !FinalPreTransformPrompts ())
 2020     {
 2021         return;
 2022     }
 2023 
 2024     CreateNonSysInplaceEncMutex ();
 2025 
 2026     bFirstNonSysInPlaceEncResumeDone = TRUE;
 2027 
 2028     SetTimer (MainDlg, TIMER_ID_NONSYS_INPLACE_ENC_PROGRESS, TIMER_INTERVAL_NONSYS_INPLACE_ENC_PROGRESS, NULL);
 2029 
 2030     bVolTransformThreadCancel = FALSE;
 2031     bVolTransformThreadToRun = TRUE;
 2032 
 2033     UpdateNonSysInPlaceEncControls ();
 2034 
 2035     LastDialogId = "NONSYS_INPLACE_ENC_IN_PROGRESS";
 2036 
 2037     _beginthread (volTransformThreadFunction, 0, MainDlg);
 2038 
 2039     return;
 2040 }
 2041 
 2042 
 2043 void ShowNonSysInPlaceEncUIStatus (void)
 2044 {
 2045     wchar_t nonSysInplaceEncUIStatus [300] = {0};
 2046 
 2047     switch (NonSysInplaceEncStatus)
 2048     {
 2049     case NONSYS_INPLACE_ENC_STATUS_PAUSED:
 2050         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_PAUSED"));
 2051         break;
 2052     case NONSYS_INPLACE_ENC_STATUS_PREPARING:
 2053         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_PREPARING"));
 2054         break;
 2055     case NONSYS_INPLACE_ENC_STATUS_RESIZING:
 2056         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_RESIZING"));
 2057         break;
 2058     case NONSYS_INPLACE_ENC_STATUS_ENCRYPTING:
 2059         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_ENCRYPTING"));
 2060         break;
 2061     case NONSYS_INPLACE_ENC_STATUS_DECRYPTING:
 2062         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_DECRYPTING"));
 2063         break;
 2064     case NONSYS_INPLACE_ENC_STATUS_FINALIZING:
 2065         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_FINALIZING"));
 2066         break;
 2067     case NONSYS_INPLACE_ENC_STATUS_FINISHED:
 2068         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_FINISHED"));
 2069         break;
 2070     case NONSYS_INPLACE_ENC_STATUS_ERROR:
 2071         StringCbCopyW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), GetString ("PROGRESS_STATUS_ERROR"));
 2072         break;
 2073     }
 2074 
 2075     StringCbCatW (nonSysInplaceEncUIStatus, sizeof(nonSysInplaceEncUIStatus), L" ");
 2076 
 2077     SetWindowTextW (GetDlgItem (hCurPage, IDC_WRITESPEED), nonSysInplaceEncUIStatus);
 2078 }
 2079 
 2080 
 2081 void UpdateNonSysInPlaceEncControls (void)
 2082 {
 2083     // Reduce flickering by updating a GUI element only when a relevant change affects it
 2084     static BOOL lastbVolTransformThreadRunning = !bVolTransformThreadRunning;
 2085     static BOOL lastbVolTransformThreadToRun = !bVolTransformThreadToRun;
 2086     static BOOL lastbInPlaceEncNonSysResumed = !bInPlaceEncNonSysResumed;
 2087 
 2088     EnableWindow (GetDlgItem (hCurPage, IDC_WIPE_MODE), !(bVolTransformThreadRunning || bVolTransformThreadToRun) && !bInPlaceDecNonSys);
 2089 
 2090     if (lastbVolTransformThreadRunning != bVolTransformThreadRunning
 2091         || lastbVolTransformThreadToRun != bVolTransformThreadToRun)
 2092     {
 2093         SetWindowTextW (GetDlgItem (hCurPage, IDC_PAUSE),
 2094             GetString ((bVolTransformThreadRunning || bVolTransformThreadToRun) ? "IDC_PAUSE" : "RESUME"));
 2095 
 2096         lastbVolTransformThreadRunning = bVolTransformThreadRunning;
 2097         lastbVolTransformThreadToRun = bVolTransformThreadToRun;
 2098     }
 2099 
 2100     if (lastbInPlaceEncNonSysResumed != bInPlaceEncNonSysResumed)
 2101     {
 2102         SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString (bInPlaceEncNonSysResumed ? "DEFER" : "CANCEL"));
 2103         lastbInPlaceEncNonSysResumed = bInPlaceEncNonSysResumed;
 2104     }
 2105 
 2106     EnableWindow (GetDlgItem (hCurPage, IDC_PAUSE), bFirstNonSysInPlaceEncResumeDone
 2107         && NonSysInplaceEncStatus != NONSYS_INPLACE_ENC_STATUS_FINALIZING
 2108         && NonSysInplaceEncStatus != NONSYS_INPLACE_ENC_STATUS_FINISHED);
 2109 
 2110     EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), !(bVolTransformThreadRunning || bVolTransformThreadToRun) && !bFirstNonSysInPlaceEncResumeDone);
 2111     EnableWindow (GetDlgItem (MainDlg, IDC_PREV), !(bVolTransformThreadRunning || bVolTransformThreadToRun) && !bInPlaceEncNonSysResumed);
 2112     EnableWindow (GetDlgItem (MainDlg, IDCANCEL),
 2113         !(bVolTransformThreadToRun
 2114         || NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_PREPARING
 2115         || NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_RESIZING
 2116         || NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINALIZING
 2117         || NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED));
 2118 
 2119     if (bVolTransformThreadRunning || bVolTransformThreadToRun)
 2120     {
 2121         switch (NonSysInplaceEncStatus)
 2122         {
 2123         case NONSYS_INPLACE_ENC_STATUS_PREPARING:
 2124         case NONSYS_INPLACE_ENC_STATUS_RESIZING:
 2125         case NONSYS_INPLACE_ENC_STATUS_FINALIZING:
 2126             ArrowWaitCursor ();
 2127             break;
 2128 
 2129         case NONSYS_INPLACE_ENC_STATUS_ENCRYPTING:
 2130             NormalCursor ();
 2131             break;
 2132 
 2133         default:
 2134             NormalCursor ();
 2135             break;
 2136         }
 2137 
 2138         if (bVolTransformThreadCancel)
 2139             WaitCursor ();
 2140     }
 2141     else
 2142     {
 2143         NormalCursor ();
 2144 
 2145         if (bInPlaceEncNonSysResumed)
 2146         {
 2147             SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PAUSED);
 2148         }
 2149         else
 2150             SetWindowText (GetDlgItem (hCurPage, IDC_WRITESPEED), L" ");
 2151 
 2152         SetWindowText (GetDlgItem (hCurPage, IDC_TIMEREMAIN), L" ");
 2153     }
 2154 
 2155     ShowNonSysInPlaceEncUIStatus ();
 2156 
 2157     UpdateNonSysInplaceEncProgressBar ();
 2158 }
 2159 
 2160 
 2161 static void UpdateNonSysInplaceEncProgressBar (void)
 2162 {
 2163     static int lastNonSysInplaceEncStatus = NONSYS_INPLACE_ENC_STATUS_NONE;
 2164     int nonSysInplaceEncStatus = NonSysInplaceEncStatus;
 2165     __int64 totalSize = NonSysInplaceEncTotalSize;
 2166 
 2167     if (bVolTransformThreadRunning
 2168         && (nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_ENCRYPTING
 2169         || nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_DECRYPTING
 2170         || nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINALIZING
 2171         || nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED))
 2172     {
 2173         if (lastNonSysInplaceEncStatus != nonSysInplaceEncStatus
 2174             && (nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_ENCRYPTING || nonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_DECRYPTING))
 2175         {
 2176             InitNonSysInplaceEncProgressBar ();
 2177         }
 2178         else
 2179         {
 2180             if (totalSize <= 0 && nVolumeSize > 0)
 2181                 totalSize = nVolumeSize;
 2182 
 2183             if (totalSize > 0)
 2184                 UpdateProgressBarProc (NonSysInplaceEncBytesDone);
 2185         }
 2186     }
 2187 
 2188     ShowNonSysInPlaceEncUIStatus ();
 2189 
 2190     lastNonSysInplaceEncStatus = nonSysInplaceEncStatus;
 2191 }
 2192 
 2193 
 2194 static void InitNonSysInplaceEncProgressBar (void)
 2195 {
 2196     __int64 totalSize = NonSysInplaceEncTotalSize;
 2197 
 2198     if (totalSize <= 0)
 2199     {
 2200         if (nVolumeSize <= 0)
 2201             return;
 2202 
 2203         totalSize = nVolumeSize;
 2204     }
 2205 
 2206     InitProgressBar (totalSize,
 2207         NonSysInplaceEncBytesDone,
 2208         bInPlaceDecNonSys,
 2209         TRUE,
 2210         TRUE,
 2211         TRUE);
 2212 }
 2213 
 2214 
 2215 void DisplayRandPool (HWND hwndDlg, HWND hPoolDisplay, BOOL bShow)
 2216 {
 2217     wchar_t tmp[4];
 2218     unsigned char tmpByte;
 2219     int col, row;
 2220     static BOOL bRandPoolDispAscii = FALSE;
 2221     DWORD mouseEventsCounter;
 2222 
 2223     RandpeekBytes (hwndDlg, randPool, sizeof (randPool), &mouseEventsCounter);
 2224 
 2225     ProcessEntropyEstimate (hEntropyBar, &mouseEventsInitialCount, mouseEventsCounter, maxEntropyLevel, &mouseEntropyGathered);
 2226 
 2227     if (memcmp (lastRandPool, randPool, sizeof(lastRandPool)) != 0)
 2228     {
 2229         outRandPoolDispBuffer[0] = 0;
 2230 
 2231         for (row = 0; row < RANDPOOL_DISPLAY_ROWS; row++)
 2232         {
 2233             for (col = 0; col < RANDPOOL_DISPLAY_COLUMNS; col++)
 2234             {
 2235                 if (bShow)
 2236                 {
 2237                     tmpByte = randPool[row * RANDPOOL_DISPLAY_COLUMNS + col];
 2238 
 2239                     StringCbPrintfW (tmp, sizeof(tmp), bRandPoolDispAscii ? ((tmpByte >= 32 && tmpByte < 255 && tmpByte != L'&') ? L" %c " : L" . ") : L"%02X ", tmpByte);
 2240                 }
 2241                 else if (bUseMask)
 2242                 {
 2243                     /* use mask to compute a randomized ASCII representation */
 2244                     tmpByte = (randPool[row * RANDPOOL_DISPLAY_COLUMNS + col] -
 2245                                  lastRandPool[row * RANDPOOL_DISPLAY_COLUMNS + col]) ^ maskRandPool [row * RANDPOOL_DISPLAY_COLUMNS + col];
 2246                     tmp[0] = (wchar_t) (((tmpByte >> 4) % 6) + L'*');
 2247                     tmp[1] = (wchar_t) (((tmpByte & 0x0F) % 6) + L'*');
 2248                     tmp[2] = L' ';
 2249                     tmp[3] = 0;
 2250                 }
 2251                 else
 2252                 {
 2253                     StringCbCopyW (tmp, sizeof(tmp), L"** ");
 2254                 }
 2255 
 2256 
 2257                 StringCbCatW (outRandPoolDispBuffer, sizeof(outRandPoolDispBuffer), tmp);
 2258             }
 2259             StringCbCatW (outRandPoolDispBuffer, sizeof(outRandPoolDispBuffer), L"\n");
 2260         }
 2261         SetWindowText (hPoolDisplay, outRandPoolDispBuffer);
 2262 
 2263         memcpy (lastRandPool, randPool, sizeof(lastRandPool));
 2264     }
 2265 }
 2266 
 2267 
 2268 void DisplayPortionsOfKeys (HWND headerKeyHandle, HWND masterKeyHandle, wchar_t *headerKeyStr, wchar_t *masterKeyStr, BOOL hideKeys)
 2269 {
 2270     const wchar_t *hiddenKey = L"********************************                                              ";
 2271 
 2272     SetWindowTextW (headerKeyHandle, hideKeys ? hiddenKey : (std::wstring (headerKeyStr) + GetString ("TRIPLE_DOT_GLYPH_ELLIPSIS")).c_str());
 2273     SetWindowTextW (masterKeyHandle, hideKeys ? hiddenKey : (std::wstring (masterKeyStr) + GetString ("TRIPLE_DOT_GLYPH_ELLIPSIS")).c_str());
 2274 }
 2275 
 2276 
 2277 static void WipeAbort (void)
 2278 {
 2279     EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), FALSE);
 2280 
 2281     if (bHiddenOS && IsHiddenOSRunning())
 2282     {
 2283         /* Decoy system partition wipe */
 2284 
 2285         DecoySystemWipeStatus decoySysPartitionWipeStatus;
 2286 
 2287         try
 2288         {
 2289             decoySysPartitionWipeStatus = BootEncObj->GetDecoyOSWipeStatus();
 2290         }
 2291         catch (Exception &e)
 2292         {
 2293             e.Show (MainDlg);
 2294             EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), TRUE);
 2295             return;
 2296         }
 2297 
 2298         if (!decoySysPartitionWipeStatus.WipeInProgress)
 2299         {
 2300             EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), TRUE);
 2301             return;
 2302         }
 2303 
 2304         WaitCursor ();
 2305 
 2306         try
 2307         {
 2308             int attempts = SYSENC_PAUSE_RETRIES;
 2309 
 2310             BootEncObj->AbortDecoyOSWipe ();
 2311 
 2312             decoySysPartitionWipeStatus = BootEncObj->GetDecoyOSWipeStatus();
 2313 
 2314             while (decoySysPartitionWipeStatus.WipeInProgress && attempts > 0)
 2315             {
 2316                 Sleep (SYSENC_PAUSE_RETRY_INTERVAL);
 2317                 attempts--;
 2318                 decoySysPartitionWipeStatus = BootEncObj->GetDecoyOSWipeStatus();
 2319             }
 2320 
 2321             if (!decoySysPartitionWipeStatus.WipeInProgress)
 2322                 BootEncObj->CheckDecoyOSWipeResult ();
 2323 
 2324         }
 2325         catch (Exception &e)
 2326         {
 2327             e.Show (MainDlg);
 2328         }
 2329 
 2330         NormalCursor ();
 2331 
 2332         if (decoySysPartitionWipeStatus.WipeInProgress)
 2333         {
 2334             SetTimer (MainDlg, TIMER_ID_WIPE_PROGRESS, TIMER_INTERVAL_WIPE_PROGRESS, NULL);
 2335             EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), TRUE);
 2336             Error ("FAILED_TO_INTERRUPT_WIPING", MainDlg);
 2337             return;
 2338         }
 2339     }
 2340     else
 2341     {
 2342         /* Regular device wipe (not decoy system partition wipe) */
 2343     }
 2344 
 2345     UpdateWipeControls ();
 2346     EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), TRUE);
 2347 }
 2348 
 2349 
 2350 static void WipeStart (void)
 2351 {
 2352     if (bHiddenOS && IsHiddenOSRunning())
 2353     {
 2354         /* Decoy system partition wipe */
 2355 
 2356         EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), FALSE);
 2357 
 2358         bDeviceWipeInProgress = FALSE;
 2359         WaitCursor ();
 2360 
 2361         try
 2362         {
 2363             BootEncObj->StartDecoyOSWipe (nWipeMode);
 2364 
 2365             bDeviceWipeInProgress = TRUE;
 2366         }
 2367         catch (Exception &e)
 2368         {
 2369             e.Show (MainDlg);
 2370         }
 2371 
 2372         NormalCursor ();
 2373 
 2374         if (!bDeviceWipeInProgress)
 2375         {
 2376             EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), TRUE);
 2377             Error ("FAILED_TO_START_WIPING", MainDlg);
 2378             return;
 2379         }
 2380     }
 2381     else
 2382     {
 2383         /* Regular device wipe (not decoy system partition wipe) */
 2384     }
 2385 
 2386     InitWipeProgressBar ();
 2387     UpdateWipeProgressBar ();
 2388     UpdateWipeControls ();
 2389     EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), TRUE);
 2390     SetTimer (MainDlg, TIMER_ID_WIPE_PROGRESS, TIMER_INTERVAL_WIPE_PROGRESS, NULL);
 2391 }
 2392 
 2393 
 2394 static void UpdateWipeProgressBar (void)
 2395 {
 2396     if (bHiddenOS && IsHiddenOSRunning())
 2397     {
 2398         /* Decoy system partition wipe */
 2399 
 2400         DecoySystemWipeStatus decoySysPartitionWipeStatus;
 2401 
 2402         try
 2403         {
 2404             decoySysPartitionWipeStatus = BootEncObj->GetDecoyOSWipeStatus();
 2405             BootEncStatus = BootEncObj->GetStatus();
 2406         }
 2407         catch (...)
 2408         {
 2409             return;
 2410         }
 2411 
 2412         if (decoySysPartitionWipeStatus.WipedAreaEnd == -1)
 2413             UpdateProgressBarProc (0);
 2414         else
 2415             UpdateProgressBarProc (decoySysPartitionWipeStatus.WipedAreaEnd - BootEncStatus.ConfiguredEncryptedAreaStart + 1);
 2416     }
 2417     else
 2418     {
 2419         /* Regular device wipe (not decoy system partition wipe) */
 2420     }
 2421 }
 2422 
 2423 
 2424 static void InitWipeProgressBar (void)
 2425 {
 2426     if (bHiddenOS && IsHiddenOSRunning())
 2427     {
 2428         /* Decoy system partition wipe */
 2429 
 2430         DecoySystemWipeStatus decoySysPartitionWipeStatus;
 2431 
 2432         try
 2433         {
 2434             decoySysPartitionWipeStatus = BootEncObj->GetDecoyOSWipeStatus();
 2435             BootEncStatus = BootEncObj->GetStatus();
 2436         }
 2437         catch (...)
 2438         {
 2439             return;
 2440         }
 2441 
 2442         if (BootEncStatus.ConfiguredEncryptedAreaEnd == -1
 2443             || BootEncStatus.ConfiguredEncryptedAreaStart == -1)
 2444             return;
 2445 
 2446         InitProgressBar (BootEncStatus.ConfiguredEncryptedAreaEnd - BootEncStatus.ConfiguredEncryptedAreaStart + 1,
 2447             (decoySysPartitionWipeStatus.WipedAreaEnd == BootEncStatus.ConfiguredEncryptedAreaStart || decoySysPartitionWipeStatus.WipedAreaEnd == -1) ?
 2448             0 : decoySysPartitionWipeStatus.WipedAreaEnd - BootEncStatus.ConfiguredEncryptedAreaStart + 1,
 2449             FALSE,
 2450             TRUE,
 2451             FALSE,
 2452             TRUE);
 2453     }
 2454     else
 2455     {
 2456         /* Regular device wipe (not decoy system partition wipe) */
 2457     }
 2458 }
 2459 
 2460 
 2461 static void UpdateWipeControls (void)
 2462 {
 2463     if (bHiddenOS && IsHiddenOSRunning())
 2464     {
 2465         /* Decoy system partition wipe */
 2466 
 2467         DecoySystemWipeStatus decoySysPartitionWipeStatus;
 2468 
 2469         try
 2470         {
 2471             decoySysPartitionWipeStatus = BootEncObj->GetDecoyOSWipeStatus();
 2472             BootEncStatus = BootEncObj->GetStatus();
 2473         }
 2474         catch (...)
 2475         {
 2476             return;
 2477         }
 2478 
 2479         EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), !decoySysPartitionWipeStatus.WipeInProgress);
 2480     }
 2481     else
 2482     {
 2483         /* Regular device wipe (not decoy system partition wipe) */
 2484 
 2485         EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), bDeviceWipeInProgress);
 2486 
 2487         if (!bDeviceWipeInProgress)
 2488         {
 2489             SetWindowText (GetDlgItem (hCurPage, IDC_TIMEREMAIN), L" ");
 2490         }
 2491     }
 2492 
 2493     EnableWindow (GetDlgItem (hCurPage, IDC_ABORT_BUTTON), bDeviceWipeInProgress);
 2494     EnableWindow (GetDlgItem (MainDlg, IDC_PREV), !bDeviceWipeInProgress);
 2495 
 2496     bConfirmQuit = bDeviceWipeInProgress;
 2497 }
 2498 
 2499 
 2500 
 2501 static void __cdecl sysEncDriveAnalysisThread (void *hwndDlgArg)
 2502 {
 2503     // Mark the detection process as 'in progress'
 2504     HiddenSectorDetectionStatus = 1;
 2505     SaveSettings (NULL);
 2506     BroadcastSysEncCfgUpdate ();
 2507 
 2508     try
 2509     {
 2510         BootEncObj->ProbeRealSystemDriveSize ();
 2511         bSysEncDriveAnalysisTimeOutOccurred = FALSE;
 2512     }
 2513     catch (TimeOut &)
 2514     {
 2515         bSysEncDriveAnalysisTimeOutOccurred = TRUE;
 2516     }
 2517     catch (Exception &e)
 2518     {
 2519         // There was a problem but the system did not freeze. Mark the detection process as completed.
 2520         HiddenSectorDetectionStatus = 0;
 2521         SaveSettings (NULL);
 2522         BroadcastSysEncCfgUpdate ();
 2523 
 2524         e.Show (NULL);
 2525         EndMainDlg (MainDlg);
 2526         exit(0);
 2527     }
 2528 
 2529     // Mark the detection process as completed
 2530     HiddenSectorDetectionStatus = 0;
 2531     SaveSettings (NULL);
 2532     BroadcastSysEncCfgUpdate ();
 2533 
 2534     // This artificial delay prevents user confusion on systems where the analysis ends almost instantly
 2535     Sleep (3000);
 2536 
 2537     bSysEncDriveAnalysisInProgress = FALSE;
 2538 }
 2539 
 2540 static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
 2541 {
 2542     int nStatus;
 2543     DWORD dwWin32FormatError;
 2544     BOOL bHidden;
 2545     HWND hwndDlg = (HWND) hwndDlgArg;
 2546     volatile FORMAT_VOL_PARAMETERS *volParams = (FORMAT_VOL_PARAMETERS *) malloc (sizeof(FORMAT_VOL_PARAMETERS));
 2547 
 2548     if (volParams == NULL)
 2549         AbortProcess ("ERR_MEM_ALLOC");
 2550 
 2551     VirtualLock ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS));
 2552 
 2553     bOperationSuccess = FALSE;
 2554 
 2555     if (bGuiMode)
 2556     {
 2557         bVolTransformThreadRunning = TRUE;
 2558         bVolTransformThreadToRun = FALSE;
 2559     }
 2560 
 2561     // Check administrator privileges
 2562     if (!IsAdmin () && !IsUacSupported ())
 2563     {
 2564         if (fileSystem == FILESYS_NTFS || fileSystem == FILESYS_EXFAT  || fileSystem == FILESYS_REFS)
 2565         {
 2566             if (Silent || (MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_NTFS"), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL))
 2567                 goto cancel;
 2568         }
 2569         if (bDevice)
 2570         {
 2571             if (Silent || (MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_DEVICES"), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL))
 2572                 goto cancel;
 2573         }
 2574     }
 2575 
 2576     if (!bInPlaceEncNonSys)
 2577     {
 2578         if (!bDevice)
 2579         {
 2580             int x = _waccess (szDiskFile, 06);
 2581             if (x == 0 || errno != ENOENT)
 2582             {
 2583                 wchar_t szTmp[512];
 2584 
 2585                 if (!bForceOperation && !((bHiddenVol && !bHiddenVolHost) && errno != EACCES))  // Only ask ask for permission to overwrite an existing volume if we're not creating a hidden volume
 2586                 {
 2587                     StringCbPrintfW (szTmp, sizeof szTmp,
 2588                         GetString (errno == EACCES ? "READONLYPROMPT" : "OVERWRITEPROMPT"),
 2589                         szDiskFile);
 2590 
 2591                     x = Silent? IDNO : MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2);
 2592 
 2593                     if (x != IDYES)
 2594                         goto cancel;
 2595                 }
 2596             }
 2597 
 2598             if (_waccess (szDiskFile, 06) != 0)
 2599             {
 2600                 if (errno == EACCES)
 2601                 {
 2602                     if (_wchmod (szDiskFile, _S_IREAD | _S_IWRITE) != 0)
 2603                     {
 2604                         if (!Silent) MessageBoxW (hwndDlg, GetString ("ACCESSMODEFAIL"), lpszTitle, ICON_HAND);
 2605                         goto cancel;
 2606                     }
 2607                 }
 2608             }
 2609 
 2610         }
 2611         else
 2612         {
 2613             // Partition / device / dynamic volume
 2614 
 2615             if (!FinalPreTransformPrompts ())
 2616                 goto cancel;
 2617         }
 2618     }
 2619 
 2620     // Prevent the OS from entering Sleep mode when idle
 2621     SetThreadExecutionState (ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
 2622 
 2623     bHidden = bHiddenVol && !bHiddenVolHost;
 2624 
 2625     volParams->bDevice = bDevice;
 2626     volParams->hiddenVol = bHidden;
 2627     volParams->volumePath = szDiskFile;
 2628     volParams->size = nVolumeSize;
 2629     volParams->hiddenVolHostSize = nHiddenVolHostSize;
 2630     volParams->ea = nVolumeEA;
 2631     volParams->pkcs5 = hash_algo;
 2632     volParams->headerFlags = (CreatingHiddenSysVol() ? TC_HEADER_FLAG_ENCRYPTED_SYSTEM : 0);
 2633     volParams->fileSystem = fileSystem;
 2634     volParams->clusterSize = clusterSize;
 2635     volParams->sparseFileSwitch = bSparseFileSwitch;
 2636     volParams->quickFormat = quickFormat;
 2637     volParams->sectorSize = GetFormatSectorSize();
 2638     volParams->realClusterSize = &realClusterSize;
 2639     volParams->password = &volumePassword;
 2640     volParams->pim = volumePim;
 2641     volParams->hwndDlg = hwndDlg;
 2642     volParams->bForceOperation = bForceOperation;
 2643     volParams->bGuiMode = bGuiMode;
 2644 
 2645     if (bInPlaceDecNonSys)
 2646     {
 2647         // In-place decryption of non-system volume
 2648 
 2649         if (!bInPlaceEncNonSysResumed)
 2650             DiscardUnreadableEncryptedSectors = FALSE;
 2651 
 2652         nStatus = DecryptPartitionInPlace (volParams, &DiscardUnreadableEncryptedSectors);
 2653     }
 2654     else if (bInPlaceEncNonSys)
 2655     {
 2656         // In-place encryption of non-system volume
 2657 
 2658         HANDLE hPartition = INVALID_HANDLE_VALUE;
 2659 
 2660         SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PREPARING);
 2661 
 2662         if (!bInPlaceEncNonSysResumed)
 2663         {
 2664             bTryToCorrectReadErrors = FALSE;
 2665 
 2666             nStatus = EncryptPartitionInPlaceBegin (volParams, &hPartition, nWipeMode);
 2667 
 2668             if (nStatus == ERR_SUCCESS)
 2669             {
 2670                 nStatus = EncryptPartitionInPlaceResume (hPartition, volParams, nWipeMode, &bTryToCorrectReadErrors);
 2671             }
 2672             else if (hPartition != INVALID_HANDLE_VALUE)
 2673             {
 2674                 CloseHandle (hPartition);
 2675                 hPartition = INVALID_HANDLE_VALUE;
 2676             }
 2677         }
 2678         else
 2679         {
 2680             nStatus = EncryptPartitionInPlaceResume (INVALID_HANDLE_VALUE, volParams, nWipeMode, &bTryToCorrectReadErrors);
 2681         }
 2682     }
 2683     else
 2684     {
 2685         // Format-encryption
 2686 
 2687         if (hwndDlg && bGuiMode) InitProgressBar (GetVolumeDataAreaSize (bHidden, nVolumeSize), 0, FALSE, FALSE, FALSE, TRUE);
 2688 
 2689         nStatus = TCFormatVolume (volParams);
 2690     }
 2691 
 2692     // Allow the OS to enter Sleep mode when idle
 2693     SetThreadExecutionState (ES_CONTINUOUS);
 2694 
 2695     if (nStatus == ERR_OUTOFMEMORY)
 2696     {
 2697         AbortProcess ("OUTOFMEMORY");
 2698     }
 2699 
 2700     if (bInPlaceEncNonSys
 2701         && nStatus == ERR_USER_ABORT
 2702         && NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED)
 2703     {
 2704         // Ignore user abort if non-system in-place encryption/decryption successfully finished
 2705         nStatus = ERR_SUCCESS;
 2706     }
 2707 
 2708 
 2709     dwWin32FormatError = GetLastError ();
 2710 
 2711     if (bHiddenVolHost && (!bGuiMode || !bVolTransformThreadCancel) && nStatus == 0)
 2712     {
 2713         /* Auto mount the newly created hidden volume host */
 2714         switch (MountHiddenVolHost (hwndDlg, szDiskFile, &hiddenVolHostDriveNo, &volumePassword, hash_algo, volumePim, FALSE))
 2715         {
 2716         case ERR_NO_FREE_DRIVES:
 2717             if (!Silent) MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVE_FOR_OUTER_VOL"), lpszTitle, ICON_HAND);
 2718             if (bGuiMode) bVolTransformThreadCancel = TRUE;
 2719             break;
 2720         case ERR_VOL_MOUNT_FAILED:
 2721         case ERR_PASSWORD_WRONG:
 2722             if (!Silent) MessageBoxW (hwndDlg, GetString ("CANT_MOUNT_OUTER_VOL"), lpszTitle, ICON_HAND);
 2723             if (bGuiMode) bVolTransformThreadCancel = TRUE;
 2724             break;
 2725         }
 2726     }
 2727 
 2728     SetLastError (dwWin32FormatError);
 2729 
 2730     if ((bVolTransformThreadCancel || nStatus == ERR_USER_ABORT)
 2731         && !(bInPlaceEncNonSys && NonSysInplaceEncStatus == NONSYS_INPLACE_ENC_STATUS_FINISHED))    // Ignore user abort if non-system in-place encryption/decryption successfully finished.
 2732     {
 2733         if (!bDevice && !(bHiddenVol && !bHiddenVolHost))   // If we're not creating a hidden volume and if it's a file container
 2734         {
 2735             _wremove (szDiskFile);      // Delete the container
 2736         }
 2737 
 2738         goto cancel;
 2739     }
 2740 
 2741     if (nStatus != ERR_USER_ABORT)
 2742     {
 2743         if (nStatus != 0)
 2744         {
 2745             /* An error occurred */
 2746 
 2747             wchar_t szMsg[8192];
 2748 
 2749             handleError (hwndDlg, nStatus, SRC_POS);
 2750 
 2751             if (bInPlaceEncNonSys)
 2752             {
 2753                 if (bInPlaceEncNonSysResumed)
 2754                 {
 2755                     SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PAUSED);
 2756                     Error ("INPLACE_ENC_GENERIC_ERR_RESUME", hwndDlg);
 2757                 }
 2758                 else
 2759                 {
 2760                     SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_ERROR);
 2761 
 2762                     if (bInPlaceDecNonSys)
 2763                         Error ("INPLACE_DEC_GENERIC_ERR", hwndDlg);
 2764                     else
 2765                         ShowInPlaceEncErrMsgWAltSteps (hwndDlg, "INPLACE_ENC_GENERIC_ERR_ALT_STEPS", TRUE);
 2766                 }
 2767             }
 2768             else if (!Silent && !(bHiddenVolHost && hiddenVolHostDriveNo < 0))  // If the error was not that the hidden volume host could not be mounted (this error has already been reported to the user)
 2769             {
 2770                 StringCbPrintfW (szMsg, sizeof(szMsg), GetString ("CREATE_FAILED"), szDiskFile);
 2771                 MessageBoxW (hwndDlg, szMsg, lpszTitle, ICON_HAND);
 2772             }
 2773 
 2774             if (!bDevice && !(bHiddenVol && !bHiddenVolHost))   // If we're not creating a hidden volume and if it's a file container
 2775             {
 2776                 _wremove (szDiskFile);      // Delete the container
 2777             }
 2778 
 2779             goto cancel;
 2780         }
 2781         else
 2782         {
 2783             /* Volume successfully created */
 2784 
 2785             RestoreDefaultKeyFilesParam ();
 2786 
 2787             PimEnable = FALSE;
 2788 
 2789             bOperationSuccess = TRUE;
 2790 
 2791             if (bDevice && !bInPlaceEncNonSys)
 2792             {
 2793                 // Handle assigned drive letter (if any)
 2794 
 2795                 HandleOldAssignedDriveLetter ();
 2796             }
 2797 
 2798             if (!bHiddenVolHost)
 2799             {
 2800                 if (bHiddenVol)
 2801                 {
 2802                     bHiddenVolFinished = TRUE;
 2803 
 2804                     if (!bHiddenOS)
 2805                         Warning ("HIDVOL_FORMAT_FINISHED_HELP", hwndDlg);
 2806                 }
 2807                 else if (bInPlaceEncNonSys)
 2808                 {
 2809                     if (!bInPlaceDecNonSys)
 2810                     {
 2811                         Warning ("NONSYS_INPLACE_ENC_FINISHED_INFO", hwndDlg);
 2812 
 2813                         HandleOldAssignedDriveLetter ();
 2814                     }
 2815                     else
 2816                     {
 2817                         // NOP - Final steps for in-place decryption are handled with the TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED message.
 2818                     }
 2819                 }
 2820                 else
 2821                 {
 2822                     Info("FORMAT_FINISHED_INFO", hwndDlg);
 2823 
 2824                     if (bSparseFileSwitch && quickFormat)
 2825                         Warning("SPARSE_FILE_SIZE_NOTE", hwndDlg);
 2826                 }
 2827             }
 2828             else
 2829             {
 2830                 /* We've just created an outer volume (to host a hidden volume within) */
 2831 
 2832                 bHiddenVolHost = FALSE;
 2833                 bHiddenVolFinished = FALSE;
 2834                 nHiddenVolHostSize = nVolumeSize;
 2835 
 2836                 // Clear the outer volume password
 2837                 burn(&szVerify[0], sizeof (szVerify));
 2838                 burn(&szRawPassword[0], sizeof (szRawPassword));
 2839 
 2840                 if (!Silent) MessageBeep (MB_OK);
 2841             }
 2842 
 2843             if (!bInPlaceEncNonSys && hwndDlg && bGuiMode)
 2844                 SetTimer (hwndDlg, TIMER_ID_RANDVIEW, TIMER_INTERVAL_RANDVIEW, NULL);
 2845 
 2846 
 2847             // volParams is ensured to be non NULL at this stage
 2848             burn ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS));
 2849             VirtualUnlock ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS));
 2850             free ((LPVOID) volParams);
 2851             volParams = NULL;
 2852 
 2853             if (bGuiMode)
 2854             {
 2855                 bVolTransformThreadRunning = FALSE;
 2856                 bVolTransformThreadCancel = FALSE;
 2857             }
 2858 
 2859             if (hwndDlg && bGuiMode) PostMessage (hwndDlg, bInPlaceEncNonSys ? TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED : TC_APPMSG_FORMAT_FINISHED, 0, 0);
 2860 
 2861             LastDialogId = "FORMAT_FINISHED";
 2862             if (bGuiMode) _endthread ();
 2863         }
 2864     }
 2865 
 2866 cancel:
 2867 
 2868     LastDialogId = (bInPlaceEncNonSys ? "NONSYS_INPLACE_ENC_CANCELED" : "FORMAT_CANCELED");
 2869 
 2870     if (!bInPlaceEncNonSys && hwndDlg && bGuiMode)
 2871         SetTimer (hwndDlg, TIMER_ID_RANDVIEW, TIMER_INTERVAL_RANDVIEW, NULL);
 2872 
 2873     if (volParams != NULL)
 2874     {
 2875         burn ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS));
 2876         VirtualUnlock ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS));
 2877         free ((LPVOID) volParams);
 2878         volParams = NULL;
 2879     }
 2880 
 2881     if (bGuiMode)
 2882     {
 2883         bVolTransformThreadRunning = FALSE;
 2884         bVolTransformThreadCancel = FALSE;
 2885     }
 2886 
 2887     // Allow the OS to enter Sleep mode when idle
 2888     SetThreadExecutionState (ES_CONTINUOUS);
 2889 
 2890     if (hwndDlg) PostMessage (hwndDlg, TC_APPMSG_VOL_TRANSFORM_THREAD_ENDED, 0, 0);
 2891 
 2892     if (bHiddenVolHost && hiddenVolHostDriveNo < -1 && !bVolTransformThreadCancel)  // If hidden volume host could not be mounted
 2893         AbortProcessSilent ();
 2894 
 2895     if (bGuiMode) _endthread ();
 2896 }
 2897 
 2898 static void LoadPage (HWND hwndDlg, int nPageNo)
 2899 {
 2900     RECT rD, rW;
 2901 
 2902     nLastPageNo = nCurPageNo;
 2903 
 2904     if (hCurPage != NULL)
 2905     {
 2906         // WARNING: nCurPageNo must be set to a non-existent ID here before wiping the password fields below in
 2907         // this function, etc. Otherwise, such actions (SetWindowText) would invoke the EN_CHANGE handlers, which
 2908         // would, if keyfiles were applied, e.g. use strlen() on a buffer full of random data, in most cases
 2909         // not null-terminated.
 2910         nCurPageNo = -1;
 2911 
 2912 
 2913         // Place here any actions that need to be performed at the latest possible time when leaving a wizard page
 2914         // (i.e. right before "destroying" the page). Also, code that needs to be executed both on IDC_NEXT and
 2915         // on IDC_PREV can be placed here so as to avoid code doubling.
 2916 
 2917         switch (nLastPageNo)
 2918         {
 2919         case PASSWORD_PAGE:
 2920             {
 2921                 wchar_t tmp[MAX_PASSWORD+1];
 2922 
 2923                 // Attempt to wipe passwords stored in the input field buffers. This is performed here (and
 2924                 // not in the IDC_PREV or IDC_NEXT sections) in order to prevent certain race conditions
 2925                 // when keyfiles are used.
 2926                 wmemset (tmp, 'X', MAX_PASSWORD);
 2927                 tmp [MAX_PASSWORD] = 0;
 2928                 SetWindowText (hPasswordInputField, tmp);
 2929                 SetWindowText (hVerifyPasswordInputField, tmp);
 2930             }
 2931             break;
 2932         }
 2933 
 2934         DestroyWindow (hCurPage);
 2935         hCurPage = NULL;
 2936     }
 2937 
 2938     // This prevents the mouse pointer from remaining as the "hand" cursor when the user presses Enter
 2939     // while hovering over a hyperlink.
 2940     bHyperLinkBeingTracked = FALSE;
 2941     NormalCursor();
 2942 
 2943     GetWindowRect (GetDlgItem (hwndDlg, IDC_POS_BOX), &rW);
 2944 
 2945 
 2946     nCurPageNo = nPageNo;
 2947 
 2948 
 2949     switch (nPageNo)
 2950     {
 2951     case INTRO_PAGE:
 2952         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INTRO_PAGE_DLG), hwndDlg,
 2953                      (DLGPROC) PageDialogProc);
 2954         break;
 2955 
 2956     case SYSENC_TYPE_PAGE:
 2957         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_TYPE_PAGE_DLG), hwndDlg,
 2958                      (DLGPROC) PageDialogProc);
 2959         break;
 2960 
 2961     case SYSENC_HIDDEN_OS_REQ_CHECK_PAGE:
 2962         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_HIDDEN_OS_REQ_CHECK_PAGE_DLG), hwndDlg,
 2963                      (DLGPROC) PageDialogProc);
 2964         break;
 2965 
 2966     case SYSENC_SPAN_PAGE:
 2967         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_SPAN_PAGE_DLG), hwndDlg,
 2968                      (DLGPROC) PageDialogProc);
 2969         break;
 2970 
 2971     case SYSENC_PRE_DRIVE_ANALYSIS_PAGE:
 2972         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_UNIVERSAL_DUAL_CHOICE_PAGE_DLG), hwndDlg,
 2973                      (DLGPROC) PageDialogProc);
 2974         break;
 2975 
 2976     case SYSENC_DRIVE_ANALYSIS_PAGE:
 2977         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_DRIVE_ANALYSIS_PAGE_DLG), hwndDlg,
 2978                      (DLGPROC) PageDialogProc);
 2979         break;
 2980 
 2981     case SYSENC_MULTI_BOOT_MODE_PAGE:
 2982         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_MULTI_BOOT_MODE_PAGE_DLG), hwndDlg,
 2983                      (DLGPROC) PageDialogProc);
 2984         break;
 2985 
 2986     case SYSENC_MULTI_BOOT_SYS_EQ_BOOT_PAGE:
 2987     case SYSENC_MULTI_BOOT_NBR_SYS_DRIVES_PAGE:
 2988     case SYSENC_MULTI_BOOT_ADJACENT_SYS_PAGE:
 2989     case SYSENC_MULTI_BOOT_NONWIN_BOOT_LOADER_PAGE:
 2990         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_UNIVERSAL_DUAL_CHOICE_PAGE_DLG), hwndDlg,
 2991                      (DLGPROC) PageDialogProc);
 2992         break;
 2993 
 2994     case SYSENC_MULTI_BOOT_OUTCOME_PAGE:
 2995         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 2996                      (DLGPROC) PageDialogProc);
 2997         break;
 2998 
 2999     case VOLUME_TYPE_PAGE:
 3000         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_VOLUME_TYPE_PAGE_DLG), hwndDlg,
 3001                      (DLGPROC) PageDialogProc);
 3002         break;
 3003 
 3004     case HIDDEN_VOL_WIZARD_MODE_PAGE:
 3005         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_HIDDEN_VOL_WIZARD_MODE_PAGE_DLG), hwndDlg,
 3006                      (DLGPROC) PageDialogProc);
 3007         break;
 3008 
 3009     case VOLUME_LOCATION_PAGE:
 3010         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_VOLUME_LOCATION_PAGE_DLG), hwndDlg,
 3011                      (DLGPROC) PageDialogProc);
 3012 
 3013         EnableWindow (GetDlgItem(hCurPage, IDC_NO_HISTORY), !bHistoryCmdLine);
 3014 
 3015         EnableWindow (GetDlgItem (hwndDlg, IDC_NEXT),
 3016             GetWindowTextLength (GetDlgItem (hCurPage, IDC_COMBO_BOX)) > 0);
 3017 
 3018         break;
 3019 
 3020     case DEVICE_TRANSFORM_MODE_PAGE:
 3021         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_DEVICE_TRANSFORM_MODE_DLG), hwndDlg,
 3022                      (DLGPROC) PageDialogProc);
 3023         break;
 3024     case HIDDEN_VOL_HOST_PRE_CIPHER_PAGE:
 3025         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 3026                      (DLGPROC) PageDialogProc);
 3027         break;
 3028     case HIDDEN_VOL_PRE_CIPHER_PAGE:
 3029         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 3030                      (DLGPROC) PageDialogProc);
 3031         break;
 3032     case CIPHER_PAGE:
 3033         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_CIPHER_PAGE_DLG), hwndDlg,
 3034                      (DLGPROC) PageDialogProc);
 3035         break;
 3036     case SIZE_PAGE:
 3037         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SIZE_PAGE_DLG), hwndDlg,
 3038                      (DLGPROC) PageDialogProc);
 3039         break;
 3040     case HIDDEN_VOL_HOST_PASSWORD_PAGE:
 3041         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_PASSWORD_ENTRY_PAGE_DLG), hwndDlg,
 3042                      (DLGPROC) PageDialogProc);
 3043         break;
 3044     case PASSWORD_PAGE:
 3045         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_PASSWORD_PAGE_DLG), hwndDlg,
 3046                      (DLGPROC) PageDialogProc);
 3047         break;
 3048     case PIM_PAGE:
 3049         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_PIM_PAGE_DLG), hwndDlg,
 3050                      (DLGPROC) PageDialogProc);
 3051         break;
 3052     case FILESYS_PAGE:
 3053         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_UNIVERSAL_DUAL_CHOICE_PAGE_DLG), hwndDlg,
 3054                      (DLGPROC) PageDialogProc);
 3055         break;
 3056     case SYSENC_COLLECTING_RANDOM_DATA_PAGE:
 3057     case NONSYS_INPLACE_ENC_RAND_DATA_PAGE:
 3058         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_COLLECTING_RANDOM_DATA_DLG), hwndDlg,
 3059                      (DLGPROC) PageDialogProc);
 3060         break;
 3061     case SYSENC_KEYS_GEN_PAGE:
 3062         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_KEYS_GEN_PAGE_DLG), hwndDlg,
 3063                      (DLGPROC) PageDialogProc);
 3064         break;
 3065     case SYSENC_RESCUE_DISK_CREATION_PAGE:
 3066         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_RESCUE_DISK_CREATION_DLG), hwndDlg,
 3067                      (DLGPROC) PageDialogProc);
 3068         break;
 3069     case SYSENC_RESCUE_DISK_BURN_PAGE:
 3070         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_RESCUE_DISK_BURN_PAGE_DLG), hwndDlg,
 3071             (DLGPROC) PageDialogProc);
 3072         break;
 3073     case SYSENC_RESCUE_DISK_VERIFIED_PAGE:
 3074         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 3075                      (DLGPROC) PageDialogProc);
 3076         break;
 3077     case SYSENC_WIPE_MODE_PAGE:
 3078     case NONSYS_INPLACE_ENC_WIPE_MODE_PAGE:
 3079         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_SYSENC_WIPE_MODE_PAGE_DLG), hwndDlg,
 3080             (DLGPROC) PageDialogProc);
 3081         break;
 3082     case SYSENC_PRETEST_INFO_PAGE:
 3083         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 3084                      (DLGPROC) PageDialogProc);
 3085         break;
 3086     case SYSENC_PRETEST_RESULT_PAGE:
 3087         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 3088                      (DLGPROC) PageDialogProc);
 3089         break;
 3090     case SYSENC_ENCRYPTION_PAGE:
 3091         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INPLACE_ENCRYPTION_PAGE_DLG), hwndDlg,
 3092             (DLGPROC) PageDialogProc);
 3093         break;
 3094 
 3095     case NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE:
 3096         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_PASSWORD_ENTRY_PAGE_DLG), hwndDlg,
 3097             (DLGPROC) PageDialogProc);
 3098         break;
 3099 
 3100     case NONSYS_INPLACE_ENC_RESUME_PARTITION_SEL_PAGE:
 3101         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_EXPANDED_LIST_SELECT_PAGE_DLG), hwndDlg,
 3102             (DLGPROC) PageDialogProc);
 3103         break;
 3104 
 3105     case NONSYS_INPLACE_ENC_TRANSFORM_PAGE:
 3106         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INPLACE_ENCRYPTION_PAGE_DLG), hwndDlg,
 3107             (DLGPROC) PageDialogProc);
 3108         break;
 3109 
 3110     case NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE:
 3111         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg,
 3112                      (DLGPROC) PageDialogProc);
 3113         break;
 3114 
 3115     case NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE:
 3116         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_DRIVE_LETTER_SELECTION_PAGE), hwndDlg,
 3117             (DLGPROC) PageDialogProc);
 3118         break;
 3119 
 3120     case FORMAT_PAGE:
 3121         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_FORMAT_PAGE_DLG), hwndDlg,
 3122                      (DLGPROC) PageDialogProc);
 3123         break;
 3124     case FORMAT_FINISHED_PAGE:
 3125         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW ((bHiddenVol && !bHiddenVolHost && !bHiddenVolFinished) ? IDD_HIDVOL_HOST_FILL_PAGE_DLG : IDD_INFO_PAGE_DLG), hwndDlg,
 3126                      (DLGPROC) PageDialogProc);
 3127         break;
 3128 
 3129     case SYSENC_HIDDEN_OS_INITIAL_INFO_PAGE:
 3130         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg, (DLGPROC) PageDialogProc);
 3131         break;
 3132 
 3133     case SYSENC_HIDDEN_OS_WIPE_INFO_PAGE:
 3134         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INFO_PAGE_DLG), hwndDlg, (DLGPROC) PageDialogProc);
 3135         break;
 3136 
 3137     case DEVICE_WIPE_MODE_PAGE:
 3138         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_DEVICE_WIPE_MODE_PAGE_DLG), hwndDlg, (DLGPROC) PageDialogProc);
 3139         break;
 3140 
 3141     case DEVICE_WIPE_PAGE:
 3142         hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_DEVICE_WIPE_PAGE_DLG), hwndDlg, (DLGPROC) PageDialogProc);
 3143         break;
 3144     }
 3145 
 3146     rD.left = 162;
 3147     rD.top = 25;
 3148     rD.right = 0;
 3149     rD.bottom = 0;
 3150     MapDialogRect (hwndDlg, &rD);
 3151 
 3152     if (hCurPage != NULL)
 3153     {
 3154         MoveWindow (hCurPage, rD.left, rD.top, rW.right - rW.left, rW.bottom - rW.top, TRUE);
 3155         ShowWindow (hCurPage, SW_SHOWNORMAL);
 3156 
 3157         // Place here any message boxes that need to be displayed as soon as a new page is displayed. This
 3158         // ensures that the page is fully rendered (otherwise it would remain blank, until the message box
 3159         // is closed).
 3160         switch (nPageNo)
 3161         {
 3162         case PASSWORD_PAGE:
 3163 
 3164             CheckCapsLock (hwndDlg, FALSE);
 3165 
 3166             if (CreatingHiddenSysVol())
 3167                 Warning ("PASSWORD_HIDDEN_OS_NOTE", MainDlg);
 3168 
 3169             break;
 3170 
 3171         case CIPHER_PAGE:
 3172 
 3173             if (CreatingHiddenSysVol())
 3174                 Warning ("HIDDEN_OS_PRE_CIPHER_WARNING", MainDlg);
 3175 
 3176             break;
 3177         }
 3178     }
 3179 }
 3180 
 3181 
 3182 __int64 PrintFreeSpace (HWND hwndTextBox, wchar_t *lpszDrive, PLARGE_INTEGER lDiskFree)
 3183 {
 3184     char *nResourceString;
 3185     __int64 nMultiplier;
 3186     wchar_t szTmp2[256];
 3187 
 3188     if (lDiskFree->QuadPart < BYTES_PER_KB)
 3189         nMultiplier = 1;
 3190     else if (lDiskFree->QuadPart < BYTES_PER_MB)
 3191         nMultiplier = BYTES_PER_KB;
 3192     else if (lDiskFree->QuadPart < BYTES_PER_GB)
 3193         nMultiplier = BYTES_PER_MB;
 3194     else if (lDiskFree->QuadPart < BYTES_PER_TB)
 3195         nMultiplier = BYTES_PER_GB;
 3196     else
 3197         nMultiplier = BYTES_PER_TB;
 3198 
 3199     if (nMultiplier == 1)
 3200     {
 3201         if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3202             nResourceString = "MAX_HIDVOL_SIZE_BYTES";
 3203         else if (bDevice)
 3204             nResourceString = "DEVICE_FREE_BYTES";
 3205         else
 3206             nResourceString = "DISK_FREE_BYTES";
 3207     }
 3208     else if (nMultiplier == BYTES_PER_KB)
 3209     {
 3210         if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3211             nResourceString = "MAX_HIDVOL_SIZE_KB";
 3212         else if (bDevice)
 3213             nResourceString = "DEVICE_FREE_KB";
 3214         else
 3215             nResourceString = "DISK_FREE_KB";
 3216     }
 3217     else if (nMultiplier == BYTES_PER_MB)
 3218     {
 3219         if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3220             nResourceString = "MAX_HIDVOL_SIZE_MB";
 3221         else if (bDevice)
 3222             nResourceString = "DEVICE_FREE_MB";
 3223         else
 3224             nResourceString = "DISK_FREE_MB";
 3225     }
 3226     else if (nMultiplier == BYTES_PER_GB)
 3227     {
 3228         if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3229             nResourceString = "MAX_HIDVOL_SIZE_GB";
 3230         else if (bDevice)
 3231             nResourceString = "DEVICE_FREE_GB";
 3232         else
 3233             nResourceString = "DISK_FREE_GB";
 3234     }
 3235     else
 3236     {
 3237         if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3238             nResourceString = "MAX_HIDVOL_SIZE_TB";
 3239         else if (bDevice)
 3240             nResourceString = "DEVICE_FREE_TB";
 3241         else
 3242             nResourceString = "DISK_FREE_TB";
 3243     }
 3244 
 3245     if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3246     {
 3247         StringCbPrintfW (szTmp2, sizeof szTmp2, GetString (nResourceString), ((double) lDiskFree->QuadPart) / nMultiplier);
 3248         SetWindowTextW (GetDlgItem (hwndTextBox, IDC_SIZEBOX), szTmp2);
 3249     }
 3250     else if (lpszDrive)
 3251         StringCbPrintfW (szTmp2, sizeof szTmp2, GetString (nResourceString), lpszDrive, ((double) lDiskFree->QuadPart) / nMultiplier);
 3252     else
 3253         szTmp2 [0] = 0;
 3254 
 3255     SetWindowTextW (hwndTextBox, szTmp2);
 3256 
 3257     if (lDiskFree->QuadPart % (__int64) BYTES_PER_MB != 0)
 3258         nMultiplier = BYTES_PER_KB;
 3259 
 3260     return nMultiplier;
 3261 }
 3262 
 3263 void DisplaySizingErrorText (HWND hwndTextBox)
 3264 {
 3265     wchar_t szTmp[1024];
 3266 
 3267     if (translateWin32Error (szTmp, sizeof (szTmp) / sizeof(szTmp[0])))
 3268     {
 3269         wchar_t szTmp2[1024];
 3270         StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s\n%s", GetString ("CANNOT_CALC_SPACE"), szTmp);
 3271         SetWindowTextW (hwndTextBox, szTmp2);
 3272     }
 3273     else
 3274     {
 3275         SetWindowText (hwndTextBox, L"");
 3276     }
 3277 }
 3278 
 3279 void EnableDisableFileNext (HWND hComboBox, HWND hMainButton)
 3280 {
 3281     int nIndex = (int) SendMessage (hComboBox, CB_GETCURSEL, 0, 0);
 3282     if (bHistory && nIndex == CB_ERR)
 3283     {
 3284         EnableWindow (hMainButton, FALSE);
 3285         SetFocus (hComboBox);
 3286     }
 3287     else
 3288     {
 3289         EnableWindow (hMainButton, TRUE);
 3290         SetFocus (hMainButton);
 3291     }
 3292 }
 3293 
 3294 // Returns TRUE if the file is a sparse file. If it's not a sparse file or in case of any error, returns FALSE.
 3295 BOOL IsSparseFile (HWND hwndDlg)
 3296 {
 3297     HANDLE hFile;
 3298     BY_HANDLE_FILE_INFORMATION bhFileInfo;
 3299 
 3300     FILETIME ftLastAccessTime;
 3301     BOOL bTimeStampValid = FALSE;
 3302 
 3303     BOOL retCode = FALSE;
 3304 
 3305     hFile = CreateFile (szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
 3306 
 3307     if (hFile == INVALID_HANDLE_VALUE)
 3308     {
 3309         MessageBoxW (hwndDlg, GetString ("CANT_ACCESS_VOL"), lpszTitle, ICON_HAND);
 3310         return FALSE;
 3311     }
 3312 
 3313     if (bPreserveTimestamp)
 3314     {
 3315         if (GetFileTime (hFile, NULL, &ftLastAccessTime, NULL) == 0)
 3316             bTimeStampValid = FALSE;
 3317         else
 3318             bTimeStampValid = TRUE;
 3319     }
 3320 
 3321     bhFileInfo.dwFileAttributes = 0;
 3322 
 3323     GetFileInformationByHandle(hFile, &bhFileInfo);
 3324 
 3325     retCode = bhFileInfo.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE;
 3326 
 3327     if (bTimeStampValid)
 3328         SetFileTime (hFile, NULL, &ftLastAccessTime, NULL);
 3329 
 3330     CloseHandle (hFile);
 3331     return retCode;
 3332 }
 3333 
 3334 
 3335 // Note: GetFileVolSize is not to be used for devices (only for file-hosted volumes)
 3336 BOOL GetFileVolSize (HWND hwndDlg, unsigned __int64 *size)
 3337 {
 3338     LARGE_INTEGER fileSize;
 3339     HANDLE hFile;
 3340 
 3341     FILETIME ftLastAccessTime;
 3342     BOOL bTimeStampValid = FALSE;
 3343 
 3344     hFile = CreateFile (szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
 3345 
 3346     if (hFile == INVALID_HANDLE_VALUE)
 3347     {
 3348         MessageBoxW (hwndDlg, GetString ("CANT_ACCESS_VOL"), lpszTitle, ICON_HAND);
 3349         return FALSE;
 3350     }
 3351 
 3352     if (bPreserveTimestamp)
 3353     {
 3354         if (GetFileTime (hFile, NULL, &ftLastAccessTime, NULL) == 0)
 3355             bTimeStampValid = FALSE;
 3356         else
 3357             bTimeStampValid = TRUE;
 3358     }
 3359 
 3360     if (GetFileSizeEx(hFile, &fileSize) == 0)
 3361     {
 3362         MessageBoxW (hwndDlg, GetString ("CANT_GET_VOLSIZE"), lpszTitle, ICON_HAND);
 3363 
 3364         if (bTimeStampValid)
 3365             SetFileTime (hFile, NULL, &ftLastAccessTime, NULL);
 3366 
 3367         CloseHandle (hFile);
 3368         return FALSE;
 3369     }
 3370 
 3371     if (bTimeStampValid)
 3372         SetFileTime (hFile, NULL, &ftLastAccessTime, NULL);
 3373 
 3374     CloseHandle (hFile);
 3375     *size = fileSize.QuadPart;
 3376     return TRUE;
 3377 }
 3378 
 3379 
 3380 BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display, LONGLONG *pFreeSpaceValue, BOOL* pbIsSparceFilesSupported)
 3381 {
 3382     if (pFreeSpaceValue)
 3383         *pFreeSpaceValue = 0;
 3384 
 3385     if (pbIsSparceFilesSupported)
 3386         *pbIsSparceFilesSupported = FALSE;
 3387 
 3388     if (bHiddenVol && !bHiddenVolHost)  // If it's a hidden volume
 3389     {
 3390         LARGE_INTEGER lDiskFree;
 3391 
 3392         lDiskFree.QuadPart = nMaximumHiddenVolSize;
 3393 
 3394         if (pFreeSpaceValue)
 3395             *pFreeSpaceValue = nMaximumHiddenVolSize;
 3396 
 3397         if (display)
 3398             PrintFreeSpace (hwndTextBox, NULL, &lDiskFree);
 3399 
 3400         return TRUE;
 3401     }
 3402     else if (bDevice == FALSE)
 3403     {
 3404         wchar_t root[TC_MAX_PATH];
 3405         DWORD fileSystemFlags = 0;
 3406         ULARGE_INTEGER free;
 3407 
 3408         if (!GetVolumePathName (szFileName, root, ARRAYSIZE (root)))
 3409         {
 3410             handleWin32Error (hwndDlg, SRC_POS);
 3411             return FALSE;
 3412         }
 3413 
 3414         if (    pbIsSparceFilesSupported
 3415             &&  GetVolumeInformation (root, NULL, 0, NULL, NULL, &fileSystemFlags, NULL, 0)
 3416             &&  (fileSystemFlags & FILE_SUPPORTS_SPARSE_FILES)
 3417             )
 3418         {
 3419             *pbIsSparceFilesSupported = TRUE;
 3420         }
 3421 
 3422         if (!GetDiskFreeSpaceEx (root, &free, 0, 0))
 3423         {
 3424             if (display)
 3425                 DisplaySizingErrorText (hwndTextBox);
 3426 
 3427             return FALSE;
 3428         }
 3429         else
 3430         {
 3431             LARGE_INTEGER lDiskFree;
 3432             lDiskFree.QuadPart = free.QuadPart;
 3433 
 3434             if (pFreeSpaceValue)
 3435                 *pFreeSpaceValue = free.QuadPart;
 3436 
 3437             if (display)
 3438                 PrintFreeSpace (hwndTextBox, root, &lDiskFree);
 3439 
 3440             return TRUE;
 3441         }
 3442     }
 3443     else
 3444     {
 3445         DISK_GEOMETRY_EX driveInfo;
 3446         PARTITION_INFORMATION diskInfo;
 3447         BOOL piValid = FALSE;
 3448         BOOL gValid = FALSE;
 3449 
 3450         // Query partition size
 3451         piValid = GetPartitionInfo (szDiskFile, &diskInfo);
 3452         gValid = GetDriveGeometry (szDiskFile, &driveInfo);
 3453 
 3454         if (!piValid && !gValid)
 3455         {
 3456             if (display)
 3457                 DisplaySizingErrorText (hwndTextBox);
 3458 
 3459             return FALSE;
 3460         }
 3461 
 3462         DWORD sectorSize = GetFormatSectorSize();
 3463 
 3464         if (sectorSize < TC_MIN_VOLUME_SECTOR_SIZE
 3465             || sectorSize > TC_MAX_VOLUME_SECTOR_SIZE
 3466             || sectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
 3467         {
 3468             Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg);
 3469             return FALSE;
 3470         }
 3471 
 3472         if (piValid)
 3473         {
 3474             nVolumeSize = diskInfo.PartitionLength.QuadPart;
 3475 
 3476             if(display)
 3477                 nMultiplier = PrintFreeSpace (hwndTextBox, szDiskFile, &diskInfo.PartitionLength);
 3478 
 3479             nUIVolumeSize = diskInfo.PartitionLength.QuadPart / nMultiplier;
 3480 
 3481             if (nVolumeSize == 0)
 3482             {
 3483                 if (display)
 3484                     SetWindowTextW (hwndTextBox, GetString ("EXT_PARTITION"));
 3485 
 3486                 return FALSE;
 3487             }
 3488         }
 3489         else
 3490         {
 3491             LARGE_INTEGER lDiskFree;
 3492 
 3493             // Drive geometry info is used only when GetPartitionInfo() fails
 3494             lDiskFree.QuadPart = driveInfo.DiskSize.QuadPart;
 3495 
 3496             nVolumeSize = lDiskFree.QuadPart;
 3497 
 3498             if (pFreeSpaceValue)
 3499                 *pFreeSpaceValue = lDiskFree.QuadPart;
 3500 
 3501             if (display)
 3502                 nMultiplier = PrintFreeSpace (hwndTextBox, szDiskFile, &lDiskFree);
 3503 
 3504             nUIVolumeSize = lDiskFree.QuadPart / nMultiplier;
 3505         }
 3506 
 3507         return TRUE;
 3508     }
 3509 }
 3510 
 3511 
 3512 static BOOL FinalPreTransformPrompts (void)
 3513 {
 3514     int x;
 3515     wchar_t szTmp[4096];
 3516     int driveNo;
 3517     WCHAR deviceName[MAX_PATH];
 3518 
 3519     StringCbCopyW (deviceName, sizeof(deviceName), szFileName);
 3520 
 3521     driveNo = GetDiskDeviceDriveLetter (deviceName);
 3522 
 3523     if (!bForceOperation && !(bHiddenVol && !bHiddenVolHost))   // Do not ask for permission to overwrite an existing volume if we're creating a hidden volume within it
 3524     {
 3525         wchar_t drive[128];
 3526         wchar_t volumeLabel[128];
 3527         wchar_t *type;
 3528         BOOL bTmpIsPartition = FALSE;
 3529 
 3530         type = GetPathType (szFileName, !bInPlaceEncNonSys, &bTmpIsPartition);
 3531 
 3532         if (driveNo != -1)
 3533         {
 3534             if (!GetDriveLabel (driveNo, volumeLabel, sizeof (volumeLabel)))
 3535                 volumeLabel[0] = 0;
 3536 
 3537             StringCbPrintfW (drive, sizeof (drive), volumeLabel[0] ? L" (%hc: '%s')" : L" (%hc:%s)", 'A' + driveNo, volumeLabel[0] ? volumeLabel : L"");
 3538         }
 3539         else
 3540         {
 3541             drive[0] = 0;
 3542             volumeLabel[0] = 0;
 3543         }
 3544 
 3545         if (bHiddenOS && bHiddenVolHost)
 3546             StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("OVERWRITEPROMPT_DEVICE_HIDDEN_OS_PARTITION"), szFileName, drive);
 3547         else
 3548             StringCbPrintfW (szTmp, sizeof(szTmp), GetString (bInPlaceEncNonSys ? (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_CONFIRM" : "NONSYS_INPLACE_ENC_CONFIRM") : "OVERWRITEPROMPT_DEVICE"), type, szFileName, drive);
 3549 
 3550         if (bInPlaceEncNonSys)
 3551             x = AskWarnYesNoString (szTmp, MainDlg);
 3552         else
 3553             x = AskWarnNoYesString (szTmp, MainDlg);
 3554 
 3555         if (x != IDYES)
 3556             return FALSE;
 3557 
 3558 
 3559         if (driveNo != -1 && bTmpIsPartition && !bInPlaceEncNonSys)
 3560         {
 3561             float percentFreeSpace = 100.0;
 3562             __int64 occupiedBytes = 0;
 3563 
 3564             // Do a second check. If we find that the partition contains more than 1GB of data or more than 12%
 3565             // of its space is occupied, we will display an extra warning, however, this time it won't be a Yes/No
 3566             // dialog box (because users often ignore such dialog boxes).
 3567 
 3568             if (GetStatsFreeSpaceOnPartition (szFileName, &percentFreeSpace, &occupiedBytes, TRUE) != -1)
 3569             {
 3570                 if (occupiedBytes > BYTES_PER_GB && percentFreeSpace < 99.99    // "percentFreeSpace < 99.99" is needed because an NTFS filesystem larger than several terabytes can have more than 1GB of data in use, even if there are no files stored on it.
 3571                     || percentFreeSpace < 88)       // A 24-MB NTFS filesystem has 11.5% of space in use even if there are no files stored on it.
 3572                 {
 3573                     wchar_t tmpMcMsg [8000];
 3574                     wchar_t tmpMcOption1 [500];
 3575                     wchar_t tmpMcOptionCancel [50];
 3576 
 3577                     StringCbCopyW (tmpMcMsg, sizeof(tmpMcMsg), GetString("OVERWRITEPROMPT_DEVICE_SECOND_WARNING_LOTS_OF_DATA"));
 3578                     StringCbCopyW (tmpMcOption1, sizeof(tmpMcOption1), GetString("ERASE_FILES_BY_CREATING_VOLUME"));
 3579                     StringCbCopyW (tmpMcOptionCancel, sizeof(tmpMcOptionCancel), GetString("CANCEL"));
 3580 
 3581                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), L"\n\n");
 3582                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), GetString("DRIVE_LETTER_ITEM"));
 3583                     StringCbPrintfW (szTmp, sizeof (szTmp), L"%hc:", 'A' + driveNo);
 3584                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), szTmp);
 3585 
 3586                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), L"\n");
 3587                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), GetString("LABEL_ITEM"));
 3588                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), volumeLabel[0] != 0 ? volumeLabel : GetString("NOT_APPLICABLE_OR_NOT_AVAILABLE"));
 3589 
 3590                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), L"\n");
 3591                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), GetString("SIZE_ITEM"));
 3592                     GetSizeString (nVolumeSize, szTmp, sizeof(szTmp));
 3593                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), szTmp);
 3594 
 3595                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), L"\n");
 3596                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), GetString("PATH_ITEM"));
 3597                     StringCbCatW (tmpMcMsg, sizeof(tmpMcMsg), deviceName);
 3598 
 3599                     wchar_t *tmpStr[] = {L"", tmpMcMsg, tmpMcOption1, tmpMcOptionCancel, 0};
 3600                     switch (AskMultiChoice ((void **) tmpStr, TRUE, MainDlg))
 3601                     {
 3602                     case 1:
 3603                         // Proceed
 3604 
 3605                         // NOP
 3606                         break;
 3607 
 3608                     default:
 3609                         return FALSE;
 3610                     }
 3611                 }
 3612             }
 3613         }
 3614     }
 3615     return TRUE;
 3616 }
 3617 
 3618 void UpdateLastDialogId (void)
 3619 {
 3620     static char PageDebugId[128];
 3621 
 3622     StringCbPrintfA (PageDebugId, sizeof(PageDebugId), "FORMAT_PAGE_%d", nCurPageNo);
 3623     LastDialogId = PageDebugId;
 3624 }
 3625 
 3626 
 3627 void HandleOldAssignedDriveLetter (void)
 3628 {
 3629     if (bDevice)
 3630     {
 3631         // Handle assigned drive letter (if any)
 3632 
 3633         WCHAR deviceName[MAX_PATH];
 3634         int driveLetter = -1;
 3635 
 3636         StringCbCopyW (deviceName, sizeof(deviceName), szDiskFile);
 3637         driveLetter = GetDiskDeviceDriveLetter (deviceName);
 3638 
 3639         if (!Silent && !bHiddenVolHost
 3640             && !bHiddenOS
 3641             && driveLetter >= 0)
 3642         {
 3643             wchar_t rootPath[] = { (wchar_t) driveLetter + L'A', L':', L'\\', 0 };
 3644             wchar_t szTmp[8192];
 3645 
 3646             StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("AFTER_FORMAT_DRIVE_LETTER_WARN"), rootPath[0], rootPath[0], rootPath[0], rootPath[0]);
 3647             MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING);
 3648         }
 3649     }
 3650 }
 3651 
 3652 
 3653 // Returns TRUE if it makes sense to ask the user whether he wants to store files larger than 4GB in the volume.
 3654 static BOOL FileSize4GBLimitQuestionNeeded (void)
 3655 {
 3656     uint64 dataAreaSize = GetVolumeDataAreaSize (bHiddenVol && !bHiddenVolHost, nVolumeSize);
 3657 
 3658     return (dataAreaSize > 4 * BYTES_PER_GB + TC_MIN_FAT_FS_SIZE
 3659         && dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize());
 3660 }
 3661 
 3662 
 3663 void DisableIfGpt(HWND control)
 3664 {
 3665    if (bSystemIsGPT) {
 3666       EnableWindow(control, FALSE);
 3667    }
 3668 }
 3669 
 3670 static void UpdateClusterSizeList (HWND hwndDlg, int fsType)
 3671 {
 3672     SendMessage (GetDlgItem (hwndDlg, IDC_CLUSTERSIZE), CB_RESETCONTENT, 0, 0);
 3673     AddComboPair (GetDlgItem (hwndDlg, IDC_CLUSTERSIZE), GetString ("DEFAULT"), 0);
 3674 
 3675     for (int i = 1; i <= 128; i *= 2)
 3676     {
 3677         wstringstream s;
 3678         DWORD size = GetFormatSectorSize() * i;
 3679 
 3680         if (size > TC_MAX_FAT_CLUSTER_SIZE)
 3681             break;
 3682 
 3683         /* ReFS supports only 4KiB and 64KiB clusters */
 3684         if ((fsType == FILESYS_REFS) && (size != 4*BYTES_PER_KB) && (size != 64*BYTES_PER_KB))
 3685             continue;
 3686 
 3687         if (size == 512)
 3688             s << L"0.5";
 3689         else
 3690             s << size / BYTES_PER_KB;
 3691 
 3692         s << L" " << GetString ("KB");
 3693 
 3694         AddComboPair (GetDlgItem (hwndDlg, IDC_CLUSTERSIZE), s.str().c_str(), i);
 3695     }
 3696 
 3697     SendMessage (GetDlgItem (hwndDlg, IDC_CLUSTERSIZE), CB_SETCURSEL, 0, 0);
 3698 }
 3699 
 3700 /* Except in response to the WM_INITDIALOG message, the dialog box procedure
 3701    should return nonzero if it processes the message, and zero if it does
 3702    not. - see DialogProc */
 3703 BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 3704 {
 3705     WORD lw = LOWORD (wParam);
 3706     WORD hw = HIWORD (wParam);
 3707     static BOOL PimValueChangedWarning = FALSE;
 3708 
 3709     hCurPage = hwndDlg;
 3710 
 3711     switch (uMsg)
 3712     {
 3713     case WM_INITDIALOG:
 3714         PimValueChangedWarning = FALSE;
 3715         LocalizeDialog (hwndDlg, "IDD_VOL_CREATION_WIZARD_DLG");
 3716 
 3717         burn (randPool, sizeof(randPool));
 3718         burn (lastRandPool, sizeof(lastRandPool));
 3719         burn (maskRandPool, sizeof (maskRandPool));
 3720 
 3721         UpdateLastDialogId ();
 3722 
 3723         switch (nCurPageNo)
 3724         {
 3725         case INTRO_PAGE:
 3726 
 3727             SendMessage (GetDlgItem (hwndDlg, IDC_FILE_CONTAINER), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3728             SendMessage (GetDlgItem (hwndDlg, IDC_NONSYS_DEVICE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3729             SendMessage (GetDlgItem (hwndDlg, IDC_SYS_DEVICE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3730 
 3731             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("INTRO_TITLE"));
 3732 
 3733             ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_CONTAINERS);
 3734             ToHyperlink (hwndDlg, IDC_MORE_INFO_ON_SYS_ENCRYPTION);
 3735 
 3736             EnableWindow (GetDlgItem (hwndDlg, IDC_STD_VOL), TRUE);
 3737             EnableWindow (GetDlgItem (hwndDlg, IDC_HIDDEN_VOL), TRUE);
 3738 
 3739             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 3740             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 3741             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
 3742             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 3743             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 3744 
 3745             UpdateWizardModeControls (hwndDlg, WizardMode);
 3746             break;
 3747 
 3748         case SYSENC_TYPE_PAGE:
 3749 
 3750             bHiddenVolHost = bHiddenVol = bHiddenOS;
 3751 
 3752             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_TYPE_PAGE_TITLE"));
 3753 
 3754             SendMessage (GetDlgItem (hwndDlg, IDC_SYSENC_HIDDEN), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3755             SendMessage (GetDlgItem (hwndDlg, IDC_SYSENC_NORMAL), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3756 
 3757             DisableIfGpt(GetDlgItem(hwndDlg, IDC_SYSENC_HIDDEN));
 3758 
 3759             CheckButton (GetDlgItem (hwndDlg, bHiddenOS ? IDC_SYSENC_HIDDEN : IDC_SYSENC_NORMAL));
 3760 
 3761             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_HIDDEN_TYPE_HELP"));
 3762             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP_SYSENC_NORMAL), GetString ("SYSENC_NORMAL_TYPE_HELP"));
 3763 
 3764             ToHyperlink (hwndDlg, IDC_HIDDEN_SYSENC_INFO_LINK);
 3765 
 3766             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 3767             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), !bDirectSysEncMode);
 3768 
 3769             SetWindowTextW (GetDlgItem (MainDlg, IDC_NEXT), GetString ("NEXT"));
 3770             SetWindowTextW (GetDlgItem (MainDlg, IDC_PREV), GetString ("PREV"));
 3771             SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
 3772             break;
 3773 
 3774         case SYSENC_HIDDEN_OS_REQ_CHECK_PAGE:
 3775 
 3776             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_HIDDEN_OS_REQ_CHECK_PAGE_TITLE"));
 3777             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_HIDDEN_OS_REQ_CHECK_PAGE_HELP"));
 3778             SetWindowTextW (GetDlgItem (MainDlg, IDC_NEXT), GetString ("NEXT"));
 3779             SetWindowTextW (GetDlgItem (MainDlg, IDC_PREV), GetString ("PREV"));
 3780             SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
 3781 
 3782             EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), TRUE);
 3783             EnableWindow (GetDlgItem (MainDlg, IDC_PREV), bDirectSysEncModeCommand != SYSENC_COMMAND_CREATE_HIDDEN_OS && bDirectSysEncModeCommand != SYSENC_COMMAND_CREATE_HIDDEN_OS_ELEV);
 3784 
 3785             ToHyperlink (hwndDlg, IDC_HIDDEN_SYSENC_INFO_LINK);
 3786             break;
 3787 
 3788         case SYSENC_SPAN_PAGE:
 3789 
 3790             SendMessage (GetDlgItem (hwndDlg, IDC_WHOLE_SYS_DRIVE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3791             SendMessage (GetDlgItem (hwndDlg, IDC_SYS_PARTITION), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3792 
 3793             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYS_ENCRYPTION_SPAN_TITLE"));
 3794 
 3795             SetWindowTextW (GetDlgItem (hwndDlg, IDT_WHOLE_SYS_DRIVE), GetString ("SYS_ENCRYPTION_SPAN_WHOLE_SYS_DRIVE_HELP"));
 3796 
 3797             CheckButton (GetDlgItem (hwndDlg, bWholeSysDrive ? IDC_WHOLE_SYS_DRIVE : IDC_SYS_PARTITION));
 3798             DisableIfGpt(GetDlgItem(hwndDlg, IDC_WHOLE_SYS_DRIVE));
 3799 
 3800             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 3801             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 3802             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
 3803 
 3804             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 3805             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 3806             break;
 3807 
 3808 
 3809         case SYSENC_PRE_DRIVE_ANALYSIS_PAGE:
 3810 
 3811             Init2RadButtonPageYesNo (SysEncDetectHiddenSectors);
 3812             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_PRE_DRIVE_ANALYSIS_TITLE"));
 3813             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_PRE_DRIVE_ANALYSIS_HELP"));
 3814             break;
 3815 
 3816 
 3817         case SYSENC_DRIVE_ANALYSIS_PAGE:
 3818 
 3819             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_DRIVE_ANALYSIS_TITLE"));
 3820             SetWindowTextW (GetDlgItem (hwndDlg, IDT_SYSENC_DRIVE_ANALYSIS_INFO), GetString ("SYSENC_DRIVE_ANALYSIS_INFO"));
 3821             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 3822             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 3823             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
 3824             EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), FALSE);
 3825             EnableWindow (GetDlgItem (MainDlg, IDC_PREV), FALSE);
 3826             EnableWindow (GetDlgItem (MainDlg, IDCANCEL), FALSE);
 3827 
 3828             LoadSettings (hwndDlg);
 3829 
 3830             if (HiddenSectorDetectionStatus == 1)
 3831             {
 3832                 // Detection of hidden sectors was already in progress but it did not finish successfully.
 3833                 // Ask the user if he wants to try again (to prevent repeated system freezing, etc.)
 3834 
 3835                 char *tmpStr[] = {0, "HIDDEN_SECTOR_DETECTION_FAILED_PREVIOUSLY", "SKIP_HIDDEN_SECTOR_DETECTION", "RETRY_HIDDEN_SECTOR_DETECTION", "IDC_EXIT", 0};
 3836                 switch (AskMultiChoice ((void **) tmpStr, FALSE, MainDlg))
 3837                 {
 3838                 case 1:
 3839                     // Do not try again
 3840                     LoadPage (MainDlg, SYSENC_DRIVE_ANALYSIS_PAGE + 1);
 3841                     return 0;
 3842 
 3843                 case 2:
 3844                     // Try again
 3845                     break;
 3846 
 3847                 default:
 3848                     EndMainDlg (MainDlg);
 3849                     return 0;
 3850                 }
 3851             }
 3852 
 3853             SetTimer (MainDlg, TIMER_ID_SYSENC_DRIVE_ANALYSIS_PROGRESS, TIMER_INTERVAL_SYSENC_DRIVE_ANALYSIS_PROGRESS, NULL);
 3854             bSysEncDriveAnalysisInProgress = TRUE;
 3855             ArrowWaitCursor ();
 3856             SysEncDriveAnalysisStart = GetTickCount ();
 3857             InitProgressBar (SYSENC_DRIVE_ANALYSIS_ETA, 0, FALSE, FALSE, FALSE, TRUE);
 3858 
 3859             _beginthread (sysEncDriveAnalysisThread, 0, hwndDlg);
 3860 
 3861             break;
 3862 
 3863 
 3864         case SYSENC_MULTI_BOOT_MODE_PAGE:
 3865 
 3866             SendMessage (GetDlgItem (hwndDlg, IDC_SINGLE_BOOT), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3867             SendMessage (GetDlgItem (hwndDlg, IDC_MULTI_BOOT), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3868 
 3869             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYS_MULTI_BOOT_MODE_TITLE"));
 3870 
 3871             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 3872             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 3873             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
 3874 
 3875             RefreshMultiBootControls (hwndDlg);
 3876             DisableIfGpt(GetDlgItem(hwndDlg, IDC_MULTI_BOOT));
 3877             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), nMultiBoot > 0);
 3878             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 3879             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
 3880             break;
 3881 
 3882 
 3883         case SYSENC_MULTI_BOOT_SYS_EQ_BOOT_PAGE:
 3884 
 3885             Init2RadButtonPageYesNo (SysEncMultiBootCfg.SystemOnBootDrive);
 3886             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_MULTI_BOOT_SYS_EQ_BOOT_TITLE"));
 3887             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_MULTI_BOOT_SYS_EQ_BOOT_HELP"));
 3888             break;
 3889 
 3890 
 3891         case SYSENC_MULTI_BOOT_NBR_SYS_DRIVES_PAGE:
 3892 
 3893             SetWindowTextW (GetDlgItem (hCurPage, IDC_CHOICE1), GetString ("DIGIT_ONE"));
 3894             SetWindowTextW (GetDlgItem (hCurPage, IDC_CHOICE2), GetString ("TWO_OR_MORE"));
 3895 
 3896             SetWindowTextW (GetDlgItem (MainDlg, IDC_NEXT), GetString ("NEXT"));
 3897             SetWindowTextW (GetDlgItem (MainDlg, IDC_PREV), GetString ("PREV"));
 3898             SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
 3899 
 3900             EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), SysEncMultiBootCfg.NumberOfSysDrives > 0);
 3901             EnableWindow (GetDlgItem (MainDlg, IDC_PREV), TRUE);
 3902 
 3903             if (SysEncMultiBootCfg.NumberOfSysDrives == 2)
 3904                 Update2RadButtonPage (0); // 2 or more drives contain an OS
 3905             else if (SysEncMultiBootCfg.NumberOfSysDrives == 1)
 3906                 Update2RadButtonPage (1); // Only 1 drive contains an OS
 3907             else
 3908                 Update2RadButtonPage (-1);
 3909 
 3910             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_MULTI_BOOT_NBR_SYS_DRIVES_TITLE"));
 3911             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_MULTI_BOOT_NBR_SYS_DRIVES_HELP"));
 3912             break;
 3913 
 3914 
 3915         case SYSENC_MULTI_BOOT_ADJACENT_SYS_PAGE:
 3916 
 3917             Init2RadButtonPageYesNo (SysEncMultiBootCfg.MultipleSystemsOnDrive);
 3918             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_MULTI_BOOT_ADJACENT_SYS_TITLE"));
 3919             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_MULTI_BOOT_ADJACENT_SYS_HELP"));
 3920             break;
 3921 
 3922 
 3923         case SYSENC_MULTI_BOOT_NONWIN_BOOT_LOADER_PAGE:
 3924 
 3925             Init2RadButtonPageYesNo (SysEncMultiBootCfg.BootLoaderBrand);
 3926             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_MULTI_BOOT_NONWIN_BOOT_LOADER_TITLE"));
 3927             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_MULTI_BOOT_NONWIN_BOOT_LOADER_HELP"));
 3928             break;
 3929 
 3930 
 3931         case SYSENC_MULTI_BOOT_OUTCOME_PAGE:
 3932 
 3933             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYSENC_MULTI_BOOT_OUTCOME_TITLE"));
 3934             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), SysEncMultiBootCfgOutcome);
 3935             SetWindowTextW (GetDlgItem (MainDlg, IDC_NEXT), GetString ("NEXT"));
 3936             SetWindowTextW (GetDlgItem (MainDlg, IDC_PREV), GetString ("PREV"));
 3937             SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
 3938             EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), TRUE);
 3939             EnableWindow (GetDlgItem (MainDlg, IDC_PREV), TRUE);
 3940             break;
 3941 
 3942 
 3943         case VOLUME_TYPE_PAGE:
 3944 
 3945             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("VOLUME_TYPE_TITLE"));
 3946 
 3947             SendMessage (GetDlgItem (hwndDlg, IDC_HIDDEN_VOL), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3948             SendMessage (GetDlgItem (hwndDlg, IDC_STD_VOL), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3949 
 3950             CheckButton (GetDlgItem (hwndDlg, bHiddenVol ? IDC_HIDDEN_VOL : IDC_STD_VOL));
 3951 
 3952             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("HIDDEN_VOLUME_TYPE_HELP"));
 3953             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP_NORMAL_VOL), GetString ("NORMAL_VOLUME_TYPE_HELP"));
 3954 
 3955             ToHyperlink (hwndDlg, IDC_HIDDEN_VOL_HELP);
 3956 
 3957             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 3958             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 3959 
 3960             SetWindowTextW (GetDlgItem (MainDlg, IDC_NEXT), GetString ("NEXT"));
 3961             SetWindowTextW (GetDlgItem (MainDlg, IDC_PREV), GetString ("PREV"));
 3962             SetWindowTextW (GetDlgItem (MainDlg, IDCANCEL), GetString ("CANCEL"));
 3963             break;
 3964 
 3965         case HIDDEN_VOL_WIZARD_MODE_PAGE:
 3966 
 3967             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("HIDDEN_VOL_WIZARD_MODE_TITLE"));
 3968 
 3969             SendMessage (GetDlgItem (hwndDlg, IDC_HIDVOL_WIZ_MODE_DIRECT), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3970             SendMessage (GetDlgItem (hwndDlg, IDC_HIDVOL_WIZ_MODE_FULL), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 3971 
 3972             CheckButton (GetDlgItem (hwndDlg, bHiddenVolDirect ? IDC_HIDVOL_WIZ_MODE_DIRECT : IDC_HIDVOL_WIZ_MODE_FULL));
 3973 
 3974             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("HIDDEN_VOL_WIZARD_MODE_NORMAL_HELP"));
 3975             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP2), GetString ("HIDDEN_VOL_WIZARD_MODE_DIRECT_HELP"));
 3976 
 3977             EnableWindow (GetDlgItem (hwndDlg, IDC_HIDVOL_WIZ_MODE_DIRECT), TRUE);
 3978             EnableWindow (GetDlgItem (hwndDlg, IDC_HIDVOL_WIZ_MODE_FULL), TRUE);
 3979 
 3980             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 3981             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 3982             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
 3983             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 3984             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 3985 
 3986             break;
 3987 
 3988         case VOLUME_LOCATION_PAGE:
 3989             {
 3990                 char *nID;
 3991 
 3992                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_SELECT_VOLUME_LOCATION),
 3993                     GetString (bDevice ? "IDC_SELECT_DEVICE" : "IDC_SELECT_FILE"));
 3994 
 3995                 if (bHiddenVolDirect && bHiddenVolHost)
 3996                 {
 3997                     nID = "FILE_HELP_HIDDEN_HOST_VOL_DIRECT";
 3998                 }
 3999                 else
 4000                 {
 4001                     if (bDevice)
 4002                         nID = bHiddenVolHost ? "DEVICE_HELP_HIDDEN_HOST_VOL" : "DEVICE_HELP";
 4003                     else
 4004                         nID = bHiddenVolHost ? "FILE_HELP_HIDDEN_HOST_VOL" : "FILE_HELP";
 4005                 }
 4006 
 4007                 SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_RESETCONTENT, 0, 0);
 4008 
 4009                 SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_LIMITTEXT, TC_MAX_PATH, 0);
 4010 
 4011                 LoadCombo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), bHistory, FALSE, NULL);
 4012 
 4013                 SendMessage (GetDlgItem (hwndDlg, IDC_NO_HISTORY), BM_SETCHECK, bHistory ? BST_UNCHECKED : BST_CHECKED, 0);
 4014 
 4015                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("FILE_TITLE"));
 4016                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (nID));
 4017 
 4018                 SetFocus (GetDlgItem (hwndDlg, IDC_COMBO_BOX));
 4019 
 4020                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4021                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4022                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4023 
 4024                 AddComboItem (GetDlgItem (hwndDlg, IDC_COMBO_BOX), szFileName, bHistory);
 4025 
 4026                 EnableDisableFileNext (GetDlgItem (hwndDlg, IDC_COMBO_BOX),
 4027                 GetDlgItem (GetParent (hwndDlg), IDC_NEXT));
 4028 
 4029             }
 4030             break;
 4031 
 4032         case DEVICE_TRANSFORM_MODE_PAGE:
 4033 
 4034             if (!bDeviceTransformModeChoiceMade && !bInPlaceEncNonSys)
 4035             {
 4036                 // The user has not chosen whether to perform in-place encryption or format yet.
 4037                 // We will preselect in-place encryption if the requirements are met and if the
 4038                 // filesystem does not appear empty.
 4039 
 4040                 WaitCursor();
 4041 
 4042                 if (CheckRequirementsForNonSysInPlaceEnc (hwndDlg, szDiskFile, TRUE))
 4043                 {
 4044                     bInPlaceEncNonSys = (FileSystemAppearsEmpty (szDiskFile) == 0);
 4045                 }
 4046             }
 4047 
 4048             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("DEVICE_TRANSFORM_MODE_PAGE_TITLE"));
 4049 
 4050             SendMessage (GetDlgItem (hwndDlg, IDC_DEVICE_TRANSFORM_MODE_INPLACE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 4051             SendMessage (GetDlgItem (hwndDlg, IDC_DEVICE_TRANSFORM_MODE_FORMAT), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
 4052 
 4053             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("DEVICE_TRANSFORM_MODE_PAGE_FORMAT_HELP"));
 4054             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP2), GetString ("DEVICE_TRANSFORM_MODE_PAGE_INPLACE_HELP"));
 4055 
 4056             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4057             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4058 
 4059             CheckButton (GetDlgItem (hwndDlg, bInPlaceEncNonSys ? IDC_DEVICE_TRANSFORM_MODE_INPLACE : IDC_DEVICE_TRANSFORM_MODE_FORMAT));
 4060 
 4061             NormalCursor();
 4062 
 4063             break;
 4064 
 4065         case HIDDEN_VOL_HOST_PRE_CIPHER_PAGE:
 4066             {
 4067                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("HIDVOL_HOST_PRE_CIPHER_TITLE"));
 4068                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bHiddenOS ? "HIDVOL_HOST_PRE_CIPHER_HELP_SYSENC" : "HIDVOL_HOST_PRE_CIPHER_HELP"));
 4069 
 4070                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4071                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4072                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4073                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4074 
 4075                 if (bHiddenOS)
 4076                 {
 4077                     if (!GetDevicePathForHiddenOS())
 4078                         AbortProcess ("INVALID_PATH");
 4079                 }
 4080             }
 4081             break;
 4082 
 4083         case HIDDEN_VOL_PRE_CIPHER_PAGE:
 4084             {
 4085                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4086                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4087                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4088                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4089                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("HIDVOL_PRE_CIPHER_TITLE"));
 4090 
 4091                 if (bHiddenOS)
 4092                 {
 4093                     // Verify whether the clone of the OS fits in the hidden volume (the hidden
 4094                     // volume is to host a hidden OS).
 4095                     if (nMaximumHiddenVolSize - TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH < GetSystemPartitionSize())
 4096                     {
 4097                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("HIDDEN_VOLUME_TOO_SMALL_FOR_OS_CLONE"));
 4098 
 4099                         SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("EXIT"));
 4100                         EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
 4101                         EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), FALSE);
 4102                         EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4103 
 4104                         bConfirmQuit = FALSE;
 4105                         bConfirmQuitSysEncPretest = FALSE;
 4106                     }
 4107                     else
 4108                     {
 4109                         // The hidden volume must be as large as the system partition
 4110                         nVolumeSize = GetSystemPartitionSize() + TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH;
 4111 
 4112                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("HIDDEN_OS_PRE_CIPHER_HELP"));
 4113                     }
 4114                 }
 4115                 else
 4116                 {
 4117                     SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("HIDVOL_PRE_CIPHER_HELP"));
 4118                 }
 4119             }
 4120             break;
 4121 
 4122         case CIPHER_PAGE:
 4123             {
 4124                 int ea, hid;
 4125                 wchar_t buf[100];
 4126 
 4127                 // Encryption algorithms
 4128 
 4129                 SendMessage (GetDlgItem (hwndDlg, IDC_COMBO_BOX), CB_RESETCONTENT, 0, 0);
 4130 
 4131                 if (bHiddenVol)
 4132                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bHiddenVolHost ? "CIPHER_HIDVOL_HOST_TITLE" : "CIPHER_HIDVOL_TITLE"));
 4133                 else
 4134                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("CIPHER_TITLE"));
 4135 
 4136                 for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
 4137                 {
 4138                     if (EAIsFormatEnabled (ea) && (!SysEncInEffect () || bSystemIsGPT || EAIsMbrSysEncEnabled (ea)))
 4139                         AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX), EAGetName (buf, ea, 1), ea);
 4140                 }
 4141 
 4142                 SelectAlgo (GetDlgItem (hwndDlg, IDC_COMBO_BOX), &nVolumeEA);
 4143                 ComboSelChangeEA (hwndDlg);
 4144                 SetFocus (GetDlgItem (hwndDlg, IDC_COMBO_BOX));
 4145 
 4146                 ToHyperlink (hwndDlg, IDC_LINK_MORE_INFO_ABOUT_CIPHER);
 4147 
 4148                 // Hash algorithms
 4149 
 4150                 if (SysEncInEffect ())
 4151                 {
 4152                     hash_algo = bSystemIsGPT? SHA512 : DEFAULT_HASH_ALGORITHM_BOOT;
 4153                     RandSetHashFunction (hash_algo);
 4154 
 4155                     for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
 4156                     {
 4157                         // For now, we keep RIPEMD160 for system encryption
 4158                         if (((hid == RIPEMD160) || !HashIsDeprecated (hid)) && (bSystemIsGPT || HashForSystemEncryption (hid)))
 4159                             AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), HashGetName(hid), hid);
 4160                     }
 4161                 }
 4162                 else
 4163                 {
 4164                     hash_algo = RandGetHashFunction();
 4165                     for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
 4166                     {
 4167                         if (!HashIsDeprecated (hid))
 4168                             AddComboPair (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), HashGetName(hid), hid);
 4169                     }
 4170                 }
 4171 
 4172                 SelectAlgo (GetDlgItem (hwndDlg, IDC_COMBO_BOX_HASH_ALGO), &hash_algo);
 4173 
 4174                 ToHyperlink (hwndDlg, IDC_LINK_HASH_INFO);
 4175 
 4176                 // Wizard buttons
 4177                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4178                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4179                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4180                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4181             }
 4182             break;
 4183 
 4184         case SIZE_PAGE:
 4185             {
 4186                 wchar_t str[1000];
 4187 
 4188                 if (bHiddenVolHost)
 4189                 {
 4190                     StringCbCopyW (str, sizeof(str), GetString ("SIZE_HELP_HIDDEN_HOST_VOL"));
 4191                 }
 4192                 else
 4193                 {
 4194                     StringCbCopyW (str, sizeof(str), GetString (bHiddenVol ? "SIZE_HELP_HIDDEN_VOL" : "SIZE_HELP"));
 4195                 }
 4196 
 4197                 if (bDevice && !(bHiddenVol && !bHiddenVolHost))    // If raw device but not a hidden volume
 4198                 {
 4199                     StringCbPrintfW (str, sizeof str, L"%s%s",
 4200                         GetString ((bHiddenOS && bHiddenVol) ? "SIZE_PARTITION_HIDDEN_SYSENC_HELP" : "SIZE_PARTITION_HELP"),
 4201                          (bHiddenVolHost && !bHiddenOS) ? GetString ("SIZE_PARTITION_HIDDEN_VOL_HELP") : L"");
 4202                 }
 4203 
 4204                 SendMessage (GetDlgItem (hwndDlg, IDC_SPACE_LEFT), WM_SETFONT, (WPARAM) hBoldFont, (LPARAM) TRUE);
 4205                 SendMessage (GetDlgItem (hwndDlg, IDC_SIZEBOX), EM_LIMITTEXT, 12, 0);
 4206 
 4207                 if(!QueryFreeSpace (hwndDlg, GetDlgItem (hwndDlg, IDC_SPACE_LEFT), TRUE, &nAvailableFreeSpace, &bIsSparseFilesSupportedByHost))
 4208                 {
 4209                     nUIVolumeSize=0;
 4210                     nVolumeSize=0;
 4211                     SetWindowTextW (GetDlgItem (hwndDlg, IDC_SIZEBOX), GetString ("UNKNOWN"));
 4212                     EnableWindow (GetDlgItem (hwndDlg, IDC_SIZEBOX), FALSE);
 4213                     EnableWindow (GetDlgItem (hwndDlg, IDC_KB), FALSE);
 4214                     EnableWindow (GetDlgItem (hwndDlg, IDC_MB), FALSE);
 4215                     EnableWindow (GetDlgItem (hwndDlg, IDC_GB), FALSE);
 4216                     EnableWindow (GetDlgItem (hwndDlg, IDC_TB), FALSE);
 4217                 }
 4218                 else if (bDevice && !(bHiddenVol && !bHiddenVolHost))   // If raw device but not a hidden volume
 4219                 {
 4220                     EnableWindow (GetDlgItem (hwndDlg, IDC_SIZEBOX), FALSE);
 4221                     EnableWindow (GetDlgItem (hwndDlg, IDC_KB), FALSE);
 4222                     EnableWindow (GetDlgItem (hwndDlg, IDC_MB), FALSE);
 4223                     EnableWindow (GetDlgItem (hwndDlg, IDC_GB), FALSE);
 4224                     EnableWindow (GetDlgItem (hwndDlg, IDC_TB), FALSE);
 4225                 }
 4226                 else
 4227                 {
 4228                     EnableWindow (GetDlgItem (hwndDlg, IDC_SIZEBOX), TRUE);
 4229                     EnableWindow (GetDlgItem (hwndDlg, IDC_KB), TRUE);
 4230                     EnableWindow (GetDlgItem (hwndDlg, IDC_MB), TRUE);
 4231                     EnableWindow (GetDlgItem (hwndDlg, IDC_GB), TRUE);
 4232                     EnableWindow (GetDlgItem (hwndDlg, IDC_TB), TRUE);
 4233                 }
 4234 
 4235                 SendMessage (GetDlgItem (hwndDlg, IDC_KB), BM_SETCHECK, BST_UNCHECKED, 0);
 4236                 SendMessage (GetDlgItem (hwndDlg, IDC_MB), BM_SETCHECK, BST_UNCHECKED, 0);
 4237                 SendMessage (GetDlgItem (hwndDlg, IDC_GB), BM_SETCHECK, BST_UNCHECKED, 0);
 4238                 SendMessage (GetDlgItem (hwndDlg, IDC_TB), BM_SETCHECK, BST_UNCHECKED, 0);
 4239 
 4240                 switch (nMultiplier)
 4241                 {
 4242                 case BYTES_PER_KB:
 4243                     SendMessage (GetDlgItem (hwndDlg, IDC_KB), BM_SETCHECK, BST_CHECKED, 0);
 4244                     break;
 4245                 case BYTES_PER_MB:
 4246                     SendMessage (GetDlgItem (hwndDlg, IDC_MB), BM_SETCHECK, BST_CHECKED, 0);
 4247                     break;
 4248                 case BYTES_PER_GB:
 4249                     SendMessage (GetDlgItem (hwndDlg, IDC_GB), BM_SETCHECK, BST_CHECKED, 0);
 4250                     break;
 4251                 case BYTES_PER_TB:
 4252                     SendMessage (GetDlgItem (hwndDlg, IDC_TB), BM_SETCHECK, BST_CHECKED, 0);
 4253                     break;
 4254                 }
 4255 
 4256                 if (nUIVolumeSize != 0)
 4257                 {
 4258                     wchar_t szTmp[32];
 4259                     StringCbPrintfW (szTmp, sizeof(szTmp), L"%I64u", nUIVolumeSize);
 4260                     SetWindowText (GetDlgItem (hwndDlg, IDC_SIZEBOX), szTmp);
 4261                 }
 4262 
 4263                 SetFocus (GetDlgItem (hwndDlg, IDC_SIZEBOX));
 4264 
 4265                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), str);
 4266 
 4267                 if (bHiddenVol)
 4268                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bHiddenVolHost ? "SIZE_HIDVOL_HOST_TITLE" : "SIZE_HIDVOL_TITLE"));
 4269                 else
 4270                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SIZE_TITLE"));
 4271 
 4272 
 4273                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4274                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4275 
 4276 
 4277                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4278 
 4279                 VerifySizeAndUpdate (hwndDlg, FALSE);
 4280             }
 4281             break;
 4282 
 4283         case HIDDEN_VOL_HOST_PASSWORD_PAGE:
 4284         case NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE:
 4285             {
 4286                 /* Populate the PRF algorithms list */
 4287                 int nIndex, i;
 4288                 HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
 4289                 SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
 4290 
 4291                 nIndex = (int) SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
 4292                 SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
 4293 
 4294                 for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
 4295                 {
 4296                     nIndex = (int) SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
 4297                     SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
 4298                 }
 4299 
 4300                 /* make autodetection the default */
 4301                 SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
 4302 
 4303                 ToNormalPwdField (hwndDlg, IDC_PASSWORD_DIRECT);
 4304 
 4305                 SetPassword (hwndDlg, IDC_PASSWORD_DIRECT, szRawPassword);
 4306 
 4307                 SetFocus (GetDlgItem (hwndDlg, IDC_PASSWORD_DIRECT));
 4308 
 4309                 SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, MAX_PIM, 0);
 4310                 SetPim (hwndDlg, IDC_PIM, volumePim);
 4311 
 4312                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_ENABLE), PimEnable? SW_HIDE : SW_SHOW);
 4313                 ShowWindow (GetDlgItem( hwndDlg, IDT_PIM), PimEnable? SW_SHOW : SW_HIDE);
 4314                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM), PimEnable? SW_SHOW : SW_HIDE);
 4315                 ShowWindow (GetDlgItem( hwndDlg, IDC_PIM_HELP), PimEnable? SW_SHOW : SW_HIDE);
 4316 
 4317                 SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
 4318 
 4319                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceEncNonSys ? (bInPlaceEncNonSysResumed ? "NONSYS_INPLACE_ENC_RESUME_PASSWORD_PAGE_HELP" : "NONSYS_INPLACE_DEC_PASSWORD_PAGE_HELP") : "PASSWORD_HIDDENVOL_HOST_DIRECT_HELP"));
 4320 
 4321                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bInPlaceEncNonSys ? "PASSWORD" : "PASSWORD_HIDVOL_HOST_TITLE"));
 4322 
 4323                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4324                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4325 
 4326                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), !bInPlaceEncNonSys);
 4327                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4328             }
 4329 
 4330             break;
 4331 
 4332         case PASSWORD_PAGE:
 4333             {
 4334                 wchar_t str[1000];
 4335 
 4336                 hPasswordInputField = GetDlgItem (hwndDlg, IDC_PASSWORD);
 4337                 hVerifyPasswordInputField = GetDlgItem (hwndDlg, IDC_VERIFY);
 4338 
 4339                 ToNormalPwdField (hwndDlg, IDC_PASSWORD);
 4340                 ToNormalPwdField (hwndDlg, IDC_VERIFY);
 4341 
 4342                 if (SysEncInEffect ())
 4343                 {
 4344                     ToBootPwdField (hwndDlg, IDC_PASSWORD);
 4345                     ToBootPwdField (hwndDlg, IDC_VERIFY);
 4346 
 4347                     StringCbPrintfW (OrigKeyboardLayout, sizeof(OrigKeyboardLayout), L"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF);
 4348 
 4349                     if ((DWORD) GetKeyboardLayout (NULL) != 0x00000409 && (DWORD) GetKeyboardLayout (NULL) != 0x04090409)
 4350                     {
 4351                         DWORD keybLayout = (DWORD) LoadKeyboardLayout (L"00000409", KLF_ACTIVATE);
 4352 
 4353                         if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
 4354                         {
 4355                             Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", MainDlg);
 4356                             EndMainDlg (MainDlg);
 4357                             return 1;
 4358                         }
 4359                         bKeyboardLayoutChanged = TRUE;
 4360                     }
 4361 
 4362 
 4363                     if (SetTimer (MainDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0)
 4364                     {
 4365                         Error ("CANNOT_SET_TIMER", MainDlg);
 4366                         EndMainDlg (MainDlg);
 4367                         return 1;
 4368                     }
 4369                 }
 4370 
 4371                 if (bHiddenVolHost)
 4372                 {
 4373                     StringCbCopyW (str, sizeof(str), GetString (bHiddenOS ? "PASSWORD_SYSENC_OUTERVOL_HELP" : "PASSWORD_HIDDENVOL_HOST_HELP"));
 4374                 }
 4375                 else if (bHiddenVol)
 4376                 {
 4377                     StringCbPrintfW (str, sizeof str, L"%s%s",
 4378                         GetString (bHiddenOS ? "PASSWORD_HIDDEN_OS_HELP" : "PASSWORD_HIDDENVOL_HELP"),
 4379                         GetString ("PASSWORD_HELP"));
 4380                 }
 4381                 else
 4382                 {
 4383                     StringCbCopyW (str, sizeof(str), GetString ("PASSWORD_HELP"));
 4384                 }
 4385 
 4386                 SetPassword (hwndDlg, IDC_PASSWORD, szRawPassword);
 4387                 SetPassword (hwndDlg, IDC_VERIFY, szVerify);
 4388 
 4389                 SetFocus (GetDlgItem (hwndDlg, IDC_PASSWORD));
 4390 
 4391                 SetCheckBox (hwndDlg, IDC_PIM_ENABLE, PimEnable);
 4392 
 4393                 SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable && !SysEncInEffect());
 4394                 EnableWindow (GetDlgItem (hwndDlg, IDC_KEY_FILES), KeyFilesEnable);
 4395 
 4396                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), str);
 4397 
 4398                 if (CreatingHiddenSysVol())
 4399                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("PASSWORD_HIDDEN_OS_TITLE"));
 4400                 else if (bHiddenVol)
 4401                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bHiddenVolHost ? "PASSWORD_HIDVOL_HOST_TITLE" : "PASSWORD_HIDVOL_TITLE"));
 4402                 else if (WizardMode == WIZARD_MODE_SYS_DEVICE)
 4403                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("PASSWORD"));
 4404                 else
 4405                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("PASSWORD_TITLE"));
 4406 
 4407                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4408                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4409 
 4410                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4411 
 4412                 VerifyPasswordAndUpdate (hwndDlg, GetDlgItem (GetParent (hwndDlg), IDC_NEXT),
 4413                      GetDlgItem (hwndDlg, IDC_PASSWORD),
 4414                        GetDlgItem (hwndDlg, IDC_VERIFY),
 4415                               NULL,
 4416                               NULL,
 4417                               KeyFilesEnable && FirstKeyFile!=NULL && !SysEncInEffect());
 4418                 volumePassword.Length = (unsigned __int32) strlen ((char *) volumePassword.Text);
 4419 
 4420             }
 4421             break;
 4422 
 4423         case PIM_PAGE:
 4424             {
 4425                 SendMessage (GetDlgItem (hwndDlg, IDC_PIM), EM_LIMITTEXT, SysEncInEffect()? MAX_BOOT_PIM: MAX_PIM, 0);
 4426                 if (volumePim > 0)
 4427                 {
 4428                     SetPim (hwndDlg, IDC_PIM, volumePim);
 4429 
 4430                     PimValueChangedWarning = TRUE;
 4431                     SetDlgItemTextW (hwndDlg, IDC_PIM_HELP, GetString (SysEncInEffect ()? "PIM_SYSENC_CHANGE_WARNING" : "PIM_CHANGE_WARNING"));
 4432                 }
 4433 
 4434                 SetFocus (GetDlgItem (hwndDlg, IDC_PIM));
 4435 
 4436                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (SysEncInEffect () && hash_algo != SHA512 && hash_algo != WHIRLPOOL? "PIM_SYSENC_HELP" : "PIM_HELP"));
 4437 
 4438                 ToHyperlink (hwndDlg, IDC_LINK_PIM_INFO);
 4439 
 4440                 if (CreatingHiddenSysVol())
 4441                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("PIM_HIDDEN_OS_TITLE"));
 4442                 else if (bHiddenVol)
 4443                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bHiddenVolHost ? "PIM_HIDVOL_HOST_TITLE" : "PIM_HIDVOL_TITLE"));
 4444                 else if (WizardMode == WIZARD_MODE_SYS_DEVICE)
 4445                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("PIM"));
 4446                 else
 4447                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("PIM_TITLE"));
 4448 
 4449                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4450                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4451 
 4452                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4453                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4454             }
 4455             break;
 4456 
 4457         case FILESYS_PAGE:
 4458             {
 4459                 wchar_t szTmp[8192];
 4460 
 4461                 Init2RadButtonPageYesNo (nNeedToStoreFilesOver4GB);
 4462                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("FILESYS_PAGE_TITLE"));
 4463 
 4464                 StringCbCopyW (szTmp, sizeof(szTmp), GetString ("FILESYS_PAGE_HELP_QUESTION"));
 4465 
 4466                 if (bHiddenVolHost)
 4467                     StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
 4468                 else
 4469                 {
 4470                     StringCbCatW (szTmp, sizeof(szTmp), L"\n\n\n");
 4471                     StringCbCatW (szTmp, sizeof(szTmp), GetString ("NOTE_BEGINNING"));
 4472                 }
 4473 
 4474                 StringCbCatW (szTmp, sizeof(szTmp), GetString ("FILESYS_PAGE_HELP_EXPLANATION"));
 4475 
 4476                 if (bHiddenVolHost)
 4477                 {
 4478                     StringCbCatW (szTmp, sizeof(szTmp), L" ");
 4479                     StringCbCatW (szTmp, sizeof(szTmp), GetString ("FILESYS_PAGE_HELP_EXPLANATION_HIDVOL"));
 4480                 }
 4481 
 4482                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), szTmp);
 4483             }
 4484             break;
 4485 
 4486         case SYSENC_COLLECTING_RANDOM_DATA_PAGE:
 4487         case NONSYS_INPLACE_ENC_RAND_DATA_PAGE:
 4488 
 4489             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("COLLECTING_RANDOM_DATA_TITLE"));
 4490             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4491             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4492             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4493             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4494 
 4495             mouseEntropyGathered = 0xFFFFFFFF;
 4496             mouseEventsInitialCount = 0;
 4497             bUseMask = FALSE;
 4498             {
 4499                 HCRYPTPROV hRngProv;
 4500                 if (CryptAcquireContext (&hRngProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
 4501                 {
 4502                     if (CryptGenRandom (hRngProv, sizeof (maskRandPool), maskRandPool))
 4503                         bUseMask = TRUE;
 4504                     CryptReleaseContext (hRngProv, 0);
 4505                 }
 4506             }
 4507 
 4508             SetTimer (GetParent (hwndDlg), TIMER_ID_RANDVIEW, TIMER_INTERVAL_RANDVIEW, NULL);
 4509 
 4510             hRandPoolSys = GetDlgItem (hwndDlg, IDC_SYS_POOL_CONTENTS);
 4511             hEntropyBar = GetDlgItem (hwndDlg, IDC_ENTROPY_BAR);
 4512             SendMessage (hEntropyBar, PBM_SETRANGE32, 0, maxEntropyLevel);
 4513             SendMessage (hEntropyBar, PBM_SETSTEP, 1, 0);
 4514 
 4515             SendMessage (GetDlgItem (hwndDlg, IDC_SYS_POOL_CONTENTS), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
 4516 
 4517             SendMessage (GetDlgItem (hwndDlg, IDC_DISPLAY_POOL_CONTENTS), BM_SETCHECK, showKeys ? BST_CHECKED : BST_UNCHECKED, 0);
 4518 
 4519             DisplayRandPool (hwndDlg, hRandPoolSys, showKeys);
 4520 
 4521             break;
 4522 
 4523         case SYSENC_KEYS_GEN_PAGE:
 4524 
 4525             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("KEYS_GEN_TITLE"));
 4526             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4527             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4528             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4529             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4530 
 4531             hMasterKey = GetDlgItem (hwndDlg, IDC_DISK_KEY);
 4532             hHeaderKey = GetDlgItem (hwndDlg, IDC_HEADER_KEY);
 4533 
 4534             SendMessage (GetDlgItem (hwndDlg, IDC_DISK_KEY), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
 4535             SendMessage (GetDlgItem (hwndDlg, IDC_HEADER_KEY), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
 4536 
 4537             SendMessage (GetDlgItem (hwndDlg, IDC_DISPLAY_KEYS), BM_SETCHECK, showKeys ? BST_CHECKED : BST_UNCHECKED, 0);
 4538 
 4539             DisplayPortionsOfKeys (hHeaderKey, hMasterKey, HeaderKeyGUIView, MasterKeyGUIView, !showKeys);
 4540 
 4541             break;
 4542 
 4543         case SYSENC_RESCUE_DISK_CREATION_PAGE:
 4544 
 4545             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("RESCUE_DISK"));
 4546             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4547             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4548             SetWindowTextW (GetDlgItem (hwndDlg, IDT_RESCUE_DISK_INFO), bSystemIsGPT? GetString ("RESCUE_DISK_EFI_INFO"): GetString ("RESCUE_DISK_INFO"));
 4549             SetDlgItemText (hwndDlg, IDC_RESCUE_DISK_ISO_PATH, szRescueDiskISO);
 4550             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), (GetWindowTextLength (GetDlgItem (hwndDlg, IDC_RESCUE_DISK_ISO_PATH)) > 1));
 4551             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4552 
 4553             break;
 4554 
 4555         case SYSENC_RESCUE_DISK_BURN_PAGE:
 4556             {
 4557                 wchar_t szTmp[8192];
 4558 
 4559                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bDontVerifyRescueDisk ? "RESCUE_DISK_CREATED_TITLE" : "RESCUE_DISK_RECORDING_TITLE"));
 4560                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4561                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4562 
 4563                 if (bSystemIsGPT)
 4564                 {
 4565                     StringCbPrintfW (szTmp, sizeof szTmp,
 4566                         GetString (bDontVerifyRescueDisk ? "RESCUE_DISK_EFI_EXTRACT_INFO_NO_CHECK" : "RESCUE_DISK_EFI_EXTRACT_INFO"),
 4567                         szRescueDiskISO, GetString ("RESCUE_DISK_EFI_EXTRACT_INFO_NOTE"));
 4568                 }
 4569                 else
 4570                 {
 4571                     StringCbPrintfW (szTmp, sizeof szTmp,
 4572                         GetString (bDontVerifyRescueDisk ? "RESCUE_DISK_BURN_INFO_NO_CHECK" : "RESCUE_DISK_BURN_INFO"),
 4573                         szRescueDiskISO, IsWindowsIsoBurnerAvailable() ? L"" : GetString ("RESCUE_DISK_BURN_INFO_NONWIN_ISO_BURNER"));
 4574 
 4575                 }
 4576                 SetWindowTextW (GetDlgItem (hwndDlg, IDT_RESCUE_DISK_BURN_INFO), szTmp);
 4577                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4578 
 4579                 /* The 'Back' button must be disabled now because the user could burn a Rescue Disk, then go back, and
 4580                 generate a different master key, which would cause the Rescue Disk verification to fail (the result
 4581                 would be confusion and bug reports). */
 4582                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4583 
 4584                 if (bSystemIsGPT)
 4585                 {
 4586                     ShowWindow (GetDlgItem (hwndDlg, IDC_DOWNLOAD_CD_BURN_SOFTWARE), SW_HIDE);
 4587                 }
 4588                 else
 4589                 {
 4590                     if (IsWindowsIsoBurnerAvailable())
 4591                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_DOWNLOAD_CD_BURN_SOFTWARE), GetString ("LAUNCH_WIN_ISOBURN"));
 4592 
 4593                     ToHyperlink (hwndDlg, IDC_DOWNLOAD_CD_BURN_SOFTWARE);
 4594 
 4595                     if (IsWindowsIsoBurnerAvailable() && !bDontVerifyRescueDisk)
 4596                         LaunchWindowsIsoBurner (hwndDlg, szRescueDiskISO);
 4597                 }
 4598             }           
 4599             break;
 4600 
 4601         case SYSENC_RESCUE_DISK_VERIFIED_PAGE:
 4602 
 4603             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("RESCUE_DISK_DISK_VERIFIED_TITLE"));
 4604             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("RESCUE_DISK_VERIFIED_INFO"));
 4605 
 4606             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4607             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4608 
 4609             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4610 
 4611             // Rescue Disk has been verified, no need to go back
 4612             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4613 
 4614             // Prevent losing the burned rescue disk by inadvertent exit
 4615             bConfirmQuit = TRUE;
 4616 
 4617             break;
 4618 
 4619         case SYSENC_WIPE_MODE_PAGE:
 4620         case NONSYS_INPLACE_ENC_WIPE_MODE_PAGE:
 4621             {
 4622                 if (nWipeMode == TC_WIPE_1_RAND)
 4623                     nWipeMode = TC_WIPE_NONE;
 4624 
 4625                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("WIPE_MODE_TITLE"));
 4626                 SetWindowTextW (GetDlgItem (hwndDlg, IDT_WIPE_MODE_INFO), GetString ("INPLACE_ENC_WIPE_MODE_INFO"));
 4627 
 4628                 PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE),
 4629                     SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING && !bInPlaceEncNonSys,
 4630                     TRUE,
 4631                     FALSE);
 4632 
 4633                 SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &nWipeMode);
 4634 
 4635                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
 4636 
 4637                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4638                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4639                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4640             }
 4641             break;
 4642 
 4643         case SYSENC_PRETEST_INFO_PAGE:
 4644 
 4645             if (bHiddenOS)
 4646             {
 4647                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("HIDDEN_OS_CREATION_PREINFO_TITLE"));
 4648                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("HIDDEN_OS_CREATION_PREINFO_HELP"));
 4649                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("START"));
 4650                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4651             }
 4652             else
 4653             {
 4654                 wchar_t finalMsg[8024] = {0};
 4655 
 4656                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYS_ENCRYPTION_PRETEST_TITLE"));
 4657 
 4658                 try
 4659                 {
 4660                     StringCbPrintfW (finalMsg, sizeof(finalMsg),
 4661                         GetString ("SYS_ENCRYPTION_PRETEST_INFO"),
 4662                         BootEncObj->GetSystemDriveConfiguration().DriveNumber);
 4663                 }
 4664                 catch (Exception &e)
 4665                 {
 4666                     e.Show (hwndDlg);
 4667                     EndMainDlg (MainDlg);
 4668                     return 0;
 4669                 }
 4670 
 4671                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), finalMsg);
 4672                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("TEST"));
 4673                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4674             }
 4675 
 4676             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4677             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4678 
 4679             break;
 4680 
 4681         case SYSENC_PRETEST_RESULT_PAGE:
 4682 
 4683             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SYS_ENCRYPTION_PRETEST_RESULT_TITLE"));
 4684             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYS_ENCRYPTION_PRETEST_RESULT_INFO"));
 4685 
 4686             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("ENCRYPT"));
 4687             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4688             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("DEFER"));
 4689 
 4690             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4691             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4692             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
 4693 
 4694             break;
 4695 
 4696         case SYSENC_ENCRYPTION_PAGE:
 4697 
 4698             if (CreateSysEncMutex ())
 4699             {
 4700                 try
 4701                 {
 4702                     BootEncStatus = BootEncObj->GetStatus();
 4703                     bSystemEncryptionInProgress = BootEncStatus.SetupInProgress;
 4704                 }
 4705                 catch (Exception &e)
 4706                 {
 4707                     e.Show (hwndDlg);
 4708                     Error ("ERR_GETTING_SYSTEM_ENCRYPTION_STATUS", MainDlg);
 4709                     EndMainDlg (MainDlg);
 4710                     return 0;
 4711                 }
 4712 
 4713                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE),
 4714                     GetString (SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING ? "ENCRYPTION" : "DECRYPTION"));
 4715 
 4716                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_ENCRYPTION_PAGE_INFO"));
 4717 
 4718                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("DEFER"));
 4719 
 4720                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4721 
 4722                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT),
 4723                     GetString (SystemEncryptionStatus != SYSENC_STATUS_DECRYPTING ? "ENCRYPT" : "DECRYPT"));
 4724 
 4725                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_PAUSE),
 4726                     GetString (bSystemEncryptionInProgress ? "IDC_PAUSE" : "RESUME"));
 4727 
 4728                 EnableWindow (GetDlgItem (hwndDlg, IDC_PAUSE), BootEncStatus.DriveEncrypted);
 4729                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4730                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), !BootEncStatus.SetupInProgress);
 4731                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
 4732                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
 4733 
 4734                 ToHyperlink (hwndDlg, IDC_MORE_INFO_SYS_ENCRYPTION);
 4735 
 4736                 if (SystemEncryptionStatus == SYSENC_STATUS_DECRYPTING)
 4737                 {
 4738                     nWipeMode = TC_WIPE_NONE;
 4739                     EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE);
 4740                     EnableWindow (GetDlgItem (hwndDlg, IDT_WIPE_MODE), FALSE);
 4741                     PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), TRUE, TRUE, FALSE);
 4742                     SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &nWipeMode);
 4743                 }
 4744                 else
 4745                 {
 4746                     EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_MODE), !bSystemEncryptionInProgress);
 4747                     PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, TRUE, FALSE);
 4748                     SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &nWipeMode);
 4749                 }
 4750 
 4751                 PostMessage (hwndDlg, TC_APPMSG_PERFORM_POST_SYSENC_WMINIT_TASKS, 0, 0);
 4752             }
 4753             else
 4754             {
 4755                 Error ("SYSTEM_ENCRYPTION_IN_PROGRESS_ELSEWHERE", MainDlg);
 4756                 EndMainDlg (MainDlg);
 4757                 return 0;
 4758             }
 4759             return 0;
 4760 
 4761         case NONSYS_INPLACE_ENC_RESUME_PARTITION_SEL_PAGE:
 4762 
 4763             {
 4764                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("FILE_TITLE"));
 4765                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("NONSYS_INPLACE_ENC_RESUME_VOL_SELECT_HELP"));
 4766 
 4767                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 4768                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), FALSE);
 4769 
 4770                 foreach (const HostDevice &device, DeferredNonSysInPlaceEncDevices)
 4771                 {
 4772                     SendMessage (GetDlgItem (hwndDlg, IDC_LIST_BOX), LB_ADDSTRING, 0, (LPARAM) device.Path.c_str());
 4773                 }
 4774 
 4775                 // Deselect all
 4776                 SendMessage (GetDlgItem (hwndDlg, IDC_LIST_BOX), LB_SETCURSEL, (WPARAM) -1, 0);
 4777             }
 4778 
 4779             break;
 4780 
 4781         case NONSYS_INPLACE_ENC_TRANSFORM_PAGE:
 4782 
 4783             if (bInPlaceEncNonSysResumed)
 4784             {
 4785                 WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE;
 4786 
 4787                 if (LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0)
 4788                     nWipeMode = savedWipeAlgorithm;
 4789             }
 4790 
 4791             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bInPlaceDecNonSys ? "DECRYPTION" : "ENCRYPTION"));
 4792 
 4793             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_DECRYPTION_PAGE_INFO" : "NONSYS_INPLACE_ENC_ENCRYPTION_PAGE_INFO"));
 4794 
 4795             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString (bInPlaceEncNonSysResumed ? "DEFER" : "CANCEL"));
 4796 
 4797             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4798 
 4799             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString (bInPlaceEncNonSysResumed ? "RESUME" : (bInPlaceDecNonSys ? "DECRYPT" : "ENCRYPT")));
 4800 
 4801             SetWindowTextW (GetDlgItem (hwndDlg, IDC_PAUSE), GetString ("IDC_PAUSE"));
 4802 
 4803             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), !bInPlaceEncNonSysResumed && !bInPlaceDecNonSys);
 4804             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4805             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
 4806             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
 4807             EnableWindow (GetDlgItem (hwndDlg, IDC_PAUSE), FALSE);
 4808 
 4809             ShowWindow (GetDlgItem (hwndDlg, IDC_MORE_INFO_SYS_ENCRYPTION), SW_HIDE);
 4810 
 4811             if (bInPlaceDecNonSys)
 4812             {
 4813                 ShowWindow(GetDlgItem(hwndDlg, IDT_FORMAT_OPTIONS), SW_HIDE);
 4814                 ShowWindow(GetDlgItem(hwndDlg, IDT_WIPE_MODE), SW_HIDE);
 4815                 ShowWindow(GetDlgItem(hwndDlg, IDC_WIPE_MODE), SW_HIDE);
 4816             }
 4817             else
 4818             {
 4819                 EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_MODE), TRUE);
 4820                 PopulateWipeModeCombo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), FALSE, TRUE, FALSE);
 4821                 SelectAlgo (GetDlgItem (hwndDlg, IDC_WIPE_MODE), (int *) &nWipeMode);
 4822             }
 4823 
 4824             break;
 4825 
 4826         case NONSYS_INPLACE_ENC_TRANSFORM_FINISHED_PAGE:
 4827 
 4828             bConfirmQuit = FALSE;
 4829 
 4830             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_FINISHED_TITLE" : "NONSYS_INPLACE_ENC_FINISHED_TITLE"));
 4831 
 4832             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_FINISHED_INFO" : "NONSYS_INPLACE_ENC_FINISHED_INFO"));
 4833 
 4834             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4835             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("FINALIZE"));
 4836             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4837             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4838 
 4839             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("EXIT"));
 4840             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), FALSE);
 4841 
 4842             break;
 4843 
 4844         case NONSYS_INPLACE_DEC_TRANSFORM_FINISHED_DRIVE_LETTER_PAGE:
 4845 
 4846             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("NONSYS_INPLACE_DEC_FINISHED_TITLE"));
 4847 
 4848             SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("NONSYS_INPLACE_DEC_FINISHED_DRIVE_LETTER_SEL_INFO"));
 4849 
 4850             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 4851             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("FINALIZE"));
 4852             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
 4853             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 4854 
 4855             SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
 4856 
 4857             // The Cancel button and the X button must be disabled to prevent the user from forgetting to assign a drive letter to the partition by closing
 4858             // the window accidentally or clicking Cancel. The user is forced to click Finish to assign at least the pre-selected free drive letter.
 4859             // This is critical because inexperienced users would not know how to access data on the decrypted volume without a drive letter.
 4860             EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), FALSE);
 4861             DisableCloseButton (MainDlg);
 4862             bConfirmQuit = TRUE;    // Alt-F4 will still work but the user will be prompted to confirm the action.
 4863 
 4864             // Decryption of non-system volume finished, no drive letter is assigned to the decrypted volume, and free drive letters are available.
 4865             // This is critical because inexperienced users would not know how to access data on the decrypted volume. We cannot allow exit
 4866             // until a drive letter is freed up and assigned to the decrypted volume.
 4867 
 4868             while (GetFirstAvailableDrive () == -1)
 4869             {
 4870                 Error ("NONSYS_INPLACE_DEC_FINISHED_NO_DRIVE_LETTER_AVAILABLE", hwndDlg);
 4871             }
 4872 
 4873             // Populate the combobox with free drive letters
 4874             {
 4875                 DWORD dwUsedDrives = GetUsedLogicalDrives();
 4876                 wchar_t szDriveLetter[] = {L' ', L':', 0 };
 4877                 int i;
 4878 
 4879                 for (i = 0; i < 26; i++)
 4880                 {
 4881                     if (!(dwUsedDrives & 1 << i))
 4882                     {
 4883                         // Add
 4884                         szDriveLetter [0] = (wchar_t) (i + L'A');
 4885                         AddComboPair (GetDlgItem (hCurPage, IDC_DRIVE_LETTER_LIST), szDriveLetter, i);
 4886                     }
 4887                 }
 4888             }
 4889             SendMessage (GetDlgItem (hwndDlg, IDC_DRIVE_LETTER_LIST), CB_SETCURSEL, 0, 0);
 4890             break;
 4891 
 4892         case FORMAT_PAGE:
 4893             {
 4894                 BOOL bNTFSallowed = FALSE;
 4895                 BOOL bFATallowed = FALSE;
 4896                 BOOL bEXFATallowed = FALSE;
 4897                 BOOL bReFSallowed = FALSE;
 4898                 BOOL bNoFSallowed = FALSE;
 4899                 HCRYPTPROV hRngProv;
 4900 
 4901                 mouseEntropyGathered = 0xFFFFFFFF;
 4902                 mouseEventsInitialCount = 0;
 4903                 bUseMask = FALSE;
 4904                 if (CryptAcquireContext (&hRngProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
 4905                 {
 4906                     if (CryptGenRandom (hRngProv, sizeof (maskRandPool), maskRandPool))
 4907                         bUseMask = TRUE;
 4908                     CryptReleaseContext (hRngProv, 0);
 4909                 }
 4910 
 4911                 SetTimer (GetParent (hwndDlg), TIMER_ID_RANDVIEW, TIMER_INTERVAL_RANDVIEW, NULL);
 4912 
 4913                 hMasterKey = GetDlgItem (hwndDlg, IDC_DISK_KEY);
 4914                 hHeaderKey = GetDlgItem (hwndDlg, IDC_HEADER_KEY);
 4915                 hRandPool = GetDlgItem (hwndDlg, IDC_RANDOM_BYTES);
 4916                 hEntropyBar = GetDlgItem (hwndDlg, IDC_ENTROPY_BAR);
 4917                 SendMessage (hEntropyBar, PBM_SETRANGE32, 0, maxEntropyLevel);
 4918                 SendMessage (hEntropyBar, PBM_SETSTEP, 1, 0);
 4919 
 4920                 SendMessage (GetDlgItem (hwndDlg, IDC_RANDOM_BYTES), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
 4921                 SendMessage (GetDlgItem (hwndDlg, IDC_DISK_KEY), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
 4922                 SendMessage (GetDlgItem (hwndDlg, IDC_HEADER_KEY), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
 4923 
 4924                 SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP),
 4925                     GetString (bHiddenVolHost ? "FORMAT_HIDVOL_HOST_HELP" : "FORMAT_HELP"));
 4926 
 4927                 if (bHiddenVol)
 4928                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bHiddenVolHost ? "FORMAT_HIDVOL_HOST_TITLE" : "FORMAT_HIDVOL_TITLE"));
 4929                 else
 4930                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("FORMAT_TITLE"));
 4931 
 4932                 /* Quick/Dynamic */
 4933 
 4934                 if (bHiddenVol)
 4935                 {
 4936                     quickFormat = !bHiddenVolHost;
 4937                     bSparseFileSwitch = FALSE;
 4938 
 4939                     SetCheckBox (hwndDlg, IDC_QUICKFORMAT, quickFormat);
 4940                     SetWindowTextW (GetDlgItem (hwndDlg, IDC_QUICKFORMAT), GetString ((bDevice || !bHiddenVolHost) ? "IDC_QUICKFORMAT" : "SPARSE_FILE"));
 4941                     EnableWindow (GetDlgItem (hwndDlg, IDC_QUICKFORMAT), bDevice && bHiddenVolHost);
 4942                 }
 4943                 else
 4944                 {
 4945                     if (bDevice)
 4946                     {
 4947                         bSparseFileSwitch = FALSE;
 4948                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_QUICKFORMAT), GetString("IDC_QUICKFORMAT"));
 4949                         EnableWindow (GetDlgItem (hwndDlg, IDC_QUICKFORMAT), TRUE);
 4950                     }
 4951                     else
 4952                     {
 4953                         wchar_t root[TC_MAX_PATH];
 4954                         DWORD fileSystemFlags = 0;
 4955 
 4956                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_QUICKFORMAT), GetString("SPARSE_FILE"));
 4957 
 4958                         /* Check if the host file system supports sparse files */
 4959 
 4960                         if (GetVolumePathName (szFileName, root, array_capacity (root)))
 4961                         {
 4962                             GetVolumeInformation (root, NULL, 0, NULL, NULL, &fileSystemFlags, NULL, 0);
 4963                             bSparseFileSwitch = fileSystemFlags & FILE_SUPPORTS_SPARSE_FILES;
 4964                         }
 4965                         else
 4966                             bSparseFileSwitch = FALSE;
 4967 
 4968                         EnableWindow (GetDlgItem (hwndDlg, IDC_QUICKFORMAT), bSparseFileSwitch);
 4969                     }
 4970                 }
 4971 
 4972                 SendMessage (GetDlgItem (hwndDlg, IDC_SHOW_KEYS), BM_SETCHECK, showKeys ? BST_CHECKED : BST_UNCHECKED, 0);
 4973                 SetWindowText (GetDlgItem (hwndDlg, IDC_RANDOM_BYTES), showKeys ? L"" : L"********************************                                              ");
 4974                 SetWindowText (GetDlgItem (hwndDlg, IDC_HEADER_KEY), showKeys ? L"" : L"********************************                                              ");
 4975                 SetWindowText (GetDlgItem (hwndDlg, IDC_DISK_KEY), showKeys ? L"" : L"********************************                                              ");
 4976 
 4977                 EnableWindow (GetDlgItem (hwndDlg, IDC_CLUSTERSIZE), TRUE);
 4978 
 4979                 /* Filesystems */
 4980 
 4981                 bNTFSallowed = FALSE;
 4982                 bFATallowed = FALSE;
 4983                 bNoFSallowed = FALSE;
 4984 
 4985                 SendMessage (GetDlgItem (hwndDlg, IDC_FILESYS), CB_RESETCONTENT, 0, 0);
 4986 
 4987                 EnableWindow (GetDlgItem (hwndDlg, IDC_FILESYS), TRUE);
 4988 
 4989                 uint64 dataAreaSize = GetVolumeDataAreaSize (bHiddenVol && !bHiddenVolHost, nVolumeSize);
 4990 
 4991                 if (!CreatingHiddenSysVol())
 4992                 {
 4993                     if (dataAreaSize >= TC_MIN_NTFS_FS_SIZE && dataAreaSize <= TC_MAX_NTFS_FS_SIZE)
 4994                     {
 4995                         AddComboPair (GetDlgItem (hwndDlg, IDC_FILESYS), L"NTFS", FILESYS_NTFS);
 4996                         bNTFSallowed = TRUE;
 4997                     }
 4998 
 4999                     if (dataAreaSize >= TC_MIN_FAT_FS_SIZE && dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize())
 5000                     {
 5001                         AddComboPair (GetDlgItem (hwndDlg, IDC_FILESYS), L"FAT", FILESYS_FAT);
 5002                         bFATallowed = TRUE;
 5003                     }
 5004 
 5005                     //exFAT support added starting from Vista SP1
 5006                     if (IsOSVersionAtLeast (WIN_VISTA, 1) && dataAreaSize >= TC_MIN_EXFAT_FS_SIZE && dataAreaSize <= TC_MAX_EXFAT_FS_SIZE)
 5007                     {
 5008                         AddComboPair (GetDlgItem (hwndDlg, IDC_FILESYS), L"exFAT", FILESYS_EXFAT);
 5009                         bEXFATallowed = TRUE;
 5010                     }
 5011 
 5012                     //ReFS write support activated by default starting from Windows 10
 5013                     //We don't support it yet for the creation of hidden volumes
 5014                     if ((!bHiddenVolHost) && IsOSVersionAtLeast (WIN_10, 0) && dataAreaSize >= TC_MIN_REFS_FS_SIZE && dataAreaSize <= TC_MAX_REFS_FS_SIZE)
 5015                     {
 5016                         AddComboPair (GetDlgItem (hwndDlg, IDC_FILESYS), L"ReFS", FILESYS_REFS);
 5017                         bReFSallowed = TRUE;
 5018                     }
 5019                 }
 5020                 else
 5021                 {
 5022                     // We're creating a hidden volume for a hidden OS, so we don't need to format it with
 5023                     // any filesystem (the entire OS will be copied to the hidden volume sector by sector).
 5024                     EnableWindow (GetDlgItem (hwndDlg, IDC_FILESYS), FALSE);
 5025                     EnableWindow (GetDlgItem (hwndDlg, IDC_CLUSTERSIZE), FALSE);
 5026                 }
 5027 
 5028                 if (!bHiddenVolHost)
 5029                 {
 5030                     AddComboPair (GetDlgItem (hwndDlg, IDC_FILESYS), GetString ("NONE"), FILESYS_NONE);
 5031                     bNoFSallowed = TRUE;
 5032                 }
 5033 
 5034                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
 5035 
 5036                 if (fileSystem == FILESYS_NONE) // If no file system has been previously selected
 5037                 {
 5038                     // Set default file system
 5039 
 5040                     if (bFATallowed && !(nNeedToStoreFilesOver4GB == 1 && (bNTFSallowed || bEXFATallowed || bReFSallowed)))
 5041                         fileSystem = FILESYS_FAT;
 5042                     else if (bEXFATallowed)
 5043                         fileSystem = FILESYS_EXFAT;
 5044                     else if (bNTFSallowed)
 5045                         fileSystem = FILESYS_NTFS;
 5046                     else if (bReFSallowed)
 5047                         fileSystem = FILESYS_REFS;
 5048                     else if (bNoFSallowed)
 5049                         fileSystem = FILESYS_NONE;
 5050                     else
 5051                     {
 5052                         AddComboPair (GetDlgItem (hwndDlg, IDC_FILESYS), L"---", 0);
 5053                         EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), FALSE);
 5054                     }
 5055                 }
 5056 
 5057                 SendMessage (GetDlgItem (hwndDlg, IDC_FILESYS), CB_SETCURSEL, 0, 0);
 5058                 SelectAlgo (GetDlgItem (hwndDlg, IDC_FILESYS), (int *) &fileSystem);
 5059 
 5060                 UpdateClusterSizeList (hwndDlg, fileSystem);
 5061 
 5062                 EnableWindow (GetDlgItem (hwndDlg, IDC_ABORT_BUTTON), FALSE);
 5063 
 5064                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("FORMAT"));
 5065                 SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
 5066 
 5067                 EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
 5068 
 5069                 SetFocus (GetDlgItem (GetParent (hwndDlg), IDC_NEXT));
 5070             }
 5071             break;
 5072 
 5073         case FORMAT_FINISHED_PAGE:
 5074             {
 5075                 if (!bHiddenVolHost && bHiddenVol && !bHiddenVolFinished)
 5076                 {
 5077                     wchar_t msg[4096];
 5078 
 5079                     nNeedToStoreFilesOver4GB = -1;
 5080 
 5081                     if (bHiddenOS)
 5082                     {
 5083                         wchar_t szMaxRecomOuterVolFillSize[100];
 5084 
 5085                         __int64 maxRecomOuterVolFillSize = 0;
 5086 
 5087                         // Determine the maximum recommended total size of files that can be copied to the outer volume
 5088                         // while leaving enough space for the hidden volume, which must contain a clone of the OS
 5089 
 5090                         maxRecomOuterVolFillSize = nVolumeSize - GetSystemPartitionSize();
 5091 
 5092                         // -50% reserve for filesystem "peculiarities"
 5093                         maxRecomOuterVolFillSize /= 2;
 5094 
 5095                         StringCbPrintfW (szMaxRecomOuterVolFillSize, sizeof(szMaxRecomOuterVolFillSize), L"%I64d %s", maxRecomOuterVolFillSize / BYTES_PER_MB, GetString ("MB"));
 5096 
 5097                         StringCbPrintfW (msg, sizeof(msg), GetString ("HIDVOL_HOST_FILLING_HELP_SYSENC"), hiddenVolHostDriveNo + 'A', szMaxRecomOuterVolFillSize);
 5098                     }
 5099                     else
 5100                         StringCbPrintfW (msg, sizeof(msg), GetString ("HIDVOL_HOST_FILLING_HELP"), hiddenVolHostDriveNo + 'A');
 5101 
 5102                     SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), msg);
 5103                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("HIDVOL_HOST_FILLING_TITLE"));
 5104                 }
 5105                 else
 5106                 {
 5107                     if (bHiddenOS)
 5108                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SYSENC_HIDDEN_VOL_FORMAT_FINISHED_HELP"));
 5109                     else
 5110                     {
 5111                         SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString (bInPlaceEncNonSys ? "NONSYS_INPLACE_ENC_FINISHED_INFO" : "FORMAT_FINISHED_HELP"));
 5112                         bConfirmQuit = FALSE;
 5113                     }
 5114 
 5115                     SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bH