Annotation of truecrypt/common/dlgcode.c, revision 1.1.1.23

1.1.1.11  root        1: /*
1.1.1.13  root        2:  Legal Notice: Some portions of the source code contained in this file were
                      3:  derived from the source code of Encryption for the Masses 2.02a, which is
                      4:  Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
                      5:  Agreement for Encryption for the Masses'. Modifications and additions to
                      6:  the original source code (contained in this file) and all other portions of
1.1.1.21  root        7:  this file are Copyright (c) 2003-2009 TrueCrypt Foundation and are governed
1.1.1.23! root        8:  by the TrueCrypt License 2.8 the full text of which is contained in the
1.1.1.13  root        9:  file License.txt included in TrueCrypt binary and source code distribution
1.1.1.11  root       10:  packages. */
1.1       root       11: 
1.1.1.7   root       12: #include "Tcdefs.h"
1.1       root       13: 
1.1.1.19  root       14: #include <windowsx.h>
1.1.1.21  root       15: #include <dbghelp.h>
1.1.1.7   root       16: #include <dbt.h>
                     17: #include <fcntl.h>
                     18: #include <io.h>
1.1.1.12  root       19: #include <math.h>
1.1.1.7   root       20: #include <shlobj.h>
                     21: #include <sys/stat.h>
1.1       root       22: #include <stdlib.h>
1.1.1.5   root       23: #include <time.h>
1.1       root       24: 
1.1.1.7   root       25: #include "Resource.h"
                     26: 
1.1.1.19  root       27: #include "Platform/Finally.h"
                     28: #include "Platform/ForEach.h"
1.1.1.7   root       29: #include "Apidrvr.h"
1.1.1.15  root       30: #include "BootEncryption.h"
1.1.1.11  root       31: #include "Combo.h"
1.1.1.12  root       32: #include "Crc.h"
1.1.1.7   root       33: #include "Crypto.h"
                     34: #include "Dictionary.h"
                     35: #include "Dlgcode.h"
1.1.1.17  root       36: #include "EncryptionThreadPool.h"
1.1.1.13  root       37: #include "Endian.h"
1.1.1.21  root       38: #include "Format/Inplace.h"
1.1.1.7   root       39: #include "Language.h"
                     40: #include "Keyfiles.h"
                     41: #include "Pkcs5.h"
                     42: #include "Random.h"
                     43: #include "Registry.h"
1.1.1.19  root       44: #include "SecurityToken.h"
1.1.1.7   root       45: #include "Tests.h"
                     46: #include "Volumes.h"
1.1.1.13  root       47: #include "Wipe.h"
1.1.1.7   root       48: #include "Xml.h"
1.1.1.13  root       49: #include "Xts.h"
1.1.1.19  root       50: #include "Boot/Windows/BootCommon.h"
1.1.1.5   root       51: 
1.1.1.23! root       52: #ifdef TCMOUNT
        !            53: #include "Mount/Mount.h"
        !            54: #endif
1.1.1.15  root       55: 
1.1.1.11  root       56: #ifdef VOLFORMAT
                     57: #include "Format/Tcformat.h"
                     58: #endif
                     59: 
1.1.1.15  root       60: #ifdef SETUP
                     61: #include "Setup/Setup.h"
                     62: #endif
                     63: 
1.1.1.23! root       64: using namespace TrueCrypt;
        !            65: 
1.1.1.11  root       66: LONG DriverVersion;
                     67: 
1.1.1.10  root       68: char *LastDialogId;
1.1       root       69: char szHelpFile[TC_MAX_PATH];
1.1.1.7   root       70: char szHelpFile2[TC_MAX_PATH];
1.1.1.19  root       71: char SecurityTokenLibraryPath[TC_MAX_PATH];
                     72: 
1.1.1.7   root       73: HFONT hFixedDigitFont = NULL;
1.1       root       74: HFONT hBoldFont = NULL;
                     75: HFONT hTitleFont = NULL;
                     76: HFONT hFixedFont = NULL;
                     77: 
                     78: HFONT hUserFont = NULL;
                     79: HFONT hUserUnderlineFont = NULL;
                     80: HFONT hUserBoldFont = NULL;
1.1.1.5   root       81: HFONT hUserUnderlineBoldFont = NULL;
1.1       root       82: 
1.1.1.23! root       83: HFONT WindowTitleBarFont;
        !            84: 
1.1.1.12  root       85: int ScreenDPI = USER_DEFAULT_SCREEN_DPI;
                     86: double DPIScaleFactorX = 1;
                     87: double DPIScaleFactorY = 1;
                     88: double DlgAspectRatio = 1;
                     89: 
1.1.1.7   root       90: HWND MainDlg = NULL;
                     91: wchar_t *lpszTitle = NULL;
                     92: 
                     93: BOOL Silent = FALSE;
                     94: BOOL bPreserveTimestamp = TRUE;
1.1.1.13  root       95: BOOL bStartOnLogon = FALSE;
                     96: BOOL bMountDevicesOnLogon = FALSE;
                     97: BOOL bMountFavoritesOnLogon = FALSE;
1.1.1.7   root       98: 
1.1.1.10  root       99: BOOL bHistory = FALSE;
                    100: 
1.1.1.16  root      101: // Status of detection of hidden sectors (whole-system-drive encryption). 
1.1.1.23! root      102: // 0 - Unknown/undetermined/completed, 1: Detection is or was in progress (but did not complete e.g. due to system crash).
1.1.1.16  root      103: int HiddenSectorDetectionStatus = 0;   
                    104: 
1.1.1.21  root      105: OSVersionEnum nCurrentOS = WIN_UNKNOWN;
1.1       root      106: int CurrentOSMajor = 0;
                    107: int CurrentOSMinor = 0;
1.1.1.10  root      108: int CurrentOSServicePack = 0;
                    109: BOOL RemoteSession = FALSE;
1.1.1.11  root      110: BOOL UacElevated = FALSE;
1.1       root      111: 
1.1.1.23! root      112: BOOL bPortableModeConfirmed = FALSE;           // TRUE if it is certain that the instance is running in portable mode
1.1.1.15  root      113: 
1.1.1.19  root      114: BOOL bInPlaceEncNonSysPending = FALSE;         // TRUE if the non-system in-place encryption config file indicates that one or more partitions are scheduled to be encrypted. This flag is set only when config files are loaded during app startup.
                    115: 
1.1.1.7   root      116: /* Globals used by Mount and Format (separately per instance) */ 
1.1.1.15  root      117: BOOL KeyFilesEnable = FALSE;
1.1.1.7   root      118: KeyFile        *FirstKeyFile = NULL;
                    119: KeyFilesDlgParam               defaultKeyFilesParam;
                    120: 
1.1.1.12  root      121: BOOL IgnoreWmDeviceChange = FALSE;
1.1.1.23! root      122: BOOL DeviceChangeBroadcastDisabled = FALSE;
        !           123: BOOL LastMountedVolumeDirty;
        !           124: BOOL MountVolumesAsSystemFavorite = FALSE;
1.1.1.12  root      125: 
1.1       root      126: /* Handle to the device driver */
                    127: HANDLE hDriver = INVALID_HANDLE_VALUE;
1.1.1.11  root      128: 
1.1.1.13  root      129: /* This mutex is used to prevent multiple instances of the wizard or main app from dealing with system encryption */
1.1.1.17  root      130: volatile HANDLE hSysEncMutex = NULL;           
1.1.1.13  root      131: 
1.1.1.19  root      132: /* This mutex is used for non-system in-place encryption but only for informative (non-blocking) purposes,
                    133: such as whether an app should prompt the user whether to resume scheduled process. */
                    134: volatile HANDLE hNonSysInplaceEncMutex = NULL;
                    135: 
1.1.1.15  root      136: /* This mutex is used to prevent multiple instances of the wizard or main app from trying to install or
1.1.1.23! root      137: register the driver or from trying to launch it in portable mode at the same time. */
1.1.1.17  root      138: volatile HANDLE hDriverSetupMutex = NULL;
                    139: 
                    140: /* This mutex is used to prevent users from running the main TrueCrypt app or the wizard while an instance
                    141: of the TrueCrypt installer is running (which is also useful for enforcing restart before the apps can be used). */
                    142: volatile HANDLE hAppSetupMutex = NULL;
1.1.1.15  root      143: 
1.1       root      144: HINSTANCE hInst = NULL;
                    145: HCURSOR hCursor = NULL;
                    146: 
                    147: ATOM hDlgClass, hSplashClass;
                    148: 
1.1.1.13  root      149: /* This value may changed only by calling ChangeSystemEncryptionStatus(). Only the wizard can change it
                    150: (others may still read it though). */
                    151: int SystemEncryptionStatus = SYSENC_STATUS_NONE;       
                    152: 
                    153: /* Only the wizard can change this value (others may only read it). */
                    154: WipeAlgorithmId nWipeMode = TC_WIPE_NONE;
                    155: 
                    156: BOOL bSysPartitionSelected = FALSE;            /* TRUE if the user selected the system partition via the Select Device dialog */
                    157: BOOL bSysDriveSelected = FALSE;                        /* TRUE if the user selected the system drive via the Select Device dialog */
                    158: 
                    159: /* To populate these arrays, call GetSysDevicePaths(). If they contain valid paths, bCachedSysDevicePathsValid is TRUE. */
                    160: char SysPartitionDevicePath [TC_MAX_PATH];
                    161: char SysDriveDevicePath [TC_MAX_PATH];
                    162: char bCachedSysDevicePathsValid = FALSE;
                    163: 
                    164: BOOL bHyperLinkBeingTracked = FALSE;
                    165: 
1.1.1.17  root      166: int WrongPwdRetryCounter = 0;
                    167: 
1.1.1.7   root      168: static FILE *ConfigFileHandle;
1.1.1.13  root      169: char *ConfigBuffer;
1.1.1.7   root      170: 
1.1.1.13  root      171: #define RANDPOOL_DISPLAY_REFRESH_INTERVAL      30
                    172: #define RANDPOOL_DISPLAY_ROWS 20
                    173: #define RANDPOOL_DISPLAY_COLUMNS 32
1.1.1.7   root      174: 
1.1       root      175: /* Windows dialog class */
                    176: #define WINDOWS_DIALOG_CLASS "#32770"
                    177: 
                    178: /* Custom class names */
                    179: #define TC_DLG_CLASS "CustomDlg"
                    180: #define TC_SPLASH_CLASS "SplashDlg"
                    181: 
1.1.1.7   root      182: /* Benchmarks */
                    183: 
1.1.1.5   root      184: #ifndef SETUP
1.1.1.7   root      185: 
1.1.1.5   root      186: #define BENCHMARK_MAX_ITEMS 100
1.1.1.7   root      187: #define BENCHMARK_DEFAULT_BUF_SIZE     BYTES_PER_MB
                    188: #define HASH_FNC_BENCHMARKS    FALSE   // For development purposes only. Must be FALSE when building a public release.
                    189: #define PKCS5_BENCHMARKS       FALSE   // For development purposes only. Must be FALSE when building a public release.
                    190: #if PKCS5_BENCHMARKS && HASH_FNC_BENCHMARKS
                    191: #error PKCS5_BENCHMARKS and HASH_FNC_BENCHMARKS are both TRUE (at least one of them should be FALSE).
                    192: #endif
1.1.1.5   root      193: 
                    194: enum 
                    195: {
                    196:        BENCHMARK_SORT_BY_NAME = 0,
                    197:        BENCHMARK_SORT_BY_SPEED
                    198: };
                    199: 
                    200: typedef struct 
                    201: {
                    202:        int id;
                    203:        char name[100];
                    204:        unsigned __int64 encSpeed;
                    205:        unsigned __int64 decSpeed;
                    206:        unsigned __int64 meanBytesPerSec;
                    207: } BENCHMARK_REC;
                    208: 
                    209: BENCHMARK_REC benchmarkTable [BENCHMARK_MAX_ITEMS];
                    210: int benchmarkTotalItems = 0;
                    211: int benchmarkBufferSize = BENCHMARK_DEFAULT_BUF_SIZE;
                    212: int benchmarkLastBufferSize = BENCHMARK_DEFAULT_BUF_SIZE;
                    213: int benchmarkSortMethod = BENCHMARK_SORT_BY_SPEED;
                    214: LARGE_INTEGER benchmarkPerformanceFrequency;
1.1.1.7   root      215: 
1.1.1.5   root      216: #endif // #ifndef SETUP
                    217: 
                    218: 
1.1.1.19  root      219: typedef struct 
                    220: {
                    221:        void *strings;
                    222:        BOOL bold;
                    223: 
                    224: } MULTI_CHOICE_DLGPROC_PARAMS;
                    225: 
                    226: 
1.1.1.17  root      227: void cleanup ()
1.1       root      228: {
                    229:        /* Cleanup the GDI fonts */
                    230:        if (hFixedFont != NULL)
                    231:                DeleteObject (hFixedFont);
1.1.1.7   root      232:        if (hFixedDigitFont != NULL)
                    233:                DeleteObject (hFixedDigitFont);
1.1       root      234:        if (hBoldFont != NULL)
                    235:                DeleteObject (hBoldFont);
                    236:        if (hTitleFont != NULL)
                    237:                DeleteObject (hTitleFont);
                    238:        if (hUserFont != NULL)
                    239:                DeleteObject (hUserFont);
                    240:        if (hUserUnderlineFont != NULL)
                    241:                DeleteObject (hUserUnderlineFont);
                    242:        if (hUserBoldFont != NULL)
                    243:                DeleteObject (hUserBoldFont);
1.1.1.5   root      244:        if (hUserUnderlineBoldFont != NULL)
                    245:                DeleteObject (hUserUnderlineBoldFont);
1.1.1.12  root      246: 
1.1       root      247:        /* Cleanup our dialog class */
                    248:        if (hDlgClass)
                    249:                UnregisterClass (TC_DLG_CLASS, hInst);
                    250:        if (hSplashClass)
                    251:                UnregisterClass (TC_SPLASH_CLASS, hInst);
1.1.1.12  root      252: 
1.1       root      253:        /* Close the device driver handle */
                    254:        if (hDriver != INVALID_HANDLE_VALUE)
                    255:        {
1.1.1.7   root      256:                // Unload driver mode if possible (non-install mode) 
                    257:                if (IsNonInstallMode ())
1.1.1.12  root      258:                {
                    259:                        // If a dismount was forced in the lifetime of the driver, Windows may later prevent it to be loaded again from
                    260:                        // the same path. Therefore, the driver will not be unloaded even though it was loaded in non-install mode.
                    261:                        int refDevDeleted;
                    262:                        DWORD dwResult;
                    263: 
1.1.1.13  root      264:                        if (!DeviceIoControl (hDriver, TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED, NULL, 0, &refDevDeleted, sizeof (refDevDeleted), &dwResult, NULL))
1.1.1.12  root      265:                                refDevDeleted = 0;
                    266: 
                    267:                        if (!refDevDeleted)
                    268:                                DriverUnload ();
                    269:                        else
1.1.1.17  root      270:                        {
1.1.1.12  root      271:                                CloseHandle (hDriver);
1.1.1.17  root      272:                                hDriver = INVALID_HANDLE_VALUE;
                    273:                        }
1.1.1.12  root      274:                }
1.1.1.7   root      275:                else
1.1.1.12  root      276:                {
1.1.1.7   root      277:                        CloseHandle (hDriver);
1.1.1.15  root      278:                        hDriver = INVALID_HANDLE_VALUE;
1.1.1.12  root      279:                }
1.1       root      280:        }
                    281: 
1.1.1.7   root      282:        if (ConfigBuffer != NULL)
                    283:        {
                    284:                free (ConfigBuffer);
                    285:                ConfigBuffer = NULL;
                    286:        }
1.1.1.10  root      287: 
                    288:        CoUninitialize ();
1.1.1.13  root      289: 
                    290:        CloseSysEncMutex ();
1.1.1.17  root      291: 
                    292: #ifndef SETUP
1.1.1.19  root      293:        try
                    294:        {
                    295:                if (SecurityToken::IsInitialized())
                    296:                        SecurityToken::CloseLibrary();
                    297:        }
                    298:        catch (...) { }
                    299: 
1.1.1.17  root      300:        EncryptionThreadPoolStop();
                    301: #endif
1.1       root      302: }
                    303: 
1.1.1.12  root      304: 
1.1.1.19  root      305: void LowerCaseCopy (char *lpszDest, const char *lpszSource)
1.1       root      306: {
                    307:        int i = strlen (lpszSource);
                    308: 
                    309:        lpszDest[i] = 0;
                    310:        while (--i >= 0)
                    311:        {
                    312:                lpszDest[i] = (char) tolower (lpszSource[i]);
                    313:        }
                    314: 
                    315: }
                    316: 
1.1.1.19  root      317: void UpperCaseCopy (char *lpszDest, const char *lpszSource)
1.1       root      318: {
                    319:        int i = strlen (lpszSource);
                    320: 
                    321:        lpszDest[i] = 0;
                    322:        while (--i >= 0)
                    323:        {
                    324:                lpszDest[i] = (char) toupper (lpszSource[i]);
                    325:        }
                    326: }
                    327: 
1.1.1.11  root      328: 
1.1.1.19  root      329: std::string ToUpperCase (const std::string &str)
                    330: {
                    331:        string u;
                    332:        foreach (char c, str)
                    333:        {
                    334:                u += (char) toupper (c);
                    335:        }
                    336: 
                    337:        return u;
                    338: }
                    339: 
                    340: 
1.1.1.11  root      341: BOOL IsVolumeDeviceHosted (char *lpszDiskFile)
                    342: {
                    343:        return strstr (lpszDiskFile, "\\Device\\") == lpszDiskFile
                    344:                || strstr (lpszDiskFile, "\\DEVICE\\") == lpszDiskFile;
                    345: }
                    346: 
                    347: 
1.1.1.19  root      348: void CreateFullVolumePath (char *lpszDiskFile, const char *lpszFileName, BOOL * bDevice)
1.1       root      349: {
                    350:        UpperCaseCopy (lpszDiskFile, lpszFileName);
                    351: 
                    352:        *bDevice = FALSE;
                    353: 
                    354:        if (memcmp (lpszDiskFile, "\\DEVICE", sizeof (char) * 7) == 0)
                    355:        {
                    356:                *bDevice = TRUE;
                    357:        }
                    358: 
                    359:        strcpy (lpszDiskFile, lpszFileName);
                    360: 
                    361: #if _DEBUG
                    362:        OutputDebugString ("CreateFullVolumePath: ");
                    363:        OutputDebugString (lpszDiskFile);
                    364:        OutputDebugString ("\n");
                    365: #endif
                    366: 
                    367: }
                    368: 
1.1.1.19  root      369: int FakeDosNameForDevice (const char *lpszDiskFile, char *lpszDosDevice, char *lpszCFDevice, BOOL bNameOnly)
1.1       root      370: {
                    371:        BOOL bDosLinkCreated = TRUE;
                    372:        sprintf (lpszDosDevice, "truecrypt%lu", GetCurrentProcessId ());
                    373: 
                    374:        if (bNameOnly == FALSE)
                    375:                bDosLinkCreated = DefineDosDevice (DDD_RAW_TARGET_PATH, lpszDosDevice, lpszDiskFile);
                    376: 
                    377:        if (bDosLinkCreated == FALSE)
                    378:                return ERR_OS_ERROR;
                    379:        else
                    380:                sprintf (lpszCFDevice, "\\\\.\\%s", lpszDosDevice);
                    381: 
                    382:        return 0;
                    383: }
                    384: 
1.1.1.19  root      385: int RemoveFakeDosName (char *lpszDiskFile, char *lpszDosDevice)
1.1       root      386: {
                    387:        BOOL bDosLinkRemoved = DefineDosDevice (DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE |
                    388:                        DDD_REMOVE_DEFINITION, lpszDosDevice, lpszDiskFile);
                    389:        if (bDosLinkRemoved == FALSE)
                    390:        {
                    391:                return ERR_OS_ERROR;
                    392:        }
                    393: 
                    394:        return 0;
                    395: }
                    396: 
                    397: 
1.1.1.19  root      398: void AbortProcess (char *stringId)
1.1       root      399: {
1.1.1.17  root      400:        // Note that this function also causes localcleanup() to be called (see atexit())
1.1       root      401:        MessageBeep (MB_ICONEXCLAMATION);
1.1.1.7   root      402:        MessageBoxW (NULL, GetString (stringId), lpszTitle, ICON_HAND);
1.1       root      403:        exit (1);
                    404: }
                    405: 
1.1.1.19  root      406: void AbortProcessSilent (void)
1.1.1.5   root      407: {
1.1.1.17  root      408:        // Note that this function also causes localcleanup() to be called (see atexit())
1.1.1.5   root      409:        exit (1);
                    410: }
                    411: 
1.1.1.23! root      412: 
        !           413: #pragma warning(push)
        !           414: #pragma warning(disable:4702)
        !           415: 
1.1.1.19  root      416: void *err_malloc (size_t size)
1.1       root      417: {
                    418:        void *z = (void *) TCalloc (size);
                    419:        if (z)
                    420:                return z;
1.1.1.7   root      421:        AbortProcess ("OUTOFMEMORY");
1.1       root      422:        return 0;
                    423: }
                    424: 
1.1.1.23! root      425: #pragma warning(pop)
        !           426: 
        !           427: 
1.1.1.19  root      428: char *err_strdup (char *lpszText)
1.1       root      429: {
                    430:        int j = (strlen (lpszText) + 1) * sizeof (char);
                    431:        char *z = (char *) err_malloc (j);
                    432:        memmove (z, lpszText, j);
                    433:        return z;
                    434: }
                    435: 
1.1.1.21  root      436: 
                    437: BOOL IsDiskReadError (DWORD error)
                    438: {
                    439:        return (error == ERROR_CRC
                    440:                || error == ERROR_IO_DEVICE
                    441:                || error == ERROR_BAD_CLUSTERS
                    442:                || error == ERROR_SECTOR_NOT_FOUND
                    443:                || error == ERROR_READ_FAULT
1.1.1.23! root      444:                || error == ERROR_INVALID_FUNCTION // I/O error may be reported as ERROR_INVALID_FUNCTION by buggy chipset drivers
1.1.1.21  root      445:                || error == ERROR_SEM_TIMEOUT); // I/O operation timeout may be reported as ERROR_SEM_TIMEOUT
                    446: }
                    447: 
                    448: 
                    449: BOOL IsDiskWriteError (DWORD error)
                    450: {
                    451:        return (error == ERROR_IO_DEVICE
                    452:                || error == ERROR_BAD_CLUSTERS
                    453:                || error == ERROR_SECTOR_NOT_FOUND
                    454:                || error == ERROR_WRITE_FAULT
1.1.1.23! root      455:                || error == ERROR_INVALID_FUNCTION // I/O error may be reported as ERROR_INVALID_FUNCTION by buggy chipset drivers
1.1.1.21  root      456:                || error == ERROR_SEM_TIMEOUT); // I/O operation timeout may be reported as ERROR_SEM_TIMEOUT
                    457: }
                    458: 
                    459: 
                    460: BOOL IsDiskError (DWORD error)
                    461: {
                    462:        return IsDiskReadError (error) || IsDiskWriteError (error);
                    463: }
                    464: 
                    465: 
1.1.1.19  root      466: DWORD handleWin32Error (HWND hwndDlg)
1.1       root      467: {
1.1.1.7   root      468:        PWSTR lpMsgBuf;
1.1       root      469:        DWORD dwError = GetLastError ();
                    470: 
1.1.1.13  root      471:        if (Silent || dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE)
1.1.1.11  root      472:                return dwError;
                    473: 
                    474:        // Access denied
                    475:        if (dwError == ERROR_ACCESS_DENIED && !IsAdmin ())
                    476:        {
                    477:                Error ("ERR_ACCESS_DENIED");
1.1.1.15  root      478:                SetLastError (dwError);         // Preserve the original error code
1.1.1.11  root      479:                return dwError;
                    480:        }
1.1.1.7   root      481: 
                    482:        FormatMessageW (
1.1       root      483:                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                    484:                              NULL,
                    485:                              dwError,
                    486:                              MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),       /* Default language */
1.1.1.7   root      487:                              (PWSTR) &lpMsgBuf,
1.1       root      488:                              0,
                    489:                              NULL
                    490:            );
                    491: 
1.1.1.7   root      492:        MessageBoxW (hwndDlg, lpMsgBuf, lpszTitle, ICON_HAND);
1.1       root      493:        LocalFree (lpMsgBuf);
1.1.1.5   root      494: 
1.1.1.14  root      495:        // User-friendly hardware error explanation
1.1.1.21  root      496:        if (IsDiskError (dwError))
1.1.1.14  root      497:                Error ("ERR_HARDWARE_ERROR");
                    498: 
1.1.1.7   root      499:        // Device not ready
                    500:        if (dwError == ERROR_NOT_READY)
1.1.1.22  root      501:                HandleDriveNotReadyError();
1.1.1.7   root      502: 
1.1.1.15  root      503:        SetLastError (dwError);         // Preserve the original error code
                    504: 
1.1.1.5   root      505:        return dwError;
1.1       root      506: }
                    507: 
1.1.1.19  root      508: BOOL translateWin32Error (wchar_t *lpszMsgBuf, int nWSizeOfBuf)
1.1       root      509: {
                    510:        DWORD dwError = GetLastError ();
                    511: 
1.1.1.7   root      512:        if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
1.1       root      513:                           MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),  /* Default language */
1.1.1.15  root      514:                           lpszMsgBuf, nWSizeOfBuf, NULL))
                    515:        {
                    516:                SetLastError (dwError);         // Preserve the original error code
1.1       root      517:                return TRUE;
1.1.1.15  root      518:        }
                    519: 
                    520:        SetLastError (dwError);                 // Preserve the original error code
                    521:        return FALSE;
1.1       root      522: }
                    523: 
1.1.1.11  root      524: 
1.1.1.12  root      525: // If the user has a non-default screen DPI, all absolute font sizes must be
                    526: // converted using this function.
                    527: int CompensateDPIFont (int val)
                    528: {
                    529:        if (ScreenDPI == USER_DEFAULT_SCREEN_DPI)
                    530:                return val;
                    531:        else
                    532:        {
                    533:                double tmpVal = (double) val * DPIScaleFactorY * DlgAspectRatio * 0.999;
                    534: 
                    535:                if (tmpVal > 0)
                    536:                        return (int) floor(tmpVal);
                    537:                else
                    538:                        return (int) ceil(tmpVal);
                    539:        }
                    540: }
                    541: 
                    542: 
                    543: // If the user has a non-default screen DPI, some screen coordinates and sizes must
                    544: // be converted using this function
                    545: int CompensateXDPI (int val)
                    546: {
                    547:        if (ScreenDPI == USER_DEFAULT_SCREEN_DPI)
                    548:                return val;
                    549:        else
                    550:        {
                    551:                double tmpVal = (double) val * DPIScaleFactorX;
                    552: 
                    553:                if (tmpVal > 0)
                    554:                        return (int) floor(tmpVal);
                    555:                else
                    556:                        return (int) ceil(tmpVal);
                    557:        }
                    558: }
                    559: 
                    560: 
                    561: // If the user has a non-default screen DPI, some screen coordinates and sizes must
                    562: // be converted using this function
                    563: int CompensateYDPI (int val)
                    564: {
                    565:        if (ScreenDPI == USER_DEFAULT_SCREEN_DPI)
                    566:                return val;
                    567:        else
                    568:        {
                    569:                double tmpVal = (double) val * DPIScaleFactorY;
                    570: 
                    571:                if (tmpVal > 0)
                    572:                        return (int) floor(tmpVal);
                    573:                else
                    574:                        return (int) ceil(tmpVal);
                    575:        }
                    576: }
                    577: 
                    578: 
1.1.1.23! root      579: int GetTextGfxWidth (HWND hwndDlgItem, const wchar_t *text, HFONT hFont)
1.1.1.11  root      580: {
                    581:        SIZE sizes;
                    582:        TEXTMETRIC textMetrics;
                    583:        HDC hdc = GetDC (hwndDlgItem); 
                    584: 
                    585:        SelectObject(hdc, (HGDIOBJ) hFont);
                    586: 
                    587:        GetTextExtentPoint32W (hdc, text, wcslen (text), &sizes);
                    588: 
                    589:        GetTextMetrics(hdc, &textMetrics);      // Necessary for non-TrueType raster fonts (tmOverhang)
                    590: 
                    591:        ReleaseDC (hwndDlgItem, hdc); 
                    592: 
                    593:        return ((int) sizes.cx - (int) textMetrics.tmOverhang);
                    594: }
                    595: 
                    596: 
1.1.1.23! root      597: int GetTextGfxHeight (HWND hwndDlgItem, const wchar_t *text, HFONT hFont)
1.1.1.11  root      598: {
                    599:        SIZE sizes;
                    600:        HDC hdc = GetDC (hwndDlgItem); 
                    601: 
                    602:        SelectObject(hdc, (HGDIOBJ) hFont);
                    603: 
                    604:        GetTextExtentPoint32W (hdc, text, wcslen (text), &sizes);
                    605: 
                    606:        ReleaseDC (hwndDlgItem, hdc); 
                    607: 
                    608:        return ((int) sizes.cy);
                    609: }
                    610: 
                    611: 
1.1.1.23! root      612: std::string FitPathInGfxWidth (HWND hwnd, HFONT hFont, LONG width, const std::string &path)
        !           613: {
        !           614:        string newPath;
        !           615: 
        !           616:        RECT rect;
        !           617:        rect.left = 0;
        !           618:        rect.top = 0;
        !           619:        rect.right = width;
        !           620:        rect.bottom = LONG_MAX;
        !           621: 
        !           622:        HDC hdc = GetDC (hwnd); 
        !           623:        SelectObject (hdc, (HGDIOBJ) hFont);
        !           624: 
        !           625:        char pathBuf[TC_MAX_PATH];
        !           626:        strcpy_s (pathBuf, sizeof (pathBuf), path.c_str());
        !           627: 
        !           628:        if (DrawText (hdc, pathBuf, path.size(), &rect, DT_CALCRECT | DT_MODIFYSTRING | DT_PATH_ELLIPSIS | DT_SINGLELINE) != 0)
        !           629:                newPath = pathBuf;
        !           630: 
        !           631:        ReleaseDC (hwnd, hdc); 
        !           632:        return newPath;
        !           633: }
        !           634: 
        !           635: 
1.1.1.11  root      636: static LRESULT CALLBACK HyperlinkProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                    637: {
                    638:        WNDPROC wp = (WNDPROC) GetWindowLongPtr (hwnd, GWL_USERDATA);
                    639: 
                    640:        switch (message)
                    641:        {
                    642:        case WM_SETCURSOR:
1.1.1.13  root      643:                if (!bHyperLinkBeingTracked)
1.1.1.11  root      644:                {
                    645:                        TRACKMOUSEEVENT trackMouseEvent;
                    646: 
                    647:                        trackMouseEvent.cbSize = sizeof(trackMouseEvent);
                    648:                        trackMouseEvent.dwFlags = TME_LEAVE;
                    649:                        trackMouseEvent.hwndTrack = hwnd;
                    650: 
1.1.1.13  root      651:                        bHyperLinkBeingTracked = TrackMouseEvent(&trackMouseEvent);
1.1.1.11  root      652: 
                    653:                        HandCursor();
                    654:                }
                    655:                return 0;
                    656: 
                    657:        case WM_MOUSELEAVE:
1.1.1.13  root      658:                bHyperLinkBeingTracked = FALSE;
1.1.1.11  root      659:                NormalCursor();
                    660:                return 0;
                    661:        }
                    662: 
                    663:        return CallWindowProc (wp, hwnd, message, wParam, lParam);
                    664: }
                    665: 
                    666: 
                    667: BOOL ToHyperlink (HWND hwndDlg, UINT ctrlId)
                    668: {
                    669:        HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId);
                    670: 
                    671:        SendMessage (hwndCtrl, WM_SETFONT, (WPARAM) hUserUnderlineFont, 0);
                    672: 
                    673:        SetWindowLongPtr (hwndCtrl, GWL_USERDATA, (LONG_PTR) GetWindowLongPtr (hwndCtrl, GWL_WNDPROC));
                    674:        SetWindowLongPtr (hwndCtrl, GWL_WNDPROC, (LONG_PTR) HyperlinkProc);
                    675: 
1.1.1.19  root      676:        // Resize the field according to its actual length in pixels and move it if centered or right-aligned.
1.1.1.12  root      677:        // This should be done again if the link text changes.
                    678:        AccommodateTextField (hwndDlg, ctrlId, TRUE);
                    679: 
                    680:        return TRUE;
                    681: }
                    682: 
                    683: 
                    684: // Resizes a text field according to its actual width in pixels (font size is taken into account) and moves
                    685: // it accordingly if the field is centered or right-aligned. Should be used on all hyperlinks upon dialog init
                    686: // after localization (bFirstUpdate should be TRUE) and later whenever a hyperlink text changes (bFirstUpdate
                    687: // must be FALSE).
                    688: void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate)
                    689: {
                    690:        RECT rec, wrec, trec;
                    691:        HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId);
                    692:        int width, origWidth, origHeight;
                    693:        int horizSubOffset, vertOffset, alignPosDiff = 0;
                    694:        wchar_t text [MAX_URL_LENGTH];
                    695:        WINDOWINFO windowInfo;
                    696:        BOOL bBorderlessWindow = !(GetWindowLongPtr (hwndDlg, GWL_STYLE) & (WS_BORDER | WS_DLGFRAME));
1.1.1.11  root      697: 
                    698:        // Resize the field according to its length and font size and move if centered or right-aligned
                    699: 
                    700:        GetWindowTextW (hwndCtrl, text, sizeof (text) / sizeof (wchar_t));
                    701: 
                    702:        width = GetTextGfxWidth (hwndCtrl, text, hUserUnderlineFont);
                    703: 
                    704:        GetClientRect (hwndCtrl, &rec);         
                    705:        origWidth = rec.right;
                    706:        origHeight = rec.bottom;
                    707: 
1.1.1.12  root      708:        if (width >= 0
                    709:                && (!bFirstUpdate || origWidth > width))        // The original width of the field is the maximum allowed size 
1.1.1.11  root      710:        {
                    711:                horizSubOffset = origWidth - width;
                    712: 
                    713:                // Window coords
                    714:                GetWindowRect(hwndDlg, &wrec);
                    715:                GetClientRect(hwndDlg, &trec);
                    716: 
                    717:                // Vertical "title bar" offset
                    718:                vertOffset = wrec.bottom - wrec.top - trec.bottom - (bBorderlessWindow ? 0 : GetSystemMetrics(SM_CYFIXEDFRAME));
                    719: 
                    720:                // Text field coords
                    721:                GetWindowRect(hwndCtrl, &rec);
                    722: 
                    723:                // Alignment offset
                    724:                windowInfo.cbSize = sizeof(windowInfo);
                    725:                GetWindowInfo (hwndCtrl, &windowInfo);
                    726: 
                    727:                if (windowInfo.dwStyle & SS_CENTER)
                    728:                        alignPosDiff = horizSubOffset / 2;
                    729:                else if (windowInfo.dwStyle & SS_RIGHT)
                    730:                        alignPosDiff = horizSubOffset;
                    731:                
                    732:                // Resize/move
                    733:                if (alignPosDiff > 0)
                    734:                {
                    735:                        // Resize and move the text field
                    736:                        MoveWindow (hwndCtrl,
                    737:                                rec.left - wrec.left - (bBorderlessWindow ? 0 : GetSystemMetrics(SM_CXFIXEDFRAME)) + alignPosDiff,
                    738:                                rec.top - wrec.top - vertOffset,
                    739:                                origWidth - horizSubOffset,
                    740:                                origHeight,
                    741:                                TRUE);
                    742:                }
                    743:                else
                    744:                {
                    745:                        // Resize the text field
                    746:                        SetWindowPos (hwndCtrl, 0, 0, 0,
                    747:                                origWidth - horizSubOffset,
                    748:                                origHeight,
                    749:                                SWP_NOMOVE | SWP_NOZORDER);
                    750:                }
1.1.1.12  root      751: 
                    752:                SetWindowPos (hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                    753: 
                    754:                InvalidateRect (hwndCtrl, NULL, TRUE);
1.1.1.11  root      755:        }
1.1.1.12  root      756: }
                    757: 
                    758: 
1.1.1.13  root      759: // Protects an input field from having its content updated by a Paste action (call ToBootPwdField() to use this).
                    760: static LRESULT CALLBACK BootPwdFieldProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                    761: {
                    762:        WNDPROC wp = (WNDPROC) GetWindowLongPtr (hwnd, GWL_USERDATA);
                    763: 
                    764:        switch (message)
                    765:        {
                    766:        case WM_PASTE:
                    767:                return 1;
                    768:        }
                    769: 
                    770:        return CallWindowProc (wp, hwnd, message, wParam, lParam);
                    771: }
                    772: 
                    773: 
1.1.1.14  root      774: // Protects an input field from having its content updated by a Paste action. Used for pre-boot password
                    775: // input fields (only the US keyboard layout is supported in pre-boot environment so we must prevent the 
                    776: // user from pasting a password typed using a non-US keyboard layout).
1.1.1.13  root      777: void ToBootPwdField (HWND hwndDlg, UINT ctrlId)
                    778: {
                    779:        HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId);
                    780: 
                    781:        SetWindowLongPtr (hwndCtrl, GWL_USERDATA, (LONG_PTR) GetWindowLongPtr (hwndCtrl, GWL_WNDPROC));
                    782:        SetWindowLongPtr (hwndCtrl, GWL_WNDPROC, (LONG_PTR) BootPwdFieldProc);
                    783: }
                    784: 
                    785: 
                    786: 
1.1.1.12  root      787: // This function currently serves the following purposes:
                    788: // - Determines scaling factors for current screen DPI and GUI aspect ratio.
                    789: // - Determines how Windows skews the GUI aspect ratio (which happens when the user has a non-default DPI).
                    790: // The determined values must be used when performing some GUI operations and calculations.
                    791: BOOL CALLBACK AuxiliaryDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                    792: {
                    793:        switch (msg)
                    794:        {
                    795:        case WM_INITDIALOG:
                    796:                {
                    797:                        HDC hDC = GetDC (hwndDlg);
                    798: 
                    799:                        ScreenDPI = GetDeviceCaps (hDC, LOGPIXELSY);
                    800:                        ReleaseDC (hwndDlg, hDC); 
                    801: 
                    802:                        DPIScaleFactorX = 1;
                    803:                        DPIScaleFactorY = 1;
                    804:                        DlgAspectRatio = 1;
                    805: 
                    806:                        if (ScreenDPI != USER_DEFAULT_SCREEN_DPI)
                    807:                        {
                    808:                                // Windows skews the GUI aspect ratio if the user has a non-default DPI. Hence, working with 
                    809:                                // actual screen DPI is redundant and leads to incorrect results. What really matters here is
                    810:                                // how Windows actually renders our GUI. This is determined by comparing the expected and current
                    811:                                // sizes of a hidden calibration text field.
                    812: 
                    813:                                RECT trec;
                    814: 
                    815:                                trec.right = 0;
                    816:                                trec.bottom = 0;
                    817: 
                    818:                                GetClientRect (GetDlgItem (hwndDlg, IDC_ASPECT_RATIO_CALIBRATION_BOX), &trec);
                    819: 
                    820:                                if (trec.right != 0 && trec.bottom != 0)
                    821:                                {
                    822:                                        // The size of the 282x282 IDC_ASPECT_RATIO_CALIBRATION_BOX rendered at the default DPI (96) is 423x458
                    823:                                        DPIScaleFactorX = (double) trec.right / 423;
                    824:                                        DPIScaleFactorY = (double) trec.bottom / 458;
                    825:                                        DlgAspectRatio = DPIScaleFactorX / DPIScaleFactorY;
                    826:                                }
                    827:                        }
                    828: 
                    829:                        EndDialog (hwndDlg, 0);
                    830:                        return 1;
                    831:                }
                    832: 
                    833:        case WM_CLOSE:
                    834:                EndDialog (hwndDlg, 0);
                    835:                return 1;
                    836:        }
                    837: 
                    838:        return 0;
1.1.1.11  root      839: }
                    840: 
                    841: 
1.1       root      842: /* Except in response to the WM_INITDIALOG message, the dialog box procedure
                    843:    should return nonzero if it processes the message, and zero if it does
                    844:    not. - see DialogProc */
1.1.1.19  root      845: BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1       root      846: {
                    847:        WORD lw = LOWORD (wParam);
1.1.1.12  root      848:        static HBITMAP hbmTextualLogoBitmapRescaled = NULL;
                    849: 
1.1       root      850:        switch (msg)
                    851:        {
                    852:        case WM_INITDIALOG:
                    853:                {
1.1.1.7   root      854:                        char szTmp[100];
1.1.1.12  root      855:                        RECT rec;
                    856: 
                    857:                        LocalizeDialog (hwndDlg, "IDD_ABOUT_DLG");
1.1       root      858: 
1.1.1.12  root      859:                        // Hyperlink
1.1.1.8   root      860:                        SetWindowText (GetDlgItem (hwndDlg, IDC_HOMEPAGE), "www.truecrypt.org");
1.1.1.11  root      861:                        ToHyperlink (hwndDlg, IDC_HOMEPAGE);
1.1.1.5   root      862: 
1.1.1.12  root      863:                        // Logo area background (must not keep aspect ratio; must retain Windows-imposed distortion)
                    864:                        GetClientRect (GetDlgItem (hwndDlg, IDC_ABOUT_LOGO_AREA), &rec);
                    865:                        SetWindowPos (GetDlgItem (hwndDlg, IDC_ABOUT_BKG), HWND_TOP, 0, 0, rec.right, rec.bottom, SWP_NOMOVE);
                    866: 
                    867:                        // Resize the logo bitmap if the user has a non-default DPI 
                    868:                        if (ScreenDPI != USER_DEFAULT_SCREEN_DPI)
                    869:                        {
                    870:                                // Logo (must recreate and keep the original aspect ratio as Windows distorts it)
                    871:                                hbmTextualLogoBitmapRescaled = RenderBitmap (MAKEINTRESOURCE (IDB_TEXTUAL_LOGO_288DPI),
                    872:                                        GetDlgItem (hwndDlg, IDC_TEXTUAL_LOGO_IMG),
                    873:                                        0, 0, 0, 0, FALSE, TRUE);
                    874: 
                    875:                                SetWindowPos (GetDlgItem (hwndDlg, IDC_ABOUT_BKG), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                    876:                        }
                    877: 
1.1.1.5   root      878:                        // Version
                    879:                        SendMessage (GetDlgItem (hwndDlg, IDT_ABOUT_VERSION), WM_SETFONT, (WPARAM) hUserBoldFont, 0);
1.1       root      880:                        sprintf (szTmp, "TrueCrypt %s", VERSION_STRING);
1.1.1.19  root      881: #if (defined(_DEBUG) || defined(DEBUG))
1.1.1.7   root      882:                        strcat (szTmp, "  (debug)");
                    883: #endif
1.1       root      884:                        SetDlgItemText (hwndDlg, IDT_ABOUT_VERSION, szTmp);
1.1.1.23! root      885:                        SetDlgItemText (hwndDlg, IDT_ABOUT_RELEASE, TC_STR_RELEASED_BY);
1.1.1.5   root      886: 
                    887:                        // Credits
                    888:                        SendMessage (GetDlgItem (hwndDlg, IDC_ABOUT_CREDITS), WM_SETFONT, (WPARAM) hUserFont, (LPARAM) 0);
1.1.1.11  root      889:                        SendMessage (hwndDlg, WM_APP, 0, 0);
1.1       root      890:                        return 1;
                    891:                }
                    892: 
1.1.1.11  root      893:        case WM_APP:
                    894:                SetWindowText (GetDlgItem (hwndDlg, IDC_ABOUT_CREDITS),
1.1.1.12  root      895:                        "Portions of this software are based in part on the works of the following people: "
1.1.1.11  root      896:                        "Paul Le Roux, "
1.1.1.12  root      897:                        "Bruce Schneier, John Kelsey, Doug Whiting, David Wagner, Chris Hall, Niels Ferguson, "
                    898:                        "Lars Knudsen, Ross Anderson, Eli Biham, "
                    899:                        "Joan Daemen, Vincent Rijmen, "
1.1.1.13  root      900:                        "Phillip Rogaway, "
1.1.1.11  root      901:                        "Hans Dobbertin, Antoon Bosselaers, Bart Preneel, "
                    902:                        "Paulo Barreto, Brian Gladman, Wei Dai, Peter Gutmann, and many others.\r\n\r\n"
1.1.1.13  root      903: 
1.1.1.11  root      904:                        "Portions of this software:\r\n"
1.1.1.21  root      905:                        "Copyright \xA9 2003-2009 TrueCrypt Foundation. All Rights Reserved.\r\n"
1.1.1.11  root      906:                        "Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\r\n"
1.1.1.15  root      907:                        "Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\r\n"
                    908:                        "Copyright \xA9 2002-2004 Mark Adler. All Rights Reserved.\r\n\r\n"
1.1.1.13  root      909: 
                    910:                        "This software as a whole:\r\n"
1.1.1.21  root      911:                        "Copyright \xA9 2009 TrueCrypt Foundation. All rights reserved.\r\n\r\n"
1.1.1.13  root      912: 
1.1.1.11  root      913:                        "A TrueCrypt Foundation Release");
1.1.1.13  root      914: 
1.1.1.11  root      915:                return 1;
                    916: 
1.1       root      917:        case WM_COMMAND:
                    918:                if (lw == IDOK || lw == IDCANCEL)
                    919:                {
1.1.1.12  root      920:                        PostMessage (hwndDlg, WM_CLOSE, 0, 0);
1.1       root      921:                        return 1;
                    922:                }
                    923: 
1.1.1.5   root      924:                if (lw == IDC_HOMEPAGE)
                    925:                {
1.1.1.11  root      926:                        Applink ("main", TRUE, "");
1.1.1.5   root      927:                        return 1;
                    928:                }
                    929: 
1.1.1.11  root      930:                if (lw == IDC_DONATIONS)
                    931:                {
                    932:                        Applink ("donate", FALSE, "");
                    933:                        return 1;
                    934:                }
1.1.1.12  root      935: 
1.1.1.5   root      936:                // Disallow modification of credits
                    937:                if (HIWORD (wParam) == EN_UPDATE)
                    938:                {
1.1.1.11  root      939:                        SendMessage (hwndDlg, WM_APP, 0, 0);
1.1.1.5   root      940:                        return 1;
                    941:                }
                    942: 
1.1       root      943:                return 0;
                    944: 
                    945:        case WM_CLOSE:
1.1.1.12  root      946:                /* Delete buffered bitmaps (if any) */
                    947:                if (hbmTextualLogoBitmapRescaled != NULL)
                    948:                {
                    949:                        DeleteObject ((HGDIOBJ) hbmTextualLogoBitmapRescaled);
                    950:                        hbmTextualLogoBitmapRescaled = NULL;
                    951:                }
                    952: 
1.1       root      953:                EndDialog (hwndDlg, 0);
                    954:                return 1;
                    955:        }
                    956: 
                    957:        return 0;
                    958: }
                    959: 
                    960: 
                    961: BOOL
                    962: IsButtonChecked (HWND hButton)
                    963: {
                    964:        if (SendMessage (hButton, BM_GETCHECK, 0, 0) == BST_CHECKED)
                    965:                return TRUE;
                    966:        else
                    967:                return FALSE;
                    968: }
                    969: 
                    970: void
                    971: CheckButton (HWND hButton)
                    972: {
                    973:        SendMessage (hButton, BM_SETCHECK, BST_CHECKED, 0);
                    974: }
                    975: 
                    976: 
1.1.1.13  root      977: void LeftPadString (char *szTmp, int len, int targetLen, char filler)
                    978: {
                    979:        int i;
                    980: 
                    981:        if (targetLen <= len)
                    982:                return;
                    983: 
                    984:        for (i = targetLen-1; i >= (targetLen-len); i--)
                    985:                szTmp [i] = szTmp [i-(targetLen-len)];
                    986: 
                    987:        memset (szTmp, filler, targetLen-len);
                    988:        szTmp [targetLen] = 0;
                    989: }
                    990: 
                    991: 
1.1       root      992: /*****************************************************************************
                    993:   ToSBCS: converts a unicode string to Single Byte Character String (SBCS).
                    994:   ***************************************************************************/
                    995: 
                    996: void
                    997: ToSBCS (LPWSTR lpszText)
                    998: {
                    999:        int j = wcslen (lpszText);
                   1000:        if (j == 0)
                   1001:        {
                   1002:                strcpy ((char *) lpszText, "");
                   1003:                return;
                   1004:        }
                   1005:        else
                   1006:        {
                   1007:                char *lpszNewText = (char *) err_malloc (j + 1);
                   1008:                j = WideCharToMultiByte (CP_ACP, 0L, lpszText, -1, lpszNewText, j + 1, NULL, NULL);
                   1009:                if (j > 0)
                   1010:                        strcpy ((char *) lpszText, lpszNewText);
                   1011:                else
                   1012:                        strcpy ((char *) lpszText, "");
                   1013:                free (lpszNewText);
                   1014:        }
                   1015: }
                   1016: 
                   1017: /*****************************************************************************
                   1018:   ToUNICODE: converts a SBCS string to a UNICODE string.
                   1019:   ***************************************************************************/
                   1020: 
1.1.1.15  root     1021: void 
1.1       root     1022: ToUNICODE (char *lpszText)
                   1023: {
                   1024:        int j = strlen (lpszText);
                   1025:        if (j == 0)
                   1026:        {
                   1027:                wcscpy ((LPWSTR) lpszText, (LPWSTR) WIDE (""));
                   1028:                return;
                   1029:        }
                   1030:        else
                   1031:        {
                   1032:                LPWSTR lpszNewText = (LPWSTR) err_malloc ((j + 1) * 2);
                   1033:                j = MultiByteToWideChar (CP_ACP, 0L, lpszText, -1, lpszNewText, j + 1);
                   1034:                if (j > 0)
                   1035:                        wcscpy ((LPWSTR) lpszText, lpszNewText);
                   1036:                else
1.1.1.15  root     1037:                        wcscpy ((LPWSTR) lpszText, (LPWSTR) WIDE (""));
1.1       root     1038:                free (lpszNewText);
                   1039:        }
                   1040: }
                   1041: 
                   1042: /* InitDialog - initialize the applications main dialog, this function should
                   1043:    be called only once in the dialogs WM_INITDIALOG message handler */
                   1044: void
                   1045: InitDialog (HWND hwndDlg)
                   1046: {
1.1.1.7   root     1047:        NONCLIENTMETRICSW metric;
                   1048:        static BOOL aboutMenuAppended = FALSE;
                   1049: 
1.1       root     1050:        int nHeight;
1.1.1.7   root     1051:        LOGFONTW lf;
1.1       root     1052:        HMENU hMenu;
1.1.1.7   root     1053:        Font *font;
1.1       root     1054: 
1.1.1.12  root     1055:        /* Fonts */
1.1       root     1056: 
1.1.1.7   root     1057:        // Normal
                   1058:        font = GetFont ("font_normal");
                   1059: 
                   1060:        metric.cbSize = sizeof (metric);
                   1061:        SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof(metric), &metric, 0);
                   1062: 
1.1.1.23! root     1063:        WindowTitleBarFont = CreateFontIndirectW (&metric.lfCaptionFont);
        !          1064: 
1.1.1.12  root     1065:        metric.lfMessageFont.lfHeight = CompensateDPIFont (!font ? -11 : -font->Size);
1.1.1.7   root     1066:        metric.lfMessageFont.lfWidth = 0;
                   1067: 
                   1068:        if (font && wcscmp (font->FaceName, L"default") != 0)
1.1.1.11  root     1069:        {
                   1070:                wcsncpy ((WCHAR *)metric.lfMessageFont.lfFaceName, font->FaceName, sizeof (metric.lfMessageFont.lfFaceName)/2);
                   1071:        }
1.1.1.21  root     1072:        else if (IsOSAtLeast (WIN_VISTA))
1.1.1.11  root     1073:        {
                   1074:                // Vista's new default font (size and spacing) breaks compatibility with Windows 2k/XP applications.
                   1075:                // Force use of Tahoma (as Microsoft does in many dialogs) until a native Vista look is implemented.
                   1076:                wcsncpy ((WCHAR *)metric.lfMessageFont.lfFaceName, L"Tahoma", sizeof (metric.lfMessageFont.lfFaceName)/2);
                   1077:        }
1.1.1.7   root     1078: 
                   1079:        hUserFont = CreateFontIndirectW (&metric.lfMessageFont);
                   1080: 
                   1081:        metric.lfMessageFont.lfUnderline = TRUE;
                   1082:        hUserUnderlineFont = CreateFontIndirectW (&metric.lfMessageFont);
                   1083: 
                   1084:        metric.lfMessageFont.lfUnderline = FALSE;
                   1085:        metric.lfMessageFont.lfWeight = FW_BOLD;
                   1086:        hUserBoldFont = CreateFontIndirectW (&metric.lfMessageFont);
                   1087: 
                   1088:        metric.lfMessageFont.lfUnderline = TRUE;
                   1089:        metric.lfMessageFont.lfWeight = FW_BOLD;
                   1090:        hUserUnderlineBoldFont = CreateFontIndirectW (&metric.lfMessageFont);
                   1091: 
1.1.1.12  root     1092:        // Fixed-size (hexadecimal digits)
                   1093:        nHeight = CompensateDPIFont (-12);
1.1       root     1094:        lf.lfHeight = nHeight;
                   1095:        lf.lfWidth = 0;
                   1096:        lf.lfEscapement = 0;
                   1097:        lf.lfOrientation = 0;
1.1.1.7   root     1098:        lf.lfWeight = FW_NORMAL;
1.1       root     1099:        lf.lfItalic = FALSE;
                   1100:        lf.lfUnderline = FALSE;
                   1101:        lf.lfStrikeOut = FALSE;
                   1102:        lf.lfCharSet = DEFAULT_CHARSET;
                   1103:        lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
                   1104:        lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
                   1105:        lf.lfQuality = PROOF_QUALITY;
                   1106:        lf.lfPitchAndFamily = FF_DONTCARE;
1.1.1.7   root     1107:        wcscpy (lf.lfFaceName, L"Courier New");
                   1108:        hFixedDigitFont = CreateFontIndirectW (&lf);
                   1109:        if (hFixedDigitFont == NULL)
1.1       root     1110:        {
                   1111:                handleWin32Error (hwndDlg);
1.1.1.7   root     1112:                AbortProcess ("NOFONT");
1.1       root     1113:        }
                   1114: 
1.1.1.7   root     1115:        // Bold
                   1116:        font = GetFont ("font_bold");
1.1       root     1117: 
1.1.1.12  root     1118:        nHeight = CompensateDPIFont (!font ? -13 : -font->Size);
1.1       root     1119:        lf.lfHeight = nHeight;
1.1.1.7   root     1120:        lf.lfWeight = FW_BLACK;
                   1121:        wcsncpy (lf.lfFaceName, !font ? L"Arial" : font->FaceName, sizeof (lf.lfFaceName)/2);
                   1122:        hBoldFont = CreateFontIndirectW (&lf);
1.1       root     1123:        if (hBoldFont == NULL)
                   1124:        {
                   1125:                handleWin32Error (hwndDlg);
1.1.1.7   root     1126:                AbortProcess ("NOFONT");
1.1       root     1127:        }
                   1128: 
1.1.1.7   root     1129:        // Title
                   1130:        font = GetFont ("font_title");
                   1131: 
1.1.1.12  root     1132:        nHeight = CompensateDPIFont (!font ? -21 : -font->Size);
1.1       root     1133:        lf.lfHeight = nHeight;
                   1134:        lf.lfWeight = FW_REGULAR;
1.1.1.7   root     1135:        wcsncpy (lf.lfFaceName, !font ? L"Times New Roman" : font->FaceName, sizeof (lf.lfFaceName)/2);
                   1136:        hTitleFont = CreateFontIndirectW (&lf);
1.1       root     1137:        if (hTitleFont == NULL)
                   1138:        {
                   1139:                handleWin32Error (hwndDlg);
1.1.1.7   root     1140:                AbortProcess ("NOFONT");
1.1       root     1141:        }
                   1142: 
1.1.1.12  root     1143:        // Fixed-size
1.1.1.7   root     1144:        font = GetFont ("font_fixed");
                   1145: 
1.1.1.12  root     1146:        nHeight = CompensateDPIFont (!font ? -12 : -font->Size);
1.1       root     1147:        lf.lfHeight = nHeight;
                   1148:        lf.lfWidth = 0;
                   1149:        lf.lfEscapement = 0;
                   1150:        lf.lfOrientation = 0;
                   1151:        lf.lfWeight = FW_NORMAL;
                   1152:        lf.lfItalic = FALSE;
                   1153:        lf.lfUnderline = FALSE;
                   1154:        lf.lfStrikeOut = FALSE;
                   1155:        lf.lfCharSet = DEFAULT_CHARSET;
                   1156:        lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
                   1157:        lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
                   1158:        lf.lfQuality = PROOF_QUALITY;
                   1159:        lf.lfPitchAndFamily = FF_DONTCARE;
1.1.1.7   root     1160:        wcsncpy (lf.lfFaceName, !font ? L"Lucida Console" : font->FaceName, sizeof (lf.lfFaceName)/2);
                   1161:        hFixedFont = CreateFontIndirectW (&lf);
1.1       root     1162:        if (hFixedFont == NULL)
                   1163:        {
                   1164:                handleWin32Error (hwndDlg);
1.1.1.7   root     1165:                AbortProcess ("NOFONT");
1.1       root     1166:        }
                   1167: 
1.1.1.7   root     1168:        if (!aboutMenuAppended)
                   1169:        {
                   1170:                hMenu = GetSystemMenu (hwndDlg, FALSE);
                   1171:                AppendMenu (hMenu, MF_SEPARATOR, 0, NULL);
                   1172:                AppendMenuW (hMenu, MF_ENABLED | MF_STRING, IDC_ABOUT, GetString ("ABOUTBOX"));
1.1.1.5   root     1173: 
1.1.1.7   root     1174:                aboutMenuAppended = TRUE;
                   1175:        }
1.1       root     1176: }
                   1177: 
1.1.1.12  root     1178: HDC CreateMemBitmap (HINSTANCE hInstance, HWND hwnd, char *resource)
1.1       root     1179: {
                   1180:        HBITMAP picture = LoadBitmap (hInstance, resource);
                   1181:        HDC viewDC = GetDC (hwnd), dcMem;
                   1182: 
                   1183:        dcMem = CreateCompatibleDC (viewDC);
                   1184: 
                   1185:        SetMapMode (dcMem, MM_TEXT);
                   1186: 
                   1187:        SelectObject (dcMem, picture);
                   1188: 
1.1.1.12  root     1189:        DeleteObject (picture);
                   1190: 
1.1       root     1191:        ReleaseDC (hwnd, viewDC);
                   1192: 
                   1193:        return dcMem;
                   1194: }
                   1195: 
1.1.1.12  root     1196: 
                   1197: /* Renders the specified bitmap at the specified location and stretches it to fit (anti-aliasing is applied). 
                   1198: If bDirectRender is FALSE and both nWidth and nHeight are zero, the width and height of hwndDest are
                   1199: retrieved and adjusted according to screen DPI (the width and height of the resultant image are adjusted the
                   1200: same way); furthermore, if bKeepAspectRatio is TRUE, the smaller DPI factor of the two (i.e. horiz. or vert.)
                   1201: is used both for horiz. and vert. scaling (note that the overall GUI aspect ratio changes irregularly in
                   1202: both directions depending on the DPI). If bDirectRender is TRUE, bKeepAspectRatio is ignored. 
                   1203: This function returns a handle to the scaled bitmap. When the bitmap is no longer needed, it should be
                   1204: deleted by calling DeleteObject() with the handle passed as the parameter. 
                   1205: Known Windows issues: 
                   1206: - For some reason, anti-aliasing is not applied if the source bitmap contains less than 16K pixels. 
                   1207: - Windows 2000 may produce slightly inaccurate colors even when source, buffer, and target are 24-bit true color. */
                   1208: HBITMAP RenderBitmap (char *resource, HWND hwndDest, int x, int y, int nWidth, int nHeight, BOOL bDirectRender, BOOL bKeepAspectRatio)
1.1       root     1209: {
1.1.1.12  root     1210:        LRESULT lResult = 0;
                   1211: 
                   1212:        HDC hdcSrc = CreateMemBitmap (hInst, hwndDest, resource);
                   1213: 
                   1214:        HGDIOBJ picture = GetCurrentObject (hdcSrc, OBJ_BITMAP);
1.1       root     1215: 
1.1.1.12  root     1216:        HBITMAP hbmpRescaled;
1.1       root     1217:        BITMAP bitmap;
1.1.1.12  root     1218: 
                   1219:        HDC hdcRescaled;
                   1220: 
                   1221:        if (!bDirectRender && nWidth == 0 && nHeight == 0)
                   1222:        {
                   1223:                RECT rec;
                   1224: 
                   1225:                GetClientRect (hwndDest, &rec);
                   1226: 
                   1227:                if (bKeepAspectRatio)
                   1228:                {
                   1229:                        if (DlgAspectRatio > 1)
                   1230:                        {
                   1231:                                // Do not fix this, it's correct. We use the Y scale factor intentionally for both
                   1232:                                // directions to maintain aspect ratio (see above for more info).
                   1233:                                nWidth = CompensateYDPI (rec.right);
                   1234:                                nHeight = CompensateYDPI (rec.bottom);
                   1235:                        }
                   1236:                        else
                   1237:                        {
                   1238:                                // Do not fix this, it's correct. We use the X scale factor intentionally for both
                   1239:                                // directions to maintain aspect ratio (see above for more info).
                   1240:                                nWidth = CompensateXDPI (rec.right);
                   1241:                                nHeight = CompensateXDPI (rec.bottom);
                   1242:                        }
                   1243:                }
                   1244:                else
                   1245:                {
                   1246:                        nWidth = CompensateXDPI (rec.right);
                   1247:                        nHeight = CompensateYDPI (rec.bottom);
                   1248:                }
                   1249:        }
                   1250: 
1.1       root     1251:        GetObject (picture, sizeof (BITMAP), &bitmap);
                   1252: 
1.1.1.12  root     1253:     hdcRescaled = CreateCompatibleDC (hdcSrc); 
                   1254:  
                   1255:     hbmpRescaled = CreateCompatibleBitmap (hdcSrc, nWidth, nHeight); 
                   1256:  
                   1257:     SelectObject (hdcRescaled, hbmpRescaled);
                   1258: 
                   1259:        /* Anti-aliasing mode (HALFTONE is the only anti-aliasing algorithm natively supported by Windows 2000.
                   1260:           TODO: GDI+ offers higher quality -- InterpolationModeHighQualityBicubic) */
                   1261:        SetStretchBltMode (hdcRescaled, HALFTONE);
                   1262: 
                   1263:        StretchBlt (hdcRescaled,
                   1264:                0,
                   1265:                0,
                   1266:                nWidth,
                   1267:                nHeight,
                   1268:                hdcSrc,
                   1269:                0,
                   1270:                0,
                   1271:                bitmap.bmWidth, 
                   1272:                bitmap.bmHeight,
                   1273:                SRCCOPY);
                   1274: 
                   1275:        DeleteDC (hdcSrc);
                   1276: 
                   1277:        if (bDirectRender)
                   1278:        {
                   1279:                HDC hdcDest = GetDC (hwndDest);
                   1280: 
                   1281:                BitBlt (hdcDest, x, y, nWidth, nHeight, hdcRescaled, 0, 0, SRCCOPY);
                   1282:                DeleteDC (hdcDest);
                   1283:        }
                   1284:        else
                   1285:        {
                   1286:                lResult = SendMessage (hwndDest, (UINT) STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) (HANDLE) hbmpRescaled);
                   1287:        }
                   1288: 
                   1289:        if ((HGDIOBJ) lResult != NULL && (HGDIOBJ) lResult != (HGDIOBJ) hbmpRescaled)
                   1290:                DeleteObject ((HGDIOBJ) lResult);
                   1291: 
                   1292:        DeleteDC (hdcRescaled);
                   1293: 
                   1294:        return hbmpRescaled;
1.1       root     1295: }
                   1296: 
1.1.1.7   root     1297: 
1.1       root     1298: LRESULT CALLBACK
1.1.1.7   root     1299: RedTick (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1.1       root     1300: {
1.1.1.12  root     1301:        if (uMsg == WM_CREATE)
1.1.1.7   root     1302:        {
                   1303:        }
1.1.1.12  root     1304:        else if (uMsg == WM_DESTROY)
1.1.1.7   root     1305:        {
                   1306:        }
1.1.1.12  root     1307:        else if (uMsg == WM_TIMER)
                   1308:        {
                   1309:        }
                   1310:        else if (uMsg == WM_PAINT)
                   1311:        {
                   1312:                PAINTSTRUCT tmp;
                   1313:                HPEN hPen;
                   1314:                HDC hDC;
                   1315:                BOOL bEndPaint;
                   1316:                RECT Rect;
1.1.1.7   root     1317: 
1.1.1.12  root     1318:                if (GetUpdateRect (hwnd, NULL, FALSE))
                   1319:                {
                   1320:                        hDC = BeginPaint (hwnd, &tmp);
                   1321:                        bEndPaint = TRUE;
                   1322:                        if (hDC == NULL)
                   1323:                                return DefWindowProc (hwnd, uMsg, wParam, lParam);
                   1324:                }
                   1325:                else
                   1326:                {
                   1327:                        hDC = GetDC (hwnd);
                   1328:                        bEndPaint = FALSE;
                   1329:                }
1.1.1.7   root     1330: 
1.1.1.12  root     1331:                GetClientRect (hwnd, &Rect);
1.1       root     1332: 
1.1.1.12  root     1333:                hPen = CreatePen (PS_SOLID, 2, RGB (0, 255, 0));
                   1334:                if (hPen != NULL)
                   1335:                {
                   1336:                        HGDIOBJ hObj = SelectObject (hDC, hPen);
                   1337:                        WORD bx = LOWORD (GetDialogBaseUnits ());
                   1338:                        WORD by = HIWORD (GetDialogBaseUnits ());
1.1       root     1339: 
1.1.1.12  root     1340:                        MoveToEx (hDC, (Rect.right - Rect.left) / 2, Rect.bottom, NULL);
                   1341:                        LineTo (hDC, Rect.right, Rect.top);
                   1342:                        MoveToEx (hDC, (Rect.right - Rect.left) / 2, Rect.bottom, NULL);
1.1       root     1343: 
1.1.1.12  root     1344:                        LineTo (hDC, (3 * bx) / 4, (2 * by) / 8);
1.1.1.7   root     1345: 
1.1.1.12  root     1346:                        SelectObject (hDC, hObj);
                   1347:                        DeleteObject (hPen);
                   1348:                }
                   1349: 
                   1350:                if (bEndPaint)
                   1351:                        EndPaint (hwnd, &tmp);
                   1352:                else
                   1353:                        ReleaseDC (hwnd, hDC);
1.1       root     1354: 
1.1.1.12  root     1355:                return TRUE;
                   1356:        }
1.1.1.7   root     1357: 
1.1.1.12  root     1358:        return DefWindowProc (hwnd, uMsg, wParam, lParam);
1.1.1.7   root     1359: }
1.1       root     1360: 
1.1.1.7   root     1361: BOOL
                   1362: RegisterRedTick (HINSTANCE hInstance)
                   1363: {
                   1364:   WNDCLASS wc;
                   1365:   ULONG rc;
1.1       root     1366: 
1.1.1.7   root     1367:   memset(&wc, 0 , sizeof wc);
1.1       root     1368: 
1.1.1.7   root     1369:   wc.style = CS_HREDRAW | CS_VREDRAW;
                   1370:   wc.cbClsExtra = 0;
                   1371:   wc.cbWndExtra = 4;
                   1372:   wc.hInstance = hInstance;
                   1373:   wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
                   1374:   wc.hCursor = NULL;
1.1.1.15  root     1375:   wc.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
1.1.1.7   root     1376:   wc.lpszClassName = "REDTICK";
                   1377:   wc.lpfnWndProc = &RedTick; 
                   1378:   
                   1379:   rc = (ULONG) RegisterClass (&wc);
1.1       root     1380: 
1.1.1.7   root     1381:   return rc == 0 ? FALSE : TRUE;
                   1382: }
1.1       root     1383: 
1.1.1.7   root     1384: BOOL
                   1385: UnregisterRedTick (HINSTANCE hInstance)
                   1386: {
                   1387:   return UnregisterClass ("REDTICK", hInstance);
                   1388: }
1.1       root     1389: 
1.1.1.7   root     1390: LRESULT CALLBACK
                   1391: SplashDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                   1392: {
1.1       root     1393:        return DefDlgProc (hwnd, uMsg, wParam, lParam);
                   1394: }
                   1395: 
                   1396: void
                   1397: WaitCursor ()
                   1398: {
                   1399:        static HCURSOR hcWait;
                   1400:        if (hcWait == NULL)
                   1401:                hcWait = LoadCursor (NULL, IDC_WAIT);
                   1402:        SetCursor (hcWait);
                   1403:        hCursor = hcWait;
                   1404: }
                   1405: 
                   1406: void
                   1407: NormalCursor ()
                   1408: {
                   1409:        static HCURSOR hcArrow;
                   1410:        if (hcArrow == NULL)
                   1411:                hcArrow = LoadCursor (NULL, IDC_ARROW);
                   1412:        SetCursor (hcArrow);
                   1413:        hCursor = NULL;
                   1414: }
                   1415: 
                   1416: void
                   1417: ArrowWaitCursor ()
                   1418: {
                   1419:        static HCURSOR hcArrowWait;
                   1420:        if (hcArrowWait == NULL)
                   1421:                hcArrowWait = LoadCursor (NULL, IDC_APPSTARTING);
                   1422:        SetCursor (hcArrowWait);
                   1423:        hCursor = hcArrowWait;
                   1424: }
1.1.1.11  root     1425: 
                   1426: void HandCursor ()
                   1427: {
                   1428:        static HCURSOR hcHand;
                   1429:        if (hcHand == NULL)
                   1430:                hcHand = LoadCursor (NULL, IDC_HAND);
                   1431:        SetCursor (hcHand);
                   1432:        hCursor = hcHand;
                   1433: }
                   1434: 
1.1.1.7   root     1435: void
1.1.1.19  root     1436: AddComboPair (HWND hComboBox, const char *lpszItem, int value)
1.1.1.7   root     1437: {
                   1438:        LPARAM nIndex;
                   1439: 
                   1440:        nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) lpszItem);
                   1441:        nIndex = SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) value);
                   1442: }
                   1443: 
                   1444: void
1.1.1.19  root     1445: AddComboPairW (HWND hComboBox, const wchar_t *lpszItem, int value)
1.1.1.7   root     1446: {
                   1447:        LPARAM nIndex;
                   1448: 
                   1449:        nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) lpszItem);
                   1450:        nIndex = SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) value);
                   1451: }
                   1452: 
                   1453: void
                   1454: SelectAlgo (HWND hComboBox, int *algo_id)
                   1455: {
                   1456:        LPARAM nCount = SendMessage (hComboBox, CB_GETCOUNT, 0, 0);
                   1457:        LPARAM x, i;
                   1458: 
                   1459:        for (i = 0; i < nCount; i++)
                   1460:        {
                   1461:                x = SendMessage (hComboBox, CB_GETITEMDATA, i, 0);
1.1.1.13  root     1462:                if (x == (LPARAM) *algo_id)
1.1.1.7   root     1463:                {
                   1464:                        SendMessage (hComboBox, CB_SETCURSEL, i, 0);
                   1465:                        return;
                   1466:                }
                   1467:        }
                   1468: 
                   1469:        /* Something went wrong ; couldn't find the requested algo id so we drop
                   1470:           back to a default */
                   1471: 
                   1472:        *algo_id = SendMessage (hComboBox, CB_GETITEMDATA, 0, 0);
                   1473: 
                   1474:        SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
                   1475: 
                   1476: }
1.1       root     1477: 
1.1.1.19  root     1478: void PopulateWipeModeCombo (HWND hComboBox, BOOL bNA, BOOL bInPlaceEncryption)
1.1.1.13  root     1479: {
                   1480:        if (bNA)
                   1481:        {
1.1.1.19  root     1482:                AddComboPairW (hComboBox, GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"), TC_WIPE_NONE);
1.1.1.13  root     1483:        }
                   1484:        else
                   1485:        {
1.1.1.19  root     1486:                if (bInPlaceEncryption)
                   1487:                        AddComboPairW (hComboBox, GetString ("WIPE_MODE_NONE"), TC_WIPE_NONE);
                   1488:                else
                   1489:                        AddComboPairW (hComboBox, GetString ("WIPE_MODE_1_RAND"), TC_WIPE_1_RAND);
                   1490: 
1.1.1.13  root     1491:                AddComboPairW (hComboBox, GetString ("WIPE_MODE_3_DOD_5220"), TC_WIPE_3_DOD_5220);
                   1492:                AddComboPairW (hComboBox, GetString ("WIPE_MODE_7_DOD_5220"), TC_WIPE_7_DOD_5220);
                   1493:                AddComboPairW (hComboBox, GetString ("WIPE_MODE_35_GUTMANN"), TC_WIPE_35_GUTMANN);
                   1494:        }
                   1495: }
                   1496: 
1.1.1.19  root     1497: wchar_t *GetWipeModeName (WipeAlgorithmId modeId)
                   1498: {
                   1499:        switch (modeId)
                   1500:        {
                   1501:        case TC_WIPE_NONE:
                   1502:                return GetString ("WIPE_MODE_NONE");
                   1503: 
                   1504:        case TC_WIPE_1_RAND:
                   1505:                return GetString ("WIPE_MODE_1_RAND");
                   1506: 
                   1507:        case TC_WIPE_3_DOD_5220:
                   1508:                return GetString ("WIPE_MODE_3_DOD_5220");
                   1509: 
                   1510:        case TC_WIPE_7_DOD_5220:
                   1511:                return GetString ("WIPE_MODE_7_DOD_5220");
                   1512: 
                   1513:        case TC_WIPE_35_GUTMANN:
                   1514:                return GetString ("WIPE_MODE_35_GUTMANN");
                   1515: 
                   1516:        default:
                   1517:                return GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE");
                   1518:        }
                   1519: }
                   1520: 
                   1521: wchar_t *GetPathType (const char *path, BOOL bUpperCase, BOOL *bIsPartition)
                   1522: {
                   1523:        if (strstr (path, "Partition")
                   1524:                && strstr (path, "Partition0") == NULL)
                   1525:        {
                   1526:                *bIsPartition = TRUE;
                   1527:                return GetString (bUpperCase ? "PARTITION_UPPER_CASE" : "PARTITION_LOWER_CASE");
                   1528:        }
                   1529:        else if (strstr (path, "HarddiskVolume"))
                   1530:        {
                   1531:                *bIsPartition = TRUE;
                   1532:                return GetString (bUpperCase ? "VOLUME_UPPER_CASE" : "VOLUME_LOWER_CASE");
                   1533:        }
                   1534: 
                   1535:        *bIsPartition = FALSE;
                   1536:        return GetString (bUpperCase ? "DEVICE_UPPER_CASE" : "DEVICE_LOWER_CASE");
                   1537: }
                   1538: 
                   1539: LRESULT CALLBACK CustomDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1.1       root     1540: {
                   1541:        if (uMsg == WM_SETCURSOR && hCursor != NULL)
                   1542:        {
                   1543:                SetCursor (hCursor);
                   1544:                return TRUE;
                   1545:        }
                   1546: 
                   1547:        return DefDlgProc (hwnd, uMsg, wParam, lParam);
                   1548: }
                   1549: 
1.1.1.7   root     1550: 
1.1.1.22  root     1551: static BOOL IsReturnAddress (DWORD64 address)
                   1552: {
                   1553:        static size_t codeEnd = 0;
                   1554:        byte *sp = (byte *) address;
                   1555: 
                   1556:        if (codeEnd == 0)
                   1557:        {
                   1558:                MEMORY_BASIC_INFORMATION mi;
                   1559:                if (VirtualQuery ((LPCVOID) 0x401000, &mi, sizeof (mi)) >= sizeof (mi))
                   1560:                        codeEnd = (size_t) mi.BaseAddress + mi.RegionSize;
                   1561:        }
                   1562: 
                   1563:        if (address < 0x401000 + 8 || address > codeEnd)
                   1564:                return FALSE;
                   1565: 
                   1566:        return sp[-5] == 0xe8                                                                   // call ADDR
                   1567:                || (sp[-6] == 0xff && sp[-5] == 0x15)                           // call [ADDR]
                   1568:                || (sp[-2] == 0xff && (sp[-1] & 0xf0) == 0xd0);         // call REG
                   1569: }
                   1570: 
                   1571: 
1.1.1.21  root     1572: typedef struct
1.1.1.9   root     1573: {
1.1.1.21  root     1574:        EXCEPTION_POINTERS *ExceptionPointers;
                   1575:        HANDLE ExceptionThread;
                   1576: 
                   1577: } ExceptionHandlerThreadArgs;
                   1578: 
                   1579: 
                   1580: void ExceptionHandlerThread (void *threadArg)
                   1581: {
                   1582:        ExceptionHandlerThreadArgs *args = (ExceptionHandlerThreadArgs *) threadArg;
                   1583: 
                   1584:        EXCEPTION_POINTERS *ep = args->ExceptionPointers;
                   1585:        DWORD addr;
1.1.1.10  root     1586:        DWORD exCode = ep->ExceptionRecord->ExceptionCode;
1.1.1.11  root     1587:        SYSTEM_INFO si;
                   1588:        wchar_t msg[8192];
1.1.1.12  root     1589:        char modPath[MAX_PATH];
                   1590:        int crc = 0;
1.1.1.11  root     1591:        char url[MAX_URL_LENGTH];
1.1.1.12  root     1592:        char lpack[128];
1.1.1.21  root     1593:        stringstream callStack;
1.1.1.10  root     1594:        addr = (DWORD) ep->ExceptionRecord->ExceptionAddress;
1.1.1.22  root     1595:        PDWORD sp = (PDWORD) ep->ContextRecord->Esp;
                   1596:        int frameNumber = 0;
1.1.1.10  root     1597: 
1.1.1.12  root     1598:        switch (exCode)
1.1.1.10  root     1599:        {
1.1.1.21  root     1600:        case STATUS_IN_PAGE_ERROR:
1.1.1.12  root     1601:        case 0xeedfade:
1.1.1.10  root     1602:                // Exception not caused by TrueCrypt
1.1.1.12  root     1603:                MessageBoxW (0, GetString ("EXCEPTION_REPORT_EXT"),
1.1.1.10  root     1604:                        GetString ("EXCEPTION_REPORT_TITLE"),
                   1605:                        MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TOPMOST);
1.1.1.11  root     1606:                return;
1.1.1.21  root     1607:        }
1.1.1.10  root     1608: 
1.1.1.21  root     1609:        // Call stack
                   1610:        HMODULE dbgDll = LoadLibrary ("dbghelp.dll");
                   1611:        if (dbgDll)
                   1612:        {
                   1613:                typedef DWORD (__stdcall *SymGetOptions_t) ();
                   1614:                typedef DWORD (__stdcall *SymSetOptions_t) (DWORD SymOptions);
                   1615:                typedef BOOL (__stdcall *SymInitialize_t) (HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess);
                   1616:                typedef BOOL (__stdcall *StackWalk64_t) (DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
                   1617:                typedef BOOL (__stdcall * SymFromAddr_t) (HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol);
                   1618: 
                   1619:                SymGetOptions_t DbgHelpSymGetOptions = (SymGetOptions_t) GetProcAddress (dbgDll, "SymGetOptions");
                   1620:                SymSetOptions_t DbgHelpSymSetOptions = (SymSetOptions_t) GetProcAddress (dbgDll, "SymSetOptions");
                   1621:                SymInitialize_t DbgHelpSymInitialize = (SymInitialize_t) GetProcAddress (dbgDll, "SymInitialize");
                   1622:                PFUNCTION_TABLE_ACCESS_ROUTINE64 DbgHelpSymFunctionTableAccess64 = (PFUNCTION_TABLE_ACCESS_ROUTINE64) GetProcAddress (dbgDll, "SymFunctionTableAccess64");
                   1623:                PGET_MODULE_BASE_ROUTINE64 DbgHelpSymGetModuleBase64 = (PGET_MODULE_BASE_ROUTINE64) GetProcAddress (dbgDll, "SymGetModuleBase64");
                   1624:                StackWalk64_t DbgHelpStackWalk64 = (StackWalk64_t) GetProcAddress (dbgDll, "StackWalk64");
                   1625:                SymFromAddr_t DbgHelpSymFromAddr = (SymFromAddr_t) GetProcAddress (dbgDll, "SymFromAddr");
                   1626: 
                   1627:                if (DbgHelpSymGetOptions && DbgHelpSymSetOptions && DbgHelpSymInitialize && DbgHelpSymFunctionTableAccess64 && DbgHelpSymGetModuleBase64 && DbgHelpStackWalk64 && DbgHelpSymFromAddr)
                   1628:                {
1.1.1.22  root     1629:                        DbgHelpSymSetOptions (DbgHelpSymGetOptions() | SYMOPT_DEFERRED_LOADS | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_NO_CPP);
1.1.1.21  root     1630: 
                   1631:                        if (DbgHelpSymInitialize (GetCurrentProcess(), NULL, TRUE))
                   1632:                        {
                   1633:                                STACKFRAME64 frame;
                   1634:                                memset (&frame, 0, sizeof (frame));
                   1635: 
                   1636:                                frame.AddrPC.Offset = ep->ContextRecord->Eip;
                   1637:                                frame.AddrPC.Mode = AddrModeFlat;
                   1638:                                frame.AddrStack.Offset = ep->ContextRecord->Esp;
                   1639:                                frame.AddrStack.Mode = AddrModeFlat;
                   1640:                                frame.AddrFrame.Offset = ep->ContextRecord->Ebp;
                   1641:                                frame.AddrFrame.Mode = AddrModeFlat;
1.1.1.12  root     1642: 
1.1.1.22  root     1643:                                string lastSymbol;
                   1644: 
1.1.1.21  root     1645:                                while (frameNumber < 32 && DbgHelpStackWalk64 (IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), args->ExceptionThread, &frame, ep->ContextRecord, NULL, DbgHelpSymFunctionTableAccess64, DbgHelpSymGetModuleBase64, NULL))
1.1.1.10  root     1646:                                {
1.1.1.21  root     1647:                                        if (!frame.AddrPC.Offset)
                   1648:                                                continue;
                   1649: 
                   1650:                                        ULONG64 symbolBuffer[(sizeof (SYMBOL_INFO) + MAX_SYM_NAME * sizeof (TCHAR) + sizeof (ULONG64) - 1) / sizeof (ULONG64)];
                   1651:                                        memset (symbolBuffer, 0, sizeof (symbolBuffer));
                   1652: 
                   1653:                                        PSYMBOL_INFO symbol = (PSYMBOL_INFO) symbolBuffer;
                   1654:                                        symbol->SizeOfStruct = sizeof (SYMBOL_INFO);
                   1655:                                        symbol->MaxNameLen = MAX_SYM_NAME;
                   1656: 
                   1657:                                        if (DbgHelpSymFromAddr (GetCurrentProcess(), frame.AddrPC.Offset, NULL, symbol) && symbol->NameLen > 0)
1.1.1.12  root     1658:                                        {
1.1.1.21  root     1659:                                                for (size_t i = 0; i < symbol->NameLen; ++i)
                   1660:                                                {
                   1661:                                                        if (!isalnum (symbol->Name[i]))
                   1662:                                                                symbol->Name[i] = '_';
                   1663:                                                }
1.1.1.12  root     1664: 
1.1.1.22  root     1665:                                                if (symbol->Name != lastSymbol)
                   1666:                                                        callStack << "&st" << frameNumber++ << "=" << symbol->Name;
                   1667: 
                   1668:                                                lastSymbol = symbol->Name;
1.1.1.21  root     1669:                                        }
1.1.1.22  root     1670:                                        else if (frameNumber == 0 || IsReturnAddress (frame.AddrPC.Offset))
                   1671:                                        {
                   1672:                                                callStack << "&st" << frameNumber++ << "=0x" << hex << frame.AddrPC.Offset << dec;
                   1673:                                        }
                   1674:                                }
                   1675:                        }
                   1676:                }
                   1677:        }
                   1678: 
                   1679:        // StackWalk64() may fail due to missing frame pointers
                   1680:        list <DWORD> retAddrs;
                   1681:        if (frameNumber == 0)
                   1682:                retAddrs.push_back (ep->ContextRecord->Eip);
                   1683: 
                   1684:        retAddrs.push_back (0);
                   1685: 
                   1686:        MEMORY_BASIC_INFORMATION mi;
                   1687:        VirtualQuery (sp, &mi, sizeof (mi));
                   1688:        PDWORD stackTop = (PDWORD)((byte *) mi.BaseAddress + mi.RegionSize);
                   1689:        int i = 0;
                   1690: 
                   1691:        while (retAddrs.size() < 16 && &sp[i] < stackTop)
                   1692:        {
                   1693:                if (IsReturnAddress (sp[i]))
                   1694:                {
                   1695:                        bool duplicate = false;
                   1696:                        foreach (DWORD prevAddr, retAddrs)
                   1697:                        {
                   1698:                                if (sp[i] == prevAddr)
                   1699:                                {
                   1700:                                        duplicate = true;
                   1701:                                        break;
1.1.1.10  root     1702:                                }
1.1.1.12  root     1703:                        }
1.1.1.22  root     1704: 
                   1705:                        if (!duplicate)
                   1706:                                retAddrs.push_back (sp[i]);
                   1707:                }
                   1708:                i++;
                   1709:        }
                   1710: 
                   1711:        if (retAddrs.size() > 1)
                   1712:        {
                   1713:                foreach (DWORD addr, retAddrs)
                   1714:                {
                   1715:                        callStack << "&st" << frameNumber++ << "=0x" << hex << addr << dec;
1.1.1.12  root     1716:                }
                   1717:        }
1.1.1.10  root     1718: 
1.1.1.13  root     1719:        // Checksum of the module
1.1.1.12  root     1720:        if (GetModuleFileName (NULL, modPath, sizeof (modPath)))
                   1721:        {
                   1722:                HANDLE h = CreateFile (modPath, FILE_READ_DATA | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   1723:                if (h != INVALID_HANDLE_VALUE)
                   1724:                {
                   1725:                        BY_HANDLE_FILE_INFORMATION fi;
                   1726:                        if (GetFileInformationByHandle (h, &fi))
                   1727:                        {
1.1.1.15  root     1728:                                char *buf = (char *) malloc (fi.nFileSizeLow);
1.1.1.12  root     1729:                                if (buf)
                   1730:                                {
                   1731:                                        DWORD bytesRead;
                   1732:                                        if (ReadFile (h, buf, fi.nFileSizeLow, &bytesRead, NULL) && bytesRead == fi.nFileSizeLow)
1.1.1.15  root     1733:                                                crc = GetCrc32 ((unsigned char *) buf, fi.nFileSizeLow);
1.1.1.12  root     1734:                                        free (buf);
                   1735:                                }
1.1.1.10  root     1736:                        }
1.1.1.12  root     1737:                        CloseHandle (h);
1.1.1.10  root     1738:                }
                   1739:        }
                   1740: 
1.1.1.11  root     1741:        GetSystemInfo (&si);
                   1742: 
1.1.1.12  root     1743:        if (LocalizationActive)
                   1744:                sprintf_s (lpack, sizeof (lpack), "&langpack=%s_%s", GetPreferredLangId (), GetActiveLangPackVersion ());
                   1745:        else
                   1746:                lpack[0] = 0;
                   1747: 
1.1.1.21  root     1748:        sprintf (url, TC_APPLINK_SECURE "&dest=err-report%s&os=%s&osver=%d.%d.%d&arch=%s&cpus=%d&app=%s&cksum=%x&dlg=%s&err=%x&addr=%x"
1.1.1.12  root     1749:                , lpack
1.1.1.21  root     1750:                , GetWindowsEdition().c_str()
1.1.1.10  root     1751:                , CurrentOSMajor
                   1752:                , CurrentOSMinor
                   1753:                , CurrentOSServicePack
1.1.1.13  root     1754:                , Is64BitOs () ? "x64" : "x86"
1.1.1.11  root     1755:                , si.dwNumberOfProcessors
1.1.1.9   root     1756: #ifdef TCMOUNT
                   1757:                ,"main"
                   1758: #endif
                   1759: #ifdef VOLFORMAT
                   1760:                ,"format"
                   1761: #endif
                   1762: #ifdef SETUP
                   1763:                ,"setup"
                   1764: #endif
1.1.1.12  root     1765:                , crc
1.1.1.10  root     1766:                , LastDialogId ? LastDialogId : "-"
                   1767:                , exCode
                   1768:                , addr);
                   1769: 
1.1.1.21  root     1770:        string urlStr = url + callStack.str();
1.1.1.11  root     1771: 
1.1.1.21  root     1772:        _snwprintf (msg, array_capacity (msg), GetString ("EXCEPTION_REPORT"), urlStr.c_str());
1.1.1.9   root     1773: 
1.1.1.17  root     1774:        if (IDYES == MessageBoxW (0, msg, GetString ("EXCEPTION_REPORT_TITLE"), MB_ICONERROR | MB_YESNO | MB_DEFBUTTON1))
1.1.1.21  root     1775:                ShellExecute (NULL, "open", urlStr.c_str(), NULL, NULL, SW_SHOWNORMAL);
1.1.1.9   root     1776:        else
                   1777:                UnhandledExceptionFilter (ep);
1.1.1.11  root     1778: }
                   1779: 
                   1780: 
                   1781: LONG __stdcall ExceptionHandler (EXCEPTION_POINTERS *ep)
                   1782: {
                   1783:        SetUnhandledExceptionFilter (NULL);
1.1.1.21  root     1784: 
                   1785:        ExceptionHandlerThreadArgs args;
                   1786:        args.ExceptionPointers = ep;
                   1787:        args.ExceptionThread = GetCurrentThread();
                   1788: 
                   1789:        WaitForSingleObject ((HANDLE) _beginthread (ExceptionHandlerThread, 0, &args), INFINITE);
1.1.1.9   root     1790: 
                   1791:        return EXCEPTION_EXECUTE_HANDLER;
                   1792: }
                   1793: 
                   1794: 
1.1.1.11  root     1795: static LRESULT CALLBACK NonInstallUacWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                   1796: {
                   1797:        return DefWindowProc (hWnd, message, wParam, lParam);
                   1798: }
                   1799: 
                   1800: 
1.1.1.13  root     1801: // Mutex handling to prevent multiple instances of the wizard or main app from dealing with system encryption.
                   1802: // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). 
                   1803: BOOL CreateSysEncMutex (void)
                   1804: {
1.1.1.17  root     1805:        return TCCreateMutex (&hSysEncMutex, TC_MUTEX_NAME_SYSENC);
                   1806: }
                   1807: 
                   1808: 
                   1809: BOOL InstanceHasSysEncMutex (void)
                   1810: {
                   1811:        return (hSysEncMutex != NULL);
1.1.1.15  root     1812: }
                   1813: 
1.1.1.13  root     1814: 
1.1.1.15  root     1815: // Mutex handling to prevent multiple instances of the wizard from dealing with system encryption
                   1816: void CloseSysEncMutex (void)
                   1817: {
                   1818:        TCCloseMutex (&hSysEncMutex);
                   1819: }
                   1820: 
                   1821: 
1.1.1.19  root     1822: // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). 
                   1823: BOOL CreateNonSysInplaceEncMutex (void)
                   1824: {
                   1825:        return TCCreateMutex (&hNonSysInplaceEncMutex, TC_MUTEX_NAME_NONSYS_INPLACE_ENC);
                   1826: }
                   1827: 
                   1828: 
                   1829: BOOL InstanceHasNonSysInplaceEncMutex (void)
                   1830: {
                   1831:        return (hNonSysInplaceEncMutex != NULL);
                   1832: }
                   1833: 
                   1834: 
                   1835: void CloseNonSysInplaceEncMutex (void)
                   1836: {
                   1837:        TCCloseMutex (&hNonSysInplaceEncMutex);
                   1838: }
                   1839: 
                   1840: 
                   1841: // Returns TRUE if another instance of the wizard is preparing, resuming or performing non-system in-place encryption
                   1842: BOOL NonSysInplaceEncInProgressElsewhere (void)
                   1843: {
                   1844:        return (!InstanceHasNonSysInplaceEncMutex () 
                   1845:                && MutexExistsOnSystem (TC_MUTEX_NAME_NONSYS_INPLACE_ENC));
                   1846: }
                   1847: 
                   1848: 
1.1.1.15  root     1849: // Mutex handling to prevent multiple instances of the wizard or main app from trying to install
1.1.1.23! root     1850: // or register the driver or from trying to launch it in portable mode at the same time.
1.1.1.15  root     1851: // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). 
                   1852: BOOL CreateDriverSetupMutex (void)
                   1853: {
1.1.1.19  root     1854:        return TCCreateMutex (&hDriverSetupMutex, TC_MUTEX_NAME_DRIVER_SETUP);
1.1.1.15  root     1855: }
                   1856: 
                   1857: 
                   1858: void CloseDriverSetupMutex (void)
                   1859: {
                   1860:        TCCloseMutex (&hDriverSetupMutex);
                   1861: }
                   1862: 
                   1863: 
1.1.1.17  root     1864: BOOL CreateAppSetupMutex (void)
                   1865: {
                   1866:        return TCCreateMutex (&hAppSetupMutex, TC_MUTEX_NAME_APP_SETUP);
                   1867: }
                   1868: 
                   1869: 
                   1870: void CloseAppSetupMutex (void)
                   1871: {
                   1872:        TCCloseMutex (&hAppSetupMutex);
                   1873: }
                   1874: 
                   1875: 
                   1876: BOOL IsTrueCryptInstallerRunning (void)
                   1877: {
                   1878:        return (MutexExistsOnSystem (TC_MUTEX_NAME_APP_SETUP));
                   1879: }
                   1880: 
                   1881: 
1.1.1.15  root     1882: // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). 
1.1.1.17  root     1883: BOOL TCCreateMutex (volatile HANDLE *hMutex, char *name)
1.1.1.15  root     1884: {
                   1885:        if (*hMutex != NULL)
                   1886:                return TRUE;    // This instance already has the mutex
                   1887: 
                   1888:        *hMutex = CreateMutex (NULL, TRUE, name);
                   1889:        if (*hMutex == NULL)
1.1.1.13  root     1890:        {
                   1891:                // In multi-user configurations, the OS returns "Access is denied" here when a user attempts
1.1.1.17  root     1892:                // to acquire the mutex if another user already has. However, on Vista, "Access is denied" is
                   1893:                // returned also if the mutex is owned by a process with admin rights while we have none.
                   1894: 
1.1.1.13  root     1895:                return FALSE;
                   1896:        }
                   1897: 
                   1898:        if (GetLastError () == ERROR_ALREADY_EXISTS)
                   1899:        {
1.1.1.15  root     1900:                ReleaseMutex (*hMutex);
                   1901:                CloseHandle (*hMutex);
1.1.1.13  root     1902: 
1.1.1.15  root     1903:                *hMutex = NULL;
1.1.1.13  root     1904:                return FALSE;
                   1905:        }
                   1906: 
                   1907:        return TRUE;
                   1908: }
                   1909: 
                   1910: 
1.1.1.17  root     1911: void TCCloseMutex (volatile HANDLE *hMutex)
1.1.1.13  root     1912: {
1.1.1.15  root     1913:        if (*hMutex != NULL)
1.1.1.13  root     1914:        {
1.1.1.15  root     1915:                if (ReleaseMutex (*hMutex)
                   1916:                        && CloseHandle (*hMutex))
                   1917:                        *hMutex = NULL;
1.1.1.13  root     1918:        }
                   1919: }
                   1920: 
1.1.1.15  root     1921: 
1.1.1.17  root     1922: // Returns TRUE if a process running on the system has the specified mutex (otherwise FALSE). 
                   1923: BOOL MutexExistsOnSystem (char *name)
                   1924: {
                   1925:        if (name[0] == 0)
                   1926:                return FALSE;
                   1927: 
                   1928:        HANDLE hMutex = OpenMutex (MUTEX_ALL_ACCESS, FALSE, name);
                   1929: 
                   1930:        if (hMutex == NULL)
                   1931:        {
                   1932:                if (GetLastError () == ERROR_FILE_NOT_FOUND)
                   1933:                        return FALSE;
                   1934: 
                   1935:                if (GetLastError () == ERROR_ACCESS_DENIED) // On Vista, this is returned if the owner of the mutex is elevated while we are not
                   1936:                        return TRUE;            
                   1937: 
                   1938:                // The call failed and it is not certain whether the mutex exists or not
                   1939:                return FALSE;
                   1940:        }
                   1941: 
                   1942:        CloseHandle (hMutex);
                   1943:        return TRUE;
                   1944: }
                   1945: 
                   1946: 
1.1.1.13  root     1947: BOOL LoadSysEncSettings (HWND hwndDlg)
                   1948: {
                   1949:        BOOL status = TRUE;
                   1950:        DWORD size = 0;
1.1.1.19  root     1951:        char *sysEncCfgFileBuf = LoadFile (GetConfigPath (TC_APPD_FILENAME_SYSTEM_ENCRYPTION), &size);
1.1.1.13  root     1952:        char *xml = sysEncCfgFileBuf;
                   1953:        char paramName[100], paramVal[MAX_PATH];
                   1954: 
                   1955:        // Defaults
                   1956:        int newSystemEncryptionStatus = SYSENC_STATUS_NONE;
                   1957:        WipeAlgorithmId newnWipeMode = TC_WIPE_NONE;
                   1958: 
1.1.1.19  root     1959:        if (!FileExists (GetConfigPath (TC_APPD_FILENAME_SYSTEM_ENCRYPTION)))
1.1.1.13  root     1960:        {
                   1961:                SystemEncryptionStatus = newSystemEncryptionStatus;
                   1962:                nWipeMode = newnWipeMode;
                   1963:        }
                   1964: 
                   1965:        if (xml == NULL)
                   1966:        {
                   1967:                return FALSE;
                   1968:        }
                   1969: 
                   1970:        while (xml = XmlFindElement (xml, "config"))
                   1971:        {
                   1972:                XmlGetAttributeText (xml, "key", paramName, sizeof (paramName));
                   1973:                XmlGetNodeText (xml, paramVal, sizeof (paramVal));
                   1974: 
                   1975:                if (strcmp (paramName, "SystemEncryptionStatus") == 0)
                   1976:                {
                   1977:                        newSystemEncryptionStatus = atoi (paramVal);
                   1978:                }
                   1979:                else if (strcmp (paramName, "WipeMode") == 0)
                   1980:                {
                   1981:                        newnWipeMode = (WipeAlgorithmId) atoi (paramVal);
                   1982:                }
                   1983: 
                   1984:                xml++;
                   1985:        }
                   1986: 
                   1987:        SystemEncryptionStatus = newSystemEncryptionStatus;
                   1988:        nWipeMode = newnWipeMode;
                   1989: 
                   1990:        free (sysEncCfgFileBuf);
                   1991:        return status;
                   1992: }
                   1993: 
1.1.1.17  root     1994: 
1.1.1.19  root     1995: // Returns the number of partitions where non-system in-place encryption is progress or had been in progress
                   1996: // but was interrupted. In addition, via the passed pointer, returns the last selected wipe algorithm ID.
                   1997: int LoadNonSysInPlaceEncSettings (WipeAlgorithmId *wipeAlgorithm)
                   1998: {
                   1999:        char *fileBuf = NULL;
                   2000:        char *fileBuf2 = NULL;
                   2001:        DWORD size, size2;
                   2002:        int count;
                   2003: 
                   2004:        *wipeAlgorithm = TC_WIPE_NONE;
                   2005: 
                   2006:        if (!FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC)))
                   2007:                return 0;
                   2008: 
                   2009:        if ((fileBuf = LoadFile (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), &size)) == NULL)
                   2010:                return 0;
                   2011: 
                   2012:        if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE)))
                   2013:        {
                   2014:                if ((fileBuf2 = LoadFile (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE), &size2)) != NULL)
                   2015:                        *wipeAlgorithm = (WipeAlgorithmId) atoi (fileBuf2);
                   2016:        }
                   2017: 
                   2018:        count = atoi (fileBuf);
                   2019: 
                   2020:        if (fileBuf != NULL)
                   2021:                TCfree (fileBuf);
                   2022: 
                   2023:        if (fileBuf2 != NULL)
                   2024:                TCfree (fileBuf2);
                   2025: 
                   2026:        return (count);
                   2027: }
                   2028: 
                   2029: 
1.1.1.21  root     2030: void RemoveNonSysInPlaceEncNotifications (void)
                   2031: {
                   2032:        if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC)))
                   2033:                remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC));
                   2034: 
                   2035:        if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE)))
                   2036:                remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE));
                   2037: 
                   2038:        if (!IsNonInstallMode () && SystemEncryptionStatus == SYSENC_STATUS_NONE)
                   2039:                ManageStartupSeqWiz (TRUE, "");
                   2040: }
                   2041: 
                   2042: 
1.1.1.17  root     2043: void SavePostInstallTasksSettings (int command)
                   2044: {
                   2045:        FILE *f = NULL;
                   2046: 
                   2047:        switch (command)
                   2048:        {
                   2049:        case TC_POST_INSTALL_CFG_REMOVE_ALL:
1.1.1.19  root     2050:                remove (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL));
                   2051:                remove (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES));
1.1.1.17  root     2052:                break;
                   2053: 
                   2054:        case TC_POST_INSTALL_CFG_TUTORIAL:
1.1.1.19  root     2055:                f = fopen (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL), "w");
1.1.1.17  root     2056:                break;
                   2057: 
                   2058:        case TC_POST_INSTALL_CFG_RELEASE_NOTES:
1.1.1.19  root     2059:                f = fopen (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES), "w");
1.1.1.17  root     2060:                break;
                   2061: 
                   2062:        default:
                   2063:                return;
                   2064:        }
                   2065: 
                   2066:        if (f == NULL)
                   2067:                return;
                   2068: 
                   2069:        if (fputs ("1", f) < 0)
                   2070:        {
                   2071:                // Error
                   2072:                fclose (f);
                   2073:                return;
                   2074:        }
                   2075: 
                   2076:        TCFlushFile (f);
                   2077: 
                   2078:        fclose (f);
                   2079: }
                   2080: 
                   2081: 
                   2082: void DoPostInstallTasks (void)
                   2083: {
                   2084:        BOOL bDone = FALSE;
                   2085: 
1.1.1.19  root     2086:        if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL)))
1.1.1.17  root     2087:        {
                   2088:                if (AskYesNo ("AFTER_INSTALL_TUTORIAL") == IDYES)
                   2089:                        Applink ("beginnerstutorial", TRUE, "");
                   2090: 
                   2091:                bDone = TRUE;
                   2092:        }
                   2093: 
1.1.1.19  root     2094:        if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES)))
1.1.1.17  root     2095:        {
                   2096:                if (AskYesNo ("AFTER_UPGRADE_RELEASE_NOTES") == IDYES)
                   2097:                        Applink ("releasenotes", TRUE, "");
                   2098: 
                   2099:                bDone = TRUE;
                   2100:        }
                   2101: 
                   2102:        if (bDone)
                   2103:                SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_REMOVE_ALL);
                   2104: }
                   2105: 
                   2106: 
1.1       root     2107: /* InitApp - initialize the application, this function is called once in the
                   2108:    applications WinMain function, but before the main dialog has been created */
1.1.1.13  root     2109: void InitApp (HINSTANCE hInstance, char *lpszCommandLine)
1.1       root     2110: {
                   2111:        WNDCLASS wc;
                   2112:        OSVERSIONINFO os;
1.1.1.7   root     2113:        char langId[6];
1.1       root     2114: 
                   2115:        /* Save the instance handle for later */
                   2116:        hInst = hInstance;
                   2117: 
                   2118:        /* Pull down the windows version */
                   2119:        os.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
1.1.1.7   root     2120: 
1.1       root     2121:        if (GetVersionEx (&os) == FALSE)
1.1.1.7   root     2122:                AbortProcess ("NO_OS_VER");
                   2123: 
                   2124:        CurrentOSMajor = os.dwMajorVersion;
                   2125:        CurrentOSMinor = os.dwMinorVersion;
                   2126: 
                   2127:        if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 5 && CurrentOSMinor == 0)
                   2128:                nCurrentOS = WIN_2000;
                   2129:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 5 && CurrentOSMinor == 1)
                   2130:                nCurrentOS = WIN_XP;
                   2131:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 5 && CurrentOSMinor == 2)
1.1.1.11  root     2132:        {
                   2133:                OSVERSIONINFOEX osEx;
                   2134: 
                   2135:                osEx.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
                   2136:                GetVersionEx ((LPOSVERSIONINFOA) &osEx);
                   2137: 
                   2138:                if (osEx.wProductType == VER_NT_SERVER || osEx.wProductType == VER_NT_DOMAIN_CONTROLLER)
                   2139:                        nCurrentOS = WIN_SERVER_2003;
                   2140:                else
                   2141:                        nCurrentOS = WIN_XP64;
                   2142:        }
1.1.1.21  root     2143:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 0)
                   2144:        {
                   2145:                OSVERSIONINFOEX osEx;
                   2146: 
                   2147:                osEx.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
                   2148:                GetVersionEx ((LPOSVERSIONINFOA) &osEx);
                   2149: 
                   2150:                if (osEx.wProductType == VER_NT_SERVER || osEx.wProductType == VER_NT_DOMAIN_CONTROLLER)
                   2151:                        nCurrentOS = WIN_SERVER_2008;
                   2152:                else
                   2153:                        nCurrentOS = WIN_VISTA;
                   2154:        }
                   2155:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 1)
1.1.1.23! root     2156:                nCurrentOS = (IsServerOS() ? WIN_SERVER_2008_R2 : WIN_7);
1.1.1.7   root     2157:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 4)
                   2158:                nCurrentOS = WIN_NT4;
1.1       root     2159:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && os.dwMajorVersion == 4 && os.dwMinorVersion == 0)
                   2160:                nCurrentOS = WIN_95;
                   2161:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && os.dwMajorVersion == 4 && os.dwMinorVersion == 10)
                   2162:                nCurrentOS = WIN_98;
1.1.1.7   root     2163:        else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && os.dwMajorVersion == 4 && os.dwMinorVersion == 90)
                   2164:                nCurrentOS = WIN_ME;
                   2165:        else if (os.dwPlatformId == VER_PLATFORM_WIN32s)
                   2166:                nCurrentOS = WIN_31;
                   2167:        else
                   2168:                nCurrentOS = WIN_UNKNOWN;
1.1       root     2169: 
1.1.1.11  root     2170:        CoInitialize (NULL);
                   2171: 
1.1.1.23! root     2172: #ifndef SETUP
        !          2173:        // Application ID
        !          2174:        typedef HRESULT (WINAPI *SetAppId_t) (PCWSTR appID);
        !          2175:        SetAppId_t setAppId = (SetAppId_t) GetProcAddress (GetModuleHandle ("shell32.dll"), "SetCurrentProcessExplicitAppUserModelID");
        !          2176: 
        !          2177:        if (setAppId)
        !          2178:                setAppId (TC_APPLICATION_ID);
        !          2179: #endif
        !          2180: 
        !          2181:        // Language
1.1.1.11  root     2182:        langId[0] = 0;
                   2183:        SetPreferredLangId (ConfigReadString ("Language", "", langId, sizeof (langId)));
                   2184:        
                   2185:        if (langId[0] == 0)
                   2186:                DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_LANGUAGE), NULL,
                   2187:                        (DLGPROC) LanguageDlgProc, (LPARAM) 1);
                   2188: 
                   2189:        LoadLanguageFile ();
                   2190: 
                   2191: #ifndef SETUP
1.1.1.23! root     2192:        // UAC elevation moniker cannot be used in portable mode.
1.1.1.11  root     2193:        // A new instance of the application must be created with elevated privileges.
                   2194:        if (IsNonInstallMode () && !IsAdmin () && IsUacSupported ())
                   2195:        {
                   2196:                char modPath[MAX_PATH], newCmdLine[4096];
                   2197:                WNDCLASSEX wcex;
                   2198:                HWND hWnd;
                   2199: 
                   2200:                if (strstr (lpszCommandLine, "/q UAC ") == lpszCommandLine)
                   2201:                {
                   2202:                        Error ("UAC_INIT_ERROR");
                   2203:                        exit (1);
                   2204:                }
                   2205: 
                   2206:                memset (&wcex, 0, sizeof (wcex));
                   2207:                wcex.cbSize = sizeof(WNDCLASSEX); 
                   2208:                wcex.lpfnWndProc = (WNDPROC) NonInstallUacWndProc;
                   2209:                wcex.hInstance = hInstance;
                   2210:                wcex.lpszClassName = "TrueCrypt";
                   2211:                RegisterClassEx (&wcex);
                   2212: 
                   2213:                // A small transparent window is necessary to bring the new instance to foreground
                   2214:                hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_LAYERED,
                   2215:                        "TrueCrypt", "TrueCrypt", 0,
                   2216:                        GetSystemMetrics (SM_CXSCREEN)/2,
                   2217:                        GetSystemMetrics (SM_CYSCREEN)/2,
                   2218:                        1, 1, NULL, NULL, hInstance, NULL);
                   2219: 
                   2220:                SetLayeredWindowAttributes (hWnd, 0, 0, LWA_ALPHA);
                   2221:                ShowWindow (hWnd, SW_SHOWNORMAL);
                   2222: 
                   2223:                GetModuleFileName (NULL, modPath, sizeof (modPath));
                   2224: 
                   2225:                strcpy (newCmdLine, "/q UAC ");
                   2226:                strcat_s (newCmdLine, sizeof (newCmdLine), lpszCommandLine);
                   2227: 
                   2228:                if ((int)ShellExecute (hWnd, "runas", modPath, newCmdLine, NULL, SW_SHOWNORMAL) <= 32)
                   2229:                        exit (1);
                   2230: 
                   2231:                Sleep (2000);
                   2232:                exit (0);
                   2233:        }
                   2234: #endif
                   2235: 
                   2236:        SetUnhandledExceptionFilter (ExceptionHandler);
                   2237: 
1.1.1.10  root     2238:        RemoteSession = GetSystemMetrics (SM_REMOTESESSION) != 0;
                   2239: 
1.1.1.6   root     2240:        // OS version check
                   2241:        if (CurrentOSMajor < 5)
                   2242:        {
1.1.1.7   root     2243:                MessageBoxW (NULL, GetString ("UNSUPPORTED_OS"), lpszTitle, MB_ICONSTOP);
1.1.1.6   root     2244:                exit (1);
                   2245:        }
1.1.1.7   root     2246:        else
                   2247:        {
                   2248:                OSVERSIONINFOEX osEx;
                   2249: 
1.1.1.12  root     2250:                // Service pack check & warnings about critical MS issues
1.1.1.7   root     2251:                osEx.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
                   2252:                if (GetVersionEx ((LPOSVERSIONINFOA) &osEx) != 0)
                   2253:                {
1.1.1.10  root     2254:                        CurrentOSServicePack = osEx.wServicePackMajor;
1.1.1.7   root     2255:                        switch (nCurrentOS)
                   2256:                        {
                   2257:                        case WIN_2000:
                   2258:                                if (osEx.wServicePackMajor < 3)
                   2259:                                        Warning ("LARGE_IDE_WARNING_2K");
1.1.1.12  root     2260:                                else
                   2261:                                {
                   2262:                                        DWORD val = 0, size = sizeof(val);
                   2263:                                        HKEY hkey;
                   2264: 
                   2265:                                        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Atapi\\Parameters", 0, KEY_READ, &hkey) == ERROR_SUCCESS
                   2266:                                                && (RegQueryValueEx (hkey, "EnableBigLba", 0, 0, (LPBYTE) &val, &size) != ERROR_SUCCESS
                   2267:                                                || val != 1))
                   2268: 
                   2269:                                        {
                   2270:                                                Warning ("LARGE_IDE_WARNING_2K_REGISTRY");
                   2271:                                        }
                   2272:                                        RegCloseKey (hkey);
                   2273:                                }
1.1.1.7   root     2274:                                break;
1.1.1.12  root     2275: 
1.1.1.7   root     2276:                        case WIN_XP:
                   2277:                                if (osEx.wServicePackMajor < 1)
1.1.1.11  root     2278:                                {
                   2279:                                        HKEY k;
                   2280:                                        // PE environment does not report version of SP
                   2281:                                        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\minint", 0, KEY_READ, &k) != ERROR_SUCCESS)
                   2282:                                                Warning ("LARGE_IDE_WARNING_XP");
                   2283:                                        else
                   2284:                                                RegCloseKey (k);
                   2285:                                }
1.1.1.7   root     2286:                                break;
                   2287:                        }
                   2288:                }
1.1.1.23! root     2289: 
        !          2290:                if (CurrentOSMajor == 6 && CurrentOSMinor == 1 
        !          2291:                        && osEx.dwBuildNumber > 0 && osEx.dwBuildNumber < 7600)
        !          2292:                {
        !          2293:                        Error ("UNSUPPORTED_BETA_OS");
        !          2294:                        exit (0);
        !          2295:                }
1.1.1.7   root     2296:        }
1.1       root     2297: 
                   2298:        /* Get the attributes for the standard dialog class */
                   2299:        if ((GetClassInfo (hInst, WINDOWS_DIALOG_CLASS, &wc)) == 0)
1.1.1.21  root     2300:        {
                   2301:                handleWin32Error (NULL);
1.1.1.7   root     2302:                AbortProcess ("INIT_REGISTER");
1.1.1.21  root     2303:        }
1.1       root     2304: 
                   2305: #ifndef SETUP
                   2306:        wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_TRUECRYPT_ICON));
                   2307: #else
                   2308: #include "../setup/resource.h"
                   2309:        wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_SETUP));
                   2310: #endif
                   2311:        wc.lpszClassName = TC_DLG_CLASS;
                   2312:        wc.lpfnWndProc = &CustomDlgProc;
                   2313:        wc.hCursor = LoadCursor (NULL, IDC_ARROW);
                   2314:        wc.cbWndExtra = DLGWINDOWEXTRA;
                   2315: 
                   2316:        hDlgClass = RegisterClass (&wc);
                   2317:        if (hDlgClass == 0)
1.1.1.21  root     2318:        {
                   2319:                handleWin32Error (NULL);
1.1.1.7   root     2320:                AbortProcess ("INIT_REGISTER");
1.1.1.21  root     2321:        }
1.1       root     2322: 
                   2323:        wc.lpszClassName = TC_SPLASH_CLASS;
                   2324:        wc.lpfnWndProc = &SplashDlgProc;
                   2325:        wc.hCursor = LoadCursor (NULL, IDC_ARROW);
                   2326:        wc.cbWndExtra = DLGWINDOWEXTRA;
                   2327: 
                   2328:        hSplashClass = RegisterClass (&wc);
                   2329:        if (hSplashClass == 0)
1.1.1.21  root     2330:        {
                   2331:                handleWin32Error (NULL);
1.1.1.7   root     2332:                AbortProcess ("INIT_REGISTER");
1.1.1.21  root     2333:        }
1.1.1.7   root     2334: 
1.1.1.19  root     2335:        // Required for RichEdit text fields to work
                   2336:        if (LoadLibrary("Riched20.dll") == NULL)
                   2337:        {
                   2338:                // This error is fatal e.g. because legal notices could not be displayed
1.1.1.21  root     2339:                handleWin32Error (NULL);
1.1.1.19  root     2340:                AbortProcess ("INIT_RICHEDIT"); 
                   2341:        }
                   2342: 
1.1.1.12  root     2343:        // DPI and GUI aspect ratio
                   2344:        DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_AUXILIARY_DLG), NULL,
                   2345:                (DLGPROC) AuxiliaryDlgProc, (LPARAM) 1);
                   2346: 
1.1.1.7   root     2347:        InitHelpFileName ();
1.1.1.17  root     2348: 
                   2349: #ifndef SETUP
                   2350:        if (!EncryptionThreadPoolStart())
                   2351:        {
                   2352:                handleWin32Error (NULL);
                   2353:                exit (1);
                   2354:        }
                   2355: #endif
1.1.1.7   root     2356: }
                   2357: 
                   2358: void InitHelpFileName (void)
                   2359: {
                   2360:        char *lpszTmp;
1.1       root     2361: 
                   2362:        GetModuleFileName (NULL, szHelpFile, sizeof (szHelpFile));
                   2363:        lpszTmp = strrchr (szHelpFile, '\\');
                   2364:        if (lpszTmp)
                   2365:        {
1.1.1.7   root     2366:                char szTemp[TC_MAX_PATH];
1.1       root     2367: 
1.1.1.7   root     2368:                // Primary file name
                   2369:                if (strcmp (GetPreferredLangId(), "en") == 0
                   2370:                        || GetPreferredLangId() == NULL)
1.1       root     2371:                {
1.1.1.7   root     2372:                        strcpy (++lpszTmp, "TrueCrypt User Guide.pdf");
1.1       root     2373:                }
                   2374:                else
1.1.1.7   root     2375:                {
                   2376:                        sprintf (szTemp, "TrueCrypt User Guide.%s.pdf", GetPreferredLangId());
                   2377:                        strcpy (++lpszTmp, szTemp);
                   2378:                }
                   2379: 
                   2380:                // Secondary file name (used when localized documentation is not found).
                   2381:                GetModuleFileName (NULL, szHelpFile2, sizeof (szHelpFile2));
                   2382:                lpszTmp = strrchr (szHelpFile2, '\\');
                   2383:                if (lpszTmp)
                   2384:                {
                   2385:                        strcpy (++lpszTmp, "TrueCrypt User Guide.pdf");
                   2386:                }
1.1       root     2387:        }
                   2388: }
                   2389: 
1.1.1.21  root     2390: BOOL OpenDevice (const char *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem)
1.1       root     2391: {
                   2392:        DWORD dwResult;
                   2393:        BOOL bResult;
                   2394: 
                   2395:        strcpy ((char *) &driver->wszFileName[0], lpszPath);
1.1.1.7   root     2396:        ToUNICODE ((char *) &driver->wszFileName[0]);
1.1       root     2397: 
1.1.1.15  root     2398:        driver->bDetectTCBootLoader = FALSE;
1.1.1.21  root     2399:        driver->DetectFilesystem = detectFilesystem;
1.1.1.15  root     2400: 
1.1.1.13  root     2401:        bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
1.1       root     2402:                                   driver, sizeof (OPEN_TEST_STRUCT),
1.1.1.21  root     2403:                                   driver, sizeof (OPEN_TEST_STRUCT),
1.1       root     2404:                                   &dwResult, NULL);
                   2405: 
                   2406:        if (bResult == FALSE)
                   2407:        {
                   2408:                dwResult = GetLastError ();
1.1.1.7   root     2409: 
1.1.1.22  root     2410:                if (dwResult == ERROR_SHARING_VIOLATION || dwResult == ERROR_NOT_READY)
                   2411:                {
                   2412:                        driver->TCBootLoaderDetected = FALSE;
                   2413:                        driver->FilesystemDetected = FALSE;
1.1       root     2414:                        return TRUE;
1.1.1.22  root     2415:                }
1.1       root     2416:                else
                   2417:                        return FALSE;
                   2418:        }
1.1.1.7   root     2419:                
                   2420:        return TRUE;
1.1       root     2421: }
                   2422: 
                   2423: 
1.1.1.23! root     2424: // Tells the driver that it's running in portable mode
        !          2425: void NotifyDriverOfPortableMode (void)
1.1.1.15  root     2426: {
                   2427:        if (hDriver != INVALID_HANDLE_VALUE)
                   2428:        {
                   2429:                DWORD dwResult;
                   2430: 
1.1.1.23! root     2431:                DeviceIoControl (hDriver, TC_IOCTL_SET_PORTABLE_MODE_STATUS, NULL, 0, NULL, 0, &dwResult, NULL);
1.1.1.15  root     2432:        }
                   2433: }
                   2434: 
                   2435: 
1.1.1.11  root     2436: BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize)
                   2437: {
                   2438:        DWORD fileSystemFlags;
1.1.1.23! root     2439:        wchar_t root[] = { L'A' + (wchar_t) driveNo, L':', L'\\', 0 };
1.1.1.11  root     2440: 
                   2441:        return GetVolumeInformationW (root, label, labelSize / 2, NULL, NULL, &fileSystemFlags, NULL, 0);
                   2442: }
                   2443: 
                   2444: 
1.1.1.13  root     2445: /* Stores the device path of the system partition in SysPartitionDevicePath and the device path of the system drive
1.1.1.17  root     2446: in SysDriveDevicePath.
1.1.1.13  root     2447: IMPORTANT: As this may take a very long time if called for the first time, it should be called only before performing 
                   2448:            a dangerous operation (such as header backup restore or formatting a supposedly non-system device) never 
                   2449:                   at WM_INITDIALOG or any other GUI events -- instead call IsSystemDevicePath (path, hwndDlg, FALSE) for 
                   2450:                   very fast preliminary GUI checks; also note that right after the "Select Device" dialog exits with an OK 
                   2451:                   return code, you can use the global flags bSysPartitionSelected and bSysDriveSelected to see if the user
                   2452:                   selected the system partition/device.
                   2453: After this function completes successfully, the results are cached for the rest of the session and repeated
                   2454: executions complete very fast. Returns TRUE if successful (otherwise FALSE). */
                   2455: BOOL GetSysDevicePaths (HWND hwndDlg)
                   2456: {
                   2457:        if (!bCachedSysDevicePathsValid
                   2458:                || strlen (SysPartitionDevicePath) <= 1 
                   2459:                || strlen (SysDriveDevicePath) <= 1)
                   2460:        {
1.1.1.19  root     2461:                foreach (const HostDevice &device, GetAvailableHostDevices (false, true))
                   2462:                {
                   2463:                        if (device.ContainsSystem)
                   2464:                                strcpy_s (device.IsPartition ? SysPartitionDevicePath : SysDriveDevicePath, TC_MAX_PATH, device.Path.c_str()); 
                   2465:                }
1.1.1.13  root     2466: 
1.1.1.19  root     2467:                bCachedSysDevicePathsValid = 1;
1.1.1.13  root     2468:        }
                   2469: 
                   2470:        return (bCachedSysDevicePathsValid 
                   2471:                && strlen (SysPartitionDevicePath) > 1 
                   2472:                && strlen (SysDriveDevicePath) > 1);
                   2473: }
                   2474: 
1.1.1.17  root     2475: /* Determines whether the device path is the path of the system partition or of the system drive (or neither). 
1.1.1.13  root     2476: If bReliableRequired is TRUE, very fast execution is guaranteed, but the results cannot be relied upon. 
                   2477: If it's FALSE and the function is called for the first time, execution may take up to one minute but the
                   2478: results are reliable.
                   2479: IMPORTANT: As the execution may take a very long time if called for the first time with bReliableRequired set
                   2480:            to TRUE, it should be called with bReliableRequired set to TRUE only before performing a dangerous
                   2481:                   operation (such as header backup restore or formatting a supposedly non-system device) never at 
                   2482:                   WM_INITDIALOG or any other GUI events (use IsSystemDevicePath(path, hwndDlg, FALSE) for fast 
                   2483:                   preliminary GUI checks; also note that right after the "Select Device" dialog exits with an OK 
                   2484:                   return code, you can use the global flags bSysPartitionSelected and bSysDriveSelected to see if the
                   2485:                   user selected the system partition/device).
                   2486: After this function completes successfully, the results are cached for the rest of the session, bReliableRequired
                   2487: is ignored (TRUE implied), repeated executions complete very fast, and the results are always reliable. 
                   2488: Return codes:
                   2489: 1  - it is the system partition path (e.g. \Device\Harddisk0\Partition1)
                   2490: 2  - it is the system drive path (e.g. \Device\Harddisk0\Partition0)
                   2491: 0  - it's not the system partition/drive path
                   2492: -1 - the result can't be determined, isn't reliable, or there was an error. */
                   2493: int IsSystemDevicePath (char *path, HWND hwndDlg, BOOL bReliableRequired)
                   2494: {
                   2495:        if (!bCachedSysDevicePathsValid
                   2496:                && bReliableRequired)
                   2497:        {
                   2498:                if (!GetSysDevicePaths (hwndDlg))
                   2499:                        return -1;
                   2500:        }
                   2501: 
                   2502:        if (strlen (SysPartitionDevicePath) <= 1 || strlen (SysDriveDevicePath) <= 1)
                   2503:                return -1;
                   2504: 
                   2505:        if (strncmp (path, SysPartitionDevicePath, max (strlen(path), strlen(SysPartitionDevicePath))) == 0)
                   2506:                return 1;
                   2507:        else if (strncmp (path, SysDriveDevicePath, max (strlen(path), strlen(SysDriveDevicePath))) == 0)
                   2508:                return 2;
                   2509: 
                   2510:        return 0;
                   2511: }
                   2512: 
1.1.1.23! root     2513: 
        !          2514: wstring GetSysEncryptionPretestInfo2String (void)
        !          2515: {
        !          2516:        // This huge string is divided into smaller portions to make it easier for translators to
        !          2517:        // re-translate it when a minor modification is made to it (the whole huge string will not be
        !          2518:        // reverted to English, so they will have to translate only a small portion of it).
        !          2519:        return (wstring (L"\n")
        !          2520:                + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_1")
        !          2521:                + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_2")
        !          2522:                + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_3")
        !          2523:                + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_4"));
        !          2524: }
        !          2525: 
        !          2526: 
        !          2527: wstring GetRescueDiskHelpString (void)
        !          2528: {
        !          2529:        // This huge string is divided into smaller portions to make it easier for translators to
        !          2530:        // re-translate it when a minor modification is made to it (the whole huge string will not be
        !          2531:        // reverted to English, so they will have to translate only a small portion of it).
        !          2532:        return (wstring (
        !          2533:                GetString ("RESCUE_DISK_HELP_PORTION_1"))
        !          2534:                + GetString ("RESCUE_DISK_HELP_PORTION_2")
        !          2535:                + GetString ("RESCUE_DISK_HELP_PORTION_3")
        !          2536:                + GetString ("RESCUE_DISK_HELP_PORTION_4")
        !          2537:                + GetString ("RESCUE_DISK_HELP_PORTION_5")
        !          2538:                + GetString ("RESCUE_DISK_HELP_PORTION_6")
        !          2539:                + GetString ("RESCUE_DISK_HELP_PORTION_7")
        !          2540:                + GetString ("RESCUE_DISK_HELP_PORTION_8")
        !          2541:                + GetString ("RESCUE_DISK_HELP_PORTION_9"));
        !          2542: }
        !          2543: 
        !          2544: 
        !          2545: wstring GetDecoyOsInstructionsString (void)
        !          2546: {
        !          2547:        // This huge string is divided into smaller portions to make it easier for translators to
        !          2548:        // re-translate it when a minor modification is made to it (the whole huge string will not be
        !          2549:        // reverted to English, so they will have to translate only a small portion of it).
        !          2550:        return (wstring (
        !          2551:                GetString ("DECOY_OS_INSTRUCTIONS_PORTION_1"))
        !          2552:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_2")
        !          2553:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_3")
        !          2554:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_4")
        !          2555:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_5")
        !          2556:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_6")
        !          2557:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_7")
        !          2558:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_8")
        !          2559:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_9")
        !          2560:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_10")
        !          2561:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_11")
        !          2562:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_12")
        !          2563:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_13")
        !          2564:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_14")
        !          2565:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_15")
        !          2566:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_16")
        !          2567:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_17")
        !          2568:                + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_18"));
        !          2569: }
        !          2570: 
        !          2571: 
1.1.1.13  root     2572: BOOL TextInfoDialogBox (int nID)
                   2573: {
                   2574:        return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TEXT_INFO_DIALOG_BOX_DLG), MainDlg, (DLGPROC) TextInfoDialogBoxDlgProc, (LPARAM) nID);
                   2575: }
                   2576: 
                   2577: BOOL CALLBACK TextInfoDialogBoxDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1       root     2578: {
                   2579:        WORD lw = LOWORD (wParam);
1.1.1.13  root     2580:        static int nID = 0;
1.1       root     2581: 
                   2582:        switch (msg)
                   2583:        {
                   2584:        case WM_INITDIALOG:
                   2585:                {
1.1.1.13  root     2586:                        nID = (int) lParam;
1.1.1.11  root     2587: 
1.1.1.19  root     2588:                        // Left margin for rich edit text field
                   2589:                        SendMessage (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_SETMARGINS, (WPARAM) EC_LEFTMARGIN, (LPARAM) CompensateXDPI (4));
                   2590: 
1.1.1.13  root     2591:                        ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_HIDE);
                   2592: 
                   2593:                        switch (nID)
1.1.1.11  root     2594:                        {
1.1.1.13  root     2595:                        case TC_TBXID_LEGAL_NOTICES:
                   2596:                                LocalizeDialog (hwndDlg, "LEGAL_NOTICES_DLG_TITLE");
                   2597:                                break;
                   2598: 
                   2599:                        case TC_TBXID_SYS_ENCRYPTION_PRETEST:
                   2600:                                LocalizeDialog (hwndDlg, NULL);
                   2601:                                ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
                   2602:                                break;
                   2603: 
                   2604:                        case TC_TBXID_SYS_ENC_RESCUE_DISK:
                   2605:                                LocalizeDialog (hwndDlg, NULL);
                   2606:                                ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
                   2607:                                break;
1.1.1.19  root     2608: 
                   2609:                        case TC_TBXID_DECOY_OS_INSTRUCTIONS:
                   2610:                                LocalizeDialog (hwndDlg, NULL);
                   2611:                                ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
                   2612:                                break;
1.1.1.23! root     2613: 
        !          2614:                        case TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS:
        !          2615:                                LocalizeDialog (hwndDlg, NULL);
        !          2616:                                ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
        !          2617:                                break;
1.1.1.11  root     2618:                        }
1.1.1.13  root     2619: 
                   2620:                        SendMessage (hwndDlg, TC_APPMSG_LOAD_TEXT_BOX_CONTENT, 0, 0);
1.1.1.7   root     2621:                }
1.1.1.13  root     2622:                return 0;
1.1       root     2623: 
1.1.1.7   root     2624:        case WM_COMMAND:
                   2625:                if (lw == IDOK || lw == IDCANCEL)
                   2626:                {
1.1.1.13  root     2627:                        NormalCursor ();
1.1.1.7   root     2628:                        EndDialog (hwndDlg, 0);
                   2629:                        return 1;
                   2630:                }
1.1       root     2631: 
1.1.1.13  root     2632:                if (lw == IDC_PRINT)
                   2633:                {
                   2634:                        switch (nID)
                   2635:                        {
                   2636:                        case TC_TBXID_SYS_ENCRYPTION_PRETEST:
1.1.1.23! root     2637:                                PrintHardCopyTextUTF16 ((wchar_t *) GetSysEncryptionPretestInfo2String ().c_str(), "Pre-Boot Troubleshooting", GetSysEncryptionPretestInfo2String ().length () * 2);
1.1.1.13  root     2638:                                break;
                   2639: 
                   2640:                        case TC_TBXID_SYS_ENC_RESCUE_DISK:
1.1.1.23! root     2641:                                PrintHardCopyTextUTF16 ((wchar_t *) GetRescueDiskHelpString ().c_str(), "TrueCrypt Rescue Disk Help", GetRescueDiskHelpString ().length () * 2);
1.1.1.13  root     2642:                                break;
                   2643: 
1.1.1.19  root     2644:                        case TC_TBXID_DECOY_OS_INSTRUCTIONS:
1.1.1.23! root     2645:                                PrintHardCopyTextUTF16 ((wchar_t *) GetDecoyOsInstructionsString ().c_str(), "How to Create Decoy OS", GetDecoyOsInstructionsString ().length () * 2);
        !          2646:                                break;
        !          2647: 
        !          2648:                        case TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS:
        !          2649:                                PrintHardCopyTextUTF16 (GetString ("EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS"), "How to Remove Extra Boot Partition", wcslen (GetString ("EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS")) * 2);
1.1.1.19  root     2650:                                break;
                   2651:                        }
1.1.1.7   root     2652:                        return 1;
                   2653:                }
                   2654: 
                   2655:                return 0;
                   2656: 
1.1.1.13  root     2657:        case TC_APPMSG_LOAD_TEXT_BOX_CONTENT:
                   2658:                {
                   2659:                        char *r = NULL;
                   2660: 
                   2661:                        switch (nID)
                   2662:                        {
                   2663:                        case TC_TBXID_LEGAL_NOTICES:
                   2664:                                LocalizeDialog (hwndDlg, "LEGAL_NOTICES_DLG_TITLE");
                   2665:                                r = GetLegalNotices ();
                   2666:                                if (r != NULL)
                   2667:                                {
                   2668:                                        SetWindowText (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), r);
                   2669:                                        free (r);
                   2670:                                }
                   2671:                                break;
                   2672: 
                   2673:                        case TC_TBXID_SYS_ENCRYPTION_PRETEST:
                   2674:                                LocalizeDialog (hwndDlg, NULL);
1.1.1.23! root     2675:                                SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), (wchar_t *) GetSysEncryptionPretestInfo2String ().c_str());
1.1.1.13  root     2676:                                break;
                   2677: 
                   2678:                        case TC_TBXID_SYS_ENC_RESCUE_DISK:
                   2679:                                LocalizeDialog (hwndDlg, NULL);
1.1.1.23! root     2680:                                SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), (wchar_t *) GetRescueDiskHelpString ().c_str());
1.1.1.13  root     2681:                                break;
1.1.1.19  root     2682: 
                   2683:                        case TC_TBXID_DECOY_OS_INSTRUCTIONS:
                   2684:                                LocalizeDialog (hwndDlg, NULL);
1.1.1.23! root     2685:                                SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), (wchar_t *) GetDecoyOsInstructionsString ().c_str());
        !          2686:                                break;
        !          2687: 
        !          2688:                        case TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS:
        !          2689:                                LocalizeDialog (hwndDlg, NULL);
        !          2690:                                SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), GetString ("EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS"));
1.1.1.19  root     2691:                                break;
1.1.1.13  root     2692:                        }
                   2693:                }
                   2694:                return 1;
                   2695: 
1.1.1.7   root     2696:        case WM_CLOSE:
1.1.1.13  root     2697:                NormalCursor ();
1.1.1.7   root     2698:                EndDialog (hwndDlg, 0);
                   2699:                return 1;
                   2700:        }
                   2701: 
                   2702:        return 0;
                   2703: }
                   2704: 
                   2705: 
                   2706: char * GetLegalNotices ()
                   2707: {
                   2708:        static char *resource;
1.1.1.11  root     2709:        static DWORD size;
1.1.1.15  root     2710:        char *buf = NULL;
1.1.1.7   root     2711: 
                   2712:        if (resource == NULL)
1.1.1.15  root     2713:                resource = (char *) MapResource ("Text", IDR_LICENSE, &size);
1.1.1.7   root     2714: 
1.1.1.11  root     2715:        if (resource != NULL)
                   2716:        {
1.1.1.15  root     2717:                buf = (char *) malloc (size + 1);
1.1.1.11  root     2718:                if (buf != NULL)
                   2719:                {
                   2720:                        memcpy (buf, resource, size);
                   2721:                        buf[size] = 0;
                   2722:                }
                   2723:        }
                   2724: 
                   2725:        return buf;
1.1.1.7   root     2726: }
                   2727: 
                   2728: 
1.1.1.19  root     2729: BOOL CALLBACK RawDevicesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1.1.7   root     2730: {
1.1.1.13  root     2731:        static char *lpszFileName;              // This is actually a pointer to a GLOBAL array
1.1.1.19  root     2732:        static vector <HostDevice> devices;
                   2733:        static map <int, HostDevice> itemToDeviceMap;
                   2734: 
1.1.1.7   root     2735:        WORD lw = LOWORD (wParam);
                   2736: 
                   2737:        switch (msg)
                   2738:        {
                   2739:        case WM_INITDIALOG:
                   2740:                {
                   2741:                        LVCOLUMNW LvCol;
                   2742:                        HWND hList = GetDlgItem (hwndDlg, IDC_DEVICELIST);
                   2743: 
                   2744:                        LocalizeDialog (hwndDlg, "IDD_RAWDEVICES_DLG");
                   2745: 
                   2746:                        SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
                   2747:                                LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_TWOCLICKACTIVATE|LVS_EX_LABELTIP 
                   2748:                                ); 
                   2749: 
                   2750:                        memset (&LvCol,0,sizeof(LvCol));               
                   2751:                        LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;  
                   2752:                        LvCol.pszText = GetString ("DEVICE");
1.1.1.12  root     2753:                        LvCol.cx = CompensateXDPI (186);
1.1.1.7   root     2754:                        LvCol.fmt = LVCFMT_LEFT;
                   2755:                        SendMessage (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&LvCol);
1.1.1.5   root     2756: 
1.1.1.7   root     2757:                        LvCol.pszText = GetString ("DRIVE");  
1.1.1.13  root     2758:                        LvCol.cx = CompensateXDPI (38);
1.1.1.11  root     2759:                        LvCol.fmt = LVCFMT_LEFT;
1.1.1.7   root     2760:                        SendMessage (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&LvCol);
1.1       root     2761: 
1.1.1.13  root     2762:                        LvCol.pszText = GetString ("SIZE");
                   2763:                        LvCol.cx = CompensateXDPI (64);
1.1       root     2764:                        LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7   root     2765:                        SendMessage (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol);
1.1       root     2766: 
1.1.1.13  root     2767:                        LvCol.pszText = GetString ("VOLUME_LABEL");
                   2768:                        LvCol.cx = CompensateXDPI (128);
1.1       root     2769:                        LvCol.fmt = LVCFMT_LEFT;
1.1.1.7   root     2770:                        SendMessage (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol);
1.1       root     2771: 
1.1.1.19  root     2772:                        devices.clear();
                   2773:                        itemToDeviceMap.clear();
                   2774: 
                   2775:                        WaitCursor();
                   2776:                        devices = GetAvailableHostDevices (false, true, false);
                   2777:                        NormalCursor();
1.1.1.13  root     2778: 
1.1.1.19  root     2779:                        if (devices.empty())
1.1.1.13  root     2780:                        {
1.1.1.19  root     2781:                                MessageBoxW (hwndDlg, GetString ("RAWDEVICES"), lpszTitle, ICON_HAND);
1.1.1.13  root     2782:                                EndDialog (hwndDlg, IDCANCEL);
                   2783:                                return 1;
                   2784:                        }
                   2785: 
1.1.1.19  root     2786:                        int line = 1;
                   2787:                        LVITEM item;
                   2788:                        memset (&item, 0, sizeof (item));
                   2789:                        item.mask = LVIF_TEXT;
1.1       root     2790: 
1.1.1.19  root     2791:                        foreach (const HostDevice &device, devices)
1.1       root     2792:                        {
1.1.1.19  root     2793:                                item.iSubItem = 1;
                   2794: 
                   2795:                                if (device.ContainsSystem)
                   2796:                                {
                   2797:                                        if (device.IsPartition)
                   2798:                                                strcpy_s (SysPartitionDevicePath, sizeof (SysPartitionDevicePath), device.Path.c_str());
                   2799:                                        else
                   2800:                                                strcpy_s (SysDriveDevicePath, sizeof (SysDriveDevicePath), device.Path.c_str());
                   2801:                                }
                   2802: 
                   2803:                                // Path
                   2804:                                if (!device.IsPartition || device.DynamicVolume)
                   2805:                                {
                   2806:                                        if (!device.Floppy && device.Size == 0)
                   2807:                                                continue;
                   2808: 
                   2809:                                        if (line > 1)
                   2810:                                        {
                   2811:                                                ListItemAdd (hList, item.iItem, "");
                   2812:                                                item.iItem = line++;   
                   2813:                                        }
                   2814: 
                   2815:                                        if (device.Floppy || device.DynamicVolume)
                   2816:                                        {
                   2817:                                                ListItemAdd (hList, item.iItem, (char *) device.Path.c_str());
                   2818:                                        }
                   2819:                                        else
                   2820:                                        {
                   2821:                                                wchar_t s[1024];
                   2822:                                                if (device.Removable)
                   2823:                                                        wsprintfW (s, L"%s %d", GetString ("REMOVABLE_DISK"), device.SystemNumber);
                   2824:                                                else
                   2825:                                                        wsprintfW (s, L"%s %d", GetString ("HARDDISK"), device.SystemNumber);
                   2826: 
                   2827:                                                if (!device.Partitions.empty())
                   2828:                                                        wcscat (s, L":");
                   2829: 
                   2830:                                                ListItemAddW (hList, item.iItem, s);
                   2831:                                        }
                   2832:                                }
                   2833:                                else
                   2834:                                {
                   2835:                                        ListItemAdd (hList, item.iItem, (char *) device.Path.c_str());
                   2836:                                }
                   2837: 
                   2838:                                itemToDeviceMap[item.iItem] = device;
                   2839: 
                   2840:                                // Size
                   2841:                                if (device.Size != 0)
                   2842:                                {
                   2843:                                        wchar_t size[100] = { 0 };
                   2844:                                        GetSizeString (device.Size, size);
                   2845:                                        ListSubItemSetW (hList, item.iItem, 2, size);
                   2846:                                }
                   2847: 
                   2848:                                // Mount point
                   2849:                                if (!device.MountPoint.empty())
                   2850:                                        ListSubItemSet (hList, item.iItem, 1, (char *) device.MountPoint.c_str());
                   2851: 
                   2852:                                // Label
                   2853:                                if (!device.Name.empty())
                   2854:                                        ListSubItemSetW (hList, item.iItem, 3, (wchar_t *) device.Name.c_str());
                   2855: 
                   2856:                                item.iItem = line++;   
1.1       root     2857:                        }
                   2858: 
                   2859:                        lpszFileName = (char *) lParam;
1.1.1.12  root     2860: 
                   2861: #ifdef VOLFORMAT
                   2862:                        EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE);
                   2863: #endif
1.1       root     2864:                        return 1;
                   2865:                }
                   2866: 
                   2867:        case WM_COMMAND:
                   2868:        case WM_NOTIFY:
                   2869:                // catch non-device line selected
                   2870:                if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED ))
                   2871:                {
                   2872:                        LVITEM LvItem;
                   2873:                        memset(&LvItem,0,sizeof(LvItem));
1.1.1.11  root     2874:                        LvItem.mask = LVIF_TEXT | LVIF_PARAM;   
1.1       root     2875:                        LvItem.iItem = ((LPNMLISTVIEW) lParam)->iItem;
                   2876:                        LvItem.pszText = lpszFileName;
                   2877:                        LvItem.cchTextMax = TC_MAX_PATH;
                   2878: 
1.1.1.11  root     2879:                        SendMessage (GetDlgItem (hwndDlg, IDC_DEVICELIST), LVM_GETITEM, LvItem.iItem, (LPARAM) &LvItem);
1.1       root     2880:                        EnableWindow (GetDlgItem ((HWND) hwndDlg, IDOK), lpszFileName[0] != 0 && lpszFileName[0] != ' ');
1.1.1.11  root     2881: 
1.1       root     2882:                        return 1;
                   2883:                }
                   2884: 
                   2885:                if (msg == WM_COMMAND && lw == IDOK || msg == WM_NOTIFY && ((NMHDR *)lParam)->code == LVN_ITEMACTIVATE)
                   2886:                {
1.1.1.19  root     2887:                        int selectedItem = ListView_GetSelectionMark (GetDlgItem (hwndDlg, IDC_DEVICELIST));
1.1       root     2888: 
1.1.1.19  root     2889:                        if (selectedItem == -1 || itemToDeviceMap.find (selectedItem) == itemToDeviceMap.end())
1.1.1.12  root     2890:                                return 1; // non-device line selected
                   2891: 
1.1.1.19  root     2892:                        const HostDevice selectedDevice = itemToDeviceMap[selectedItem];
                   2893:                        strcpy_s (lpszFileName, TC_MAX_PATH, selectedDevice.Path.c_str());
                   2894: 
1.1.1.12  root     2895: #ifdef VOLFORMAT
1.1.1.19  root     2896:                        if (selectedDevice.ContainsSystem && selectedDevice.IsPartition)
1.1.1.12  root     2897:                        {
1.1.1.13  root     2898:                                if (WizardMode != WIZARD_MODE_SYS_DEVICE)
                   2899:                                {
                   2900:                                        if (AskYesNo ("CONFIRM_SYSTEM_ENCRYPTION_MODE") == IDNO)
                   2901:                                        {
                   2902:                                                EndDialog (hwndDlg, IDCANCEL);
                   2903:                                                return 1;
                   2904:                                        }
                   2905: 
                   2906:                                        bSysPartitionSelected = TRUE;
                   2907:                                        bSysDriveSelected = FALSE;
                   2908:                                        lpszFileName[0] = 0;
                   2909:                                        SwitchWizardToSysEncMode ();
                   2910: 
                   2911:                                        NormalCursor ();
                   2912:                                        EndDialog (hwndDlg, IDOK);
                   2913:                                        return 1;
                   2914:                                }
                   2915:                                else
                   2916:                                {
                   2917:                                        // This should never be the case because the Select Device dialog is not available in this wizard mode
                   2918:                                        bSysPartitionSelected = TRUE;
                   2919:                                        bSysDriveSelected = FALSE;
                   2920:                                        lpszFileName[0] = 0;
                   2921:                                        SwitchWizardToSysEncMode ();
                   2922:                                        NormalCursor ();
                   2923:                                        EndDialog (hwndDlg, IDCANCEL);
                   2924:                                        return 1;
                   2925:                                }
1.1.1.12  root     2926:                        }
                   2927: 
1.1.1.19  root     2928:                        if (!(selectedDevice.ContainsSystem && !selectedDevice.IsPartition))
1.1.1.13  root     2929:                        {
                   2930:                                if (bWarnDeviceFormatAdvanced
                   2931:                                        && !bHiddenVolDirect
                   2932:                                        && AskWarnNoYes("FORMAT_DEVICE_FOR_ADVANCED_ONLY") == IDNO)
                   2933:                                {
                   2934:                                        if (AskNoYes("CONFIRM_CHANGE_WIZARD_MODE_TO_FILE_CONTAINER") == IDYES)
                   2935:                                        {
                   2936:                                                SwitchWizardToFileContainerMode ();
                   2937:                                        }
                   2938:                                        EndDialog (hwndDlg, IDCANCEL);
                   2939:                                        return 1;
                   2940:                                }
1.1.1.12  root     2941: 
1.1.1.13  root     2942:                                if (!bHiddenVolDirect)
                   2943:                                        bWarnDeviceFormatAdvanced = FALSE;
                   2944:                        }
                   2945: 
                   2946: #else  // #ifdef VOLFORMAT
                   2947: 
1.1.1.19  root     2948:                        bSysPartitionSelected = (selectedDevice.ContainsSystem && selectedDevice.IsPartition);
1.1.1.13  root     2949:                        bSysDriveSelected = FALSE;
                   2950: 
                   2951: #endif // #ifdef VOLFORMAT
1.1       root     2952: 
1.1.1.19  root     2953:                        if (!selectedDevice.IsPartition && !selectedDevice.Floppy)
1.1.1.5   root     2954:                        {
                   2955:                                // Whole device selected
1.1.1.11  root     2956: 
1.1.1.5   root     2957: #ifdef VOLFORMAT
1.1.1.19  root     2958:                                if (selectedDevice.ContainsSystem && !selectedDevice.IsPartition)
1.1.1.13  root     2959:                                {
                   2960:                                        if (WizardMode != WIZARD_MODE_SYS_DEVICE)
                   2961:                                        {
                   2962:                                                if (AskYesNo ("CONFIRM_SYSTEM_ENCRYPTION_MODE") == IDNO)
                   2963:                                                {
                   2964:                                                        NormalCursor ();
                   2965:                                                        EndDialog (hwndDlg, IDCANCEL);
                   2966:                                                        return 1;
                   2967:                                                }
                   2968: 
                   2969:                                                bSysDriveSelected = TRUE;
                   2970:                                                bSysPartitionSelected = FALSE;
                   2971:                                                lpszFileName[0] = 0;
                   2972:                                                SwitchWizardToSysEncMode ();
                   2973: 
                   2974:                                                NormalCursor ();
                   2975:                                                EndDialog (hwndDlg, IDOK);
                   2976:                                                return 1;
                   2977:                                        }
                   2978:                                        else
                   2979:                                        {
                   2980:                                                // This should never be the case because the Select Device dialog is not available in this wizard mode
                   2981:                                                bSysDriveSelected = TRUE;
                   2982:                                                bSysPartitionSelected = FALSE;
                   2983:                                                lpszFileName[0] = 0;
                   2984:                                                SwitchWizardToSysEncMode ();
                   2985:                                                NormalCursor ();
                   2986:                                                EndDialog (hwndDlg, IDCANCEL);
                   2987:                                                return 1;
                   2988:                                        }
                   2989:                                }
                   2990: 
                   2991:                                // Disallow format if the device contains partitions, but not if the partition is virtual or system 
1.1.1.19  root     2992:                                if (!selectedDevice.IsVirtualPartition
1.1.1.11  root     2993:                                        && !bHiddenVolDirect)
1.1.1.5   root     2994:                                {
1.1.1.19  root     2995:                                        if (!selectedDevice.Partitions.empty())
1.1.1.7   root     2996:                                        {
1.1.1.11  root     2997:                                                EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE);
1.1.1.19  root     2998:                                                Error ("DEVICE_PARTITIONS_ERR_W_INPLACE_ENC_NOTE");
1.1.1.11  root     2999:                                                return 1;
                   3000:                                        }
1.1.1.19  root     3001: 
                   3002:                                        if (AskWarnNoYes ("WHOLE_NONSYS_DEVICE_ENC_CONFIRM") == IDNO)
                   3003:                                                return 1;
1.1.1.5   root     3004:                                }
1.1.1.13  root     3005: #else  // #ifdef VOLFORMAT
                   3006: 
1.1.1.19  root     3007:                                bSysDriveSelected = (selectedDevice.ContainsSystem && !selectedDevice.IsPartition);
1.1.1.13  root     3008:                                bSysPartitionSelected = FALSE;
                   3009: 
                   3010: #endif // #ifdef VOLFORMAT
1.1.1.5   root     3011:                        }
1.1.1.13  root     3012:                        else 
                   3013:                                bSysDriveSelected = FALSE;
1.1.1.5   root     3014: 
1.1.1.12  root     3015: #ifdef VOLFORMAT
1.1.1.19  root     3016:                        bRemovableHostDevice = selectedDevice.Removable;
1.1.1.12  root     3017: #endif
1.1.1.13  root     3018:                        NormalCursor ();
1.1       root     3019:                        EndDialog (hwndDlg, IDOK);
1.1.1.7   root     3020:                        return 1;
1.1       root     3021:                }
                   3022: 
                   3023:                if (lw == IDCANCEL)
                   3024:                {
1.1.1.13  root     3025:                        NormalCursor ();
1.1       root     3026:                        EndDialog (hwndDlg, IDCANCEL);
1.1.1.7   root     3027:                        return 1;
1.1       root     3028:                }
                   3029:                return 0;
                   3030:        }
                   3031:        return 0;
                   3032: }
                   3033: 
1.1.1.6   root     3034: 
1.1.1.15  root     3035: BOOL DoDriverInstall (HWND hwndDlg)
                   3036: {
                   3037: #ifdef SETUP
                   3038:        if (SystemEncryptionUpgrade)
                   3039:                return TRUE;
                   3040: #endif
                   3041: 
                   3042:        SC_HANDLE hManager, hService = NULL;
                   3043:        BOOL bOK = FALSE, bRet;
                   3044: 
                   3045:        hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
                   3046:        if (hManager == NULL)
                   3047:                goto error;
                   3048: 
                   3049: #ifdef SETUP
                   3050:        StatusMessage (hwndDlg, "INSTALLING_DRIVER");
                   3051: #endif
                   3052: 
                   3053:        hService = CreateService (hManager, "truecrypt", "truecrypt",
                   3054:                SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_SYSTEM_START, SERVICE_ERROR_NORMAL,
                   3055:                !Is64BitOs () ? "System32\\drivers\\truecrypt.sys" : "SysWOW64\\drivers\\truecrypt.sys",
                   3056:                NULL, NULL, NULL, NULL, NULL);
                   3057: 
                   3058:        if (hService == NULL)
                   3059:                goto error;
                   3060:        else
                   3061:                CloseServiceHandle (hService);
                   3062: 
                   3063:        hService = OpenService (hManager, "truecrypt", SERVICE_ALL_ACCESS);
                   3064:        if (hService == NULL)
                   3065:                goto error;
                   3066: 
                   3067: #ifdef SETUP
                   3068:        StatusMessage (hwndDlg, "STARTING_DRIVER");
                   3069: #endif
                   3070: 
                   3071:        bRet = StartService (hService, 0, NULL);
                   3072:        if (bRet == FALSE)
                   3073:                goto error;
                   3074: 
                   3075:        bOK = TRUE;
                   3076: 
                   3077: error:
                   3078:        if (bOK == FALSE && GetLastError () != ERROR_SERVICE_ALREADY_RUNNING)
                   3079:        {
                   3080:                handleWin32Error (hwndDlg);
                   3081:                MessageBoxW (hwndDlg, GetString ("DRIVER_INSTALL_FAILED"), lpszTitle, MB_ICONHAND);
                   3082:        }
                   3083:        else
                   3084:                bOK = TRUE;
                   3085: 
                   3086:        if (hService != NULL)
                   3087:                CloseServiceHandle (hService);
                   3088: 
                   3089:        if (hManager != NULL)
                   3090:                CloseServiceHandle (hManager);
                   3091: 
                   3092:        return bOK;
                   3093: }
                   3094: 
                   3095: 
1.1.1.6   root     3096: // Install and start driver service and mark it for removal (non-install mode)
                   3097: static int DriverLoad ()
                   3098: {
                   3099:        HANDLE file;
                   3100:        WIN32_FIND_DATA find;
                   3101:        SC_HANDLE hManager, hService = NULL;
                   3102:        char driverPath[TC_MAX_PATH*2];
                   3103:        BOOL res;
                   3104:        char *tmp;
                   3105: 
                   3106:        GetModuleFileName (NULL, driverPath, sizeof (driverPath));
                   3107:        tmp = strrchr (driverPath, '\\');
                   3108:        if (!tmp)
                   3109:        {
                   3110:                strcpy (driverPath, ".");
                   3111:                tmp = driverPath + 1;
                   3112:        }
                   3113: 
1.1.1.7   root     3114:        strcpy (tmp, !Is64BitOs () ? "\\truecrypt.sys" : "\\truecrypt-x64.sys");
1.1.1.6   root     3115: 
                   3116:        file = FindFirstFile (driverPath, &find);
                   3117: 
                   3118:        if (file == INVALID_HANDLE_VALUE)
                   3119:        {
1.1.1.7   root     3120:                MessageBoxW (0, GetString ("DRIVER_NOT_FOUND"), lpszTitle, ICON_HAND);
1.1.1.6   root     3121:                return ERR_DONT_REPORT;
                   3122:        }
                   3123: 
                   3124:        FindClose (file);
                   3125: 
                   3126:        hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
                   3127:        if (hManager == NULL)
1.1.1.7   root     3128:        {
                   3129:                if (GetLastError () == ERROR_ACCESS_DENIED)
                   3130:                {
                   3131:                        MessageBoxW (0, GetString ("ADMIN_PRIVILEGES_DRIVER"), lpszTitle, ICON_HAND);
                   3132:                        return ERR_DONT_REPORT;
                   3133:                }
                   3134: 
1.1.1.6   root     3135:                return ERR_OS_ERROR;
1.1.1.7   root     3136:        }
1.1.1.6   root     3137: 
1.1.1.12  root     3138:        hService = OpenService (hManager, "truecrypt", SERVICE_ALL_ACCESS);
                   3139:        if (hService != NULL)
                   3140:        {
                   3141:                // Remove stale service (driver is not loaded but service exists)
                   3142:                DeleteService (hService);
                   3143:                CloseServiceHandle (hService);
                   3144:                Sleep (500);
                   3145:        }
                   3146: 
1.1.1.6   root     3147:        hService = CreateService (hManager, "truecrypt", "truecrypt",
                   3148:                SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
                   3149:                driverPath, NULL, NULL, NULL, NULL, NULL);
                   3150: 
                   3151:        if (hService == NULL)
                   3152:        {
                   3153:                CloseServiceHandle (hManager);
                   3154:                return ERR_OS_ERROR;
                   3155:        }
                   3156: 
                   3157:        res = StartService (hService, 0, NULL);
                   3158:        DeleteService (hService);
1.1.1.12  root     3159: 
1.1.1.6   root     3160:        CloseServiceHandle (hManager);
                   3161:        CloseServiceHandle (hService);
                   3162: 
                   3163:        return !res ? ERR_OS_ERROR : ERROR_SUCCESS;
                   3164: }
                   3165: 
                   3166: 
1.1.1.7   root     3167: BOOL DriverUnload ()
                   3168: {
                   3169:        MOUNT_LIST_STRUCT driver;
                   3170:        int refCount;
1.1.1.13  root     3171:        int volumesMounted;
1.1.1.7   root     3172:        DWORD dwResult;
                   3173:        BOOL bResult;
                   3174: 
                   3175:        SC_HANDLE hManager, hService = NULL;
                   3176:        BOOL bRet;
                   3177:        SERVICE_STATUS status;
                   3178:        int x;
1.1.1.23! root     3179:        BOOL driverUnloaded = FALSE;
1.1.1.7   root     3180: 
                   3181:        if (hDriver == INVALID_HANDLE_VALUE)
                   3182:                return TRUE;
1.1.1.15  root     3183:        
                   3184:        try
                   3185:        {
                   3186:                if (BootEncryption (NULL).GetStatus().DeviceFilterActive)
                   3187:                        return FALSE;
                   3188:        }
                   3189:        catch (...) { }
1.1.1.7   root     3190: 
                   3191:        // Test for mounted volumes
1.1.1.13  root     3192:        bResult = DeviceIoControl (hDriver, TC_IOCTL_IS_ANY_VOLUME_MOUNTED, NULL, 0, &volumesMounted, sizeof (volumesMounted), &dwResult, NULL);
                   3193: 
                   3194:        if (!bResult)
                   3195:        {
                   3196:                bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES, NULL, 0, &driver, sizeof (driver), &dwResult, NULL);
                   3197:                if (bResult)
                   3198:                        volumesMounted = driver.ulMountedDrives;
                   3199:        }
1.1.1.7   root     3200: 
                   3201:        if (bResult)
                   3202:        {
1.1.1.13  root     3203:                if (volumesMounted != 0)
1.1.1.7   root     3204:                        return FALSE;
                   3205:        }
                   3206:        else
                   3207:                return TRUE;
                   3208: 
                   3209:        // Test for any applications attached to driver
                   3210:        refCount = GetDriverRefCount ();
                   3211: 
                   3212:        if (refCount > 1)
                   3213:                return FALSE;
                   3214: 
                   3215:        CloseHandle (hDriver);
1.1.1.12  root     3216:        hDriver = INVALID_HANDLE_VALUE;
1.1.1.7   root     3217: 
                   3218:        // Stop driver service
                   3219: 
                   3220:        hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
                   3221:        if (hManager == NULL)
                   3222:                goto error;
                   3223: 
                   3224:        hService = OpenService (hManager, "truecrypt", SERVICE_ALL_ACCESS);
                   3225:        if (hService == NULL)
                   3226:                goto error;
                   3227: 
                   3228:        bRet = QueryServiceStatus (hService, &status);
                   3229:        if (bRet != TRUE)
                   3230:                goto error;
                   3231: 
                   3232:        if (status.dwCurrentState != SERVICE_STOPPED)
                   3233:        {
                   3234:                ControlService (hService, SERVICE_CONTROL_STOP, &status);
                   3235: 
1.1.1.23! root     3236:                for (x = 0; x < 10; x++)
1.1.1.7   root     3237:                {
                   3238:                        bRet = QueryServiceStatus (hService, &status);
                   3239:                        if (bRet != TRUE)
                   3240:                                goto error;
                   3241: 
                   3242:                        if (status.dwCurrentState == SERVICE_STOPPED)
1.1.1.23! root     3243:                        {
        !          3244:                                driverUnloaded = TRUE;
1.1.1.7   root     3245:                                break;
1.1.1.23! root     3246:                        }
1.1.1.7   root     3247: 
                   3248:                        Sleep (200);
                   3249:                }
                   3250:        }
1.1.1.23! root     3251:        else
        !          3252:                driverUnloaded = TRUE;
1.1.1.7   root     3253: 
                   3254: error:
                   3255:        if (hService != NULL)
                   3256:                CloseServiceHandle (hService);
                   3257: 
                   3258:        if (hManager != NULL)
                   3259:                CloseServiceHandle (hManager);
                   3260: 
1.1.1.23! root     3261:        if (driverUnloaded)
1.1.1.7   root     3262:        {
                   3263:                hDriver = INVALID_HANDLE_VALUE;
                   3264:                return TRUE;
                   3265:        }
                   3266: 
                   3267:        return FALSE;
                   3268: }
                   3269: 
                   3270: 
1.1.1.15  root     3271: int DriverAttach (void)
1.1       root     3272: {
1.1.1.6   root     3273:        /* Try to open a handle to the device driver. It will be closed later. */
1.1       root     3274: 
1.1.1.15  root     3275: #ifndef SETUP
                   3276: 
                   3277:        int nLoadRetryCount = 0;
                   3278: start:
                   3279: 
                   3280: #endif
                   3281: 
1.1.1.6   root     3282:        hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1.1       root     3283: 
                   3284:        if (hDriver == INVALID_HANDLE_VALUE)
                   3285:        {
1.1.1.6   root     3286: #ifndef SETUP
1.1.1.15  root     3287: 
                   3288:                LoadSysEncSettings (NULL);
                   3289: 
                   3290:                if (!CreateDriverSetupMutex ())
                   3291:                {
                   3292:                        // Another instance is already attempting to install, register or start the driver
                   3293: 
                   3294:                        while (!CreateDriverSetupMutex ())
                   3295:                        {
                   3296:                                Sleep (100);    // Wait until the other instance finishes
                   3297:                        }
                   3298: 
                   3299:                        // Try to open a handle to the driver again (keep the mutex in case the other instance failed)
                   3300:                        goto start;             
                   3301:                }
                   3302:                else
1.1.1.8   root     3303:                {
1.1.1.15  root     3304:                        // No other instance is currently attempting to install, register or start the driver
1.1.1.6   root     3305: 
1.1.1.15  root     3306:                        if (SystemEncryptionStatus != SYSENC_STATUS_NONE)
                   3307:                        {
                   3308:                                // This is an inconsistent state. The config file indicates system encryption should be
                   3309:                                // active, but the driver is not running. This may happen e.g. when the pretest fails and 
                   3310:                                // the user selects "Last Known Good Configuration" from the Windows boot menu.
                   3311:                                // To fix this, we're going to reinstall the driver, start it, and register it for boot.
                   3312: 
                   3313:                                if (DoDriverInstall (NULL))
                   3314:                                {
                   3315:                                        Sleep (1000);
1.1.1.19  root     3316:                                        hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
                   3317: 
                   3318:                                        try
                   3319:                                        {
                   3320:                                                BootEncryption bootEnc (NULL);
                   3321:                                                bootEnc.RegisterBootDriver (bootEnc.GetHiddenOSCreationPhase() != TC_HIDDEN_OS_CREATION_PHASE_NONE ? true : false);
                   3322:                                        }
                   3323:                                        catch (Exception &e)
                   3324:                                        {
                   3325:                                                e.Show (NULL);
                   3326:                                        }
1.1.1.15  root     3327:                                }
                   3328: 
                   3329:                                CloseDriverSetupMutex ();
                   3330:                        }
                   3331:                        else
                   3332:                        {
1.1.1.23! root     3333:                                // Attempt to load the driver (non-install/portable mode)
1.1.1.15  root     3334: load:
                   3335:                                BOOL res = DriverLoad ();
                   3336: 
                   3337:                                CloseDriverSetupMutex ();
                   3338: 
                   3339:                                if (res != ERROR_SUCCESS)
                   3340:                                        return res;
                   3341: 
1.1.1.23! root     3342:                                bPortableModeConfirmed = TRUE;
1.1.1.6   root     3343: 
1.1.1.19  root     3344:                                hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
                   3345:                        }
1.1.1.15  root     3346: 
1.1.1.23! root     3347:                        if (bPortableModeConfirmed)
        !          3348:                                NotifyDriverOfPortableMode ();
1.1.1.8   root     3349:                }
1.1.1.15  root     3350: 
                   3351: #endif // #ifndef SETUP
                   3352: 
1.1.1.6   root     3353:                if (hDriver == INVALID_HANDLE_VALUE)
                   3354:                        return ERR_OS_ERROR;
1.1       root     3355:        }
1.1.1.7   root     3356: 
1.1.1.15  root     3357:        CloseDriverSetupMutex ();
                   3358: 
1.1.1.7   root     3359:        if (hDriver != INVALID_HANDLE_VALUE)
1.1       root     3360:        {
                   3361:                DWORD dwResult;
                   3362: 
1.1.1.13  root     3363:                BOOL bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &DriverVersion, sizeof (DriverVersion), &dwResult, NULL);
                   3364: 
                   3365:                if (!bResult)
                   3366:                        bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_DRIVER_VERSION, NULL, 0, &DriverVersion, sizeof (DriverVersion), &dwResult, NULL);
1.1       root     3367: 
1.1.1.11  root     3368: #ifndef SETUP // Don't check version during setup to allow removal of another version
1.1       root     3369:                if (bResult == FALSE)
1.1.1.12  root     3370:                {
1.1       root     3371:                        return ERR_OS_ERROR;
1.1.1.12  root     3372:                }
1.1.1.11  root     3373:                else if (DriverVersion != VERSION_NUM)
1.1.1.12  root     3374:                {
                   3375:                        // Unload an incompatbile version of the driver loaded in non-install mode and load the required version
1.1.1.15  root     3376:                        if (IsNonInstallMode () && CreateDriverSetupMutex () && DriverUnload () && nLoadRetryCount++ < 3)
1.1.1.12  root     3377:                                goto load;
                   3378: 
1.1.1.15  root     3379:                        CloseDriverSetupMutex ();
1.1.1.12  root     3380:                        CloseHandle (hDriver);
                   3381:                        hDriver = INVALID_HANDLE_VALUE;
1.1       root     3382:                        return ERR_DRIVER_VERSION;
1.1.1.12  root     3383:                }
1.1.1.11  root     3384: #else
                   3385:                if (!bResult)
                   3386:                        DriverVersion = 0;
1.1       root     3387: #endif
1.1.1.11  root     3388:        }
1.1       root     3389: 
                   3390:        return 0;
                   3391: }
                   3392: 
1.1.1.5   root     3393: 
1.1.1.10  root     3394: void ResetCurrentDirectory ()
                   3395: {
                   3396:        char p[MAX_PATH];
                   3397:        if (!IsNonInstallMode () && SHGetFolderPath (NULL, CSIDL_PROFILE, NULL, 0, p) == ERROR_SUCCESS)
                   3398:        {
                   3399:                SetCurrentDirectory (p);
                   3400:        }
                   3401:        else
                   3402:        {
1.1.1.11  root     3403:                GetModPath (p, sizeof (p));
1.1.1.10  root     3404:                SetCurrentDirectory (p);
                   3405:        }
                   3406: }
                   3407: 
                   3408: 
1.1.1.19  root     3409: BOOL BrowseFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter)
1.1.1.11  root     3410: {
1.1.1.19  root     3411:        return BrowseFilesInDir (hwndDlg, stringId, NULL, lpszFileName, keepHistory, saveMode, browseFilter);
1.1.1.11  root     3412: }
                   3413: 
                   3414: 
1.1.1.23! root     3415: BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, char *initialDir, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter, const wchar_t *initialFileName, const wchar_t *defaultExtension)
1.1       root     3416: {
1.1.1.7   root     3417:        OPENFILENAMEW ofn;
                   3418:        wchar_t file[TC_MAX_PATH] = { 0 };
1.1.1.11  root     3419:        wchar_t wInitialDir[TC_MAX_PATH] = { 0 };
1.1.1.7   root     3420:        wchar_t filter[1024];
1.1.1.17  root     3421:        BOOL status = FALSE;
                   3422: 
                   3423:        CoInitialize (NULL);
1.1.1.7   root     3424: 
1.1.1.10  root     3425:        ZeroMemory (&ofn, sizeof (ofn));
1.1.1.7   root     3426:        *lpszFileName = 0;
1.1.1.11  root     3427: 
                   3428:        if (initialDir)
                   3429:        {
                   3430:                swprintf_s (wInitialDir, sizeof (wInitialDir) / 2, L"%hs", initialDir);
                   3431:                ofn.lpstrInitialDir                     = wInitialDir;
                   3432:        }
                   3433: 
1.1.1.23! root     3434:        if (initialFileName)
        !          3435:                wcscpy_s (file, array_capacity (file), initialFileName);
        !          3436: 
1.1.1.10  root     3437:        ofn.lStructSize                         = sizeof (ofn);
                   3438:        ofn.hwndOwner                           = hwndDlg;
1.1.1.19  root     3439: 
1.1.1.10  root     3440:        wsprintfW (filter, L"%ls (*.*)%c*.*%c%ls (*.tc)%c*.tc%c%c",
                   3441:                GetString ("ALL_FILES"), 0, 0, GetString ("TC_VOLUMES"), 0, 0, 0);
1.1.1.19  root     3442:        ofn.lpstrFilter                         = browseFilter ? browseFilter : filter;
1.1.1.10  root     3443:        ofn.nFilterIndex                        = 1;
                   3444:        ofn.lpstrFile                           = file;
                   3445:        ofn.nMaxFile                            = sizeof (file) / sizeof (file[0]);
                   3446:        ofn.lpstrTitle                          = GetString (stringId);
1.1.1.23! root     3447:        ofn.lpstrDefExt                         = defaultExtension;
1.1.1.10  root     3448:        ofn.Flags                                       = OFN_HIDEREADONLY
1.1.1.8   root     3449:                | OFN_PATHMUSTEXIST
                   3450:                | (keepHistory ? 0 : OFN_DONTADDTORECENT)
                   3451:                | (saveMode ? OFN_OVERWRITEPROMPT : 0);
1.1.1.23! root     3452: 
1.1.1.11  root     3453:        if (!keepHistory)
                   3454:                CleanLastVisitedMRU ();
                   3455: 
1.1.1.8   root     3456:        if (!saveMode)
1.1.1.7   root     3457:        {
1.1.1.8   root     3458:                if (!GetOpenFileNameW (&ofn))
1.1.1.17  root     3459:                        goto ret;
1.1.1.7   root     3460:        }
1.1       root     3461:        else
1.1.1.7   root     3462:        {
1.1.1.8   root     3463:                if (!GetSaveFileNameW (&ofn))
1.1.1.17  root     3464:                        goto ret;
1.1.1.7   root     3465:        }
1.1.1.8   root     3466: 
                   3467:        WideCharToMultiByte (CP_ACP, 0, file, -1, lpszFileName, MAX_PATH, NULL, NULL);
1.1.1.9   root     3468: 
1.1.1.11  root     3469:        if (!keepHistory)
                   3470:                CleanLastVisitedMRU ();
1.1.1.9   root     3471: 
1.1.1.17  root     3472:        status = TRUE;
1.1.1.9   root     3473: 
1.1.1.17  root     3474: ret:
1.1.1.23! root     3475:        ResetCurrentDirectory();
1.1.1.17  root     3476:        CoUninitialize();
1.1.1.23! root     3477: 
1.1.1.17  root     3478:        return status;
1.1.1.9   root     3479: }
                   3480: 
                   3481: 
1.1.1.19  root     3482: static char SelectMultipleFilesPath[131072];
1.1.1.9   root     3483: static int SelectMultipleFilesOffset;
                   3484: 
                   3485: BOOL SelectMultipleFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory)
                   3486: {
                   3487:        OPENFILENAMEW ofn;
1.1.1.20  root     3488:        wchar_t file[0xffff * 2] = { 0 };       // The size must not exceed 0xffff*2 due to a bug in Windows 2000 and XP SP1
1.1.1.9   root     3489:        wchar_t filter[1024];
1.1.1.17  root     3490:        BOOL status = FALSE;
                   3491: 
                   3492:        CoInitialize (NULL);
1.1.1.9   root     3493: 
1.1.1.10  root     3494:        ZeroMemory (&ofn, sizeof (ofn));
1.1.1.9   root     3495: 
                   3496:        *lpszFileName = 0;
1.1.1.10  root     3497:        ofn.lStructSize                         = sizeof (ofn);
                   3498:        ofn.hwndOwner                           = hwndDlg;
                   3499:        wsprintfW (filter, L"%ls (*.*)%c*.*%c%ls (*.tc)%c*.tc%c%c",
                   3500:                GetString ("ALL_FILES"), 0, 0, GetString ("TC_VOLUMES"), 0, 0, 0);
                   3501:        ofn.lpstrFilter                         = filter;
                   3502:        ofn.nFilterIndex                        = 1;
                   3503:        ofn.lpstrFile                           = file;
                   3504:        ofn.nMaxFile                            = sizeof (file) / sizeof (file[0]);
                   3505:        ofn.lpstrTitle                          = GetString (stringId);
                   3506:        ofn.Flags                                       = OFN_HIDEREADONLY
1.1.1.9   root     3507:                | OFN_EXPLORER
                   3508:                | OFN_PATHMUSTEXIST
                   3509:                | OFN_ALLOWMULTISELECT
                   3510:                | (keepHistory ? 0 : OFN_DONTADDTORECENT);
                   3511:        
                   3512:        if (!keepHistory)
                   3513:                CleanLastVisitedMRU ();
                   3514: 
1.1.1.11  root     3515:        if (!GetOpenFileNameW (&ofn))
1.1.1.17  root     3516:                goto ret;
1.1.1.11  root     3517: 
1.1.1.9   root     3518:        if (file[ofn.nFileOffset - 1] != 0)
                   3519:        {
                   3520:                // Single file selected
                   3521:                WideCharToMultiByte (CP_ACP, 0, file, -1, lpszFileName, MAX_PATH, NULL, NULL);
                   3522:                SelectMultipleFilesOffset = 0;
                   3523:        }
                   3524:        else
                   3525:        {
                   3526:                // Multiple files selected
                   3527:                int n;
                   3528:                wchar_t *f = file;
                   3529:                char *s = SelectMultipleFilesPath;
                   3530:                while ((n = WideCharToMultiByte (CP_ACP, 0, f, -1, s, MAX_PATH, NULL, NULL)) > 1)
                   3531:                {
                   3532:                        f += n;
                   3533:                        s += n;
                   3534:                }
                   3535: 
                   3536:                SelectMultipleFilesOffset = ofn.nFileOffset;
                   3537:                SelectMultipleFilesNext (lpszFileName);
                   3538:        }
                   3539: 
1.1.1.11  root     3540:        if (!keepHistory)
                   3541:                CleanLastVisitedMRU ();
1.1.1.9   root     3542: 
1.1.1.17  root     3543:        status = TRUE;
                   3544:        
                   3545: ret:
1.1.1.23! root     3546:        ResetCurrentDirectory();
1.1.1.17  root     3547:        CoUninitialize();
1.1.1.23! root     3548: 
1.1.1.17  root     3549:        return status;
1.1.1.9   root     3550: }
                   3551: 
                   3552: 
                   3553: BOOL SelectMultipleFilesNext (char *lpszFileName)
                   3554: {
                   3555:        if (SelectMultipleFilesOffset == 0)
                   3556:                return FALSE;
                   3557: 
1.1.1.19  root     3558:        strncpy (lpszFileName, SelectMultipleFilesPath, TC_MAX_PATH);
                   3559:        lpszFileName[TC_MAX_PATH - 1] = 0;
1.1.1.9   root     3560: 
                   3561:        if (lpszFileName[strlen (lpszFileName) - 1] != '\\')
                   3562:                strcat (lpszFileName, "\\");
                   3563: 
                   3564:        strcat (lpszFileName, SelectMultipleFilesPath + SelectMultipleFilesOffset);
                   3565: 
                   3566:        SelectMultipleFilesOffset += strlen (SelectMultipleFilesPath + SelectMultipleFilesOffset) + 1;
                   3567:        if (SelectMultipleFilesPath[SelectMultipleFilesOffset] == 0)
                   3568:                SelectMultipleFilesOffset = 0;
                   3569: 
1.1.1.8   root     3570:        return TRUE;
1.1       root     3571: }
                   3572: 
                   3573: 
1.1.1.19  root     3574: static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData) 
1.1.1.6   root     3575: {
1.1.1.7   root     3576:        switch(uMsg) {
                   3577:        case BFFM_INITIALIZED: 
                   3578:        {
                   3579:          /* WParam is TRUE since we are passing a path.
                   3580:           It would be FALSE if we were passing a pidl. */
                   3581:           SendMessage (hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)pData);
                   3582:           break;
                   3583:        }
                   3584: 
                   3585:        case BFFM_SELCHANGED: 
                   3586:        {
                   3587:                char szDir[TC_MAX_PATH];
                   3588: 
                   3589:           /* Set the status window to the currently selected path. */
                   3590:           if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szDir)) 
                   3591:           {
                   3592:                  SendMessage (hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
                   3593:           }
                   3594:           break;
                   3595:        }
                   3596: 
                   3597:        default:
                   3598:           break;
                   3599:        }
                   3600: 
                   3601:        return 0;
                   3602: }
1.1.1.6   root     3603: 
                   3604: 
1.1.1.19  root     3605: BOOL BrowseDirectories (HWND hwndDlg, char *lpszTitle, char *dirName)
1.1.1.7   root     3606: {
                   3607:        BROWSEINFOW bi;
                   3608:        LPITEMIDLIST pidl;
                   3609:        LPMALLOC pMalloc;
                   3610:        BOOL bOK  = FALSE;
1.1.1.6   root     3611: 
1.1.1.17  root     3612:        CoInitialize (NULL);
                   3613: 
1.1.1.15  root     3614:        if (SUCCEEDED (SHGetMalloc (&pMalloc))) 
1.1.1.6   root     3615:        {
1.1.1.15  root     3616:                ZeroMemory (&bi, sizeof(bi));
1.1.1.7   root     3617:                bi.hwndOwner = hwndDlg;
                   3618:                bi.pszDisplayName = 0;
                   3619:                bi.lpszTitle = GetString (lpszTitle);
                   3620:                bi.pidlRoot = 0;
1.1.1.15  root     3621:                bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
1.1.1.7   root     3622:                bi.lpfn = BrowseCallbackProc;
                   3623:                bi.lParam = (LPARAM)dirName;
1.1.1.6   root     3624: 
1.1.1.7   root     3625:                pidl = SHBrowseForFolderW (&bi);
1.1.1.15  root     3626:                if (pidl != NULL) 
1.1.1.7   root     3627:                {
                   3628:                        if (SHGetPathFromIDList(pidl, dirName)) 
                   3629:                        {
                   3630:                                bOK = TRUE;
                   3631:                        }
                   3632: 
1.1.1.15  root     3633:                        pMalloc->Free (pidl);
                   3634:                        pMalloc->Release();
1.1.1.7   root     3635:                }
1.1.1.6   root     3636:        }
                   3637: 
1.1.1.17  root     3638:        CoUninitialize();
                   3639: 
1.1.1.7   root     3640:        return bOK;
1.1.1.6   root     3641: }
                   3642: 
                   3643: 
1.1.1.21  root     3644: std::wstring GetWrongPasswordErrorMessage (HWND hwndDlg)
                   3645: {
                   3646:        WCHAR szTmp[8192];
                   3647: 
                   3648:        swprintf (szTmp, GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_WRONG" : "PASSWORD_WRONG"));
                   3649:        if (CheckCapsLock (hwndDlg, TRUE))
                   3650:                wcscat (szTmp, GetString ("PASSWORD_WRONG_CAPSLOCK_ON"));
                   3651: 
                   3652: #ifdef TCMOUNT
                   3653:        if (TCBootLoaderOnInactiveSysEncDrive ())
                   3654:        {
                   3655:                swprintf (szTmp, GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_OR_MODE_WRONG" : "PASSWORD_OR_MODE_WRONG"));
                   3656: 
                   3657:                if (CheckCapsLock (hwndDlg, TRUE))
                   3658:                        wcscat (szTmp, GetString ("PASSWORD_WRONG_CAPSLOCK_ON"));
                   3659: 
                   3660:                wcscat (szTmp, GetString ("SYSENC_MOUNT_WITHOUT_PBA_NOTE"));
                   3661:        }
                   3662: #endif
                   3663: 
                   3664:        return szTmp;
                   3665: }
                   3666: 
                   3667: 
1.1.1.15  root     3668: void handleError (HWND hwndDlg, int code)
1.1       root     3669: {
1.1.1.11  root     3670:        WCHAR szTmp[4096];
1.1.1.7   root     3671: 
                   3672:        if (Silent) return;
1.1       root     3673: 
                   3674:        switch (code)
                   3675:        {
                   3676:        case ERR_OS_ERROR:
                   3677:                handleWin32Error (hwndDlg);
                   3678:                break;
                   3679:        case ERR_OUTOFMEMORY:
1.1.1.7   root     3680:                MessageBoxW (hwndDlg, GetString ("OUTOFMEMORY"), lpszTitle, ICON_HAND);
1.1       root     3681:                break;
1.1.1.7   root     3682: 
1.1       root     3683:        case ERR_PASSWORD_WRONG:
1.1.1.21  root     3684:                MessageBoxW (hwndDlg, GetWrongPasswordErrorMessage (hwndDlg).c_str(), lpszTitle, MB_ICONWARNING);
1.1       root     3685:                break;
1.1.1.7   root     3686: 
1.1       root     3687:        case ERR_DRIVE_NOT_FOUND:
1.1.1.7   root     3688:                MessageBoxW (hwndDlg, GetString ("NOT_FOUND"), lpszTitle, ICON_HAND);
1.1       root     3689:                break;
                   3690:        case ERR_FILES_OPEN:
1.1.1.7   root     3691:                MessageBoxW (hwndDlg, GetString ("OPENFILES_DRIVER"), lpszTitle, ICON_HAND);
1.1       root     3692:                break;
                   3693:        case ERR_FILES_OPEN_LOCK:
1.1.1.7   root     3694:                MessageBoxW (hwndDlg, GetString ("OPENFILES_LOCK"), lpszTitle, ICON_HAND);
1.1       root     3695:                break;
                   3696:        case ERR_VOL_SIZE_WRONG:
1.1.1.7   root     3697:                MessageBoxW (hwndDlg, GetString ("VOL_SIZE_WRONG"), lpszTitle, ICON_HAND);
1.1       root     3698:                break;
                   3699:        case ERR_COMPRESSION_NOT_SUPPORTED:
1.1.1.7   root     3700:                MessageBoxW (hwndDlg, GetString ("COMPRESSION_NOT_SUPPORTED"), lpszTitle, ICON_HAND);
1.1       root     3701:                break;
                   3702:        case ERR_PASSWORD_CHANGE_VOL_TYPE:
1.1.1.7   root     3703:                MessageBoxW (hwndDlg, GetString ("WRONG_VOL_TYPE"), lpszTitle, ICON_HAND);
1.1       root     3704:                break;
                   3705:        case ERR_VOL_SEEKING:
1.1.1.7   root     3706:                MessageBoxW (hwndDlg, GetString ("VOL_SEEKING"), lpszTitle, ICON_HAND);
1.1       root     3707:                break;
1.1.1.7   root     3708:        case ERR_CIPHER_INIT_FAILURE:
                   3709:                MessageBoxW (hwndDlg, GetString ("ERR_CIPHER_INIT_FAILURE"), lpszTitle, ICON_HAND);
                   3710:                break;
                   3711:        case ERR_CIPHER_INIT_WEAK_KEY:
                   3712:                MessageBoxW (hwndDlg, GetString ("ERR_CIPHER_INIT_WEAK_KEY"), lpszTitle, ICON_HAND);
1.1       root     3713:                break;
                   3714:        case ERR_VOL_ALREADY_MOUNTED:
1.1.1.7   root     3715:                MessageBoxW (hwndDlg, GetString ("VOL_ALREADY_MOUNTED"), lpszTitle, ICON_HAND);
1.1       root     3716:                break;
                   3717:        case ERR_FILE_OPEN_FAILED:
1.1.1.7   root     3718:                MessageBoxW (hwndDlg, GetString ("FILE_OPEN_FAILED"), lpszTitle, ICON_HAND);
1.1       root     3719:                break;
                   3720:        case ERR_VOL_MOUNT_FAILED:
1.1.1.7   root     3721:                MessageBoxW (hwndDlg, GetString  ("VOL_MOUNT_FAILED"), lpszTitle, ICON_HAND);
1.1       root     3722:                break;
                   3723:        case ERR_NO_FREE_DRIVES:
1.1.1.7   root     3724:                MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
1.1       root     3725:                break;
                   3726:        case ERR_ACCESS_DENIED:
1.1.1.7   root     3727:                MessageBoxW (hwndDlg, GetString ("ACCESS_DENIED"), lpszTitle, ICON_HAND);
1.1       root     3728:                break;
                   3729: 
                   3730:        case ERR_DRIVER_VERSION:
1.1.1.7   root     3731:                wsprintfW (szTmp, GetString ("DRIVER_VERSION"), VERSION_STRING);
                   3732:                MessageBoxW (hwndDlg, szTmp, lpszTitle, ICON_HAND);
1.1       root     3733:                break;
                   3734: 
                   3735:        case ERR_NEW_VERSION_REQUIRED:
1.1.1.7   root     3736:                MessageBoxW (hwndDlg, GetString ("NEW_VERSION_REQUIRED"), lpszTitle, ICON_HAND);
                   3737:                break;
                   3738: 
                   3739:        case ERR_SELF_TESTS_FAILED:
                   3740:                Error ("ERR_SELF_TESTS_FAILED");
1.1       root     3741:                break;
                   3742: 
1.1.1.13  root     3743:        case ERR_VOL_FORMAT_BAD:
                   3744:                Error ("ERR_VOL_FORMAT_BAD");
                   3745:                break;
                   3746: 
1.1.1.15  root     3747:        case ERR_ENCRYPTION_NOT_COMPLETED:
                   3748:                Error ("ERR_ENCRYPTION_NOT_COMPLETED");
                   3749:                break;
                   3750: 
1.1.1.19  root     3751:        case ERR_NONSYS_INPLACE_ENC_INCOMPLETE:
                   3752:                Error ("ERR_NONSYS_INPLACE_ENC_INCOMPLETE");
                   3753:                break;
                   3754: 
1.1.1.17  root     3755:        case ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG:
                   3756:                Error ("ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG");
                   3757:                break;
                   3758: 
1.1.1.15  root     3759:        case ERR_PARAMETER_INCORRECT:
                   3760:                Error ("ERR_PARAMETER_INCORRECT");
                   3761:                break;
                   3762: 
1.1.1.19  root     3763:        case ERR_USER_ABORT:
1.1.1.6   root     3764:        case ERR_DONT_REPORT:
1.1.1.19  root     3765:                // A non-error
1.1.1.6   root     3766:                break;
                   3767: 
1.1       root     3768:        default:
1.1.1.7   root     3769:                wsprintfW (szTmp, GetString ("ERR_UNKNOWN"), code);
                   3770:                MessageBoxW (hwndDlg, szTmp, lpszTitle, ICON_HAND);
1.1       root     3771:        }
                   3772: }
                   3773: 
1.1.1.7   root     3774: static BOOL CALLBACK LocalizeDialogEnum( HWND hwnd, LPARAM font)
1.1       root     3775: {
1.1.1.7   root     3776:        // Localization of controls
1.1       root     3777: 
1.1.1.7   root     3778:        if (LocalizationActive)
1.1       root     3779:        {
1.1.1.7   root     3780:                int ctrlId = GetDlgCtrlID (hwnd);
                   3781:                if (ctrlId != 0)
                   3782:                {
                   3783:                        char name[10] = { 0 };
                   3784:                        GetClassName (hwnd, name, sizeof (name));
1.1.1.5   root     3785: 
1.1.1.7   root     3786:                        if (_stricmp (name, "Button") == 0 || _stricmp (name, "Static") == 0)
                   3787:                        {
1.1.1.15  root     3788:                                wchar_t *str = (wchar_t *) GetDictionaryValueByInt (ctrlId);
1.1.1.7   root     3789:                                if (str != NULL)
                   3790:                                        SetWindowTextW (hwnd, str);
                   3791:                        }
                   3792:                }
                   3793:        }
1.1       root     3794: 
1.1.1.7   root     3795:        // Font
                   3796:        SendMessage (hwnd, WM_SETFONT, (WPARAM) font, 0);
                   3797:        
                   3798:        return TRUE;
                   3799: }
1.1       root     3800: 
1.1.1.7   root     3801: void LocalizeDialog (HWND hwnd, char *stringId)
                   3802: {
1.1.1.10  root     3803:        LastDialogId = stringId;
1.1.1.7   root     3804:        SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) 'TRUE');
1.1.1.8   root     3805:        SendMessage (hwnd, WM_SETFONT, (WPARAM) hUserFont, 0);
1.1.1.5   root     3806: 
1.1.1.11  root     3807:        if (stringId == NULL)
                   3808:                SetWindowText (hwnd, "TrueCrypt");
1.1.1.13  root     3809:        else
1.1.1.7   root     3810:                SetWindowTextW (hwnd, GetString (stringId));
1.1.1.11  root     3811:        
1.1.1.7   root     3812:        if (hUserFont != 0)
                   3813:                EnumChildWindows (hwnd, LocalizeDialogEnum, (LPARAM) hUserFont);
1.1.1.5   root     3814: }
                   3815: 
                   3816: void OpenVolumeExplorerWindow (int driveNo)
                   3817: {
                   3818:        char dosName[5];
                   3819:        SHFILEINFO fInfo;
                   3820: 
                   3821:        sprintf (dosName, "%c:\\", (char) driveNo + 'A');
                   3822: 
                   3823:        // Force explorer to discover the drive
                   3824:        SHGetFileInfo (dosName, 0, &fInfo, sizeof (fInfo), 0);
                   3825: 
                   3826:        ShellExecute (NULL, "open", dosName, NULL, NULL, SW_SHOWNORMAL);
                   3827: }
                   3828: 
                   3829: static BOOL explorerCloseSent;
1.1.1.11  root     3830: static HWND explorerTopLevelWindow;
1.1.1.5   root     3831: 
1.1.1.11  root     3832: static BOOL CALLBACK CloseVolumeExplorerWindowsChildEnum (HWND hwnd, LPARAM driveStr)
1.1.1.5   root     3833: {
1.1.1.11  root     3834:        char s[MAX_PATH];
                   3835:        SendMessage (hwnd, WM_GETTEXT, sizeof (s), (LPARAM) s);
1.1.1.5   root     3836: 
1.1.1.11  root     3837:        if (strstr (s, (char *) driveStr) != NULL)
1.1.1.5   root     3838:        {
1.1.1.11  root     3839:                PostMessage (explorerTopLevelWindow, WM_CLOSE, 0, 0);
                   3840:                explorerCloseSent = TRUE;
                   3841:                return FALSE;
                   3842:        }
1.1.1.5   root     3843: 
1.1.1.11  root     3844:        return TRUE;
                   3845: }
                   3846: 
                   3847: static BOOL CALLBACK CloseVolumeExplorerWindowsEnum (HWND hwnd, LPARAM driveNo)
                   3848: {
                   3849:        char driveStr[10];
                   3850:        char s[MAX_PATH];
                   3851: 
                   3852:        sprintf (driveStr, "%c:\\", driveNo + 'A');
                   3853: 
                   3854:        GetClassName (hwnd, s, sizeof s);
                   3855:        if (strcmp (s, "CabinetWClass") == 0)
                   3856:        {
                   3857:                GetWindowText (hwnd, s, sizeof s);
                   3858:                if (strstr (s, driveStr) != NULL)
1.1.1.5   root     3859:                {
                   3860:                        PostMessage (hwnd, WM_CLOSE, 0, 0);
                   3861:                        explorerCloseSent = TRUE;
1.1.1.12  root     3862:                        return TRUE;
1.1.1.5   root     3863:                }
                   3864: 
1.1.1.11  root     3865:                explorerTopLevelWindow = hwnd;
                   3866:                EnumChildWindows (hwnd, CloseVolumeExplorerWindowsChildEnum, (LPARAM) driveStr);
1.1.1.5   root     3867:        }
1.1.1.11  root     3868: 
1.1.1.5   root     3869:        return TRUE;
                   3870: }
                   3871: 
                   3872: BOOL CloseVolumeExplorerWindows (HWND hwnd, int driveNo)
                   3873: {
1.1.1.19  root     3874:        if (driveNo >= 0)
                   3875:        {
                   3876:                explorerCloseSent = FALSE;
                   3877:                EnumWindows (CloseVolumeExplorerWindowsEnum, (LPARAM) driveNo);
                   3878:        }
1.1.1.5   root     3879: 
                   3880:        return explorerCloseSent;
                   3881: }
                   3882: 
1.1.1.7   root     3883: void GetSizeString (unsigned __int64 size, wchar_t *str)
                   3884: {
                   3885:        static wchar_t *b, *kb, *mb, *gb, *tb, *pb;
                   3886:        static int serNo;
                   3887: 
                   3888:        if (b == NULL || serNo != LocalizationSerialNo)
                   3889:        {
                   3890:                serNo = LocalizationSerialNo;
                   3891:                kb = GetString ("KB");
                   3892:                mb = GetString ("MB");
                   3893:                gb = GetString ("GB");
                   3894:                tb = GetString ("TB");
                   3895:                pb = GetString ("PB");
                   3896:                b = GetString ("BYTE");
                   3897:        }
                   3898: 
                   3899:        if (size > 1024I64*1024*1024*1024*1024*99)
                   3900:                swprintf (str, L"%I64d %s", size/1024/1024/1024/1024/1024, pb);
                   3901:        else if (size > 1024I64*1024*1024*1024*1024)
                   3902:                swprintf (str, L"%.1f %s",(double)(size/1024.0/1024/1024/1024/1024), pb);
                   3903:        else if (size > 1024I64*1024*1024*1024*99)
                   3904:                swprintf (str, L"%I64d %s",size/1024/1024/1024/1024, tb);
                   3905:        else if (size > 1024I64*1024*1024*1024)
                   3906:                swprintf (str, L"%.1f %s",(double)(size/1024.0/1024/1024/1024), tb);
                   3907:        else if (size > 1024I64*1024*1024*99)
                   3908:                swprintf (str, L"%I64d %s",size/1024/1024/1024, gb);
                   3909:        else if (size > 1024I64*1024*1024)
                   3910:                swprintf (str, L"%.1f %s",(double)(size/1024.0/1024/1024), gb);
                   3911:        else if (size > 1024I64*1024*99)
                   3912:                swprintf (str, L"%I64d %s", size/1024/1024, mb);
                   3913:        else if (size > 1024I64*1024)
                   3914:                swprintf (str, L"%.1f %s",(double)(size/1024.0/1024), mb);
1.1.1.19  root     3915:        else if (size >= 1024I64)
1.1.1.7   root     3916:                swprintf (str, L"%I64d %s", size/1024, kb);
                   3917:        else
                   3918:                swprintf (str, L"%I64d %s", size, b);
                   3919: }
1.1.1.5   root     3920: 
                   3921: #ifndef SETUP
1.1.1.7   root     3922: void GetSpeedString (unsigned __int64 speed, wchar_t *str)
1.1.1.5   root     3923: {
1.1.1.7   root     3924:        static wchar_t *b, *kb, *mb, *gb, *tb, *pb;
                   3925:        static int serNo;
                   3926:        
                   3927:        if (b == NULL || serNo != LocalizationSerialNo)
                   3928:        {
                   3929:                serNo = LocalizationSerialNo;
                   3930:                kb = GetString ("KB_PER_SEC");
                   3931:                mb = GetString ("MB_PER_SEC");
                   3932:                gb = GetString ("GB_PER_SEC");
                   3933:                tb = GetString ("TB_PER_SEC");
                   3934:                pb = GetString ("PB_PER_SEC");
                   3935:                b = GetString ("B_PER_SEC");
                   3936:        }
                   3937: 
1.1.1.5   root     3938:        if (speed > 1024I64*1024*1024*1024*1024*99)
1.1.1.7   root     3939:                swprintf (str, L"%I64d %s", speed/1024/1024/1024/1024/1024, pb);
1.1.1.5   root     3940:        else if (speed > 1024I64*1024*1024*1024*1024)
1.1.1.7   root     3941:                swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024/1024/1024/1024), pb);
1.1.1.5   root     3942:        else if (speed > 1024I64*1024*1024*1024*99)
1.1.1.7   root     3943:                swprintf (str, L"%I64d %s",speed/1024/1024/1024/1024, tb);
1.1.1.5   root     3944:        else if (speed > 1024I64*1024*1024*1024)
1.1.1.7   root     3945:                swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024/1024/1024), tb);
1.1.1.5   root     3946:        else if (speed > 1024I64*1024*1024*99)
1.1.1.7   root     3947:                swprintf (str, L"%I64d %s",speed/1024/1024/1024, gb);
1.1.1.5   root     3948:        else if (speed > 1024I64*1024*1024)
1.1.1.7   root     3949:                swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024/1024), gb);
1.1.1.5   root     3950:        else if (speed > 1024I64*1024*99)
1.1.1.7   root     3951:                swprintf (str, L"%I64d %s", speed/1024/1024, mb);
1.1.1.5   root     3952:        else if (speed > 1024I64*1024)
1.1.1.7   root     3953:                swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024), mb);
                   3954:        else if (speed > 1024I64)
                   3955:                swprintf (str, L"%I64d %s", speed/1024, kb);
1.1.1.5   root     3956:        else
1.1.1.7   root     3957:                swprintf (str, L"%I64d %s", speed, b);
1.1.1.5   root     3958: }
                   3959: 
                   3960: static void DisplayBenchmarkResults (HWND hwndDlg)
                   3961: {
1.1.1.7   root     3962:        wchar_t item1[100]={0};
                   3963:        LVITEMW LvItem;
1.1.1.5   root     3964:        HWND hList = GetDlgItem (hwndDlg, IDC_RESULTS);
                   3965:        int ea, i;
                   3966:        BOOL unsorted = TRUE;
1.1.1.7   root     3967:        BENCHMARK_REC tmp_line;
1.1.1.5   root     3968: 
                   3969:        /* Sort the list */
                   3970: 
                   3971:        switch (benchmarkSortMethod)
                   3972:        {
                   3973:        case BENCHMARK_SORT_BY_SPEED:
                   3974: 
                   3975:                while (unsorted)
                   3976:                {
                   3977:                        unsorted = FALSE;
                   3978:                        for (i = 0; i < benchmarkTotalItems - 1; i++)
                   3979:                        {
                   3980:                                if (benchmarkTable[i].meanBytesPerSec < benchmarkTable[i+1].meanBytesPerSec)
                   3981:                                {
                   3982:                                        unsorted = TRUE;
                   3983:                                        memcpy (&tmp_line, &benchmarkTable[i], sizeof(BENCHMARK_REC));
                   3984:                                        memcpy (&benchmarkTable[i], &benchmarkTable[i+1], sizeof(BENCHMARK_REC));
                   3985:                                        memcpy (&benchmarkTable[i+1], &tmp_line, sizeof(BENCHMARK_REC));
                   3986:                                }
                   3987:                        }
                   3988:                }
                   3989:                break;
                   3990: 
                   3991:        case BENCHMARK_SORT_BY_NAME:
                   3992: 
                   3993:                while (unsorted)
                   3994:                {
                   3995:                        unsorted = FALSE;
                   3996:                        for (i = 0; i < benchmarkTotalItems - 1; i++)
                   3997:                        {
                   3998:                                if (benchmarkTable[i].id > benchmarkTable[i+1].id)
                   3999:                                {
                   4000:                                        unsorted = TRUE;
                   4001:                                        memcpy (&tmp_line, &benchmarkTable[i], sizeof(BENCHMARK_REC));
                   4002:                                        memcpy (&benchmarkTable[i], &benchmarkTable[i+1], sizeof(BENCHMARK_REC));
                   4003:                                        memcpy (&benchmarkTable[i+1], &tmp_line, sizeof(BENCHMARK_REC));
                   4004:                                }
                   4005:                        }
                   4006:                }
                   4007:                break;
                   4008:        }
                   4009:   
                   4010:        /* Render the results */
                   4011: 
                   4012:        SendMessage (hList,LVM_DELETEALLITEMS,0,(LPARAM)&LvItem);
                   4013: 
                   4014:        for (i = 0; i < benchmarkTotalItems; i++)
                   4015:        {
                   4016:                ea = benchmarkTable[i].id;
                   4017: 
                   4018:                memset (&LvItem,0,sizeof(LvItem));
                   4019:                LvItem.mask = LVIF_TEXT;
1.1.1.7   root     4020:                LvItem.iItem = i;
1.1.1.5   root     4021:                LvItem.iSubItem = 0;
1.1.1.7   root     4022:                LvItem.pszText = (LPWSTR) benchmarkTable[i].name;
                   4023:                SendMessageW (hList, LVM_INSERTITEM, 0, (LPARAM)&LvItem); 
1.1.1.5   root     4024: 
1.1.1.7   root     4025: #if PKCS5_BENCHMARKS
                   4026:                wcscpy (item1, L"-");
                   4027: #else
                   4028:                GetSpeedString ((unsigned __int64) (benchmarkLastBufferSize / ((float) benchmarkTable[i].encSpeed / benchmarkPerformanceFrequency.QuadPart)), item1);
                   4029: #endif
1.1.1.5   root     4030:                LvItem.iSubItem = 1;
                   4031:                LvItem.pszText = item1;
                   4032: 
1.1.1.7   root     4033:                SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); 
                   4034: 
                   4035: #if PKCS5_BENCHMARKS
                   4036:                wcscpy (item1, L"-");
                   4037: #else
                   4038:                GetSpeedString ((unsigned __int64) (benchmarkLastBufferSize / ((float) benchmarkTable[i].decSpeed / benchmarkPerformanceFrequency.QuadPart)), item1);
                   4039: #endif
1.1.1.5   root     4040:                LvItem.iSubItem = 2;
                   4041:                LvItem.pszText = item1;
                   4042: 
1.1.1.7   root     4043:                SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); 
1.1.1.5   root     4044: 
1.1.1.7   root     4045: #if PKCS5_BENCHMARKS
                   4046:                swprintf (item1, L"%d t", benchmarkTable[i].encSpeed);
                   4047: #else
                   4048:                GetSpeedString (benchmarkTable[i].meanBytesPerSec, item1);
                   4049: #endif
1.1.1.5   root     4050:                LvItem.iSubItem = 3;
                   4051:                LvItem.pszText = item1;
                   4052: 
1.1.1.7   root     4053:                SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); 
1.1.1.5   root     4054:        }
                   4055: }
                   4056: 
                   4057: static BOOL PerformBenchmark(HWND hwndDlg)
                   4058: {
                   4059:     LARGE_INTEGER performanceCountStart, performanceCountEnd;
                   4060:        BYTE *lpTestBuffer;
1.1.1.8   root     4061:        PCRYPTO_INFO ci = NULL;
1.1.1.17  root     4062:        UINT64_STRUCT startDataUnitNo;
                   4063: 
                   4064:        startDataUnitNo.Value = 0;
                   4065: 
1.1.1.7   root     4066: #if !(PKCS5_BENCHMARKS || HASH_FNC_BENCHMARKS)
1.1.1.8   root     4067:        ci = crypto_open ();
                   4068:        if (!ci)
                   4069:                return FALSE;
1.1.1.7   root     4070: #endif
1.1.1.5   root     4071: 
                   4072:        if (QueryPerformanceFrequency (&benchmarkPerformanceFrequency) == 0)
                   4073:        {
1.1.1.7   root     4074:                MessageBoxW (hwndDlg, GetString ("ERR_PERF_COUNTER"), lpszTitle, ICON_HAND);
1.1.1.5   root     4075:                return FALSE;
                   4076:        }
                   4077: 
1.1.1.15  root     4078:        lpTestBuffer = (BYTE *) malloc(benchmarkBufferSize - (benchmarkBufferSize % 16));
1.1.1.5   root     4079:        if (lpTestBuffer == NULL)
                   4080:        {
1.1.1.7   root     4081:                MessageBoxW (hwndDlg, GetString ("ERR_MEM_ALLOC"), lpszTitle, ICON_HAND);
1.1.1.5   root     4082:                return FALSE;
                   4083:        }
                   4084:        VirtualLock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16));
                   4085: 
1.1.1.11  root     4086:        WaitCursor ();
1.1.1.5   root     4087:        benchmarkTotalItems = 0;
1.1.1.7   root     4088: 
1.1.1.13  root     4089: #if !(PKCS5_BENCHMARKS || HASH_FNC_BENCHMARKS)
1.1.1.11  root     4090:        // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency
                   4091:        // gradually changes depending on CPU load).
                   4092:        ci->ea = EAGetFirst();
1.1.1.13  root     4093:        if (!EAInit (ci->ea, ci->master_keydata, ci->ks))
1.1.1.11  root     4094:        {
1.1.1.13  root     4095:                ci->mode = FIRST_MODE_OF_OPERATION_ID;
1.1.1.11  root     4096:                if (EAInitMode (ci))
                   4097:                {
                   4098:                        int i;
                   4099: 
                   4100:                        for (i = 0; i < 2; i++)
                   4101:                        {
1.1.1.17  root     4102:                                EncryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
                   4103:                                DecryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
1.1.1.11  root     4104:                        }
                   4105:                }
                   4106:        }
1.1.1.13  root     4107: #endif
1.1.1.11  root     4108: 
1.1.1.7   root     4109: #if HASH_FNC_BENCHMARKS
                   4110: 
                   4111:        /* Measures the speed at which each of the hash algorithms processes the message to produce
                   4112:           a single digest. 
                   4113: 
                   4114:           The hash algorithm benchmarks are included here for development purposes only. Do not enable 
                   4115:           them when building a public release (the benchmark GUI strings wouldn't make sense). */
                   4116: 
                   4117:        {
                   4118:                BYTE *digest [MAX_DIGESTSIZE];
                   4119:                WHIRLPOOL_CTX   wctx;
                   4120:                RMD160_CTX              rctx;
                   4121:                sha1_ctx                sctx;
1.1.1.13  root     4122:                sha512_ctx              s2ctx;
1.1.1.7   root     4123:                int hid;
                   4124: 
1.1.1.13  root     4125:                for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) 
1.1.1.7   root     4126:                {
                   4127:                        if (QueryPerformanceCounter (&performanceCountStart) == 0)
                   4128:                                goto counter_error;
                   4129: 
                   4130:                        switch (hid)
                   4131:                        {
                   4132:                        case SHA1:
                   4133:                                sha1_begin (&sctx);
                   4134:                                sha1_hash (lpTestBuffer, benchmarkBufferSize, &sctx);
                   4135:                                sha1_end ((unsigned char *) digest, &sctx);
                   4136:                                break;
                   4137: 
1.1.1.13  root     4138:                        case SHA512:
                   4139:                                sha512_begin (&s2ctx);
                   4140:                                sha512_hash (lpTestBuffer, benchmarkBufferSize, &s2ctx);
                   4141:                                sha512_end ((unsigned char *) digest, &s2ctx);
                   4142:                                break;
                   4143: 
1.1.1.7   root     4144:                        case RIPEMD160:
                   4145:                                RMD160Init(&rctx);
                   4146:                                RMD160Update(&rctx, lpTestBuffer, benchmarkBufferSize);
                   4147:                                RMD160Final((unsigned char *) digest, &rctx);
                   4148:                                break;
                   4149: 
                   4150:                        case WHIRLPOOL:
                   4151:                                WHIRLPOOL_init (&wctx);
                   4152:                                WHIRLPOOL_add (lpTestBuffer, benchmarkBufferSize * 8, &wctx);
                   4153:                                WHIRLPOOL_finalize (&wctx, (unsigned char *) digest);
                   4154:                                break;
                   4155:                        }
                   4156: 
                   4157:                        if (QueryPerformanceCounter (&performanceCountEnd) == 0)
                   4158:                                goto counter_error;
                   4159: 
                   4160:                        benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
                   4161: 
                   4162:                        benchmarkTable[benchmarkTotalItems].decSpeed = benchmarkTable[benchmarkTotalItems].encSpeed;
                   4163:                        benchmarkTable[benchmarkTotalItems].id = hid;
                   4164:                        benchmarkTable[benchmarkTotalItems].meanBytesPerSec = ((unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart)) + (unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].decSpeed / benchmarkPerformanceFrequency.QuadPart))) / 2;
1.1.1.9   root     4165:                        sprintf (benchmarkTable[benchmarkTotalItems].name, "%s", HashGetName(hid));
1.1.1.7   root     4166: 
                   4167:                        benchmarkTotalItems++;
                   4168:                }
                   4169:        }
                   4170: 
                   4171: #elif PKCS5_BENCHMARKS // #if HASH_FNC_BENCHMARKS
                   4172: 
                   4173:        /* Measures the time that it takes for the PKCS-5 routine to derive a header key using
                   4174:           each of the implemented PRF algorithms. 
                   4175: 
                   4176:           The PKCS-5 benchmarks are included here for development purposes only. Do not enable 
                   4177:           them when building a public release (the benchmark GUI strings wouldn't make sense). */
                   4178:        {
                   4179:                int thid, i;
1.1.1.13  root     4180:                char dk[MASTER_KEYDATA_SIZE];
1.1.1.7   root     4181:                char *tmp_salt = {"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"};
                   4182: 
1.1.1.13  root     4183:                for (thid = FIRST_PRF_ID; thid <= LAST_PRF_ID; thid++) 
1.1.1.7   root     4184:                {
                   4185:                        if (QueryPerformanceCounter (&performanceCountStart) == 0)
                   4186:                                goto counter_error;
                   4187: 
                   4188:                        for (i = 1; i <= 5; i++) 
                   4189:                        {
                   4190:                                switch (thid)
                   4191:                                {
                   4192:                                case SHA1:
                   4193:                                        /* PKCS-5 test with HMAC-SHA-1 used as the PRF */
1.1.1.13  root     4194:                                        derive_key_sha1 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
                   4195:                                        break;
                   4196: 
                   4197:                                case SHA512:
                   4198:                                        /* PKCS-5 test with HMAC-SHA-512 used as the PRF */
                   4199:                                        derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
1.1.1.7   root     4200:                                        break;
                   4201: 
                   4202:                                case RIPEMD160:
                   4203:                                        /* PKCS-5 test with HMAC-RIPEMD-160 used as the PRF */
1.1.1.13  root     4204:                                        derive_key_ripemd160 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
1.1.1.7   root     4205:                                        break;
                   4206: 
                   4207:                                case WHIRLPOOL:
                   4208:                                        /* PKCS-5 test with HMAC-Whirlpool used as the PRF */
1.1.1.13  root     4209:                                        derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
1.1.1.7   root     4210:                                        break;
                   4211:                                }
                   4212:                        }
                   4213: 
                   4214:                        if (QueryPerformanceCounter (&performanceCountEnd) == 0)
                   4215:                                goto counter_error;
                   4216: 
                   4217:                        benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
                   4218:                        benchmarkTable[benchmarkTotalItems].id = thid;
                   4219:                        sprintf (benchmarkTable[benchmarkTotalItems].name, "%s", get_pkcs5_prf_name (thid));
                   4220: 
                   4221:                        benchmarkTotalItems++;
                   4222:                }
                   4223:        }
                   4224: 
                   4225: #else  // #elif PKCS5_BENCHMARKS
                   4226: 
                   4227:        /* Encryption algorithm benchmarks */
1.1.1.8   root     4228:                
                   4229:        for (ci->ea = EAGetFirst(); ci->ea != 0; ci->ea = EAGetNext(ci->ea))
1.1.1.5   root     4230:        {
1.1.1.11  root     4231:                if (!EAIsFormatEnabled (ci->ea))
1.1.1.8   root     4232:                        continue;
                   4233: 
1.1.1.13  root     4234:                EAInit (ci->ea, ci->master_keydata, ci->ks);
1.1.1.8   root     4235: 
1.1.1.13  root     4236:                ci->mode = FIRST_MODE_OF_OPERATION_ID;
1.1.1.19  root     4237:                EAInitMode (ci);
1.1.1.8   root     4238: 
1.1.1.5   root     4239:                if (QueryPerformanceCounter (&performanceCountStart) == 0)
                   4240:                        goto counter_error;
                   4241: 
1.1.1.17  root     4242:                EncryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
1.1.1.5   root     4243: 
                   4244:                if (QueryPerformanceCounter (&performanceCountEnd) == 0)
                   4245:                        goto counter_error;
                   4246: 
                   4247:                benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
                   4248: 
                   4249:                if (QueryPerformanceCounter (&performanceCountStart) == 0)
                   4250:                        goto counter_error;
                   4251: 
1.1.1.17  root     4252:                DecryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
1.1.1.8   root     4253: 
1.1.1.5   root     4254:                if (QueryPerformanceCounter (&performanceCountEnd) == 0)
                   4255:                        goto counter_error;
                   4256: 
                   4257:                benchmarkTable[benchmarkTotalItems].decSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
1.1.1.8   root     4258:                benchmarkTable[benchmarkTotalItems].id = ci->ea;
1.1.1.5   root     4259:                benchmarkTable[benchmarkTotalItems].meanBytesPerSec = ((unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart)) + (unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].decSpeed / benchmarkPerformanceFrequency.QuadPart))) / 2;
1.1.1.8   root     4260:                EAGetName (benchmarkTable[benchmarkTotalItems].name, ci->ea);
1.1.1.5   root     4261: 
                   4262:                benchmarkTotalItems++;
                   4263:        }
                   4264: 
1.1.1.7   root     4265: #endif // #elif PKCS5_BENCHMARKS (#else)
                   4266: 
1.1.1.8   root     4267:        if (ci)
                   4268:                crypto_close (ci);
                   4269: 
1.1.1.5   root     4270:        VirtualUnlock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16));
                   4271: 
                   4272:        free(lpTestBuffer);
                   4273: 
                   4274:        benchmarkLastBufferSize = benchmarkBufferSize;
                   4275: 
                   4276:        DisplayBenchmarkResults(hwndDlg);
                   4277: 
1.1.1.7   root     4278:        EnableWindow (GetDlgItem (hwndDlg, IDC_PERFORM_BENCHMARK), TRUE);
1.1.1.5   root     4279:        EnableWindow (GetDlgItem (hwndDlg, IDCLOSE), TRUE);
                   4280: 
                   4281:        NormalCursor ();
                   4282:        return TRUE;
                   4283: 
                   4284: counter_error:
1.1.1.8   root     4285:        
                   4286:        if (ci)
                   4287:                crypto_close (ci);
1.1.1.5   root     4288: 
                   4289:        VirtualUnlock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16));
                   4290: 
                   4291:        free(lpTestBuffer);
                   4292: 
                   4293:        NormalCursor ();
                   4294: 
1.1.1.7   root     4295:        EnableWindow (GetDlgItem (hwndDlg, IDC_PERFORM_BENCHMARK), TRUE);
1.1.1.5   root     4296:        EnableWindow (GetDlgItem (hwndDlg, IDCLOSE), TRUE);
                   4297: 
1.1.1.7   root     4298:        MessageBoxW (hwndDlg, GetString ("ERR_PERF_COUNTER"), lpszTitle, ICON_HAND);
1.1.1.5   root     4299:        return FALSE;
                   4300: }
                   4301: 
                   4302: 
1.1.1.12  root     4303: BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1.1.5   root     4304: {
                   4305:        WORD lw = LOWORD (wParam);
                   4306:        LPARAM nIndex;
                   4307:        HWND hCboxSortMethod = GetDlgItem (hwndDlg, IDC_BENCHMARK_SORT_METHOD);
                   4308:        HWND hCboxBufferSize = GetDlgItem (hwndDlg, IDC_BENCHMARK_BUFFER_SIZE);
                   4309: 
                   4310:        switch (msg)
                   4311:        {
                   4312:        case WM_INITDIALOG:
                   4313:                {
1.1.1.7   root     4314:                        LVCOLUMNW LvCol;
                   4315:                        wchar_t s[128];
1.1.1.5   root     4316:                        HWND hList = GetDlgItem (hwndDlg, IDC_RESULTS);
                   4317: 
1.1.1.7   root     4318:                        LocalizeDialog (hwndDlg, "IDD_BENCHMARK_DLG");
1.1.1.5   root     4319: 
                   4320:                        benchmarkBufferSize = BENCHMARK_DEFAULT_BUF_SIZE;
                   4321:                        benchmarkSortMethod = BENCHMARK_SORT_BY_SPEED;
                   4322: 
                   4323:                        SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
1.1.1.7   root     4324:                                LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP 
1.1.1.5   root     4325:                                ); 
                   4326: 
                   4327:                        memset (&LvCol,0,sizeof(LvCol));               
                   4328:                        LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;  
1.1.1.12  root     4329:                        LvCol.pszText = GetString ("ALGORITHM");
                   4330:                        LvCol.cx = CompensateXDPI (114);
1.1.1.5   root     4331:                        LvCol.fmt = LVCFMT_LEFT;
1.1.1.7   root     4332:                        SendMessage (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&LvCol);
1.1.1.5   root     4333: 
1.1.1.12  root     4334:                        LvCol.pszText = GetString ("ENCRYPTION");
                   4335:                        LvCol.cx = CompensateXDPI (80);
1.1.1.5   root     4336:                        LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7   root     4337:                        SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&LvCol);
1.1.1.5   root     4338: 
1.1.1.12  root     4339:                        LvCol.pszText = GetString ("DECRYPTION");
                   4340:                        LvCol.cx = CompensateXDPI (80);
1.1.1.5   root     4341:                        LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7   root     4342:                        SendMessageW (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol);
1.1.1.5   root     4343: 
1.1.1.12  root     4344:                        LvCol.pszText = GetString ("MEAN");
                   4345:                        LvCol.cx = CompensateXDPI (80);
1.1.1.5   root     4346:                        LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7   root     4347:                        SendMessageW (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol);
1.1.1.5   root     4348: 
                   4349:                        /* Combo boxes */
                   4350: 
                   4351:                        // Sort method
                   4352: 
                   4353:                        SendMessage (hCboxSortMethod, CB_RESETCONTENT, 0, 0);
                   4354: 
1.1.1.7   root     4355:                        nIndex = SendMessageW (hCboxSortMethod, CB_ADDSTRING, 0, (LPARAM) GetString ("ALPHABETICAL_CATEGORIZED"));
1.1.1.5   root     4356:                        SendMessage (hCboxSortMethod, CB_SETITEMDATA, nIndex, (LPARAM) 0);
                   4357: 
1.1.1.7   root     4358:                        nIndex = SendMessageW (hCboxSortMethod, CB_ADDSTRING, 0, (LPARAM) GetString ("MEAN_SPEED"));
1.1.1.5   root     4359:                        SendMessage (hCboxSortMethod, CB_SETITEMDATA, nIndex, (LPARAM) 0);
                   4360: 
                   4361:                        SendMessage (hCboxSortMethod, CB_SETCURSEL, 1, 0);              // Default sort method
                   4362: 
                   4363:                        // Buffer size
                   4364: 
                   4365:                        SendMessage (hCboxBufferSize, CB_RESETCONTENT, 0, 0);
                   4366: 
1.1.1.7   root     4367:                        swprintf (s, L"100 %s", GetString ("KB"));
                   4368:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4369:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 100 * BYTES_PER_KB);
                   4370: 
1.1.1.7   root     4371:                        swprintf (s, L"500 %s", GetString ("KB"));
                   4372:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4373:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 500 * BYTES_PER_KB);
                   4374: 
1.1.1.7   root     4375:                        swprintf (s, L"1 %s", GetString ("MB"));
                   4376:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4377:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 1 * BYTES_PER_MB);
                   4378: 
1.1.1.7   root     4379:                        swprintf (s, L"5 %s", GetString ("MB"));
                   4380:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4381:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 5 * BYTES_PER_MB);
                   4382: 
1.1.1.7   root     4383:                        swprintf (s, L"10 %s", GetString ("MB"));
                   4384:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4385:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 10 * BYTES_PER_MB);
                   4386: 
1.1.1.7   root     4387:                        swprintf (s, L"50 %s", GetString ("MB"));
                   4388:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4389:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 50 * BYTES_PER_MB);
                   4390: 
1.1.1.7   root     4391:                        swprintf (s, L"100 %s", GetString ("MB"));
                   4392:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4393:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 100 * BYTES_PER_MB);
                   4394: 
1.1.1.7   root     4395:                        swprintf (s, L"200 %s", GetString ("MB"));
                   4396:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4397:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 200 * BYTES_PER_MB);
                   4398: 
1.1.1.7   root     4399:                        swprintf (s, L"500 %s", GetString ("MB"));
                   4400:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4401:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 500 * BYTES_PER_MB);
                   4402: 
1.1.1.7   root     4403:                        swprintf (s, L"1 %s", GetString ("GB"));
                   4404:                        nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5   root     4405:                        SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 1 * BYTES_PER_GB);
                   4406: 
1.1.1.17  root     4407:                        SendMessage (hCboxBufferSize, CB_SETCURSEL, 3, 0);              // Default buffer size
1.1.1.5   root     4408: 
                   4409:                        return 1;
                   4410:                }
                   4411:                break;
                   4412: 
                   4413:        case WM_COMMAND:
                   4414:        case WM_NOTIFY:
                   4415: 
                   4416:                if (lw == IDC_BENCHMARK_SORT_METHOD)
                   4417:                {
                   4418:                        nIndex = SendMessage (hCboxSortMethod, CB_GETCURSEL, 0, 0);
                   4419:                        if (nIndex != benchmarkSortMethod)
                   4420:                        {
                   4421:                                benchmarkSortMethod = nIndex;
                   4422:                                DisplayBenchmarkResults (hwndDlg);
                   4423:                        }
1.1.1.7   root     4424:                        return 1;
1.1.1.5   root     4425:                }
                   4426: 
1.1.1.7   root     4427:                if (lw == IDC_PERFORM_BENCHMARK)
1.1.1.5   root     4428:                {
                   4429:                        nIndex = SendMessage (hCboxBufferSize, CB_GETCURSEL, 0, 0);
                   4430:                        benchmarkBufferSize = SendMessage (hCboxBufferSize, CB_GETITEMDATA, nIndex, 0);
                   4431: 
1.1.1.11  root     4432:                        if (PerformBenchmark (hwndDlg) == FALSE)
1.1.1.5   root     4433:                        {
                   4434:                                EndDialog (hwndDlg, IDCLOSE);
                   4435:                        }
1.1.1.7   root     4436:                        return 1;
1.1.1.5   root     4437:                }
1.1.1.7   root     4438:                if (lw == IDCLOSE || lw == IDCANCEL)
1.1.1.5   root     4439:                {
                   4440:                        EndDialog (hwndDlg, IDCLOSE);
1.1.1.7   root     4441:                        return 1;
1.1.1.5   root     4442:                }
                   4443:                return 0;
                   4444: 
                   4445:                break;
                   4446: 
                   4447:        case WM_CLOSE:
                   4448:                EndDialog (hwndDlg, IDCLOSE);
1.1.1.7   root     4449:                return 1;
1.1.1.5   root     4450: 
                   4451:                break;
                   4452: 
                   4453:        }
                   4454:        return 0;
                   4455: }
                   4456: 
                   4457: 
1.1.1.21  root     4458: static BOOL CALLBACK RandomPoolEnrichementDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                   4459: {
                   4460:        WORD lw = LOWORD (wParam);
                   4461:        WORD hw = HIWORD (wParam);
                   4462:        static unsigned char randPool [RNG_POOL_SIZE];
                   4463:        static unsigned char lastRandPool [RNG_POOL_SIZE];
                   4464:        static char outputDispBuffer [RNG_POOL_SIZE * 3 + RANDPOOL_DISPLAY_ROWS + 2];
                   4465:        static BOOL bDisplayPoolContents = TRUE;
                   4466:        static BOOL bRandPoolDispAscii = FALSE;
                   4467:        int hash_algo = RandGetHashFunction();
                   4468:        int hid;
                   4469: 
                   4470:        switch (msg)
                   4471:        {
                   4472:        case WM_INITDIALOG:
                   4473:                {
                   4474:                        HWND hComboBox = GetDlgItem (hwndDlg, IDC_PRF_ID);
                   4475: 
                   4476:                        VirtualLock (randPool, sizeof(randPool));
                   4477:                        VirtualLock (lastRandPool, sizeof(lastRandPool));
                   4478:                        VirtualLock (outputDispBuffer, sizeof(outputDispBuffer));
                   4479: 
                   4480:                        LocalizeDialog (hwndDlg, "IDD_RANDOM_POOL_ENRICHMENT");
                   4481: 
                   4482:                        SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
                   4483:                        for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
                   4484:                        {
                   4485:                                if (!HashIsDeprecated (hid))
                   4486:                                        AddComboPair (hComboBox, HashGetName(hid), hid);
                   4487:                        }
                   4488:                        SelectAlgo (hComboBox, &hash_algo);
                   4489: 
                   4490:                        SetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS, bDisplayPoolContents);
                   4491: 
                   4492:                        SetTimer (hwndDlg, 0xfd, RANDPOOL_DISPLAY_REFRESH_INTERVAL, NULL);
                   4493:                        SendMessage (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
                   4494:                        return 1;
                   4495:                }
                   4496: 
                   4497:        case WM_TIMER:
                   4498:                {
                   4499:                        char tmp[4];
                   4500:                        unsigned char tmpByte;
                   4501:                        int col, row;
                   4502: 
                   4503:                        if (bDisplayPoolContents)
                   4504:                        {
                   4505:                                RandpeekBytes (randPool, sizeof (randPool));
                   4506: 
                   4507:                                if (memcmp (lastRandPool, randPool, sizeof(lastRandPool)) != 0)
                   4508:                                {
                   4509:                                        outputDispBuffer[0] = 0;
                   4510: 
                   4511:                                        for (row = 0; row < RANDPOOL_DISPLAY_ROWS; row++)
                   4512:                                        {
                   4513:                                                for (col = 0; col < RANDPOOL_DISPLAY_COLUMNS; col++)
                   4514:                                                {
                   4515:                                                        tmpByte = randPool[row * RANDPOOL_DISPLAY_COLUMNS + col];
                   4516: 
                   4517:                                                        sprintf (tmp, bRandPoolDispAscii ? ((tmpByte >= 32 && tmpByte < 255 && tmpByte != '&') ? " %c " : " . ") : "%02X ", tmpByte);
                   4518:                                                        strcat (outputDispBuffer, tmp);
                   4519:                                                }
                   4520:                                                strcat (outputDispBuffer, "\n");
                   4521:                                        }
                   4522:                                        SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), outputDispBuffer);
                   4523: 
                   4524:                                        memcpy (lastRandPool, randPool, sizeof(lastRandPool));
                   4525:                                }
                   4526:                        }
                   4527:                        return 1;
                   4528:                }
                   4529: 
                   4530:        case WM_COMMAND:
                   4531:                if (lw == IDC_CONTINUE)
                   4532:                        lw = IDOK;
                   4533: 
                   4534:                if (lw == IDOK || lw == IDCLOSE || lw == IDCANCEL)
                   4535:                {
                   4536:                        goto exit;
                   4537:                }
                   4538: 
                   4539:                if (lw == IDC_PRF_ID && hw == CBN_SELCHANGE)
                   4540:                {
                   4541:                        hid = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETCURSEL, 0, 0);
                   4542:                        hash_algo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETITEMDATA, hid, 0);
                   4543:                        RandSetHashFunction (hash_algo);
                   4544:                        return 1;
                   4545:                }
                   4546: 
                   4547:                if (lw == IDC_DISPLAY_POOL_CONTENTS)
                   4548:                {
                   4549:                        if (!(bDisplayPoolContents = GetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS)))
                   4550:                        {
                   4551:                                char tmp[RNG_POOL_SIZE+1];
                   4552: 
                   4553:                                memset (tmp, ' ', sizeof(tmp));
                   4554:                                tmp [RNG_POOL_SIZE] = 0;
                   4555:                                SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp);
                   4556:                        }
                   4557: 
                   4558:                        return 1;
                   4559:                }
                   4560: 
                   4561:                return 0;
                   4562: 
                   4563:        case WM_CLOSE:
                   4564:                {
                   4565:                        char tmp[RNG_POOL_SIZE+1];
                   4566: exit:
                   4567:                        KillTimer (hwndDlg, 0xfd);
                   4568: 
                   4569:                        burn (randPool, sizeof(randPool));
                   4570:                        burn (lastRandPool, sizeof(lastRandPool));
                   4571:                        burn (outputDispBuffer, sizeof(outputDispBuffer));
                   4572: 
                   4573:                        // Attempt to wipe the pool contents in the GUI text area
                   4574:                        memset (tmp, 'X', RNG_POOL_SIZE);
                   4575:                        tmp [RNG_POOL_SIZE] = 0;
                   4576:                        SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp);
                   4577: 
                   4578:                        if (msg == WM_COMMAND && lw == IDOK)
                   4579:                                EndDialog (hwndDlg, IDOK);
                   4580:                        else
                   4581:                                EndDialog (hwndDlg, IDCLOSE);
                   4582: 
                   4583:                        return 1;
                   4584:                }
                   4585:        }
                   4586:        return 0;
                   4587: }
                   4588: 
                   4589: 
                   4590: void UserEnrichRandomPool (HWND hwndDlg)
                   4591: {
                   4592:        Randinit();
                   4593: 
                   4594:        if (!IsRandomPoolEnrichedByUser())
                   4595:        {
                   4596:                INT_PTR result = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_RANDOM_POOL_ENRICHMENT), hwndDlg ? hwndDlg : MainDlg, (DLGPROC) RandomPoolEnrichementDlgProc, (LPARAM) 0);
                   4597:                SetRandomPoolEnrichedByUserStatus (result == IDOK);
                   4598:        }
                   4599: }
                   4600: 
1.1.1.7   root     4601: 
                   4602: /* Except in response to the WM_INITDIALOG message, the dialog box procedure
                   4603:    should return nonzero if it processes the message, and zero if it does
                   4604:    not. - see DialogProc */
1.1.1.12  root     4605: BOOL CALLBACK
1.1.1.7   root     4606: KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                   4607: {
                   4608:        WORD lw = LOWORD (wParam);
                   4609:        WORD hw = HIWORD (wParam);
                   4610:        static unsigned char randPool [RNG_POOL_SIZE];
                   4611:        static unsigned char lastRandPool [RNG_POOL_SIZE];
1.1.1.13  root     4612:        static char outputDispBuffer [RNG_POOL_SIZE * 3 + RANDPOOL_DISPLAY_ROWS + 2];
1.1.1.10  root     4613:        static BOOL bDisplayPoolContents = TRUE;
1.1.1.13  root     4614:        static BOOL bRandPoolDispAscii = FALSE;
1.1.1.7   root     4615:        int hash_algo = RandGetHashFunction();
                   4616:        int hid;
                   4617: 
                   4618:        switch (msg)
                   4619:        {
                   4620:        case WM_INITDIALOG:
1.1.1.5   root     4621:                {
1.1.1.7   root     4622:                        HWND hComboBox = GetDlgItem (hwndDlg, IDC_PRF_ID);
                   4623: 
                   4624:                        VirtualLock (randPool, sizeof(randPool));
                   4625:                        VirtualLock (lastRandPool, sizeof(lastRandPool));
                   4626:                        VirtualLock (outputDispBuffer, sizeof(outputDispBuffer));
                   4627: 
                   4628:                        LocalizeDialog (hwndDlg, "IDD_KEYFILE_GENERATOR_DLG");
                   4629: 
                   4630:                        SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
1.1.1.13  root     4631:                        for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
1.1.1.7   root     4632:                        {
1.1.1.13  root     4633:                                if (!HashIsDeprecated (hid))
                   4634:                                        AddComboPair (hComboBox, HashGetName(hid), hid);
1.1.1.7   root     4635:                        }
                   4636:                        SelectAlgo (hComboBox, &hash_algo);
                   4637: 
                   4638:                        SetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS, bDisplayPoolContents);
                   4639: 
                   4640: #ifndef VOLFORMAT                      
                   4641:                        if (Randinit ()) 
                   4642:                        {
                   4643:                                Error ("INIT_RAND");
                   4644:                                EndDialog (hwndDlg, IDCLOSE);
                   4645:                        }
                   4646: #endif
1.1.1.13  root     4647:                        SetTimer (hwndDlg, 0xfd, RANDPOOL_DISPLAY_REFRESH_INTERVAL, NULL);
1.1.1.7   root     4648:                        SendMessage (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
                   4649:                        return 1;
                   4650:                }
                   4651: 
                   4652:        case WM_TIMER:
                   4653:                {
                   4654:                        char tmp[4];
1.1.1.13  root     4655:                        unsigned char tmpByte;
1.1.1.7   root     4656:                        int col, row;
                   4657: 
                   4658:                        if (bDisplayPoolContents)
                   4659:                        {
                   4660:                                RandpeekBytes (randPool, sizeof (randPool));
                   4661: 
                   4662:                                if (memcmp (lastRandPool, randPool, sizeof(lastRandPool)) != 0)
                   4663:                                {
                   4664:                                        outputDispBuffer[0] = 0;
                   4665: 
1.1.1.13  root     4666:                                        for (row = 0; row < RANDPOOL_DISPLAY_ROWS; row++)
1.1.1.7   root     4667:                                        {
1.1.1.13  root     4668:                                                for (col = 0; col < RANDPOOL_DISPLAY_COLUMNS; col++)
1.1.1.7   root     4669:                                                {
1.1.1.13  root     4670:                                                        tmpByte = randPool[row * RANDPOOL_DISPLAY_COLUMNS + col];
                   4671: 
                   4672:                                                        sprintf (tmp, bRandPoolDispAscii ? ((tmpByte >= 32 && tmpByte < 255 && tmpByte != '&') ? " %c " : " . ") : "%02X ", tmpByte);
1.1.1.7   root     4673:                                                        strcat (outputDispBuffer, tmp);
                   4674:                                                }
                   4675:                                                strcat (outputDispBuffer, "\n");
                   4676:                                        }
                   4677:                                        SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), outputDispBuffer);
                   4678: 
                   4679:                                        memcpy (lastRandPool, randPool, sizeof(lastRandPool));
                   4680:                                }
                   4681:                        }
                   4682:                        return 1;
                   4683:                }
                   4684: 
                   4685:        case WM_COMMAND:
                   4686: 
                   4687:                if (lw == IDCLOSE || lw == IDCANCEL)
                   4688:                {
                   4689:                        goto exit;
                   4690:                }
                   4691: 
                   4692:                if (lw == IDC_PRF_ID && hw == CBN_SELCHANGE)
                   4693:                {
                   4694:                        hid = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETCURSEL, 0, 0);
                   4695:                        hash_algo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETITEMDATA, hid, 0);
                   4696:                        RandSetHashFunction (hash_algo);
                   4697:                        return 1;
                   4698:                }
                   4699: 
                   4700:                if (lw == IDC_DISPLAY_POOL_CONTENTS)
                   4701:                {
                   4702:                        if (!(bDisplayPoolContents = GetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS)))
1.1.1.13  root     4703:                        {
                   4704:                                char tmp[RNG_POOL_SIZE+1];
                   4705: 
                   4706:                                memset (tmp, ' ', sizeof(tmp));
                   4707:                                tmp [RNG_POOL_SIZE] = 0;
                   4708:                                SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp);
                   4709:                        }
1.1.1.21  root     4710:                        return 1;
1.1.1.7   root     4711:                }
                   4712: 
                   4713:                if (lw == IDC_GENERATE_AND_SAVE_KEYFILE)
                   4714:                {
                   4715:                        char szFileName [TC_MAX_PATH];
                   4716:                        unsigned char keyfile [MAX_PASSWORD];
                   4717:                        int fhKeyfile = -1;
                   4718: 
                   4719:                        /* Select filename */
1.1.1.19  root     4720:                        if (!BrowseFiles (hwndDlg, "OPEN_TITLE", szFileName, bHistory, TRUE, NULL))
1.1.1.7   root     4721:                                return 1;
                   4722: 
                   4723:                        /* Conceive the file */
                   4724:                        if ((fhKeyfile = _open(szFileName, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) == -1)
                   4725:                        {
1.1.1.10  root     4726:                                handleWin32Error (hwndDlg);
1.1.1.7   root     4727:                                return 1;
                   4728:                        }
                   4729: 
                   4730:                        /* Generate the keyfile */ 
                   4731:                        WaitCursor();
1.1.1.10  root     4732:                        if (!RandgetBytes (keyfile, sizeof(keyfile), TRUE))
                   4733:                        {
                   4734:                                _close (fhKeyfile);
                   4735:                                DeleteFile (szFileName);
                   4736:                                NormalCursor();
                   4737:                                return 1;
                   4738:                        }
1.1.1.7   root     4739:                        NormalCursor();
                   4740: 
                   4741:                        /* Write the keyfile */
                   4742:                        if (_write (fhKeyfile, keyfile, sizeof(keyfile)) == -1)
                   4743:                                handleWin32Error (hwndDlg);
                   4744:                        else
                   4745:                                Info("KEYFILE_CREATED");
                   4746: 
1.1.1.13  root     4747:                        burn (keyfile, sizeof(keyfile));
1.1.1.7   root     4748:                        _close (fhKeyfile);
                   4749:                        return 1;
                   4750:                }
                   4751:                return 0;
                   4752: 
                   4753:        case WM_CLOSE:
                   4754:                {
                   4755:                        char tmp[RNG_POOL_SIZE+1];
                   4756: exit:
1.1.1.13  root     4757:                        WaitCursor();
1.1.1.7   root     4758:                        KillTimer (hwndDlg, 0xfd);
                   4759: 
                   4760: #ifndef VOLFORMAT                      
1.1.1.21  root     4761:                        RandStop (FALSE);
1.1.1.7   root     4762: #endif
                   4763:                        /* Cleanup */
                   4764: 
1.1.1.13  root     4765:                        burn (randPool, sizeof(randPool));
                   4766:                        burn (lastRandPool, sizeof(lastRandPool));
                   4767:                        burn (outputDispBuffer, sizeof(outputDispBuffer));
1.1.1.7   root     4768: 
                   4769:                        // Attempt to wipe the pool contents in the GUI text area
                   4770:                        memset (tmp, 'X', RNG_POOL_SIZE);
                   4771:                        tmp [RNG_POOL_SIZE] = 0;
                   4772:                        SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp);
                   4773: 
                   4774:                        EndDialog (hwndDlg, IDCLOSE);
1.1.1.13  root     4775:                        NormalCursor ();
1.1.1.7   root     4776:                        return 1;
1.1.1.5   root     4777:                }
                   4778:        }
1.1.1.7   root     4779:        return 0;
1.1.1.5   root     4780: }
                   4781: 
                   4782: 
1.1.1.7   root     4783: 
                   4784: /* Except in response to the WM_INITDIALOG message, the dialog box procedure
                   4785: should return nonzero if it processes the message, and zero if it does
                   4786: not. - see DialogProc */
                   4787: BOOL CALLBACK
                   4788: CipherTestDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1.1.1.5   root     4789: {
1.1.1.8   root     4790:        static int idTestCipher = -1;           /* Currently selected cipher for the test vector facility (none = -1). */
1.1.1.13  root     4791:        static BOOL bXTSTestEnabled = FALSE;
1.1.1.8   root     4792: 
                   4793:        PCRYPTO_INFO ci;
1.1.1.7   root     4794:        WORD lw = LOWORD (wParam);
                   4795:        WORD hw = HIWORD (wParam);
                   4796: 
                   4797:        switch (uMsg)
1.1.1.5   root     4798:        {
1.1.1.7   root     4799:        case WM_INITDIALOG:
                   4800:                {
                   4801:                        int ea;
                   4802:                        char buf[100];
                   4803: 
                   4804:                        LocalizeDialog (hwndDlg, "IDD_CIPHER_TEST_DLG");
                   4805: 
                   4806:                        SendMessage(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), WM_SETFONT, (WPARAM)hBoldFont, MAKELPARAM(TRUE,0));
                   4807:                        SendMessage(GetDlgItem(hwndDlg, IDC_KEY), EM_LIMITTEXT, 128,0);
                   4808:                        SendMessage(GetDlgItem(hwndDlg, IDC_KEY), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
1.1.1.13  root     4809:                        SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT), EM_LIMITTEXT,64,0);
1.1.1.7   root     4810:                        SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
1.1.1.13  root     4811:                        SendMessage(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), EM_LIMITTEXT,64,0);
1.1.1.7   root     4812:                        SendMessage(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
1.1.1.13  root     4813:                        SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), EM_LIMITTEXT, 128,0);
                   4814:                        SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
                   4815:                        SendMessage(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), EM_LIMITTEXT,32,0);
                   4816:                        SendMessage(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
                   4817:                        SetCheckBox (hwndDlg, IDC_XTS_MODE_ENABLED, bXTSTestEnabled);
                   4818:                        EnableWindow (GetDlgItem (hwndDlg, IDC_SECONDARY_KEY), bXTSTestEnabled);
                   4819:                        EnableWindow (GetDlgItem (hwndDlg, IDT_SECONDARY_KEY), bXTSTestEnabled);
                   4820:                        EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), bXTSTestEnabled);
                   4821:                        EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_BLOCK_NUMBER), bXTSTestEnabled);
                   4822:                        EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
                   4823:                        EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
1.1.1.7   root     4824: 
                   4825:                        if (idTestCipher == -1)
                   4826:                                idTestCipher = (int) lParam;
                   4827: 
                   4828:                        SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_RESETCONTENT, 0, 0);
                   4829:                        for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
                   4830:                        {
1.1.1.11  root     4831:                                if (EAGetCipherCount (ea) == 1 && EAIsFormatEnabled (ea))
1.1.1.12  root     4832:                                        AddComboPair (GetDlgItem (hwndDlg, IDC_CIPHER), EAGetName (buf, ea), EAGetFirstCipher (ea));
1.1.1.7   root     4833:                        }
                   4834: 
                   4835:                        ResetCipherTest(hwndDlg, idTestCipher);
                   4836: 
                   4837:                        SelectAlgo (GetDlgItem (hwndDlg, IDC_CIPHER), &idTestCipher);
                   4838: 
                   4839:                        return 1;
                   4840:                }
                   4841: 
                   4842:        case WM_COMMAND:
                   4843: 
                   4844:                if (hw == CBN_SELCHANGE && lw == IDC_CIPHER)
                   4845:                {
                   4846:                        idTestCipher = (int) SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_GETCURSEL, 0, 0), 0);
                   4847:                        ResetCipherTest(hwndDlg, idTestCipher);
                   4848:                        SendMessage (hwndDlg, WM_INITDIALOG, 0, 0);
                   4849:                        return 1;
                   4850:                }
                   4851: 
                   4852:                if (hw == CBN_SELCHANGE && lw == IDC_KEY_SIZE)
                   4853:                {
                   4854:                        // NOP
                   4855:                        return 1;
                   4856:                }
                   4857: 
                   4858:                if (lw == IDC_RESET)
                   4859:                {
                   4860:                        ResetCipherTest(hwndDlg, idTestCipher);
                   4861: 
                   4862:                        return 1;
                   4863:                }
                   4864: 
                   4865:                if (lw == IDC_AUTO)
                   4866:                {
1.1.1.13  root     4867:                        WaitCursor ();
1.1.1.7   root     4868:                        if (!AutoTestAlgorithms())
                   4869:                        {
                   4870:                                ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_SHOWNORMAL);
                   4871:                                SetWindowTextW(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), GetString ("TESTS_FAILED"));
                   4872:                        } 
                   4873:                        else
                   4874:                        {
                   4875:                                ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_SHOWNORMAL);
                   4876:                                SetWindowTextW(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), GetString ("TESTS_PASSED"));
                   4877:                                ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_SHOWNORMAL);
                   4878:                        }
1.1.1.13  root     4879:                        NormalCursor ();
1.1.1.7   root     4880: 
                   4881:                        return 1;
                   4882: 
                   4883:                }
                   4884: 
1.1.1.13  root     4885:                if (lw == IDC_XTS_MODE_ENABLED)
1.1.1.8   root     4886:                {
1.1.1.13  root     4887:                        bXTSTestEnabled = GetCheckBox (hwndDlg, IDC_XTS_MODE_ENABLED);
                   4888:                        EnableWindow (GetDlgItem (hwndDlg, IDC_SECONDARY_KEY), bXTSTestEnabled);
                   4889:                        EnableWindow (GetDlgItem (hwndDlg, IDT_SECONDARY_KEY), bXTSTestEnabled);
                   4890:                        EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), bXTSTestEnabled);
                   4891:                        EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_BLOCK_NUMBER), bXTSTestEnabled);
                   4892:                        EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
                   4893:                        EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
                   4894:                        if (bXTSTestEnabled)
1.1.1.9   root     4895:                                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, 0,0);
1.1.1.8   root     4896:                }
                   4897: 
1.1.1.7   root     4898:                if (lw == IDOK || lw == IDC_ENCRYPT || lw == IDC_DECRYPT)
                   4899:                {
1.1.1.13  root     4900:                        char key[128+1], inputtext[128+1], secondaryKey[64+1], dataUnitNo[16+1], szTmp[128+1];
                   4901:                        int ks, pt, n, tlen, blockNo = 0;
1.1.1.7   root     4902:                        BOOL bEncrypt;
                   4903: 
                   4904:                        ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_HIDE);
                   4905:                        ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_HIDE);
                   4906: 
                   4907:                        ks = (int) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_GETCURSEL, 0,0);
                   4908:                        ks = (int) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_GETITEMDATA, ks,0);
                   4909:                        pt = (int) SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_GETITEMDATA, 0,0);
                   4910: 
                   4911:                        bEncrypt = lw == IDC_ENCRYPT;
                   4912: 
                   4913:                        memset(key,0,sizeof(key));
                   4914:                        memset(szTmp,0,sizeof(szTmp));
                   4915:                        n = GetWindowText(GetDlgItem(hwndDlg, IDC_KEY), szTmp, sizeof(szTmp));
                   4916:                        if (n != ks * 2)
                   4917:                        {
1.1.1.13  root     4918:                                Warning ("TEST_KEY_SIZE");
1.1.1.7   root     4919:                                return 1;
                   4920:                        }
                   4921: 
                   4922:                        for (n = 0; n < ks; n ++)
                   4923:                        {
                   4924:                                char szTmp2[3], *ptr;
                   4925:                                long x;
                   4926: 
                   4927:                                szTmp2[2] = 0;
                   4928:                                szTmp2[0] = szTmp[n * 2];
                   4929:                                szTmp2[1] = szTmp[n * 2 + 1];
                   4930: 
                   4931:                                x = strtol(szTmp2, &ptr, 16);
                   4932: 
                   4933:                                key[n] = (char) x;
                   4934:                        }
                   4935: 
1.1.1.8   root     4936:                        memset(inputtext, 0, sizeof(inputtext));
1.1.1.13  root     4937:                        memset(secondaryKey, 0, sizeof(secondaryKey));
                   4938:                        memset(dataUnitNo, 0, sizeof(dataUnitNo));
1.1.1.8   root     4939:                        memset(szTmp, 0, sizeof(szTmp));
1.1.1.7   root     4940: 
                   4941:                        if (bEncrypt)
                   4942:                        {
                   4943:                                n = GetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), szTmp, sizeof(szTmp));
                   4944:                        }
                   4945:                        else
                   4946:                        {
                   4947:                                n = GetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), szTmp, sizeof(szTmp));
                   4948:                        }
                   4949: 
                   4950:                        if (n != pt * 2)
                   4951:                        {
                   4952:                                if (bEncrypt)
                   4953:                                {
1.1.1.13  root     4954:                                        Warning ("TEST_PLAINTEXT_SIZE");
1.1.1.7   root     4955:                                        return 1;
                   4956:                                }
                   4957:                                else
                   4958:                                {
1.1.1.13  root     4959:                                        Warning  ("TEST_CIPHERTEXT_SIZE");
1.1.1.7   root     4960:                                        return 1;
                   4961:                                }
                   4962:                        }
1.1.1.8   root     4963: 
1.1.1.7   root     4964:                        for (n = 0; n < pt; n ++)
                   4965:                        {
                   4966:                                char szTmp2[3], *ptr;
                   4967:                                long x;
                   4968: 
                   4969:                                szTmp2[2] = 0;
                   4970:                                szTmp2[0] = szTmp[n * 2];
                   4971:                                szTmp2[1] = szTmp[n * 2 + 1];
                   4972: 
                   4973:                                x = strtol(szTmp2, &ptr, 16);
                   4974: 
                   4975:                                inputtext[n] = (char) x;
                   4976:                        }
                   4977:                        
1.1.1.13  root     4978:                        // XTS
                   4979:                        if (bXTSTestEnabled)
1.1.1.7   root     4980:                        {
1.1.1.13  root     4981:                                // Secondary key
                   4982: 
                   4983:                                if (GetWindowText(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), szTmp, sizeof(szTmp)) != 64)
1.1.1.8   root     4984:                                {
1.1.1.13  root     4985:                                        Warning ("TEST_INCORRECT_SECONDARY_KEY_SIZE");
1.1.1.8   root     4986:                                        return 1;
                   4987:                                }
1.1.1.7   root     4988: 
1.1.1.13  root     4989:                                for (n = 0; n < 64; n ++)
1.1.1.7   root     4990:                                {
1.1.1.8   root     4991:                                        char szTmp2[3], *ptr;
                   4992:                                        long x;
                   4993: 
                   4994:                                        szTmp2[2] = 0;
                   4995:                                        szTmp2[0] = szTmp[n * 2];
                   4996:                                        szTmp2[1] = szTmp[n * 2 + 1];
                   4997: 
                   4998:                                        x = strtol(szTmp2, &ptr, 16);
                   4999: 
1.1.1.13  root     5000:                                        secondaryKey[n] = (char) x;
1.1.1.7   root     5001:                                }
                   5002: 
1.1.1.13  root     5003:                                // Data unit number
1.1.1.7   root     5004: 
1.1.1.13  root     5005:                                tlen = GetWindowText(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), szTmp, sizeof(szTmp));
                   5006: 
                   5007:                                if (tlen > 16 || tlen < 1)
1.1.1.7   root     5008:                                {
1.1.1.13  root     5009:                                        Warning ("TEST_INCORRECT_TEST_DATA_UNIT_SIZE");
1.1.1.8   root     5010:                                        return 1;
1.1.1.7   root     5011:                                }
1.1.1.13  root     5012: 
                   5013:                                LeftPadString (szTmp, tlen, 16, '0');
                   5014: 
                   5015:                                for (n = 0; n < 16; n ++)
1.1.1.7   root     5016:                                {
1.1.1.8   root     5017:                                        char szTmp2[3], *ptr;
                   5018:                                        long x;
                   5019: 
                   5020:                                        szTmp2[2] = 0;
                   5021:                                        szTmp2[0] = szTmp[n * 2];
                   5022:                                        szTmp2[1] = szTmp[n * 2 + 1];
                   5023: 
                   5024:                                        x = strtol(szTmp2, &ptr, 16);
                   5025: 
1.1.1.13  root     5026:                                        dataUnitNo[n] = (char) x;
1.1.1.7   root     5027:                                }
1.1.1.9   root     5028: 
1.1.1.13  root     5029:                                // Block number
                   5030: 
                   5031:                                blockNo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_GETCURSEL, 0, 0), 0);
                   5032:                        }       // if (bXTSTestEnabled)
1.1.1.7   root     5033: 
1.1.1.8   root     5034:                        
                   5035:                        /* Perform the actual tests */
                   5036: 
                   5037:                        if (ks != CB_ERR && pt != CB_ERR) 
                   5038:                        {
                   5039:                                char tmp[128];
1.1.1.9   root     5040:                                int tmpRetVal;
1.1.1.8   root     5041: 
                   5042:                                /* Copy the plain/ciphertext */
                   5043:                                memcpy(tmp,inputtext, pt);
                   5044: 
1.1.1.13  root     5045:                                if (bXTSTestEnabled)
1.1.1.7   root     5046:                                {
1.1.1.13  root     5047:                                        UINT64_STRUCT structDataUnitNo;
                   5048: 
                   5049:                                        /* XTS mode */
1.1.1.8   root     5050: 
                   5051:                                        ci = crypto_open ();
                   5052:                                        if (!ci)
                   5053:                                                return 1;
                   5054: 
1.1.1.13  root     5055:                                        ci->mode = XTS;
1.1.1.12  root     5056: 
                   5057:                                        for (ci->ea = EAGetFirst (); ci->ea != 0 ; ci->ea = EAGetNext (ci->ea))
                   5058:                                                if (EAGetCipherCount (ci->ea) == 1 && EAGetFirstCipher (ci->ea) == idTestCipher)
                   5059:                                                        break;
1.1.1.8   root     5060: 
1.1.1.15  root     5061:                                        if ((tmpRetVal = EAInit (ci->ea, (unsigned char *) key, ci->ks)) != ERR_SUCCESS)
1.1.1.9   root     5062:                                        {
                   5063:                                                handleError (hwndDlg, tmpRetVal);
1.1.1.8   root     5064:                                                return 1;
1.1.1.9   root     5065:                                        }
1.1.1.8   root     5066: 
1.1.1.13  root     5067:                                        memcpy (&ci->k2, secondaryKey, sizeof (secondaryKey));
1.1.1.8   root     5068:                                        if (!EAInitMode (ci))
                   5069:                                                return 1;
                   5070: 
1.1.1.13  root     5071:                                        structDataUnitNo.Value = BE64(((unsigned __int64 *)dataUnitNo)[0]);
1.1.1.12  root     5072: 
1.1.1.13  root     5073:                                        if (bEncrypt)
1.1.1.15  root     5074:                                                EncryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher);
1.1.1.13  root     5075:                                        else
1.1.1.15  root     5076:                                                DecryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher);
1.1.1.9   root     5077: 
1.1.1.8   root     5078:                                        crypto_close (ci);
1.1.1.7   root     5079:                                }
1.1.1.8   root     5080:                                else
                   5081:                                {
                   5082:                                        if (idTestCipher == BLOWFISH)
                   5083:                                        {
1.1.1.12  root     5084:                                                /* Deprecated/legacy */
                   5085: 
1.1.1.8   root     5086:                                                /* Convert to little-endian, this is needed here and not in
                   5087:                                                above auto-tests because BF_ecb_encrypt above correctly converts
                   5088:                                                from big to little endian, and EncipherBlock does not! */
1.1.1.15  root     5089:                                                LongReverse((unsigned int *) tmp, pt);
1.1.1.8   root     5090:                                        }
                   5091: 
                   5092:                                        CipherInit2(idTestCipher, key, ks_tmp, ks);
                   5093: 
                   5094:                                        if (bEncrypt)
                   5095:                                        {
                   5096:                                                EncipherBlock(idTestCipher, tmp, ks_tmp);
                   5097:                                        }
                   5098:                                        else
                   5099:                                        {
                   5100:                                                DecipherBlock(idTestCipher, tmp, ks_tmp);
                   5101:                                        }
1.1.1.7   root     5102: 
1.1.1.8   root     5103:                                        if (idTestCipher == BLOWFISH)
                   5104:                                        {
1.1.1.12  root     5105:                                                /* Deprecated/legacy */
                   5106: 
1.1.1.8   root     5107:                                                /* Convert back to big-endian */
1.1.1.15  root     5108:                                                LongReverse((unsigned int *) tmp, pt);
1.1.1.8   root     5109:                                        }
                   5110:                                }
1.1.1.7   root     5111:                                *szTmp = 0;
                   5112: 
1.1.1.8   root     5113:                                for (n = 0; n < pt; n ++)
1.1.1.7   root     5114:                                {
                   5115:                                        char szTmp2[3];
                   5116:                                        sprintf(szTmp2, "%02x", (int)((unsigned char)tmp[n]));
                   5117:                                        strcat(szTmp, szTmp2);
                   5118:                                }
                   5119: 
                   5120:                                if (bEncrypt)
                   5121:                                        SetWindowText(GetDlgItem(hwndDlg,IDC_CIPHERTEXT), szTmp);
                   5122:                                else
                   5123:                                        SetWindowText(GetDlgItem(hwndDlg,IDC_PLAINTEXT), szTmp);
                   5124:                        }
1.1.1.8   root     5125: 
1.1.1.7   root     5126:                        return 1;
                   5127:                }
                   5128: 
                   5129:                if (lw == IDCLOSE || lw == IDCANCEL)
                   5130:                {
                   5131:                        idTestCipher = -1;
                   5132:                        EndDialog (hwndDlg, 0);
                   5133:                        return 1;
                   5134:                }
                   5135:                break;
                   5136: 
                   5137:        case WM_CLOSE:
                   5138:                idTestCipher = -1;
                   5139:                EndDialog (hwndDlg, 0);
                   5140:                return 1;
1.1.1.5   root     5141:        }
1.1.1.7   root     5142: 
                   5143:        return 0;
                   5144: }
                   5145: 
                   5146: void 
                   5147: ResetCipherTest(HWND hwndDlg, int idTestCipher)
                   5148: {
                   5149:        int ndx;
                   5150: 
                   5151:        ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_HIDE);
                   5152:        ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_HIDE);
                   5153: 
1.1.1.11  root     5154:        EnableWindow(GetDlgItem(hwndDlg,IDC_KEY_SIZE), FALSE);
1.1.1.7   root     5155: 
                   5156:        /* Setup the keysize and plaintext sizes for the selected cipher */
                   5157: 
                   5158:        SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_RESETCONTENT, 0,0);
                   5159:        SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_RESETCONTENT, 0,0);
1.1.1.13  root     5160:        SendMessage (GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_RESETCONTENT, 0,0);
1.1.1.7   root     5161: 
                   5162:        ndx = SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_ADDSTRING, 0,(LPARAM) "64");
                   5163:        SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 8);
                   5164:        SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETCURSEL, ndx,0);
                   5165: 
1.1.1.13  root     5166:        for (ndx = 0; ndx < BLOCKS_PER_XTS_DATA_UNIT; ndx++)
                   5167:        {
                   5168:                char tmpStr [16];
                   5169: 
                   5170:                sprintf (tmpStr, "%d", ndx);
                   5171: 
                   5172:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_ADDSTRING, 0,(LPARAM) tmpStr);
                   5173:                SendMessage(GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_SETITEMDATA, ndx,(LPARAM) ndx);
                   5174:        }
                   5175: 
                   5176:        SendMessage(GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_SETCURSEL, 0, 0);
                   5177: 
                   5178:        SetWindowText(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), "0000000000000000000000000000000000000000000000000000000000000000");
                   5179:        SetWindowText(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), "0");
1.1.1.8   root     5180: 
1.1.1.7   root     5181:        if (idTestCipher == BLOWFISH)
                   5182:        {
1.1.1.12  root     5183:                /* Deprecated/legacy */
                   5184: 
1.1.1.7   root     5185:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "448");
                   5186:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 56);
                   5187:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "256");
                   5188:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 32);
                   5189:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "128");
                   5190:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16);
                   5191:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "64");
                   5192:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 8);
                   5193:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, 0,0);
                   5194:                SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
                   5195:        } 
                   5196: 
                   5197: 
                   5198:        if (idTestCipher == CAST)
                   5199:        {
1.1.1.12  root     5200:                /* Deprecated/legacy */
                   5201: 
1.1.1.7   root     5202:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "128");
                   5203:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16);
                   5204:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0);
                   5205:                SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "00000000000000000000000000000000");
                   5206:        }
                   5207: 
                   5208:        if (idTestCipher == TRIPLEDES)
                   5209:        {
1.1.1.12  root     5210:                /* Deprecated/legacy */
                   5211: 
1.1.1.7   root     5212:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "168");
                   5213:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 24);
                   5214:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0);
                   5215:                SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "000000000000000000000000000000000000000000000000");
                   5216:        }
                   5217:        
                   5218:        SetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), "0000000000000000");
                   5219:        SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), "0000000000000000");
                   5220: 
                   5221:        if (idTestCipher == AES || idTestCipher == SERPENT || idTestCipher == TWOFISH)
                   5222:        {
                   5223:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "256");
                   5224:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 32);
                   5225:                SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0);
                   5226: 
                   5227:                SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_RESETCONTENT, 0,0);
                   5228:                ndx = SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_ADDSTRING, 0,(LPARAM) "128");
                   5229:                SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16);
                   5230:                SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETCURSEL, ndx,0);
                   5231: 
                   5232:                SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "0000000000000000000000000000000000000000000000000000000000000000");
                   5233:                SetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), "00000000000000000000000000000000");
                   5234:                SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), "00000000000000000000000000000000");
                   5235:        }
                   5236: }
                   5237: 
                   5238: #endif // #ifndef SETUP
                   5239: 
                   5240: 
1.1.1.11  root     5241: BOOL CALLBACK MultiChoiceDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
                   5242: {
                   5243:        int nChoiceIDs [MAX_MULTI_CHOICES+1] = { IDC_MULTI_CHOICE_MSG, IDC_CHOICE1, IDC_CHOICE2, IDC_CHOICE3,
                   5244:                IDC_CHOICE4, IDC_CHOICE5, IDC_CHOICE6, IDC_CHOICE7, IDC_CHOICE8, IDC_CHOICE9, IDC_CHOICE10 };
                   5245:        int nBaseButtonWidth = 0;
                   5246:        int nBaseButtonHeight = 0;
                   5247:        int nActiveChoices = -1;
                   5248:        int nStr = 0;
                   5249:        int vertSubOffset, horizSubOffset, vertMsgHeightOffset;
                   5250:        int vertOffset = 0;
                   5251:        int nLongestButtonCaptionWidth = 6;
1.1.1.17  root     5252:        int nLongestButtonCaptionCharLen = 1;
1.1.1.11  root     5253:        int nTextGfxLineHeight = 0;
1.1.1.17  root     5254:        int nMainTextLenInChars = 0;
1.1.1.19  root     5255:        int newLineSeqCount = 0;
1.1.1.11  root     5256:        RECT rec, wrec, wtrec, trec;
                   5257:        BOOL bResolve;
                   5258: 
                   5259:        WORD lw = LOWORD (wParam);
                   5260: 
                   5261:        switch (uMsg)
                   5262:        {
                   5263:        case WM_INITDIALOG:
                   5264:                {
1.1.1.19  root     5265:                        char **pStr = (char **) ((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->strings;
                   5266:                        char **pStrOrig = pStr;
                   5267:                        wchar_t **pwStr = (wchar_t **) ((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->strings;
                   5268:                        wchar_t **pwStrOrig = pwStr;
                   5269: 
                   5270:                        LocalizeDialog (hwndDlg, NULL);
1.1.1.11  root     5271: 
                   5272:                        SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                   5273:                        SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
                   5274: 
                   5275:                        bResolve = (*pStr == NULL);
                   5276: 
1.1.1.19  root     5277:                        // Style
                   5278:                        if (((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->bold)
                   5279:                        {
                   5280:                                SendMessage (GetDlgItem (hwndDlg, IDC_MULTI_CHOICE_MSG), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
                   5281:                        }
                   5282: 
1.1.1.11  root     5283:                        // Process the strings
                   5284:                        pStr++;
                   5285:                        pwStr++;
                   5286: 
                   5287:                        do 
                   5288:                        {
                   5289:                                if (*pStr != 0)
                   5290:                                {
                   5291:                                        SetWindowTextW (GetDlgItem(hwndDlg, nChoiceIDs[nStr]), bResolve ? GetString(*pStr) : *pwStr);
                   5292: 
                   5293:                                        if (nStr > 0)
                   5294:                                        {
                   5295:                                                nLongestButtonCaptionWidth = max (
                   5296:                                                        GetTextGfxWidth (GetDlgItem(hwndDlg, IDC_CHOICE1),
                   5297:                                                                                        bResolve ? GetString(*pStr) : *pwStr,
                   5298:                                                                                        hUserFont),
                   5299:                                                        nLongestButtonCaptionWidth);
1.1.1.17  root     5300: 
                   5301:                                                nLongestButtonCaptionCharLen = max (nLongestButtonCaptionCharLen, 
                   5302:                                                        (int) wcslen ((const wchar_t *) (bResolve ? GetString(*pStr) : *pwStr)));
1.1.1.11  root     5303:                                        }
                   5304: 
                   5305:                                        nActiveChoices++;
                   5306:                                        pStr++;
                   5307:                                        pwStr++;
                   5308:                                }
                   5309:                                else
                   5310:                                {
                   5311:                                        ShowWindow(GetDlgItem(hwndDlg, nChoiceIDs[nStr]), SW_HIDE);
                   5312:                                }
                   5313:                                nStr++;
                   5314: 
                   5315:                        } while (nStr < MAX_MULTI_CHOICES+1);
                   5316: 
1.1.1.17  root     5317:                        // Length of main message in characters (not bytes)
                   5318:                        nMainTextLenInChars = wcslen ((const wchar_t *) (bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1)));
                   5319: 
1.1.1.19  root     5320:                        if (nMainTextLenInChars > 200 
1.1.1.17  root     5321:                                && nMainTextLenInChars / nLongestButtonCaptionCharLen >= 10)
                   5322:                        {
1.1.1.19  root     5323:                                // As the main text is longer than 200 characters, we will "pad" the widest button caption with 
1.1.1.17  root     5324:                                // spaces (if it is not wide enough) so as to increase the width of the whole dialog window. 
                   5325:                                // Otherwise, it would look too tall (dialog boxes look better when they are more wide than tall).
                   5326:                                nLongestButtonCaptionWidth = CompensateXDPI (max (
                   5327:                                        nLongestButtonCaptionWidth, 
                   5328:                                        min (350, nMainTextLenInChars)));
                   5329:                        }
                   5330: 
1.1.1.11  root     5331:                        // Get the window coords
                   5332:                        GetWindowRect(hwndDlg, &wrec);
                   5333: 
                   5334:                        // Get the base button size
                   5335:                        GetClientRect(GetDlgItem(hwndDlg, IDC_CHOICE1), &rec);
                   5336:                        nBaseButtonWidth = rec.right + 2;
                   5337:                        nBaseButtonHeight = rec.bottom + 2;
                   5338: 
                   5339:                        // Increase in width based on the gfx length of the widest button caption
1.1.1.12  root     5340:                        horizSubOffset = min (CompensateXDPI (500), max (0, nLongestButtonCaptionWidth + CompensateXDPI (50) - nBaseButtonWidth));
1.1.1.11  root     5341: 
                   5342:                        // Vertical "title bar" offset
                   5343:                        GetClientRect(hwndDlg, &wtrec);
                   5344:                        vertOffset = wrec.bottom - wrec.top - wtrec.bottom - GetSystemMetrics(SM_CYFIXEDFRAME);
                   5345: 
                   5346:                        // Height/width of the message text
                   5347:                        GetClientRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &trec);
                   5348: 
1.1.1.19  root     5349:                        // Determine the number of newlines contained in the message text
                   5350:                        {
                   5351:                                int64 offset = -1;
                   5352: 
                   5353:                                do
                   5354:                                {
                   5355:                                        offset = FindString ((char *) (bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1)), 
                   5356:                                                (char *) L"\n",
                   5357:                                                nMainTextLenInChars * 2, 
                   5358:                                                wcslen (L"\n") * 2, 
                   5359:                                                offset + 1);
                   5360: 
                   5361:                                        newLineSeqCount++;
                   5362: 
                   5363:                                } while (offset != -1);
                   5364:                        }
                   5365: 
1.1.1.11  root     5366:                        nTextGfxLineHeight = GetTextGfxHeight (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG),
                   5367:                                                                bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1),
                   5368:                                                                hUserFont);
                   5369: 
                   5370:                        vertMsgHeightOffset = ((GetTextGfxWidth (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG),
                   5371:                                                                bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1),
                   5372:                                                                hUserFont) / (trec.right + horizSubOffset) + 1) * nTextGfxLineHeight) - trec.bottom;
                   5373: 
1.1.1.19  root     5374:                        vertMsgHeightOffset = min (CompensateYDPI (350), vertMsgHeightOffset + newLineSeqCount * nTextGfxLineHeight + (trec.bottom + vertMsgHeightOffset) / 10);        // As reserve, we are adding 10% and the number of lines equal to the number of newlines in the message
1.1.1.11  root     5375: 
                   5376:                        // Reduction in height according to the number of shown buttons
                   5377:                        vertSubOffset = ((MAX_MULTI_CHOICES - nActiveChoices) * nBaseButtonHeight);
                   5378: 
                   5379:                        if (horizSubOffset > 0 
                   5380:                                || vertMsgHeightOffset > 0 
                   5381:                                || vertOffset > 0)
                   5382:                        {
                   5383:                                // Resize/move each button if necessary
                   5384:                                for (nStr = 1; nStr < MAX_MULTI_CHOICES+1; nStr++)
                   5385:                                {
                   5386:                                        GetWindowRect(GetDlgItem(hwndDlg, nChoiceIDs[nStr]), &rec);
                   5387: 
                   5388:                                        MoveWindow (GetDlgItem(hwndDlg, nChoiceIDs[nStr]),
                   5389:                                                rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
                   5390:                                                rec.top - wrec.top - vertOffset + vertMsgHeightOffset,
                   5391:                                                nBaseButtonWidth + horizSubOffset,
                   5392:                                                nBaseButtonHeight,
                   5393:                                                TRUE);
                   5394:                                }
                   5395: 
                   5396:                                // Resize/move the remaining GUI elements
                   5397:                                GetWindowRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &rec);
                   5398:                                GetClientRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &trec);
                   5399:                                MoveWindow (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG),
                   5400:                                        rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
                   5401:                                        rec.top - wrec.top - vertOffset,
                   5402:                                        trec.right + 2 + horizSubOffset,
                   5403:                                        trec.bottom + 2 + vertMsgHeightOffset,
                   5404:                                        TRUE);
                   5405: 
                   5406:                                GetWindowRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), &rec);
                   5407:                                GetClientRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), &trec);
                   5408:                                MoveWindow (GetDlgItem(hwndDlg, IDC_MC_DLG_HR1),
                   5409:                                        rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
                   5410:                                        rec.top - wrec.top - vertOffset,
                   5411:                                        trec.right + 2 + horizSubOffset,
                   5412:                                        trec.bottom + 2,
                   5413:                                        TRUE);
                   5414:                                
                   5415:                                GetWindowRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), &rec);
                   5416:                                GetClientRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), &trec);
                   5417:                                MoveWindow (GetDlgItem(hwndDlg, IDC_MC_DLG_HR2),
                   5418:                                        rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
                   5419:                                        rec.top - wrec.top - vertOffset + vertMsgHeightOffset,
                   5420:                                        trec.right + 2 + horizSubOffset,
                   5421:                                        trec.bottom + 2,
                   5422:                                        TRUE);
                   5423:                        }
                   5424: 
                   5425:                        // Resize the window according to number of shown buttons and the longest button caption
                   5426:                        MoveWindow (hwndDlg,
                   5427:                                wrec.left - horizSubOffset / 2,
                   5428:                                wrec.top + vertSubOffset / 2 - vertMsgHeightOffset / 2,
                   5429:                                wrec.right - wrec.left + horizSubOffset,
                   5430:                                wrec.bottom - wrec.top - vertSubOffset + 1 + vertMsgHeightOffset,
                   5431:                                TRUE);
                   5432: 
                   5433:                        return 1;
                   5434:                }
                   5435: 
                   5436:        case WM_COMMAND:
                   5437: 
                   5438:                if (lw == IDCLOSE || lw == IDCANCEL)
                   5439:                {
                   5440:                        EndDialog (hwndDlg, 0);
                   5441:                        return 1;
                   5442:                }
                   5443: 
                   5444:                for (nStr = 1; nStr < MAX_MULTI_CHOICES+1; nStr++)
                   5445:                {
                   5446:                        if (lw == nChoiceIDs[nStr])
                   5447:                        {
                   5448:                                EndDialog (hwndDlg, nStr);
                   5449:                                return 1;
                   5450:                        }
                   5451:                }
                   5452:                break;
                   5453: 
                   5454:        case WM_CLOSE:
                   5455:                EndDialog (hwndDlg, 0);
                   5456:                return 1;
                   5457:        }
                   5458: 
                   5459:        return 0;
                   5460: }
                   5461: 
                   5462: 
1.1.1.7   root     5463: BOOL CheckCapsLock (HWND hwnd, BOOL quiet)
                   5464: {
                   5465:        if ((GetKeyState(VK_CAPITAL) & 1) != 0) 
                   5466:        {
                   5467:                if (!quiet)
                   5468:                {
                   5469:                        MessageBoxW (hwnd, GetString ("CAPSLOCK_ON"), lpszTitle, MB_ICONEXCLAMATION);
                   5470:                }
                   5471:                return TRUE;
                   5472:        }
                   5473:        return FALSE;
1.1.1.5   root     5474: }
                   5475: 
                   5476: 
1.1.1.13  root     5477: // Checks whether the file extension is not used for executable files or similarly problematic, which often
                   5478: // causes Windows and antivirus software to interfere with the container 
1.1.1.11  root     5479: BOOL CheckFileExtension (char *fileName)
                   5480: {
1.1.1.13  root     5481:        int i = 0;
1.1.1.12  root     5482:        char *ext = strrchr (fileName, '.');
1.1.1.13  root     5483:        static char *problemFileExt[] = {
                   5484:                // These are protected by the Windows Resource Protection
                   5485:                ".asa", ".asp", ".aspx", ".ax", ".bas", ".bat", ".bin", ".cer", ".chm", ".clb", ".cmd", ".cnt", ".cnv",
                   5486:                ".com", ".cpl", ".cpx", ".crt", ".csh", ".dll", ".drv", ".dtd", ".exe", ".fxp", ".grp", ".h1s", ".hlp",
                   5487:                ".hta", ".ime", ".inf", ".ins", ".isp", ".its", ".js", ".jse", ".ksh", ".lnk", ".mad", ".maf", ".mag",
                   5488:                ".mam", ".man", ".maq", ".mar", ".mas", ".mat", ".mau", ".mav", ".maw", ".mda", ".mdb", ".mde", ".mdt",
                   5489:                ".mdw", ".mdz", ".msc", ".msi", ".msp", ".mst", ".mui", ".nls", ".ocx", ".ops", ".pal", ".pcd", ".pif",
                   5490:                ".prf", ".prg", ".pst", ".reg", ".scf", ".scr", ".sct", ".shb", ".shs", ".sys", ".tlb", ".tsp", ".url",
                   5491:                ".vb", ".vbe", ".vbs", ".vsmacros", ".vss", ".vst", ".vsw", ".ws", ".wsc", ".wsf", ".wsh", ".xsd", ".xsl",
                   5492:                // These additional file extensions are usually watched by antivirus programs
1.1.1.17  root     5493:                ".386", ".acm", ".ade", ".adp", ".ani", ".app", ".asd", ".asf", ".asx", ".awx", ".ax", ".boo", ".bz2", ".cdf",
                   5494:                ".class", ".dhtm", ".dhtml",".dlo", ".emf", ".eml", ".flt", ".fot", ".gz", ".hlp", ".htm", ".html", ".ini", 
1.1.1.13  root     5495:                ".j2k", ".jar", ".jff", ".jif", ".jmh", ".jng", ".jp2", ".jpe", ".jpeg", ".jpg", ".lsp", ".mod", ".nws",
                   5496:                ".obj", ".olb", ".osd", ".ov1", ".ov2", ".ov3", ".ovl", ".ovl", ".ovr", ".pdr", ".pgm", ".php", ".pkg",
1.1.1.23! root     5497:                ".pl", ".png", ".pot", ".pps", ".ppt", ".ps1", ".ps1xml", ".psc1", ".rar", ".rpl", ".rtf", ".sbf", ".script", ".sh", ".sha", ".shtm",
1.1.1.17  root     5498:                ".shtml", ".spl", ".swf", ".tar", ".tgz", ".tmp", ".ttf", ".vcs", ".vlm", ".vxd", ".vxo", ".wiz", ".wll", ".wmd",
                   5499:                ".wmf", ".wms", ".wmz", ".wpc", ".wsc", ".wsh", ".wwk", ".xhtm", ".xhtml", ".xl", ".xml", ".zip", ".7z", 0};
1.1.1.11  root     5500: 
1.1.1.13  root     5501:        if (!ext)
                   5502:                return FALSE;
                   5503: 
                   5504:        while (problemFileExt[i])
                   5505:        {
                   5506:                if (!_stricmp (ext, problemFileExt[i++]))
                   5507:                        return TRUE;
                   5508:        }
1.1.1.11  root     5509: 
                   5510:        return FALSE;
                   5511: }
                   5512: 
                   5513: 
1.1.1.17  root     5514: void IncreaseWrongPwdRetryCount (int count)
                   5515: {
                   5516:        WrongPwdRetryCounter += count;
                   5517: }
                   5518: 
                   5519: 
                   5520: void ResetWrongPwdRetryCount (void)
                   5521: {
                   5522:        WrongPwdRetryCounter = 0;
                   5523: }
                   5524: 
                   5525: 
                   5526: BOOL WrongPwdRetryCountOverLimit (void)
                   5527: {
                   5528:        return (WrongPwdRetryCounter > TC_TRY_HEADER_BAK_AFTER_NBR_WRONG_PWD_TRIES);
                   5529: }
                   5530: 
                   5531: 
1.1.1.5   root     5532: int GetFirstAvailableDrive ()
                   5533: {
                   5534:        DWORD dwUsedDrives = GetLogicalDrives();
                   5535:        int i;
                   5536: 
                   5537:        for (i = 3; i < 26; i++)
                   5538:        {
                   5539:                if (!(dwUsedDrives & 1 << i))
                   5540:                        return i;
                   5541:        }
                   5542: 
                   5543:        return -1;
                   5544: }
                   5545: 
                   5546: 
                   5547: int GetLastAvailableDrive ()
                   5548: {
                   5549:        DWORD dwUsedDrives = GetLogicalDrives();
                   5550:        int i;
                   5551: 
                   5552:        for (i = 25; i > 2; i--)
                   5553:        {
                   5554:                if (!(dwUsedDrives & 1 << i))
                   5555:                        return i;
                   5556:        }
                   5557: 
                   5558:        return -1;
                   5559: }
                   5560: 
                   5561: 
                   5562: BOOL IsDriveAvailable (int driveNo)
                   5563: {
                   5564:        return (GetLogicalDrives() & (1 << driveNo)) == 0;
                   5565: }
                   5566: 
                   5567: 
1.1.1.11  root     5568: BOOL IsDeviceMounted (char *deviceName)
                   5569: {
                   5570:        BOOL bResult = FALSE;
                   5571:        DWORD dwResult;
                   5572:        HANDLE dev = INVALID_HANDLE_VALUE;
                   5573: 
                   5574:        if ((dev = CreateFile (deviceName,
1.1.1.12  root     5575:                GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1.1.1.11  root     5576:                NULL,
                   5577:                OPEN_EXISTING,
                   5578:                0,
                   5579:                NULL)) != INVALID_HANDLE_VALUE)
                   5580:        {
                   5581:                bResult = DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL);
                   5582:                CloseHandle (dev);
                   5583:        }
                   5584: 
                   5585:        return bResult;
                   5586: }
                   5587: 
                   5588: 
1.1.1.5   root     5589: int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced)
                   5590: {
                   5591:        UNMOUNT_STRUCT unmount;
                   5592:        DWORD dwResult;
                   5593: 
                   5594:        BOOL bResult;
                   5595:        
                   5596:        unmount.nDosDriveNo = nDosDriveNo;
                   5597:        unmount.ignoreOpenFiles = forced;
                   5598: 
1.1.1.13  root     5599:        bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_VOLUME, &unmount,
1.1.1.5   root     5600:                sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL);
                   5601: 
                   5602:        if (bResult == FALSE)
                   5603:        {
                   5604:                handleWin32Error (hwndDlg);
                   5605:                return 1;
                   5606:        }
                   5607: 
1.1.1.17  root     5608: #ifdef TCMOUNT
                   5609: 
                   5610:        if (unmount.nReturnCode == ERR_SUCCESS
                   5611:                && unmount.HiddenVolumeProtectionTriggered
                   5612:                && !VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo])
                   5613:        {
                   5614:                wchar_t msg[4096];
                   5615: 
                   5616:                VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo] = TRUE;
                   5617:                swprintf (msg, GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), nDosDriveNo + 'A');
                   5618:                SetForegroundWindow (hwndDlg);
                   5619:                MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
                   5620:        }
                   5621: 
                   5622: #endif // #ifdef TCMOUNT
                   5623: 
1.1.1.5   root     5624:        return unmount.nReturnCode;
                   5625: }
                   5626: 
                   5627: 
1.1.1.6   root     5628: void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap)
1.1.1.5   root     5629: {
                   5630:        DEV_BROADCAST_VOLUME dbv;
1.1.1.6   root     5631:        DWORD dwResult;
1.1.1.11  root     5632:        LONG eventId = 0;
1.1.1.7   root     5633:        int i;
1.1.1.6   root     5634: 
1.1.1.23! root     5635:        if (DeviceChangeBroadcastDisabled)
        !          5636:                return;
        !          5637: 
1.1.1.10  root     5638:        if (message == DBT_DEVICEARRIVAL)
1.1.1.11  root     5639:                eventId = SHCNE_DRIVEADD;
1.1.1.10  root     5640:        else if (message == DBT_DEVICEREMOVECOMPLETE)
1.1.1.11  root     5641:                eventId = SHCNE_DRIVEREMOVED;
1.1.1.23! root     5642:        else if (IsOSAtLeast (WIN_7) && message == DBT_DEVICEREMOVEPENDING) // Explorer on Windows 7 holds open handles of all drives when 'Computer' is expanded in navigation pane. SHCNE_DRIVEREMOVED must be used as DBT_DEVICEREMOVEPENDING is ignored.
        !          5643:                eventId = SHCNE_DRIVEREMOVED;
1.1.1.5   root     5644: 
1.1.1.7   root     5645:        if (driveMap == 0)
1.1.1.10  root     5646:                driveMap = (1 << nDosDriveNo);
                   5647: 
1.1.1.11  root     5648:        if (eventId != 0)
1.1.1.7   root     5649:        {
1.1.1.11  root     5650:                for (i = 0; i < 26; i++)
1.1.1.7   root     5651:                {
1.1.1.11  root     5652:                        if (driveMap & (1 << i))
1.1.1.7   root     5653:                        {
1.1.1.23! root     5654:                                char root[] = { (char) i + 'A', ':', '\\', 0 };
1.1.1.11  root     5655:                                SHChangeNotify (eventId, SHCNF_PATH, root, NULL);
1.1.1.10  root     5656: 
1.1.1.11  root     5657:                                if (nCurrentOS == WIN_2000 && RemoteSession)
                   5658:                                {
                   5659:                                        char target[32];
                   5660:                                        wsprintf (target, "%ls%c", TC_MOUNT_PREFIX, i + 'A');
                   5661:                                        root[2] = 0;
                   5662: 
                   5663:                                        if (message == DBT_DEVICEARRIVAL)
                   5664:                                                DefineDosDevice (DDD_RAW_TARGET_PATH, root, target);
                   5665:                                        else if (message == DBT_DEVICEREMOVECOMPLETE)
                   5666:                                                DefineDosDevice (DDD_RAW_TARGET_PATH| DDD_REMOVE_DEFINITION
1.1.1.10  root     5667:                                                | DDD_EXACT_MATCH_ON_REMOVE, root, target);
1.1.1.11  root     5668:                                }
1.1.1.7   root     5669:                        }
                   5670:                }
                   5671:        }
1.1.1.5   root     5672: 
1.1.1.11  root     5673:        dbv.dbcv_size = sizeof (dbv); 
1.1.1.5   root     5674:        dbv.dbcv_devicetype = DBT_DEVTYP_VOLUME; 
                   5675:        dbv.dbcv_reserved = 0;
1.1.1.10  root     5676:        dbv.dbcv_unitmask = driveMap;
1.1.1.5   root     5677:        dbv.dbcv_flags = 0; 
                   5678: 
1.1.1.17  root     5679:        UINT timeOut = 1000;
                   5680: 
                   5681:        // SHChangeNotify() works on Vista, so the Explorer does not require WM_DEVICECHANGE
                   5682:        if (CurrentOSMajor >= 6)
                   5683:                timeOut = 100;
                   5684: 
1.1.1.12  root     5685:        IgnoreWmDeviceChange = TRUE;
1.1.1.23! root     5686:        SendMessageTimeout (HWND_BROADCAST, WM_DEVICECHANGE, message, (LPARAM)(&dbv), SMTO_ABORTIFHUNG, timeOut, &dwResult);
1.1.1.12  root     5687: 
1.1.1.17  root     5688:        // Explorer prior Vista sometimes fails to register a new drive
                   5689:        if (CurrentOSMajor < 6 && message == DBT_DEVICEARRIVAL)
1.1.1.23! root     5690:                SendMessageTimeout (HWND_BROADCAST, WM_DEVICECHANGE, message, (LPARAM)(&dbv), SMTO_ABORTIFHUNG, 200, &dwResult);
1.1.1.17  root     5691: 
1.1.1.12  root     5692:        IgnoreWmDeviceChange = FALSE;
1.1.1.5   root     5693: }
                   5694: 
                   5695: 
1.1.1.7   root     5696: // Use only cached passwords if password = NULL
                   5697: //
1.1.1.5   root     5698: // Returns:
                   5699: // -1 = user aborted mount / error
                   5700: // 0  = mount failed
                   5701: // 1  = mount OK
                   5702: // 2  = mount OK in shared mode
                   5703: 
                   5704: int MountVolume (HWND hwndDlg,
                   5705:                                 int driveNo,
                   5706:                                 char *volumePath,
1.1.1.7   root     5707:                                 Password *password,
1.1.1.5   root     5708:                                 BOOL cachePassword,
                   5709:                                 BOOL sharedAccess,
1.1.1.6   root     5710:                                 MountOptions *mountOptions,
1.1.1.7   root     5711:                                 BOOL quiet,
                   5712:                                 BOOL bReportWrongPassword)
1.1.1.5   root     5713: {
1.1.1.7   root     5714:        MOUNT_STRUCT mount;
1.1.1.5   root     5715:        DWORD dwResult;
                   5716:        BOOL bResult, bDevice;
1.1.1.11  root     5717:        char root[MAX_PATH];
1.1.1.5   root     5718: 
1.1.1.15  root     5719: #ifdef TCMOUNT
                   5720:        if (mountOptions->PartitionInInactiveSysEncScope)
                   5721:        {
                   5722:                if (!CheckSysEncMountWithoutPBA (volumePath, quiet))
                   5723:                        return -1;
                   5724:        }
                   5725: #endif
                   5726: 
1.1.1.5   root     5727:        if (IsMountedVolume (volumePath))
                   5728:        {
                   5729:                if (!quiet)
1.1.1.11  root     5730:                        Error ("VOL_ALREADY_MOUNTED");
1.1.1.5   root     5731:                return -1;
                   5732:        }
                   5733: 
                   5734:        if (!IsDriveAvailable (driveNo))
1.1.1.10  root     5735:        {
1.1.1.17  root     5736:                if (!quiet)
                   5737:                        Error ("DRIVE_LETTER_UNAVAILABLE");
                   5738: 
1.1.1.5   root     5739:                return -1;
1.1.1.10  root     5740:        }
1.1.1.5   root     5741: 
                   5742:        // If using cached passwords, check cache status first
1.1.1.7   root     5743:        if (password == NULL && IsPasswordCacheEmpty ())
1.1.1.5   root     5744:                return 0;
                   5745: 
1.1.1.7   root     5746:        ZeroMemory (&mount, sizeof (mount));
                   5747:        mount.bExclusiveAccess = sharedAccess ? FALSE : TRUE;
1.1.1.23! root     5748:        mount.SystemFavorite = MountVolumesAsSystemFavorite;
1.1.1.17  root     5749:        mount.UseBackupHeader =  mountOptions->UseBackupHeader;
1.1.1.19  root     5750:        mount.RecoveryMode = mountOptions->RecoveryMode;
1.1.1.17  root     5751: 
1.1.1.5   root     5752: retry:
1.1.1.7   root     5753:        mount.nDosDriveNo = driveNo;
                   5754:        mount.bCache = cachePassword;
                   5755: 
1.1.1.15  root     5756:        mount.bPartitionInInactiveSysEncScope = FALSE;
                   5757: 
1.1.1.7   root     5758:        if (password != NULL)
                   5759:                mount.VolumePassword = *password;
                   5760:        else
                   5761:                mount.VolumePassword.Length = 0;
                   5762: 
                   5763:        if (!mountOptions->ReadOnly && mountOptions->ProtectHiddenVolume)
                   5764:        {
                   5765:                mount.ProtectedHidVolPassword = mountOptions->ProtectedHidVolPassword;
                   5766:                mount.bProtectHiddenVolume = TRUE;
                   5767:        }
                   5768:        else
                   5769:                mount.bProtectHiddenVolume = FALSE;
                   5770: 
                   5771:        mount.bMountReadOnly = mountOptions->ReadOnly;
                   5772:        mount.bMountRemovable = mountOptions->Removable;
                   5773:        mount.bPreserveTimestamp = mountOptions->PreserveTimestamp;
                   5774: 
                   5775:        mount.bMountManager = TRUE;
1.1.1.5   root     5776: 
                   5777:        // Windows 2000 mount manager causes problems with remounted volumes
                   5778:        if (CurrentOSMajor == 5 && CurrentOSMinor == 0)
1.1.1.7   root     5779:                mount.bMountManager = FALSE;
1.1.1.5   root     5780: 
1.1.1.21  root     5781:        string path = volumePath;
                   5782:        if (path.find ("\\\\?\\") == 0)
                   5783:        {
                   5784:                // Remove \\?\ prefix
                   5785:                path = path.substr (4);
                   5786:                strcpy_s (volumePath, TC_MAX_PATH, path.c_str());
                   5787:        }
                   5788:        
                   5789:        if (path.find ("Volume{") == 0 && path.rfind ("}\\") == path.size() - 2)
                   5790:        {
                   5791:                // Resolve volume name
1.1.1.23! root     5792:                if (QueryDosDevice (path.substr (0, path.size() - 1).c_str(), volumePath, TC_MAX_PATH) != 0)
        !          5793:                {
        !          5794:                        foreach (const HostDevice &device, GetAvailableHostDevices (true, true))
        !          5795:                        {
        !          5796:                                if (!device.DynamicVolume)
        !          5797:                                {
        !          5798:                                        wchar_t resolvedVolumePath[TC_MAX_PATH];
        !          5799: 
        !          5800:                                        if (ResolveSymbolicLink (SingleStringToWide (device.Path).c_str(), resolvedVolumePath)
        !          5801:                                                && SingleStringToWide (volumePath) == resolvedVolumePath)
        !          5802:                                        {
        !          5803:                                                strcpy_s (volumePath, TC_MAX_PATH, device.Path.c_str());
        !          5804:                                                break;
        !          5805:                                        }
        !          5806:                                }
        !          5807:                        }
        !          5808:                }
        !          5809:                else
1.1.1.21  root     5810:                        strcpy_s (volumePath, TC_MAX_PATH, path.c_str());
                   5811:        }
                   5812: 
1.1.1.7   root     5813:        CreateFullVolumePath ((char *) mount.wszVolume, volumePath, &bDevice);
1.1.1.5   root     5814: 
1.1.1.11  root     5815:        if (!bDevice)
1.1.1.7   root     5816:        {
1.1.1.11  root     5817:                // UNC path
1.1.1.21  root     5818:                if (path.find ("\\\\") == 0)
1.1.1.11  root     5819:                {
1.1.1.23! root     5820:                        strcpy_s ((char *)mount.wszVolume, array_capacity (mount.wszVolume), ("UNC" + path.substr (1)).c_str());
1.1.1.11  root     5821:                }
                   5822: 
                   5823:                if (GetVolumePathName (volumePath, root, sizeof (root) - 1))
                   5824:                {
                   5825:                        DWORD bps, flags, d;
                   5826:                        if (GetDiskFreeSpace (root, &d, &bps, &d, &d))
                   5827:                                mount.BytesPerSector = bps;
                   5828: 
                   5829:                        // Read-only host filesystem
                   5830:                        if (!mount.bMountReadOnly && GetVolumeInformation (root, NULL, 0,  NULL, &d, &flags, NULL, 0))
                   5831:                                mount.bMountReadOnly = (flags & FILE_READ_ONLY_VOLUME) != 0;
                   5832:                }
1.1.1.7   root     5833:        }
                   5834: 
                   5835:        ToUNICODE ((char *) mount.wszVolume);
1.1.1.5   root     5836: 
1.1.1.15  root     5837:        if (mountOptions->PartitionInInactiveSysEncScope)
                   5838:        {
                   5839:                if (mount.wszVolume == NULL || swscanf_s ((const wchar_t *) mount.wszVolume,
                   5840:                        WIDE("\\Device\\Harddisk%d\\Partition"),
                   5841:                        &mount.nPartitionInInactiveSysEncScopeDriveNo,
                   5842:                        sizeof(mount.nPartitionInInactiveSysEncScopeDriveNo)) != 1)
                   5843:                {
                   5844:                        return -1;
                   5845:                }
                   5846: 
                   5847:                mount.bPartitionInInactiveSysEncScope = TRUE;
                   5848:        }
                   5849: 
1.1.1.13  root     5850:        bResult = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, &mount,
1.1.1.7   root     5851:                sizeof (mount), &mount, sizeof (mount), &dwResult, NULL);
                   5852: 
                   5853:        burn (&mount.VolumePassword, sizeof (mount.VolumePassword));
                   5854:        burn (&mount.ProtectedHidVolPassword, sizeof (mount.ProtectedHidVolPassword));
1.1.1.5   root     5855: 
                   5856:        if (bResult == FALSE)
                   5857:        {
                   5858:                // Volume already open by another process
1.1.1.8   root     5859:                if (GetLastError () == ERROR_SHARING_VIOLATION)
1.1.1.5   root     5860:                {
1.1.1.7   root     5861:                        if (mount.bExclusiveAccess == FALSE)
1.1.1.5   root     5862:                        {
                   5863:                                if (!quiet)
1.1.1.23! root     5864:                                        Error ("FILE_IN_USE_FAILED");
1.1.1.5   root     5865: 
                   5866:                                return -1;
                   5867:                        }
                   5868:                        else
                   5869:                        {
                   5870:                                if (quiet)
                   5871:                                {
1.1.1.7   root     5872:                                        mount.bExclusiveAccess = FALSE;
1.1.1.5   root     5873:                                        goto retry;
                   5874:                                }
                   5875: 
                   5876:                                // Ask user 
1.1.1.23! root     5877:                                if (IDYES == AskWarnNoYes ("FILE_IN_USE"))
1.1.1.5   root     5878:                                {
1.1.1.7   root     5879:                                        mount.bExclusiveAccess = FALSE;
1.1.1.5   root     5880:                                        goto retry;
                   5881:                                }
                   5882:                        }
                   5883: 
                   5884:                        return -1;
                   5885:                }
                   5886: 
                   5887:                if (!quiet)
                   5888:                        handleWin32Error (hwndDlg);
                   5889: 
                   5890:                return -1;
                   5891:        }
                   5892: 
1.1.1.7   root     5893:        if (mount.nReturnCode != 0)
1.1.1.5   root     5894:        {
1.1.1.7   root     5895:                if (mount.nReturnCode == ERR_PASSWORD_WRONG)
                   5896:                {
                   5897:                        // Do not report wrong password, if not instructed to 
                   5898:                        if (bReportWrongPassword)
1.1.1.17  root     5899:                        {
                   5900:                                IncreaseWrongPwdRetryCount (1);         // We increase the count here only if bReportWrongPassword is TRUE, because "Auto-Mount All Devices" and other callers do it separately
                   5901: 
                   5902:                                if (WrongPwdRetryCountOverLimit () 
                   5903:                                        && !mount.UseBackupHeader)
                   5904:                                {
                   5905:                                        // Retry using embedded header backup (if any)
                   5906:                                        mount.UseBackupHeader = TRUE;
                   5907:                                        goto retry;
                   5908:                                }
                   5909: 
1.1.1.21  root     5910:                                if (bDevice && mount.bProtectHiddenVolume)
                   5911:                                {
                   5912:                                        int driveNo;
                   5913: 
                   5914:                                        if (sscanf (volumePath, "\\Device\\Harddisk%d\\Partition", &driveNo) == 1)
                   5915:                                        {
                   5916:                                                OPEN_TEST_STRUCT openTestStruct;
                   5917:                                                memset (&openTestStruct, 0, sizeof (openTestStruct));
                   5918: 
                   5919:                                                openTestStruct.bDetectTCBootLoader = TRUE;
                   5920:                                                _snwprintf ((wchar_t *) openTestStruct.wszFileName, array_capacity (openTestStruct.wszFileName), L"\\Device\\Harddisk%d\\Partition0", driveNo);
                   5921: 
                   5922:                                                DWORD dwResult;
                   5923:                                                if (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, &openTestStruct, sizeof (OPEN_TEST_STRUCT), &openTestStruct, sizeof (OPEN_TEST_STRUCT), &dwResult, NULL) && openTestStruct.TCBootLoaderDetected)
                   5924:                                                        WarningDirect ((GetWrongPasswordErrorMessage (hwndDlg) + L"\n\n" + GetString ("HIDDEN_VOL_PROT_PASSWORD_US_KEYB_LAYOUT")).c_str());
                   5925:                                                else
                   5926:                                                        handleError (hwndDlg, mount.nReturnCode);
                   5927:                                        }
                   5928:                                }
                   5929:                                else
                   5930:                                        handleError (hwndDlg, mount.nReturnCode);
1.1.1.17  root     5931:                        }
1.1.1.7   root     5932: 
                   5933:                        return 0;
                   5934:                }
1.1.1.5   root     5935: 
1.1.1.7   root     5936:                if (!quiet)
                   5937:                        handleError (hwndDlg, mount.nReturnCode);
1.1.1.5   root     5938: 
                   5939:                return 0;
                   5940:        }
                   5941: 
1.1.1.17  root     5942:        // Mount successful
                   5943: 
                   5944:        if (mount.UseBackupHeader != mountOptions->UseBackupHeader
                   5945:                && mount.UseBackupHeader)
                   5946:        {
1.1.1.20  root     5947:                if (bReportWrongPassword && !Silent)
1.1.1.17  root     5948:                        Warning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK");
                   5949:        }
1.1.1.19  root     5950:        
1.1.1.23! root     5951:        LastMountedVolumeDirty = mount.FilesystemDirty;
        !          5952: 
1.1.1.19  root     5953:        if (mount.FilesystemDirty)
                   5954:        {
                   5955:                wchar_t msg[1024];
1.1.1.23! root     5956:                wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 };
1.1.1.19  root     5957:                wsprintfW (msg, GetString ("MOUNTED_VOLUME_DIRTY"), mountPoint);
                   5958: 
                   5959:                if (AskWarnYesNoString (msg) == IDYES)
                   5960:                        CheckFilesystem (driveNo, TRUE);
                   5961:        }
1.1.1.17  root     5962: 
1.1.1.20  root     5963:        if (mount.VolumeMountedReadOnlyAfterAccessDenied
                   5964:                && !Silent
                   5965:                && !bDevice
                   5966:                && !FileHasReadOnlyAttribute (volumePath)
                   5967:                && !IsFileOnReadOnlyFilesystem (volumePath))
                   5968:        {
                   5969:                wchar_t msg[1024];
1.1.1.23! root     5970:                wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 };
1.1.1.20  root     5971:                wsprintfW (msg, GetString ("MOUNTED_CONTAINER_FORCED_READ_ONLY"), mountPoint);
                   5972: 
                   5973:                WarningDirect (msg);
                   5974:        }
                   5975: 
                   5976:        if (mount.VolumeMountedReadOnlyAfterAccessDenied
                   5977:                && !Silent
                   5978:                && bDevice)
                   5979:        {
                   5980:                wchar_t msg[1024];
1.1.1.23! root     5981:                wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 };
1.1.1.20  root     5982:                wsprintfW (msg, GetString ("MOUNTED_DEVICE_FORCED_READ_ONLY"), mountPoint);
                   5983: 
                   5984:                WarningDirect (msg);
                   5985:        }
                   5986: 
1.1.1.21  root     5987:        if (mount.VolumeMountedReadOnlyAfterDeviceWriteProtected
                   5988:                && !Silent
                   5989:                && strstr (volumePath, "\\Device\\Harddisk") == volumePath)
                   5990:        {
                   5991:                wchar_t msg[1024];
1.1.1.23! root     5992:                wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 };
1.1.1.21  root     5993:                wsprintfW (msg, GetString ("MOUNTED_DEVICE_FORCED_READ_ONLY_WRITE_PROTECTION"), mountPoint);
                   5994: 
                   5995:                WarningDirect (msg);
                   5996: 
                   5997:                if (CurrentOSMajor >= 6
                   5998:                        && strstr (volumePath, "\\Device\\HarddiskVolume") != volumePath
                   5999:                        && AskNoYes ("ASK_REMOVE_DEVICE_WRITE_PROTECTION") == IDYES)
                   6000:                {
                   6001:                        RemoveDeviceWriteProtection (hwndDlg, volumePath);
                   6002:                }
                   6003:        }
                   6004: 
1.1.1.17  root     6005:        ResetWrongPwdRetryCount ();
                   6006: 
1.1.1.6   root     6007:        BroadcastDeviceChange (DBT_DEVICEARRIVAL, driveNo, 0);
1.1.1.5   root     6008: 
1.1.1.7   root     6009:        if (mount.bExclusiveAccess == FALSE)
1.1.1.5   root     6010:                return 2;
                   6011: 
                   6012:        return 1;
                   6013: }
                   6014: 
                   6015: 
1.1.1.11  root     6016: BOOL UnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount)
1.1.1.5   root     6017: {
                   6018:        int result;
                   6019:        BOOL forced = forceUnmount;
1.1.1.6   root     6020:        int dismountMaxRetries = UNMOUNT_MAX_AUTO_RETRIES;
1.1.1.5   root     6021: 
                   6022: retry:
1.1.1.11  root     6023:        BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, nDosDriveNo, 0);
                   6024: 
1.1.1.6   root     6025:        do
                   6026:        {
                   6027:                result = DriverUnmountVolume (hwndDlg, nDosDriveNo, forced);
                   6028: 
                   6029:                if (result == ERR_FILES_OPEN)
                   6030:                        Sleep (UNMOUNT_AUTO_RETRY_DELAY);
                   6031:                else
                   6032:                        break;
                   6033: 
                   6034:        } while (--dismountMaxRetries > 0);
1.1.1.5   root     6035: 
                   6036:        if (result != 0)
                   6037:        {
1.1.1.7   root     6038:                if (result == ERR_FILES_OPEN && !Silent)
1.1.1.5   root     6039:                {
1.1.1.12  root     6040:                        if (IDYES == AskWarnNoYes ("UNMOUNT_LOCK_FAILED"))
1.1.1.5   root     6041:                        {
                   6042:                                forced = TRUE;
                   6043:                                goto retry;
                   6044:                        }
                   6045: 
1.1.1.23! root     6046:                        if (IsOSAtLeast (WIN_7))
        !          6047:                        {
        !          6048:                                // Undo SHCNE_DRIVEREMOVED
        !          6049:                                char root[] = { (char) nDosDriveNo + 'A', ':', '\\', 0 };
        !          6050:                                SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL);
        !          6051:                        }
        !          6052: 
1.1.1.5   root     6053:                        return FALSE;
                   6054:                }
                   6055: 
1.1.1.7   root     6056:                Error ("UNMOUNT_FAILED");
1.1.1.5   root     6057: 
                   6058:                return FALSE;
                   6059:        } 
                   6060:        
1.1.1.6   root     6061:        BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0);
1.1.1.5   root     6062: 
                   6063:        return TRUE;
                   6064: }
                   6065: 
                   6066: 
                   6067: BOOL IsPasswordCacheEmpty (void)
                   6068: {
                   6069:        DWORD dw;
1.1.1.13  root     6070:        return !DeviceIoControl (hDriver, TC_IOCTL_GET_PASSWORD_CACHE_STATUS, 0, 0, 0, 0, &dw, 0);
1.1.1.5   root     6071: }
                   6072: 
1.1.1.15  root     6073: 
1.1.1.19  root     6074: BOOL IsMountedVolume (const char *volname)
1.1.1.5   root     6075: {
                   6076:        MOUNT_LIST_STRUCT mlist;
                   6077:        DWORD dwResult;
                   6078:        int i;
                   6079:        char volume[TC_MAX_PATH*2+16];
                   6080: 
                   6081:        strcpy (volume, volname);
1.1.1.7   root     6082: 
                   6083:        if (strstr (volname, "\\Device\\") != volname)
                   6084:                sprintf(volume, "\\??\\%s", volname);
                   6085:        ToUNICODE (volume);
1.1.1.5   root     6086: 
                   6087:        memset (&mlist, 0, sizeof (mlist));
1.1.1.13  root     6088:        DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
1.1.1.5   root     6089:                sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
                   6090:                NULL);
                   6091: 
                   6092:        for (i=0 ; i<26; i++)
1.1.1.19  root     6093:                if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume))
1.1.1.5   root     6094:                        return TRUE;
                   6095: 
                   6096:        return FALSE;
                   6097: }
                   6098: 
                   6099: 
1.1.1.12  root     6100: int GetMountedVolumeDriveNo (char *volname)
                   6101: {
                   6102:        MOUNT_LIST_STRUCT mlist;
                   6103:        DWORD dwResult;
                   6104:        int i;
                   6105:        char volume[TC_MAX_PATH*2+16];
                   6106: 
                   6107:        if (volname == NULL)
                   6108:                return -1;
                   6109: 
                   6110:        strcpy (volume, volname);
                   6111: 
                   6112:        if (strstr (volname, "\\Device\\") != volname)
                   6113:                sprintf(volume, "\\??\\%s", volname);
                   6114:        ToUNICODE (volume);
                   6115: 
                   6116:        memset (&mlist, 0, sizeof (mlist));
1.1.1.13  root     6117:        DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
1.1.1.12  root     6118:                sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
                   6119:                NULL);
                   6120: 
                   6121:        for (i=0 ; i<26; i++)
1.1.1.19  root     6122:                if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume))
1.1.1.12  root     6123:                        return i;
                   6124: 
                   6125:        return -1;
                   6126: }
                   6127: 
                   6128: 
1.1.1.5   root     6129: BOOL IsAdmin (void)
                   6130: {
1.1.1.11  root     6131:        return IsUserAnAdmin ();
                   6132: }
1.1.1.5   root     6133: 
                   6134: 
1.1.1.23! root     6135: BOOL IsBuiltInAdmin ()
        !          6136: {
        !          6137:        HANDLE procToken;
        !          6138:        DWORD size;
        !          6139: 
        !          6140:        if (!IsAdmin() || !OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &procToken))
        !          6141:                return FALSE;
        !          6142: 
        !          6143:        finally_do_arg (HANDLE, procToken, { CloseHandle (finally_arg); });
        !          6144: 
        !          6145:        if (GetTokenInformation (procToken, TokenUser, NULL, 0, &size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        !          6146:                return FALSE;
        !          6147: 
        !          6148:        TOKEN_USER *tokenUser = (TOKEN_USER *) malloc (size);
        !          6149:        if (!tokenUser)
        !          6150:                return FALSE;
        !          6151: 
        !          6152:        finally_do_arg (void *, tokenUser, { free (finally_arg); });
        !          6153: 
        !          6154:        if (!GetTokenInformation (procToken, TokenUser, tokenUser, size, &size))
        !          6155:                return FALSE;
        !          6156: 
        !          6157:        return IsWellKnownSid (tokenUser->User.Sid, WinAccountAdministratorSid);
        !          6158: }
        !          6159: 
        !          6160: 
1.1.1.11  root     6161: BOOL IsUacSupported ()
                   6162: {
                   6163:        HKEY hkey;
                   6164:        DWORD value = 1, size = sizeof (DWORD);
1.1.1.5   root     6165: 
1.1.1.21  root     6166:        if (!IsOSAtLeast (WIN_VISTA))
1.1.1.5   root     6167:                return FALSE;
                   6168: 
1.1.1.11  root     6169:        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
1.1.1.5   root     6170:        {
1.1.1.11  root     6171:                if (RegQueryValueEx (hkey, "EnableLUA", 0, 0, (LPBYTE) &value, &size) != ERROR_SUCCESS)
                   6172:                        value = 1;
1.1.1.5   root     6173: 
1.1.1.11  root     6174:                RegCloseKey (hkey);
1.1.1.5   root     6175:        }
                   6176: 
1.1.1.11  root     6177:        return value != 0;
1.1.1.5   root     6178: }
                   6179: 
                   6180: 
1.1.1.23! root     6181: BOOL ResolveSymbolicLink (const wchar_t *symLinkName, PWSTR targetName)
1.1.1.5   root     6182: {
                   6183:        BOOL bResult;
                   6184:        DWORD dwResult;
                   6185:        RESOLVE_SYMLINK_STRUCT resolve;
                   6186: 
                   6187:        memset (&resolve, 0, sizeof(resolve));
                   6188:        wcscpy ((PWSTR) &resolve.symLinkName, symLinkName);
                   6189: 
1.1.1.13  root     6190:        bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_RESOLVED_SYMLINK, &resolve,
1.1.1.5   root     6191:                sizeof (resolve), &resolve, sizeof (resolve), &dwResult,
                   6192:                NULL);
                   6193: 
                   6194:        wcscpy (targetName, (PWSTR) &resolve.targetName);
                   6195: 
                   6196:        return bResult;
                   6197: }
                   6198: 
                   6199: 
1.1.1.19  root     6200: BOOL GetPartitionInfo (const char *deviceName, PPARTITION_INFORMATION rpartInfo)
1.1.1.11  root     6201: {
                   6202:        BOOL bResult;
                   6203:        DWORD dwResult;
                   6204:        DISK_PARTITION_INFO_STRUCT dpi;
                   6205: 
                   6206:        memset (&dpi, 0, sizeof(dpi));
                   6207:        wsprintfW ((PWSTR) &dpi.deviceName, L"%hs", deviceName);
                   6208: 
1.1.1.13  root     6209:        bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_PARTITION_INFO, &dpi,
1.1.1.11  root     6210:                sizeof (dpi), &dpi, sizeof (dpi), &dwResult, NULL);
                   6211: 
                   6212:        memcpy (rpartInfo, &dpi.partInfo, sizeof (PARTITION_INFORMATION));
                   6213:        return bResult;
                   6214: }
                   6215: 
                   6216: 
1.1.1.19  root     6217: BOOL GetDeviceInfo (const char *deviceName, DISK_PARTITION_INFO_STRUCT *info)
                   6218: {
                   6219:        DWORD dwResult;
                   6220: 
                   6221:        memset (info, 0, sizeof(*info));
                   6222:        wsprintfW ((PWSTR) &info->deviceName, L"%hs", deviceName);
                   6223: 
                   6224:        return DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_PARTITION_INFO, info, sizeof (*info), info, sizeof (*info), &dwResult, NULL);
                   6225: }
                   6226: 
                   6227: 
                   6228: BOOL GetDriveGeometry (const char *deviceName, PDISK_GEOMETRY diskGeometry)
1.1.1.11  root     6229: {
                   6230:        BOOL bResult;
                   6231:        DWORD dwResult;
                   6232:        DISK_GEOMETRY_STRUCT dg;
                   6233: 
                   6234:        memset (&dg, 0, sizeof(dg));
                   6235:        wsprintfW ((PWSTR) &dg.deviceName, L"%hs", deviceName);
                   6236: 
1.1.1.13  root     6237:        bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_GEOMETRY, &dg,
1.1.1.11  root     6238:                sizeof (dg), &dg, sizeof (dg), &dwResult, NULL);
                   6239: 
                   6240:        memcpy (diskGeometry, &dg.diskGeometry, sizeof (DISK_GEOMETRY));
                   6241:        return bResult;
                   6242: }
                   6243: 
                   6244: 
1.1.1.5   root     6245: // Returns drive letter number assigned to device (-1 if none)
                   6246: int GetDiskDeviceDriveLetter (PWSTR deviceName)
                   6247: {
                   6248:        int i;
                   6249:        WCHAR link[MAX_PATH];
                   6250:        WCHAR target[MAX_PATH];
                   6251:        WCHAR device[MAX_PATH];
                   6252: 
                   6253:        if (!ResolveSymbolicLink (deviceName, device))
                   6254:                wcscpy (device, deviceName);
                   6255: 
                   6256:        for (i = 0; i < 26; i++)
                   6257:        {
1.1.1.23! root     6258:                WCHAR drive[] = { (WCHAR) i + 'A', ':', 0 };
1.1.1.5   root     6259: 
                   6260:                wcscpy (link, L"\\DosDevices\\");
                   6261:                wcscat (link, drive);
                   6262: 
                   6263:                ResolveSymbolicLink (link, target);
                   6264: 
                   6265:                if (wcscmp (device, target) == 0)
                   6266:                        return i;
                   6267:        }
                   6268: 
                   6269:        return -1;
                   6270: }
                   6271: 
                   6272: 
1.1.1.19  root     6273: // WARNING: This function does NOT provide 100% reliable results -- do NOT use it for critical/dangerous operations!
                   6274: // Return values: 0 - filesystem does not appear empty, 1 - filesystem appears empty, -1 - an error occurred
                   6275: int FileSystemAppearsEmpty (const char *devicePath)
                   6276: {
                   6277:        float percentFreeSpace = 0.0;
                   6278:        __int64 occupiedBytes = 0;
                   6279: 
                   6280:        if (GetStatsFreeSpaceOnPartition (devicePath, &percentFreeSpace, &occupiedBytes, TRUE) != -1)
                   6281:        {
                   6282:                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.
                   6283:                        || percentFreeSpace < 88)               // A 24-MB NTFS filesystem has 11.5% of space in use even if there are no files stored on it.
                   6284:                {
                   6285:                        return 0;
                   6286:                }
                   6287:                else
                   6288:                        return 1;
                   6289:        }
                   6290:        else
                   6291:                return -1;
                   6292: }
                   6293: 
                   6294: 
                   6295: // Returns the free space on the specified partition (volume) in bytes. If the 'occupiedBytes' pointer
                   6296: // is not NULL, size of occupied space (in bytes) is written to the pointed location. In addition, if the
                   6297: // 'percent' pointer is not NULL, % of free space is stored in the pointed location. If there's an error, 
                   6298: // returns -1.
                   6299: __int64 GetStatsFreeSpaceOnPartition (const char *devicePath, float *percentFree, __int64 *occupiedBytes, BOOL silent)
                   6300: {
                   6301:        WCHAR devPath [MAX_PATH];
                   6302:        int driveLetterNo = -1;
                   6303:        char szRootPath[4] = {0, ':', '\\', 0};
                   6304:        ULARGE_INTEGER freeSpaceSize;
                   6305:        ULARGE_INTEGER totalNumberOfBytes;
                   6306:        ULARGE_INTEGER totalNumberOfFreeBytes;
                   6307: 
                   6308:        strcpy ((char *) devPath, devicePath);
                   6309:        ToUNICODE ((char *) devPath);
                   6310: 
                   6311:        driveLetterNo = GetDiskDeviceDriveLetter (devPath);
1.1.1.23! root     6312:        szRootPath[0] = (char) driveLetterNo + 'A';
1.1.1.19  root     6313: 
                   6314: 
                   6315:        if (!GetDiskFreeSpaceEx (szRootPath, &freeSpaceSize, &totalNumberOfBytes, &totalNumberOfFreeBytes))
                   6316:        {
                   6317:                if (!silent)
                   6318:                {
                   6319:                        handleWin32Error (MainDlg);
                   6320:                        Error ("CANNOT_CALC_SPACE");
                   6321:                }
                   6322: 
                   6323:                return -1;
                   6324:        }
                   6325: 
                   6326: 
                   6327:        if (percentFree != NULL || occupiedBytes != NULL)
                   6328:        {
                   6329:                // Determine occupied space and % of free space
                   6330: 
                   6331:                PARTITION_INFORMATION partitionInfo;
                   6332: 
                   6333:                if (!GetPartitionInfo (devicePath, &partitionInfo))
                   6334:                {
                   6335:                        if (!silent)
                   6336:                        {
                   6337:                                handleWin32Error (MainDlg);
                   6338:                                Error ("CANT_GET_VOLSIZE");
                   6339:                        }
                   6340:                        return -1;
                   6341:                }
                   6342: 
                   6343:                if (occupiedBytes != NULL)
                   6344:                        *occupiedBytes = partitionInfo.PartitionLength.QuadPart - freeSpaceSize.QuadPart;
                   6345: 
                   6346:                if (percentFree != NULL)
                   6347:                        *percentFree = (float) ((double) freeSpaceSize.QuadPart / (double) partitionInfo.PartitionLength.QuadPart * 100.0);
                   6348:        }
                   6349: 
                   6350:        return freeSpaceSize.QuadPart;
                   6351: }
                   6352: 
                   6353: 
                   6354: // Returns -1 if there's an error.
                   6355: __int64 GetDeviceSize (const char *devicePath)
                   6356: {
                   6357:        PARTITION_INFORMATION partitionInfo;
                   6358: 
                   6359:        if (!GetPartitionInfo (devicePath, &partitionInfo))
                   6360:                return -1;
                   6361: 
                   6362:        return partitionInfo.PartitionLength.QuadPart;
                   6363: }
                   6364: 
                   6365: 
                   6366: HANDLE DismountDrive (char *devName, char *devicePath)
1.1.1.5   root     6367: {
                   6368:        DWORD dwResult;
                   6369:        HANDLE hVolume;
1.1.1.11  root     6370:        BOOL bResult = FALSE;
1.1.1.19  root     6371:        int attempt = UNMOUNT_MAX_AUTO_RETRIES;
                   6372:        int driveLetterNo = -1;
                   6373:        WCHAR devPath [MAX_PATH];
                   6374: 
                   6375:        strcpy ((char *) devPath, devicePath);
                   6376:        ToUNICODE ((char *) devPath);
                   6377:        driveLetterNo = GetDiskDeviceDriveLetter (devPath);
                   6378: 
1.1.1.5   root     6379: 
1.1.1.11  root     6380:        hVolume = CreateFile (devName, GENERIC_READ | GENERIC_WRITE,
                   6381:                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.5   root     6382: 
1.1.1.11  root     6383:        if (hVolume == INVALID_HANDLE_VALUE)
                   6384:                return INVALID_HANDLE_VALUE;
1.1.1.5   root     6385: 
1.1.1.19  root     6386: 
                   6387:        // Try to lock the volume first so that dismount is not forced. 
                   6388:        // If we fail, we will dismount anyway even if it needs to be forced.
                   6389: 
                   6390:        CloseVolumeExplorerWindows (MainDlg, driveLetterNo);
                   6391: 
                   6392:        while (!(bResult = DeviceIoControl (hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL)) 
                   6393:                && attempt > 0)
                   6394:        {
                   6395:                Sleep (UNMOUNT_AUTO_RETRY_DELAY);
                   6396:                attempt--;
                   6397:        }
                   6398: 
                   6399: 
                   6400:        // Try to dismount the volume
                   6401: 
                   6402:        attempt = UNMOUNT_MAX_AUTO_RETRIES;
                   6403: 
1.1.1.11  root     6404:        while (!(bResult = DeviceIoControl (hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL)) 
                   6405:                && attempt > 0)
                   6406:        {
                   6407:                Sleep (UNMOUNT_AUTO_RETRY_DELAY);
                   6408:                attempt--;
                   6409:        }
1.1.1.5   root     6410: 
1.1.1.11  root     6411:        if (!bResult)
                   6412:                CloseHandle (hVolume);
1.1.1.5   root     6413: 
1.1.1.11  root     6414:        return (bResult ? hVolume : INVALID_HANDLE_VALUE);
1.1.1.6   root     6415: }
                   6416: 
1.1.1.19  root     6417: // Returns -1 if the specified string is not found in the buffer. Otherwise, returns the
                   6418: // offset of the first occurrence of the string. The string and the buffer may contain zeroes, 
                   6419: // which do NOT terminate them.
                   6420: int64 FindString (const char *buf, const char *str, int64 bufLen, size_t strLen, int64 startOffset)
                   6421: {
                   6422:        if (buf == NULL 
                   6423:                || str == NULL 
                   6424:                || strLen > bufLen
                   6425:                || bufLen < 1
                   6426:                || strLen < 1
                   6427:                || startOffset > bufLen - strLen)
                   6428:        {
                   6429:                return -1;
                   6430:        }
                   6431: 
                   6432:        for (int64 i = startOffset; i < bufLen - strLen; i++)
                   6433:        {
                   6434:                if (memcmp (buf + i, str, strLen) == 0)
                   6435:                        return i;
                   6436:        }
                   6437: 
                   6438:        return -1;
                   6439: }
                   6440: 
1.1.1.13  root     6441: // Returns TRUE if the file exists (otherwise FALSE).
                   6442: BOOL FileExists (const char *filePathPtr)
                   6443: {
                   6444:        char filePath [TC_MAX_PATH];
                   6445: 
                   6446:        // Strip quotation marks (if any)
                   6447:        if (filePathPtr [0] == '"')
                   6448:        {
                   6449:                strcpy (filePath, filePathPtr + 1);
                   6450:        }
                   6451:        else
                   6452:        {
                   6453:                strcpy (filePath, filePathPtr);
                   6454:        }
                   6455: 
                   6456:        // Strip quotation marks (if any)
                   6457:        if (filePath [strlen (filePath) - 1] == '"')
                   6458:                filePath [strlen (filePath) - 1] = 0;
                   6459: 
                   6460:     return (_access (filePath, 0) != -1);
                   6461: }
                   6462: 
                   6463: // Searches the file from its end for the LAST occurrence of the string str.
                   6464: // The string may contain zeroes, which do NOT terminate the string.
                   6465: // If the string is found, its offset from the start of the file is returned. 
                   6466: // If the string isn't found or if any error occurs, -1 is returned.
1.1.1.19  root     6467: __int64 FindStringInFile (const char *filePath, const char* str, int strLen)
1.1.1.13  root     6468: {
                   6469:        int bufSize = 64 * BYTES_PER_KB;
1.1.1.15  root     6470:        char *buffer = (char *) malloc (bufSize);
1.1.1.13  root     6471:        HANDLE src = NULL;
                   6472:        DWORD bytesRead;
                   6473:        BOOL readRetVal;
                   6474:        __int64 filePos = GetFileSize64 (filePath);
                   6475:        int bufPos = 0;
                   6476:        LARGE_INTEGER seekOffset, seekOffsetNew;
                   6477:        BOOL bExit = FALSE;
                   6478:        int filePosStep;
                   6479:        __int64 retVal = -1;
                   6480: 
                   6481:        if (filePos <= 0 
                   6482:                || buffer == NULL 
                   6483:                || strLen > bufSize
                   6484:                || strLen < 1)
                   6485:                return -1;
                   6486: 
                   6487:        src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   6488: 
                   6489:        if (src == INVALID_HANDLE_VALUE)
                   6490:        {
                   6491:                free (buffer);
                   6492:                return -1;
                   6493:        }
                   6494: 
                   6495:        filePosStep = bufSize - strLen + 1;
                   6496: 
                   6497:        do
                   6498:        {
                   6499:                filePos -= filePosStep;
                   6500: 
                   6501:                if (filePos < 0)
                   6502:                {
                   6503:                        filePos = 0;
                   6504:                        bExit = TRUE;
                   6505:                }
                   6506: 
                   6507:                seekOffset.QuadPart = filePos;
                   6508: 
                   6509:                if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
                   6510:                        goto fsif_end;
                   6511: 
                   6512:                if ((readRetVal = ReadFile (src, buffer, bufSize, &bytesRead, NULL)) == 0 
                   6513:                        || bytesRead == 0)
                   6514:                        goto fsif_end;
                   6515: 
                   6516:                bufPos = bytesRead - strLen;
                   6517: 
                   6518:                while (bufPos > 0)
                   6519:                {
                   6520:                        if (memcmp (buffer + bufPos, str, strLen) == 0)
                   6521:                        {
                   6522:                                // String found
                   6523:                                retVal = filePos + bufPos;
                   6524:                                goto fsif_end;
                   6525:                        }
                   6526:                        bufPos--;
                   6527:                }
                   6528: 
                   6529:        } while (!bExit);
                   6530: 
                   6531: fsif_end:
                   6532:        CloseHandle (src);
                   6533:        free (buffer);
                   6534: 
                   6535:        return retVal;
                   6536: }
1.1.1.11  root     6537: 
1.1.1.6   root     6538: // System CopyFile() copies source file attributes (like FILE_ATTRIBUTE_ENCRYPTED)
                   6539: // so we need to use our own copy function
                   6540: BOOL TCCopyFile (char *sourceFileName, char *destinationFile)
                   6541: {
                   6542:        __int8 *buffer;
                   6543:        HANDLE src, dst;
                   6544:        FILETIME fileTime;
                   6545:        DWORD bytesRead, bytesWritten;
                   6546:        BOOL res;
                   6547: 
                   6548:        src = CreateFile (sourceFileName,
                   6549:                GENERIC_READ,
                   6550:                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   6551: 
                   6552:        if (src == INVALID_HANDLE_VALUE)
                   6553:                return FALSE;
                   6554: 
                   6555:        dst = CreateFile (destinationFile,
                   6556:                GENERIC_WRITE,
                   6557:                0, NULL, CREATE_ALWAYS, 0, NULL);
                   6558: 
                   6559:        if (dst == INVALID_HANDLE_VALUE)
                   6560:        {
                   6561:                CloseHandle (src);
                   6562:                return FALSE;
                   6563:        }
                   6564: 
1.1.1.15  root     6565:        buffer = (char *) malloc (64 * 1024);
1.1.1.6   root     6566:        if (!buffer)
                   6567:        {
                   6568:                CloseHandle (src);
                   6569:                CloseHandle (dst);
                   6570:                return FALSE;
                   6571:        }
                   6572: 
                   6573:        while (res = ReadFile (src, buffer, 64 * 1024, &bytesRead, NULL))
                   6574:        {
                   6575:                if (bytesRead == 0)
                   6576:                {
                   6577:                        res = 1;
                   6578:                        break;
                   6579:                }
                   6580: 
                   6581:                if (!WriteFile (dst, buffer, bytesRead, &bytesWritten, NULL)
                   6582:                        || bytesRead != bytesWritten)
                   6583:                {
                   6584:                        res = 0;
                   6585:                        break;
                   6586:                }
                   6587:        }
                   6588: 
                   6589:        GetFileTime (src, NULL, NULL, &fileTime);
                   6590:        SetFileTime (dst, NULL, NULL, &fileTime);
                   6591: 
                   6592:        CloseHandle (src);
                   6593:        CloseHandle (dst);
                   6594: 
                   6595:        free (buffer);
                   6596:        return res != 0;
                   6597: }
                   6598: 
1.1.1.15  root     6599: // If bAppend is TRUE, the buffer is appended to an existing file. If bAppend is FALSE, any existing file 
                   6600: // is replaced. If an error occurs, the incomplete file is deleted (provided that bAppend is FALSE).
1.1.1.13  root     6601: BOOL SaveBufferToFile (char *inputBuffer, char *destinationFile, DWORD inputLength, BOOL bAppend)
                   6602: {
                   6603:        HANDLE dst;
                   6604:        DWORD bytesWritten;
                   6605:        BOOL res = TRUE;
                   6606: 
                   6607:        dst = CreateFile (destinationFile,
                   6608:                GENERIC_WRITE,
                   6609:                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
                   6610: 
                   6611:        if (dst == INVALID_HANDLE_VALUE)
                   6612:        {
                   6613:                handleWin32Error (MainDlg);
                   6614:                return FALSE;
                   6615:        }
                   6616: 
                   6617:        if (bAppend)
                   6618:                SetFilePointer (dst, 0, NULL, FILE_END);
                   6619: 
                   6620:        if (!WriteFile (dst, inputBuffer, inputLength, &bytesWritten, NULL)
                   6621:                || inputLength != bytesWritten)
                   6622:        {
                   6623:                res = FALSE;
                   6624:        }
                   6625: 
                   6626:        if (!res)
                   6627:        {
                   6628:                // If CREATE_ALWAYS is used, ERROR_ALREADY_EXISTS is returned after successful overwrite
                   6629:                // of an existing file (it's not an error)
                   6630:                if (! (GetLastError() == ERROR_ALREADY_EXISTS && !bAppend) )    
                   6631:                        handleWin32Error (MainDlg);
                   6632:        }
                   6633: 
                   6634:        CloseHandle (dst);
                   6635:        FlushFileBuffers (dst);
                   6636: 
                   6637:        if (!res && !bAppend)
                   6638:                remove (destinationFile);
                   6639: 
                   6640:        return res;
                   6641: }
                   6642: 
1.1.1.17  root     6643: 
                   6644: // Proper flush for Windows systems. Returns TRUE if successful.
                   6645: BOOL TCFlushFile (FILE *f)
                   6646: {
                   6647:        HANDLE hf = (HANDLE) _get_osfhandle (_fileno (f));
                   6648: 
                   6649:        fflush (f);
                   6650: 
                   6651:        if (hf == INVALID_HANDLE_VALUE)
                   6652:                return FALSE;
                   6653: 
                   6654:        return FlushFileBuffers (hf) != 0;
                   6655: }
                   6656: 
                   6657: 
1.1.1.13  root     6658: // Prints a UTF-16 text (note that this involves a real printer, not a screen).
                   6659: // textByteLen - length of the text in bytes
                   6660: // title - printed as part of the page header and used as the filename for a temporary file 
                   6661: BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, int textByteLen)
                   6662: {
                   6663:        char cl [MAX_PATH*3] = {"/p \""};
                   6664:        char path [MAX_PATH * 2] = { 0 };
                   6665:        char filename [MAX_PATH + 1] = { 0 };
                   6666: 
                   6667:        strcpy (filename, title);
                   6668:        //strcat (filename, ".txt");
                   6669: 
                   6670:        GetTempPath (sizeof (path), path);
                   6671: 
                   6672:        if (!FileExists (path))
                   6673:        {
                   6674:                strcpy (path, GetConfigPath (filename));
                   6675: 
                   6676:                if (strlen(path) < 2)
                   6677:                        return FALSE;
                   6678:        }
                   6679:        else
                   6680:        {
                   6681:                strcat (path, filename);
                   6682:        }
                   6683: 
                   6684:        // Write the Unicode signature
                   6685:        if (!SaveBufferToFile ("\xFF\xFE", path, 2, FALSE))
                   6686:        {
                   6687:                remove (path);
                   6688:                return FALSE;
                   6689:        }
                   6690: 
                   6691:        // Write the actual text
                   6692:        if (!SaveBufferToFile ((char *) text, path, textByteLen, TRUE))
                   6693:        {
                   6694:                remove (path);
                   6695:                return FALSE;
                   6696:        }
                   6697: 
                   6698:        strcat (cl, path);
                   6699:        strcat (cl, "\"");
                   6700: 
                   6701:        WaitCursor ();
                   6702:        ShellExecute (NULL, "open", PRINT_TOOL, cl, NULL, SW_HIDE);
                   6703:        Sleep (6000);
                   6704:        NormalCursor();
                   6705: 
                   6706:        remove (path);
                   6707: 
                   6708:        return TRUE;
                   6709: }
                   6710: 
                   6711: 
1.1.1.17  root     6712: BOOL IsNonInstallMode ()
1.1.1.7   root     6713: {
1.1.1.17  root     6714:        HKEY hkey;
                   6715:        DWORD dw;
1.1.1.13  root     6716: 
1.1.1.23! root     6717:        if (bPortableModeConfirmed)
1.1.1.17  root     6718:                return TRUE;
1.1.1.7   root     6719: 
1.1.1.17  root     6720:        if (hDriver != INVALID_HANDLE_VALUE)
1.1.1.7   root     6721:        {
1.1.1.17  root     6722:                // The driver is running
1.1.1.23! root     6723:                if (DeviceIoControl (hDriver, TC_IOCTL_GET_PORTABLE_MODE_STATUS, NULL, 0, NULL, 0, &dw, 0))
1.1.1.17  root     6724:                {
1.1.1.23! root     6725:                        bPortableModeConfirmed = TRUE;
1.1.1.17  root     6726:                        return TRUE;
                   6727:                }
                   6728:                else
                   6729:                {
1.1.1.23! root     6730:                        // This is also returned if we fail to determine the status (it does not mean that portable mode is disproved).
1.1.1.17  root     6731:                        return FALSE;   
                   6732:                }
1.1.1.7   root     6733:        }
1.1.1.17  root     6734:        else
                   6735:        {
                   6736:                // The tests in this block are necessary because this function is in some cases called before DriverAttach().
1.1.1.7   root     6737: 
1.1.1.17  root     6738:                HANDLE hDriverTmp = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.7   root     6739: 
1.1.1.17  root     6740:                if (hDriverTmp == INVALID_HANDLE_VALUE)
                   6741:                {
                   6742:                        // The driver was not found in the system path
1.1.1.7   root     6743: 
1.1.1.17  root     6744:                        char path[MAX_PATH * 2] = { 0 };
1.1.1.7   root     6745: 
1.1.1.17  root     6746:                        // We can't use GetConfigPath() here because it would call us back (indirect recursion)
1.1.1.18  root     6747:                        if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path)))
1.1.1.17  root     6748:                        {
                   6749:                                strcat (path, "\\TrueCrypt\\");
1.1.1.19  root     6750:                                strcat (path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION);
1.1.1.7   root     6751: 
1.1.1.17  root     6752:                                if (FileExists (path))
                   6753:                                {
                   6754:                                        // To maintain consistency and safety, if the system encryption config file exits, we cannot
1.1.1.23! root     6755:                                        // allow portable mode. (This happens e.g. when the pretest fails and the user selects 
1.1.1.17  root     6756:                                        // "Last Known Good Configuration" from the Windows boot menu.)
1.1.1.7   root     6757: 
1.1.1.23! root     6758:                                        // However, if UAC elevation is needed, we have to confirm portable mode first (after we are elevated, we won't).
1.1.1.17  root     6759:                                        if (!IsAdmin () && IsUacSupported ())
                   6760:                                                return TRUE;
1.1.1.7   root     6761: 
1.1.1.17  root     6762:                                        return FALSE;
                   6763:                                }
                   6764:                        }
1.1.1.7   root     6765: 
1.1.1.23! root     6766:                        // As the driver was not found in the system path, we can predict that we will run in portable mode
1.1.1.17  root     6767:                        return TRUE;    
                   6768:                }
                   6769:                else
                   6770:                        CloseHandle (hDriverTmp);
1.1.1.7   root     6771:        }
                   6772: 
1.1.1.17  root     6773:        // The following test may be unreliable in some cases (e.g. after the user selects restore "Last Known Good
                   6774:        // Configuration" from the Windows boot menu).
                   6775:        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\TrueCrypt", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
1.1.1.7   root     6776:        {
1.1.1.11  root     6777:                RegCloseKey (hkey);
                   6778:                return FALSE;
1.1.1.7   root     6779:        }
1.1.1.15  root     6780:        else
                   6781:                return TRUE;
1.1.1.6   root     6782: }
                   6783: 
                   6784: 
1.1.1.7   root     6785: LRESULT SetCheckBox (HWND hwndDlg, int dlgItem, BOOL state)
1.1.1.6   root     6786: {
1.1.1.7   root     6787:        return SendDlgItemMessage (hwndDlg, dlgItem, BM_SETCHECK, state ? BST_CHECKED : BST_UNCHECKED, 0);
                   6788: }
1.1.1.6   root     6789: 
1.1.1.7   root     6790: 
                   6791: BOOL GetCheckBox (HWND hwndDlg, int dlgItem)
                   6792: {
                   6793:        return IsButtonChecked (GetDlgItem (hwndDlg, dlgItem));
                   6794: }
                   6795: 
                   6796: 
1.1.1.13  root     6797: // Adds or removes TrueCrypt.exe to/from the system startup sequence (with appropriate command line arguments)
                   6798: void ManageStartupSeq (void)
                   6799: {
                   6800:        if (!IsNonInstallMode ())
                   6801:        {
                   6802:                char regk [64];
                   6803: 
                   6804:                // Split the string in order to prevent some antivirus packages from falsely reporting  
                   6805:                // TrueCrypt.exe to contain a possible Trojan horse because of this string (heuristic scan).
                   6806:                sprintf (regk, "%s%s", "Software\\Microsoft\\Windows\\Curren", "tVersion\\Run");
                   6807: 
1.1.1.19  root     6808:                if (bStartOnLogon || bMountDevicesOnLogon || bMountFavoritesOnLogon)
1.1.1.13  root     6809:                {
                   6810:                        char exe[MAX_PATH * 2] = { '"' };
                   6811: 
                   6812:                        GetModuleFileName (NULL, exe + 1, sizeof (exe) - 1);
                   6813: 
                   6814: #ifdef VOLFORMAT
                   6815:                        {
                   6816:                                char *tmp = NULL;
                   6817: 
                   6818:                                if (tmp = strrchr (exe, '\\'))
                   6819:                                        strcpy (++tmp, "TrueCrypt.exe");
                   6820:                        }
                   6821: #endif
                   6822:                        strcat (exe, "\" /q preferences");
                   6823: 
                   6824:                        if (bMountDevicesOnLogon) strcat (exe, " /a devices");
                   6825:                        if (bMountFavoritesOnLogon) strcat (exe, " /a favorites");
                   6826: 
                   6827:                        WriteRegistryString (regk, "TrueCrypt", exe);
                   6828:                }
                   6829:                else
                   6830:                        DeleteRegistryValue (regk, "TrueCrypt");
                   6831:        }
                   6832: }
                   6833: 
                   6834: 
1.1.1.21  root     6835: // Adds or removes the TrueCrypt Volume Creation Wizard to/from the system startup sequence
                   6836: void ManageStartupSeqWiz (BOOL bRemove, const char *arg)
                   6837: {
                   6838:        char regk [64];
                   6839: 
                   6840:        // Split this string in order to prevent some low-quality antivirus software from falsely reporting  
                   6841:        // our .exe files to contain a possible Trojan horse because of this string (heuristic scan).
                   6842:        sprintf (regk, "%s%s", "Software\\Microsoft\\Windows\\Curren", "tVersion\\Run");
                   6843: 
                   6844:        if (!bRemove)
                   6845:        {
                   6846:                char exe[MAX_PATH * 2] = { '"' };
                   6847:                GetModuleFileName (NULL, exe + 1, sizeof (exe) - 1);
                   6848: 
                   6849: #ifndef VOLFORMAT
                   6850:                        {
                   6851:                                char *tmp = NULL;
                   6852: 
                   6853:                                if (tmp = strrchr (exe, '\\'))
                   6854:                                        strcpy (++tmp, "TrueCrypt Format.exe");
                   6855:                        }
                   6856: #endif
                   6857: 
                   6858:                if (strlen (arg) > 0)
                   6859:                {
                   6860:                        strcat (exe, "\" ");
                   6861:                        strcat (exe, arg);
                   6862:                }
                   6863: 
                   6864:                WriteRegistryString (regk, "TrueCrypt Format", exe);
                   6865:        }
                   6866:        else
                   6867:                DeleteRegistryValue (regk, "TrueCrypt Format");
                   6868: }
                   6869: 
                   6870: 
1.1.1.11  root     6871: // Delete the last used Windows file selector path for TrueCrypt from the registry
1.1.1.7   root     6872: void CleanLastVisitedMRU (void)
                   6873: {
                   6874:        WCHAR exeFilename[MAX_PATH];
                   6875:        WCHAR *strToMatch;
                   6876: 
1.1.1.11  root     6877:        WCHAR strTmp[4096];
                   6878:        char regPath[128];
                   6879:        char key[64];
                   6880:        int id, len;
1.1.1.7   root     6881: 
1.1.1.15  root     6882:        GetModuleFileNameW (NULL, exeFilename, sizeof (exeFilename) / sizeof(exeFilename[0]));
1.1.1.7   root     6883:        strToMatch = wcsrchr (exeFilename, '\\') + 1;
                   6884: 
1.1.1.21  root     6885:        sprintf (regPath, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisited%sMRU", IsOSAtLeast (WIN_VISTA) ? "Pidl" : "");
1.1.1.11  root     6886: 
1.1.1.21  root     6887:        for (id = (IsOSAtLeast (WIN_VISTA) ? 0 : 'a'); id <= (IsOSAtLeast (WIN_VISTA) ? 1000 : 'z'); id++)
1.1.1.6   root     6888:        {
1.1.1.7   root     6889:                *strTmp = 0;
1.1.1.21  root     6890:                sprintf (key, (IsOSAtLeast (WIN_VISTA) ? "%d" : "%c"), id);
1.1.1.11  root     6891: 
                   6892:                if ((len = ReadRegistryBytes (regPath, key, (char *) strTmp, sizeof (strTmp))) > 0)
1.1.1.6   root     6893:                {
1.1.1.11  root     6894:                        if (_wcsicmp (strTmp, strToMatch) == 0) 
1.1.1.7   root     6895:                        {
1.1.1.11  root     6896:                                char buf[65536], bufout[sizeof (buf)];
                   6897: 
1.1.1.7   root     6898:                                // Overwrite the entry with zeroes while keeping its original size
                   6899:                                memset (strTmp, 0, len);
1.1.1.11  root     6900:                                if (!WriteRegistryBytes (regPath, key, (char *) strTmp, len))
1.1.1.7   root     6901:                                        MessageBoxW (NULL, GetString ("CLEAN_WINMRU_FAILED"), lpszTitle, ICON_HAND);
                   6902: 
1.1.1.11  root     6903:                                DeleteRegistryValue (regPath, key);
                   6904: 
                   6905:                                // Remove ID from MRUList
1.1.1.21  root     6906:                                if (IsOSAtLeast (WIN_VISTA))
1.1.1.11  root     6907:                                {
                   6908:                                        int *p = (int *)buf;
                   6909:                                        int *pout = (int *)bufout;
                   6910:                                        int l;
                   6911: 
                   6912:                                        l = len = ReadRegistryBytes ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", "MRUListEx", buf, sizeof (buf));
                   6913:                                        while (l > 0)
                   6914:                                        {
                   6915:                                                l -= sizeof (int);
                   6916: 
                   6917:                                                if (*p == id)
                   6918:                                                {
                   6919:                                                        p++;
                   6920:                                                        len -= sizeof (int);
                   6921:                                                        continue;
                   6922:                                                }
                   6923:                                                *pout++ = *p++;
                   6924:                                        }
                   6925: 
                   6926:                                        WriteRegistryBytes ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", "MRUListEx", bufout, len);
                   6927:                                }
                   6928:                                else
                   6929:                                {
                   6930:                                        char *p = buf;
                   6931:                                        char *pout = bufout;
                   6932: 
                   6933:                                        ReadRegistryString ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", "MRUList", "", buf, sizeof (buf));
                   6934:                                        while (*p)
                   6935:                                        {
                   6936:                                                if (*p == id)
                   6937:                                                {
                   6938:                                                        p++;
                   6939:                                                        continue;
                   6940:                                                }
                   6941:                                                *pout++ = *p++;
                   6942:                                        }
                   6943:                                        *pout++ = 0;
                   6944: 
                   6945:                                        WriteRegistryString ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", "MRUList", bufout);
                   6946:                                }
                   6947: 
                   6948:                                break;
1.1.1.7   root     6949:                        }
                   6950:                }
                   6951:        }
                   6952: }
1.1.1.6   root     6953: 
                   6954: 
1.1.1.11  root     6955: #ifndef SETUP
                   6956: void ClearHistory (HWND hwndDlgItem)
                   6957: {
                   6958:        ArrowWaitCursor ();
                   6959: 
                   6960:        ClearCombo (hwndDlgItem);
                   6961:        DumpCombo (hwndDlgItem, TRUE);
                   6962: 
                   6963:        CleanLastVisitedMRU ();
                   6964: 
                   6965:        NormalCursor ();
                   6966: }
                   6967: #endif // #ifndef SETUP
                   6968: 
                   6969: 
1.1.1.7   root     6970: LRESULT ListItemAdd (HWND list, int index, char *string)
                   6971: {
                   6972:        LVITEM li;
                   6973:        memset (&li, 0, sizeof(li));
1.1.1.6   root     6974: 
1.1.1.7   root     6975:        li.mask = LVIF_TEXT;
                   6976:        li.pszText = string;
                   6977:        li.iItem = index; 
                   6978:        li.iSubItem = 0;
                   6979:        return ListView_InsertItem (list, &li);
                   6980: }
1.1.1.6   root     6981: 
1.1.1.7   root     6982: 
                   6983: LRESULT ListItemAddW (HWND list, int index, wchar_t *string)
                   6984: {
                   6985:        LVITEMW li;
                   6986:        memset (&li, 0, sizeof(li));
                   6987: 
                   6988:        li.mask = LVIF_TEXT;
                   6989:        li.pszText = string;
                   6990:        li.iItem = index; 
                   6991:        li.iSubItem = 0;
                   6992:        return SendMessageW (list, LVM_INSERTITEMW, 0, (LPARAM)(&li));
                   6993: }
                   6994: 
                   6995: 
                   6996: LRESULT ListSubItemSet (HWND list, int index, int subIndex, char *string)
                   6997: {
                   6998:        LVITEM li;
                   6999:        memset (&li, 0, sizeof(li));
                   7000: 
                   7001:        li.mask = LVIF_TEXT;
                   7002:        li.pszText = string;
                   7003:        li.iItem = index; 
                   7004:        li.iSubItem = subIndex;
                   7005:        return ListView_SetItem (list, &li);
                   7006: }
                   7007: 
                   7008: 
                   7009: LRESULT ListSubItemSetW (HWND list, int index, int subIndex, wchar_t *string)
                   7010: {
                   7011:        LVITEMW li;
                   7012:        memset (&li, 0, sizeof(li));
                   7013: 
                   7014:        li.mask = LVIF_TEXT;
                   7015:        li.pszText = string;
                   7016:        li.iItem = index; 
                   7017:        li.iSubItem = subIndex;
                   7018:        return SendMessageW (list, LVM_SETITEMW, 0, (LPARAM)(&li));
                   7019: }
                   7020: 
                   7021: 
                   7022: BOOL GetMountList (MOUNT_LIST_STRUCT *list)
                   7023: {
                   7024:        DWORD dwResult;
                   7025: 
                   7026:        memset (list, 0, sizeof (*list));
1.1.1.13  root     7027:        return DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, list,
1.1.1.7   root     7028:                sizeof (*list), list, sizeof (*list), &dwResult,
                   7029:                NULL);
                   7030: }
                   7031: 
                   7032: 
                   7033: int GetDriverRefCount ()
                   7034: {
                   7035:        DWORD dwResult;
                   7036:        BOOL bResult;
                   7037:        int refCount;
                   7038: 
1.1.1.13  root     7039:        bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DEVICE_REFCOUNT, &refCount, sizeof (refCount), &refCount,
1.1.1.7   root     7040:                sizeof (refCount), &dwResult, NULL);
                   7041: 
                   7042:        if (bResult)
                   7043:                return refCount;
                   7044:        else
                   7045:                return -1;
                   7046: }
                   7047: 
1.1.1.13  root     7048: // Loads a 32-bit integer from the file at the specified file offset. The saved value is assumed to have been
                   7049: // processed by mputLong(). The result is stored in *result. Returns TRUE if successful (otherwise FALSE).
                   7050: BOOL LoadInt32 (char *filePath, unsigned __int32 *result, __int64 fileOffset)
                   7051: {
1.1.1.23! root     7052:        size_t bufSize = sizeof(__int32);
1.1.1.15  root     7053:        unsigned char *buffer = (unsigned char *) malloc (bufSize);
1.1.1.13  root     7054:        unsigned char *bufferPtr = buffer;
                   7055:        HANDLE src = NULL;
                   7056:        DWORD bytesRead;
                   7057:        LARGE_INTEGER seekOffset, seekOffsetNew;
                   7058:        BOOL retVal = FALSE;
                   7059: 
                   7060:        if (buffer == NULL)
                   7061:                return -1;
                   7062: 
                   7063:        src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   7064: 
                   7065:        if (src == INVALID_HANDLE_VALUE)
                   7066:        {
                   7067:                free (buffer);
                   7068:                return FALSE;
                   7069:        }
                   7070: 
                   7071:        seekOffset.QuadPart = fileOffset;
                   7072: 
                   7073:        if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
                   7074:                goto fsif_end;
                   7075: 
                   7076:        if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0 
                   7077:                || bytesRead != bufSize)
                   7078:                goto fsif_end;
                   7079: 
                   7080: 
                   7081:        retVal = TRUE;
                   7082: 
                   7083:        *result = mgetLong(bufferPtr);
                   7084: 
                   7085: fsif_end:
                   7086:        CloseHandle (src);
                   7087:        free (buffer);
                   7088: 
                   7089:        return retVal;
                   7090: }
                   7091: 
                   7092: // Loads a 16-bit integer from the file at the specified file offset. The saved value is assumed to have been
                   7093: // processed by mputWord(). The result is stored in *result. Returns TRUE if successful (otherwise FALSE).
                   7094: BOOL LoadInt16 (char *filePath, int *result, __int64 fileOffset)
                   7095: {
1.1.1.23! root     7096:        size_t bufSize = sizeof(__int16);
1.1.1.15  root     7097:        unsigned char *buffer = (unsigned char *) malloc (bufSize);
1.1.1.13  root     7098:        unsigned char *bufferPtr = buffer;
                   7099:        HANDLE src = NULL;
                   7100:        DWORD bytesRead;
                   7101:        LARGE_INTEGER seekOffset, seekOffsetNew;
                   7102:        BOOL retVal = FALSE;
                   7103: 
                   7104:        if (buffer == NULL)
                   7105:                return -1;
                   7106: 
                   7107:        src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   7108: 
                   7109:        if (src == INVALID_HANDLE_VALUE)
                   7110:        {
                   7111:                free (buffer);
                   7112:                return FALSE;
                   7113:        }
                   7114: 
                   7115:        seekOffset.QuadPart = fileOffset;
                   7116: 
                   7117:        if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
                   7118:                goto fsif_end;
                   7119: 
                   7120:        if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0 
                   7121:                || bytesRead != bufSize)
                   7122:                goto fsif_end;
                   7123: 
1.1.1.7   root     7124: 
1.1.1.13  root     7125:        retVal = TRUE;
                   7126: 
                   7127:        *result = mgetWord(bufferPtr);
                   7128: 
                   7129: fsif_end:
                   7130:        CloseHandle (src);
                   7131:        free (buffer);
                   7132: 
                   7133:        return retVal;
                   7134: }
                   7135: 
1.1.1.19  root     7136: // Returns NULL if there's any error. Although the buffer can contain binary data, it is always null-terminated.
                   7137: char *LoadFile (const char *fileName, DWORD *size)
1.1.1.7   root     7138: {
                   7139:        char *buf;
1.1.1.13  root     7140:        HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.7   root     7141:        if (h == INVALID_HANDLE_VALUE)
                   7142:                return NULL;
                   7143: 
                   7144:        *size = GetFileSize (h, NULL);
1.1.1.15  root     7145:        buf = (char *) malloc (*size + 1);
1.1.1.13  root     7146: 
                   7147:        if (buf == NULL)
                   7148:        {
                   7149:                CloseHandle (h);
                   7150:                return NULL;
                   7151:        }
                   7152: 
1.1.1.7   root     7153:        ZeroMemory (buf, *size + 1);
                   7154: 
1.1.1.13  root     7155:        if (!ReadFile (h, buf, *size, size, NULL))
                   7156:        {
                   7157:                free (buf);
                   7158:                buf = NULL;
                   7159:        }
                   7160: 
                   7161:        CloseHandle (h);
                   7162:        return buf;
                   7163: }
                   7164: 
                   7165: 
                   7166: // Returns NULL if there's any error.
1.1.1.23! root     7167: char *LoadFileBlock (char *fileName, __int64 fileOffset, size_t count)
1.1.1.13  root     7168: {
                   7169:        char *buf;
                   7170:        DWORD bytesRead = 0;
                   7171:        LARGE_INTEGER seekOffset, seekOffsetNew;
                   7172: 
                   7173:        HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   7174:        if (h == INVALID_HANDLE_VALUE)
                   7175:                return NULL;
                   7176: 
                   7177:        seekOffset.QuadPart = fileOffset;
                   7178: 
                   7179:        if (SetFilePointerEx (h, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
                   7180:        {
                   7181:                CloseHandle (h);
                   7182:                return NULL;
                   7183:        }
                   7184: 
1.1.1.15  root     7185:        buf = (char *) malloc (count);
1.1.1.13  root     7186: 
                   7187:        if (buf == NULL)
                   7188:        {
                   7189:                CloseHandle (h);
                   7190:                return NULL;
                   7191:        }
                   7192:  
                   7193:        ZeroMemory (buf, count);
                   7194: 
1.1.1.7   root     7195:        if (buf != NULL)
1.1.1.13  root     7196:                ReadFile (h, buf, count, &bytesRead, NULL);
1.1.1.7   root     7197: 
                   7198:        CloseHandle (h);
1.1.1.13  root     7199: 
                   7200:        if (bytesRead != count)
                   7201:        {
                   7202:                free (buf);
                   7203:                return NULL;
                   7204:        }
                   7205: 
1.1.1.7   root     7206:        return buf;
                   7207: }
                   7208: 
                   7209: 
1.1.1.13  root     7210: // Returns -1 if there is an error, or the size of the file.
1.1.1.19  root     7211: __int64 GetFileSize64 (const char *path)
1.1.1.13  root     7212: {
                   7213:        HANDLE h = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   7214:        LARGE_INTEGER size;
                   7215: 
                   7216:        if (h == INVALID_HANDLE_VALUE)
                   7217:                return -1;
                   7218: 
                   7219:        if (GetFileSizeEx (h, &size) == 0)
                   7220:                return -1;
                   7221: 
                   7222:        CloseHandle (h);
                   7223: 
                   7224:        return size.QuadPart;
                   7225: }
                   7226: 
                   7227: 
1.1.1.11  root     7228: char *GetModPath (char *path, int maxSize)
1.1.1.10  root     7229: {
                   7230:        GetModuleFileName (NULL, path, maxSize);
                   7231:        strrchr (path, '\\')[1] = 0;
                   7232:        return path;
                   7233: }
                   7234: 
                   7235: 
1.1.1.7   root     7236: char *GetConfigPath (char *fileName)
                   7237: {
1.1.1.10  root     7238:        static char path[MAX_PATH * 2] = { 0 };
1.1.1.11  root     7239: 
                   7240:        if (IsNonInstallMode ())
1.1.1.12  root     7241:        {
                   7242:                GetModPath (path, sizeof (path));
                   7243:                strcat (path, fileName);
                   7244: 
1.1.1.11  root     7245:                return path;
1.1.1.12  root     7246:        }
1.1.1.7   root     7247: 
1.1.1.12  root     7248:        if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path)))
1.1.1.7   root     7249:        {
                   7250:                strcat (path, "\\TrueCrypt\\");
                   7251:                CreateDirectory (path, NULL);
                   7252:                strcat (path, fileName);
                   7253:        }
                   7254:        else
1.1.1.12  root     7255:                path[0] = 0;
1.1.1.7   root     7256: 
                   7257:        return path;
                   7258: }
                   7259: 
1.1.1.23! root     7260: 
        !          7261: char *GetProgramConfigPath (char *fileName)
        !          7262: {
        !          7263:        static char path[MAX_PATH * 2] = { 0 };
        !          7264: 
        !          7265:        if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path)))
        !          7266:        {
        !          7267:                strcat (path, "\\TrueCrypt\\");
        !          7268:                CreateDirectory (path, NULL);
        !          7269:                strcat (path, fileName);
        !          7270:        }
        !          7271:        else
        !          7272:                path[0] = 0;
        !          7273: 
        !          7274:        return path;
        !          7275: }
        !          7276: 
        !          7277: 
1.1.1.13  root     7278: // Returns 0 if an error occurs or the drive letter (as an upper-case char) of the system partition (e.g. 'C');
                   7279: char GetSystemDriveLetter (void)
                   7280: {
                   7281:        char systemDir [MAX_PATH];
                   7282: 
                   7283:        if (GetSystemDirectory (systemDir, sizeof (systemDir)))
1.1.1.23! root     7284:                return (char) (toupper (systemDir [0]));
1.1.1.13  root     7285:        else
                   7286:                return 0;
                   7287: }
1.1.1.7   root     7288: 
                   7289: int Info (char *stringId)
                   7290: {
                   7291:        if (Silent) return 0;
1.1.1.17  root     7292:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONINFORMATION);
                   7293: }
                   7294: 
                   7295: 
1.1.1.20  root     7296: int InfoTopMost (char *stringId)
                   7297: {
                   7298:        if (Silent) return 0;
                   7299:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
                   7300: }
                   7301: 
                   7302: 
1.1.1.17  root     7303: int InfoDirect (const wchar_t *msg)
                   7304: {
                   7305:        if (Silent) return 0;
                   7306:        return MessageBoxW (MainDlg, msg, lpszTitle, MB_ICONINFORMATION);
1.1.1.7   root     7307: }
                   7308: 
                   7309: 
                   7310: int Warning (char *stringId)
                   7311: {
                   7312:        if (Silent) return 0;
1.1.1.17  root     7313:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING);
                   7314: }
                   7315: 
                   7316: 
                   7317: int WarningTopMost (char *stringId)
                   7318: {
                   7319:        if (Silent) return 0;
1.1.1.7   root     7320:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
                   7321: }
                   7322: 
                   7323: 
1.1.1.17  root     7324: int WarningDirect (const wchar_t *warnMsg)
                   7325: {
                   7326:        if (Silent) return 0;
1.1.1.19  root     7327:        return MessageBoxW (MainDlg, warnMsg, lpszTitle, MB_ICONWARNING);
1.1.1.17  root     7328: }
                   7329: 
                   7330: 
1.1.1.7   root     7331: int Error (char *stringId)
                   7332: {
                   7333:        if (Silent) return 0;
1.1.1.17  root     7334:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR);
                   7335: }
                   7336: 
                   7337: 
                   7338: int ErrorTopMost (char *stringId)
                   7339: {
                   7340:        if (Silent) return 0;
1.1.1.7   root     7341:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
                   7342: }
                   7343: 
                   7344: 
1.1.1.17  root     7345: int ErrorDirect (const wchar_t *errMsg)
                   7346: {
                   7347:        if (Silent) return 0;
                   7348:        return MessageBoxW (MainDlg, errMsg, lpszTitle, MB_ICONERROR);
                   7349: }
                   7350: 
                   7351: 
1.1.1.7   root     7352: int AskYesNo (char *stringId)
                   7353: {
1.1.1.23! root     7354:        if (Silent) return IDNO;
1.1.1.17  root     7355:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1);
1.1.1.7   root     7356: }
                   7357: 
                   7358: 
1.1.1.23! root     7359: int AskYesNoString (const wchar_t *str)
        !          7360: {
        !          7361:        if (Silent) return IDNO;
        !          7362:        return MessageBoxW (MainDlg, str, lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1);
        !          7363: }
        !          7364: 
        !          7365: 
1.1.1.7   root     7366: int AskNoYes (char *stringId)
                   7367: {
1.1.1.23! root     7368:        if (Silent) return IDNO;
1.1.1.17  root     7369:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
1.1.1.7   root     7370: }
                   7371: 
                   7372: 
1.1.1.13  root     7373: int AskOkCancel (char *stringId)
                   7374: {
1.1.1.23! root     7375:        if (Silent) return IDCANCEL;
1.1.1.17  root     7376:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_OKCANCEL | MB_DEFBUTTON1);
1.1.1.13  root     7377: }
                   7378: 
                   7379: 
1.1.1.7   root     7380: int AskWarnYesNo (char *stringId)
                   7381: {
1.1.1.23! root     7382:        if (Silent) return IDNO;
1.1.1.17  root     7383:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1);
1.1.1.7   root     7384: }
                   7385: 
                   7386: 
                   7387: int AskWarnNoYes (char *stringId)
                   7388: {
1.1.1.23! root     7389:        if (Silent) return IDNO;
1.1.1.17  root     7390:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
1.1.1.7   root     7391: }
                   7392: 
                   7393: 
1.1.1.23! root     7394: int AskWarnNoYesString (const wchar_t *string)
1.1.1.12  root     7395: {
1.1.1.23! root     7396:        if (Silent) return IDNO;
1.1.1.17  root     7397:        return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
1.1.1.12  root     7398: }
                   7399: 
                   7400: 
1.1.1.23! root     7401: int AskWarnYesNoString (const wchar_t *string)
1.1.1.19  root     7402: {
1.1.1.23! root     7403:        if (Silent) return IDNO;
1.1.1.19  root     7404:        return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1);
                   7405: }
                   7406: 
                   7407: 
                   7408: int AskWarnOkCancel (char *stringId)
                   7409: {
1.1.1.23! root     7410:        if (Silent) return IDCANCEL;
1.1.1.19  root     7411:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON1);
                   7412: }
                   7413: 
                   7414: 
1.1.1.7   root     7415: int AskWarnCancelOk (char *stringId)
                   7416: {
1.1.1.23! root     7417:        if (Silent) return IDCANCEL;
1.1.1.17  root     7418:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2);
1.1.1.7   root     7419: }
                   7420: 
                   7421: 
1.1.1.13  root     7422: int AskErrYesNo (char *stringId)
                   7423: {
1.1.1.23! root     7424:        if (Silent) return IDNO;
1.1.1.17  root     7425:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_YESNO | MB_DEFBUTTON1);
1.1.1.13  root     7426: }
                   7427: 
                   7428: 
                   7429: int AskErrNoYes (char *stringId)
                   7430: {
1.1.1.23! root     7431:        if (Silent) return IDNO;
1.1.1.17  root     7432:        return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_YESNO | MB_DEFBUTTON2);
1.1.1.13  root     7433: }
                   7434: 
                   7435: 
1.1.1.11  root     7436: // The function accepts two input formats:
                   7437: // Input format 1: {0, "MESSAGE_STRING_ID", "BUTTON_1_STRING_ID", ... "LAST_BUTTON_STRING_ID", 0};
                   7438: // Input format 2: {L"", L"Message text", L"Button caption 1", ... L"Last button caption", 0};
                   7439: // The second format is to be used if any of the strings contains format specification (e.g. %s, %d) or
                   7440: // in any other cases where a string needs to be resolved before calling this function.
                   7441: // If the returned value is 0, the user closed the dialog window without making a choice. 
                   7442: // If the user made a choice, the returned value is the ordinal number of the choice (1..MAX_MULTI_CHOICES)
1.1.1.19  root     7443: int AskMultiChoice (void *strings[], BOOL bBold)
1.1.1.11  root     7444: {
1.1.1.19  root     7445:        MULTI_CHOICE_DLGPROC_PARAMS params;
                   7446: 
                   7447:        params.strings = &strings[0];
                   7448:        params.bold = bBold;
                   7449: 
1.1.1.11  root     7450:        return DialogBoxParamW (hInst, 
                   7451:                MAKEINTRESOURCEW (IDD_MULTI_CHOICE_DLG), MainDlg,
1.1.1.19  root     7452:                (DLGPROC) MultiChoiceDialogProc, (LPARAM) &params);
1.1.1.11  root     7453: }
                   7454: 
                   7455: 
1.1.1.7   root     7456: BOOL ConfigWriteBegin ()
                   7457: {
                   7458:        DWORD size;
1.1.1.13  root     7459:        if (ConfigFileHandle != NULL) 
                   7460:                return FALSE;
1.1.1.7   root     7461: 
                   7462:        if (ConfigBuffer == NULL)
1.1.1.19  root     7463:                ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size);
1.1.1.7   root     7464: 
1.1.1.19  root     7465:        ConfigFileHandle = fopen (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), "w");
1.1.1.7   root     7466:        if (ConfigFileHandle == NULL)
                   7467:        {
                   7468:                free (ConfigBuffer);
                   7469:                ConfigBuffer = NULL;
                   7470:                return FALSE;
                   7471:        }
                   7472:        XmlWriteHeader (ConfigFileHandle);
                   7473:        fputs ("\n\t<configuration>", ConfigFileHandle);
                   7474: 
                   7475:        return TRUE;
                   7476: }
                   7477: 
                   7478: 
                   7479: BOOL ConfigWriteEnd ()
                   7480: {
                   7481:        char *xml = ConfigBuffer;
                   7482:        char key[128], value[2048];
                   7483: 
                   7484:        if (ConfigFileHandle == NULL) return FALSE;
                   7485: 
                   7486:        // Write unmodified values
                   7487:        while (xml && (xml = XmlFindElement (xml, "config")))
                   7488:        {
1.1.1.11  root     7489:                XmlGetAttributeText (xml, "key", key, sizeof (key));
                   7490:                XmlGetNodeText (xml, value, sizeof (value));
1.1.1.7   root     7491: 
                   7492:                fprintf (ConfigFileHandle, "\n\t\t<config key=\"%s\">%s</config>", key, value);
                   7493:                xml++;
                   7494:        }
                   7495: 
                   7496:        fputs ("\n\t</configuration>", ConfigFileHandle);
                   7497:        XmlWriteFooter (ConfigFileHandle);
                   7498: 
1.1.1.17  root     7499:        TCFlushFile (ConfigFileHandle);
1.1.1.16  root     7500: 
1.1.1.7   root     7501:        fclose (ConfigFileHandle);
                   7502:        ConfigFileHandle = NULL;
                   7503: 
                   7504:        if (ConfigBuffer != NULL)
                   7505:        {
                   7506:                DWORD size;
                   7507:                free (ConfigBuffer);
1.1.1.19  root     7508:                ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size);
1.1.1.7   root     7509:        }
                   7510: 
                   7511:        return TRUE;
                   7512: }
                   7513: 
                   7514: 
                   7515: BOOL ConfigWriteString (char *configKey, char *configValue)
                   7516: {
                   7517:        char *c;
                   7518:        if (ConfigFileHandle == NULL)
                   7519:                return FALSE;
                   7520: 
                   7521:        // Mark previous config value as updated
                   7522:        if (ConfigBuffer != NULL)
                   7523:        {
                   7524:                c = XmlFindElementByAttributeValue (ConfigBuffer, "config", "key", configKey);
                   7525:                if (c != NULL)
                   7526:                        c[1] = '!';
                   7527:        }
                   7528: 
                   7529:        return 0 != fprintf (
                   7530:                ConfigFileHandle, "\n\t\t<config key=\"%s\">%s</config>",
                   7531:                configKey, configValue);
                   7532: }
                   7533: 
                   7534: 
                   7535: BOOL ConfigWriteInt (char *configKey, int configValue)
                   7536: {
                   7537:        char val[32];
                   7538:        sprintf (val, "%d", configValue);
                   7539:        return ConfigWriteString (configKey, val);
                   7540: }
                   7541: 
                   7542: 
                   7543: static BOOL ConfigRead (char *configKey, char *configValue, int maxValueSize)
                   7544: {
                   7545:        DWORD size;
                   7546:        char *xml;
                   7547: 
                   7548:        if (ConfigBuffer == NULL)
1.1.1.19  root     7549:                ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size);
1.1.1.7   root     7550: 
                   7551:        xml = ConfigBuffer;
                   7552:        if (xml != NULL)
                   7553:        {
                   7554:                xml = XmlFindElementByAttributeValue (xml, "config", "key", configKey);
                   7555:                if (xml != NULL)
1.1.1.6   root     7556:                {
1.1.1.11  root     7557:                        XmlGetNodeText (xml, configValue, maxValueSize);
1.1.1.7   root     7558:                        return TRUE;
1.1.1.6   root     7559:                }
1.1.1.7   root     7560:        }
                   7561: 
                   7562:        return FALSE;
                   7563: }
                   7564: 
                   7565: 
                   7566: int ConfigReadInt (char *configKey, int defaultValue)
                   7567: {
                   7568:        char s[32];
                   7569: 
                   7570:        if (ConfigRead (configKey, s, sizeof (s)))
                   7571:                return atoi (s);
                   7572:        else
                   7573:                return defaultValue;
                   7574: }
                   7575: 
                   7576: 
                   7577: char *ConfigReadString (char *configKey, char *defaultValue, char *str, int maxLen)
                   7578: {
                   7579:        if (ConfigRead (configKey, str, maxLen))
                   7580:                return str;
                   7581:        else
                   7582:                return defaultValue;
                   7583: }
                   7584: 
                   7585: 
                   7586: void OpenPageHelp (HWND hwndDlg, int nPage)
                   7587: {
                   7588:        int r = (int)ShellExecute (NULL, "open", szHelpFile, NULL, NULL, SW_SHOWNORMAL);
1.1.1.6   root     7589: 
1.1.1.7   root     7590:        if (r == ERROR_FILE_NOT_FOUND)
                   7591:        {
                   7592:                // Try the secondary help file
                   7593:                r = (int)ShellExecute (NULL, "open", szHelpFile2, NULL, NULL, SW_SHOWNORMAL);
                   7594: 
                   7595:                if (r == ERROR_FILE_NOT_FOUND)
1.1.1.10  root     7596:                {
                   7597:                        OpenOnlineHelp ();
                   7598:                        return;
                   7599:                }
1.1.1.7   root     7600:        }
1.1.1.10  root     7601: 
1.1.1.7   root     7602:        if (r == SE_ERR_NOASSOC)
1.1.1.10  root     7603:        {
                   7604:                if (AskYesNo ("HELP_READER_ERROR") == IDYES)
                   7605:                        OpenOnlineHelp ();
                   7606:        }
                   7607: }
                   7608: 
                   7609: 
                   7610: void OpenOnlineHelp ()
                   7611: {
1.1.1.11  root     7612:        Applink ("help", TRUE, "");
1.1.1.7   root     7613: }
                   7614: 
                   7615: 
                   7616: #ifndef SETUP
                   7617: 
                   7618: void RestoreDefaultKeyFilesParam (void)
                   7619: {
                   7620:        KeyFileRemoveAll (&FirstKeyFile);
                   7621:        if (defaultKeyFilesParam.FirstKeyFile != NULL)
                   7622:        {
                   7623:                FirstKeyFile = KeyFileCloneAll (defaultKeyFilesParam.FirstKeyFile);
                   7624:                KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles;
                   7625:        }
                   7626:        else
                   7627:                KeyFilesEnable = FALSE;
                   7628: }
                   7629: 
                   7630: 
                   7631: BOOL LoadDefaultKeyFilesParam (void)
                   7632: {
                   7633:        BOOL status = TRUE;
                   7634:        DWORD size;
1.1.1.19  root     7635:        char *defaultKeyfilesFile = LoadFile (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES), &size);
1.1.1.7   root     7636:        char *xml = defaultKeyfilesFile;
                   7637:        KeyFile *kf;
                   7638: 
                   7639:        if (xml == NULL) 
                   7640:                return FALSE;
                   7641: 
                   7642:        KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile);
                   7643: 
                   7644:        while (xml = XmlFindElement (xml, "keyfile"))
                   7645:        {
1.1.1.15  root     7646:                kf = (KeyFile *) malloc (sizeof (KeyFile));
1.1.1.7   root     7647: 
1.1.1.11  root     7648:                if (XmlGetNodeText (xml, kf->FileName, sizeof (kf->FileName)) != NULL)
1.1.1.7   root     7649:                        defaultKeyFilesParam.FirstKeyFile = KeyFileAdd (defaultKeyFilesParam.FirstKeyFile, kf);
                   7650:                else
                   7651:                        free (kf);
                   7652: 
                   7653:                xml++;
                   7654:        }
                   7655: 
                   7656:        free (defaultKeyfilesFile);
                   7657:        KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles;
                   7658: 
                   7659:        return status;
                   7660: }
                   7661: 
                   7662: #endif /* #ifndef SETUP */
                   7663: 
                   7664: 
                   7665: void Debug (char *format, ...)
                   7666: {
                   7667:        char buf[1024];
                   7668:        va_list val;
                   7669: 
                   7670:        va_start(val, format);
                   7671:        _vsnprintf (buf, sizeof (buf), format, val);
                   7672:        va_end(val);
                   7673: 
                   7674:        OutputDebugString (buf);
                   7675: }
                   7676: 
                   7677: 
                   7678: void DebugMsgBox (char *format, ...)
                   7679: {
                   7680:        char buf[1024];
                   7681:        va_list val;
                   7682: 
                   7683:        va_start(val, format);
                   7684:        _vsnprintf (buf, sizeof (buf), format, val);
                   7685:        va_end(val);
                   7686: 
                   7687:        MessageBox (MainDlg, buf, "TrueCrypt debug", 0);
                   7688: }
                   7689: 
                   7690: 
1.1.1.21  root     7691: BOOL IsOSAtLeast (OSVersionEnum reqMinOS)
                   7692: {
                   7693:        return IsOSVersionAtLeast (reqMinOS, 0);
                   7694: }
                   7695: 
                   7696: 
                   7697: // Returns TRUE if the operating system is at least reqMinOS and service pack at least reqMinServicePack.
                   7698: // Example 1: IsOSVersionAtLeast (WIN_VISTA, 1) called under Windows 2008, returns TRUE.
                   7699: // Example 2: IsOSVersionAtLeast (WIN_XP, 3) called under Windows XP SP1, returns FALSE.
                   7700: // Example 3: IsOSVersionAtLeast (WIN_XP, 3) called under Windows Vista SP1, returns TRUE.
                   7701: BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack)
                   7702: {
1.1.1.23! root     7703:        /* When updating this function, update IsOSAtLeast() in Ntdriver.c too. */
        !          7704: 
        !          7705:        if (CurrentOSMajor <= 0)
        !          7706:                TC_THROW_FATAL_EXCEPTION;
        !          7707: 
        !          7708:        int major = 0, minor = 0;
1.1.1.21  root     7709: 
                   7710:        switch (reqMinOS)
                   7711:        {
                   7712:        case WIN_2000:                  major = 5; minor = 0; break;
                   7713:        case WIN_XP:                    major = 5; minor = 1; break;
                   7714:        case WIN_SERVER_2003:   major = 5; minor = 2; break;
                   7715:        case WIN_VISTA:                 major = 6; minor = 0; break;
                   7716:        case WIN_7:                             major = 6; minor = 1; break;
                   7717: 
                   7718:        default:
                   7719:                TC_THROW_FATAL_EXCEPTION;
                   7720:                break;
                   7721:        }
                   7722: 
                   7723:        return ((CurrentOSMajor << 16 | CurrentOSMinor << 8 | CurrentOSServicePack)
                   7724:                >= (major << 16 | minor << 8 | reqMinServicePack));
                   7725: }
                   7726: 
                   7727: 
1.1.1.7   root     7728: BOOL Is64BitOs ()
                   7729: {
                   7730:     static BOOL isWow64 = FALSE;
                   7731:        static BOOL valid = FALSE;
                   7732:        typedef BOOL (__stdcall *LPFN_ISWOW64PROCESS ) (HANDLE hProcess,PBOOL Wow64Process);
                   7733:        LPFN_ISWOW64PROCESS fnIsWow64Process;
                   7734: 
                   7735:        if (valid)
                   7736:                return isWow64;
                   7737: 
                   7738:        fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle("kernel32"), "IsWow64Process");
                   7739: 
                   7740:     if (fnIsWow64Process != NULL)
                   7741:         if (!fnIsWow64Process (GetCurrentProcess(), &isWow64))
                   7742:                        isWow64 = FALSE;
                   7743: 
                   7744:        valid = TRUE;
                   7745:     return isWow64;
                   7746: }
                   7747: 
                   7748: 
1.1.1.23! root     7749: BOOL IsServerOS ()
        !          7750: {
        !          7751:        OSVERSIONINFOEXA osVer;
        !          7752:        osVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXA);
        !          7753:        GetVersionExA ((LPOSVERSIONINFOA) &osVer);
        !          7754: 
        !          7755:        return (osVer.wProductType == VER_NT_SERVER || osVer.wProductType == VER_NT_DOMAIN_CONTROLLER);
        !          7756: }
        !          7757: 
        !          7758: 
1.1.1.17  root     7759: // Returns TRUE, if the currently running operating system is installed in a hidden volume. If it's not, or if 
                   7760: // there's an error, returns FALSE.
                   7761: BOOL IsHiddenOSRunning (void)
                   7762: {
                   7763:        static BOOL statusCached = FALSE;
                   7764:        static BOOL hiddenOSRunning;
                   7765: 
                   7766:        if (!statusCached)
                   7767:        {
                   7768:                try
                   7769:                {
                   7770:                        hiddenOSRunning = BootEncryption (MainDlg).IsHiddenSystemRunning();
                   7771:                }
                   7772:                catch (...)
                   7773:                {
                   7774:                        hiddenOSRunning = FALSE;
                   7775:                }
                   7776: 
                   7777:                statusCached = TRUE;
                   7778:        }
                   7779: 
                   7780:        return hiddenOSRunning;
                   7781: }
                   7782: 
                   7783: 
                   7784: BOOL RestartComputer (void)
                   7785: {
                   7786:        TOKEN_PRIVILEGES tokenPrivil; 
                   7787:        HANDLE hTkn; 
                   7788: 
                   7789:        if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hTkn))
                   7790:        {
                   7791:                return false; 
                   7792:        }
                   7793: 
                   7794:        LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &tokenPrivil.Privileges[0].Luid); 
                   7795:        tokenPrivil.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
                   7796:        tokenPrivil.PrivilegeCount = 1;    
                   7797: 
                   7798:        AdjustTokenPrivileges (hTkn, false, &tokenPrivil, 0, (PTOKEN_PRIVILEGES) NULL, 0); 
                   7799:        if (GetLastError() != ERROR_SUCCESS) 
                   7800:                return false; 
                   7801: 
                   7802:        if (!ExitWindowsEx (EWX_REBOOT | EWX_FORCE, 
                   7803:                SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) 
                   7804:                return false; 
                   7805: 
                   7806:        return true;
                   7807: }
                   7808: 
                   7809: 
1.1.1.21  root     7810: std::string GetWindowsEdition ()
1.1.1.11  root     7811: {
1.1.1.21  root     7812:        string osname = "win";
                   7813: 
                   7814:        OSVERSIONINFOEXA osVer;
                   7815:        osVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXA);
                   7816:        GetVersionExA ((LPOSVERSIONINFOA) &osVer);
1.1.1.11  root     7817: 
1.1.1.21  root     7818:        BOOL home = (osVer.wSuiteMask & VER_SUITE_PERSONAL);
                   7819:        BOOL server = (osVer.wProductType == VER_NT_SERVER || osVer.wProductType == VER_NT_DOMAIN_CONTROLLER);
                   7820: 
                   7821:        HKEY hkey;
                   7822:        char productName[300] = {0};
                   7823:        DWORD productNameSize = sizeof (productName);
                   7824:        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
1.1.1.11  root     7825:        {
1.1.1.21  root     7826:                if (RegQueryValueEx (hkey, "ProductName", 0, 0, (LPBYTE) &productName, &productNameSize) != ERROR_SUCCESS || productNameSize < 1)
                   7827:                        productName[0] = 0;
1.1.1.17  root     7828: 
1.1.1.21  root     7829:                RegCloseKey (hkey);
                   7830:        }
1.1.1.11  root     7831: 
1.1.1.21  root     7832:        switch (nCurrentOS)
                   7833:        {
                   7834:        case WIN_2000:
                   7835:                osname += "2000";
                   7836:                break;
1.1.1.11  root     7837: 
1.1.1.21  root     7838:        case WIN_XP:
                   7839:        case WIN_XP64:
                   7840:                osname += "xp";
                   7841:                osname += home ? "-home" : "-pro";
                   7842:                break;
1.1.1.11  root     7843: 
1.1.1.21  root     7844:        case WIN_SERVER_2003:
                   7845:                osname += "2003";
                   7846:                break;
1.1.1.11  root     7847: 
1.1.1.21  root     7848:        case WIN_VISTA:
                   7849:                osname += "vista";
                   7850:                break;
1.1.1.17  root     7851: 
1.1.1.21  root     7852:        case WIN_SERVER_2008:
                   7853:                osname += "2008";
                   7854:                break;
1.1.1.11  root     7855: 
1.1.1.21  root     7856:        case WIN_7:
                   7857:                osname += "7";
                   7858:                break;
1.1.1.11  root     7859: 
1.1.1.23! root     7860:        case WIN_SERVER_2008_R2:
        !          7861:                osname += "2008r2";
        !          7862:                break;
        !          7863: 
1.1.1.21  root     7864:        default:
                   7865:                stringstream s;
                   7866:                s << CurrentOSMajor << "." << CurrentOSMinor;
                   7867:                osname += s.str();
                   7868:                break;
                   7869:        }
1.1.1.11  root     7870: 
1.1.1.21  root     7871:        if (server)
                   7872:                osname += "-server";
1.1.1.13  root     7873: 
1.1.1.21  root     7874:        if (IsOSAtLeast (WIN_VISTA))
                   7875:        {       
                   7876:                if (home)
                   7877:                        osname += "-home";
                   7878:                else if (strstr (productName, "Standard") != 0)
                   7879:                        osname += "-standard";
                   7880:                else if (strstr (productName, "Professional") != 0)
                   7881:                        osname += "-pro";
                   7882:                else if (strstr (productName, "Business") != 0)
                   7883:                        osname += "-business";
                   7884:                else if (strstr (productName, "Enterprise") != 0)
                   7885:                        osname += "-enterprise";
                   7886:                else if (strstr (productName, "Datacenter") != 0)
                   7887:                        osname += "-datacenter";
                   7888:                else if (strstr (productName, "Ultimate") != 0)
                   7889:                        osname += "-ultimate";
                   7890:        }
                   7891: 
                   7892:        if (GetSystemMetrics (SM_STARTER))
                   7893:                osname += "-starter";
                   7894:        else if (strstr (productName, "Basic") != 0)
                   7895:                osname += "-basic";
1.1.1.12  root     7896: 
1.1.1.21  root     7897:        if (Is64BitOs())
                   7898:                osname += "-x64";
1.1.1.12  root     7899: 
1.1.1.21  root     7900:        if (CurrentOSServicePack > 0)
                   7901:        {
                   7902:                stringstream s;
                   7903:                s << "-sp" << CurrentOSServicePack;
                   7904:                osname += s.str();
                   7905:        }
1.1.1.11  root     7906: 
1.1.1.21  root     7907:        return osname;
                   7908: }
1.1.1.11  root     7909: 
                   7910: 
1.1.1.21  root     7911: void Applink (char *dest, BOOL bSendOS, char *extraOutput)
                   7912: {
                   7913:        char url [MAX_URL_LENGTH];
1.1.1.11  root     7914: 
                   7915:        ArrowWaitCursor ();
                   7916: 
1.1.1.21  root     7917:        sprintf_s (url, sizeof (url), TC_APPLINK "%s%s&dest=%s", bSendOS ? ("&os=" + GetWindowsEdition()).c_str() : "", extraOutput, dest);
1.1.1.11  root     7918:        ShellExecute (NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
                   7919: 
                   7920:        Sleep (200);
                   7921:        NormalCursor ();
                   7922: }
                   7923: 
                   7924: 
1.1.1.7   root     7925: char *RelativePath2Absolute (char *szFileName)
                   7926: {
                   7927:        if (szFileName[0] != '\\'
                   7928:                && strchr (szFileName, ':') == 0
                   7929:                && strstr (szFileName, "Volume{") != szFileName)
                   7930:        {
                   7931:                char path[MAX_PATH*2];
                   7932:                GetCurrentDirectory (MAX_PATH, path);
                   7933: 
                   7934:                if (path[strlen (path) - 1] != '\\')
                   7935:                        strcat (path, "\\");
                   7936: 
                   7937:                strcat (path, szFileName);
                   7938:                strncpy (szFileName, path, MAX_PATH-1);
                   7939:        }
                   7940: 
                   7941:        return szFileName;
                   7942: }
                   7943: 
                   7944: 
1.1.1.22  root     7945: void HandleDriveNotReadyError ()
1.1.1.7   root     7946: {
                   7947:        HKEY hkey = 0;
                   7948:        DWORD value = 0, size = sizeof (DWORD);
                   7949: 
1.1.1.22  root     7950:        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\MountMgr",
1.1.1.7   root     7951:                0, KEY_READ, &hkey) != ERROR_SUCCESS)
                   7952:                return;
                   7953: 
                   7954:        if (RegQueryValueEx (hkey, "NoAutoMount", 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS
                   7955:                && value != 0)
                   7956:                Warning ("SYS_AUTOMOUNT_DISABLED");
1.1.1.22  root     7957:        else if (nCurrentOS == WIN_VISTA && CurrentOSServicePack < 1)
1.1.1.11  root     7958:                Warning ("SYS_ASSIGN_DRIVE_LETTER");
1.1.1.22  root     7959:        else
                   7960:                Error ("ERR_HARDWARE_ERROR");
1.1.1.11  root     7961: 
1.1.1.7   root     7962:        RegCloseKey (hkey);
                   7963: }
                   7964: 
                   7965: 
1.1.1.8   root     7966: BOOL CALLBACK CloseTCWindowsEnum (HWND hwnd, LPARAM lParam)
1.1.1.7   root     7967: {
                   7968:        if (GetWindowLongPtr (hwnd, GWLP_USERDATA) == (LONG_PTR) 'TRUE')
                   7969:        {
1.1.1.12  root     7970:                char name[1024] = { 0 };
1.1.1.7   root     7971:                GetWindowText (hwnd, name, sizeof (name) - 1);
1.1.1.12  root     7972:                if (hwnd != MainDlg && strstr (name, "TrueCrypt"))
1.1.1.6   root     7973:                {
1.1.1.13  root     7974:                        PostMessage (hwnd, TC_APPMSG_CLOSE_BKG_TASK, 0, 0);
1.1.1.11  root     7975: 
                   7976:                        if (DriverVersion < 0x0430)
                   7977:                                PostMessage (hwnd, WM_ENDSESSION, 0, 0);
                   7978: 
1.1.1.7   root     7979:                        PostMessage (hwnd, WM_CLOSE, 0, 0);
1.1.1.6   root     7980: 
1.1.1.7   root     7981:                        if (lParam != 0)
                   7982:                                *((BOOL *)lParam) = TRUE;
1.1.1.6   root     7983:                }
                   7984:        }
1.1.1.7   root     7985:        return TRUE;
1.1.1.6   root     7986: }
1.1.1.7   root     7987: 
1.1.1.8   root     7988: BOOL CALLBACK FindTCWindowEnum (HWND hwnd, LPARAM lParam)
                   7989: {
                   7990:        if (*(HWND *)lParam == hwnd)
                   7991:                return TRUE;
                   7992: 
                   7993:        if (GetWindowLongPtr (hwnd, GWLP_USERDATA) == (LONG_PTR) 'TRUE')
                   7994:        {
                   7995:                char name[32] = { 0 };
                   7996:                GetWindowText (hwnd, name, sizeof (name) - 1);
1.1.1.9   root     7997:                if (hwnd != MainDlg && strcmp (name, "TrueCrypt") == 0)
1.1.1.8   root     7998:                {
                   7999:                        if (lParam != 0)
                   8000:                                *((HWND *)lParam) = hwnd;
                   8001:                }
                   8002:        }
                   8003:        return TRUE;
                   8004: }
                   8005: 
                   8006: 
1.1.1.7   root     8007: BYTE *MapResource (char *resourceType, int resourceId, PDWORD size)
                   8008: {
                   8009:        HGLOBAL hResL; 
                   8010:     HRSRC hRes;
                   8011: 
                   8012:        hRes = FindResource (NULL, MAKEINTRESOURCE(resourceId), resourceType);
                   8013:        hResL = LoadResource (NULL, hRes);
                   8014: 
                   8015:        if (size != NULL)
                   8016:                *size = SizeofResource (NULL, hRes);
                   8017:   
                   8018:        return (BYTE *) LockResource (hResL);
1.1.1.13  root     8019: }
                   8020: 
                   8021: 
                   8022: void InconsistencyResolved (char *techInfo)
                   8023: {
                   8024:        wchar_t finalMsg[8024];
                   8025: 
                   8026:        wsprintfW (finalMsg, GetString ("INCONSISTENCY_RESOLVED"), techInfo);
                   8027:        MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
                   8028: }
1.1.1.17  root     8029: 
                   8030: 
1.1.1.19  root     8031: void ReportUnexpectedState (char *techInfo)
                   8032: {
                   8033:        wchar_t finalMsg[8024];
                   8034: 
                   8035:        wsprintfW (finalMsg, GetString ("UNEXPECTED_STATE"), techInfo);
                   8036:        MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
                   8037: }
                   8038: 
                   8039: 
1.1.1.17  root     8040: #ifndef SETUP
                   8041: 
1.1.1.19  root     8042: int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader)
1.1.1.17  root     8043: {
1.1.1.19  root     8044:        int status = ERR_PARAMETER_INCORRECT;
1.1.1.17  root     8045:        int volumeType;
                   8046:        char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH];
                   8047:        char szDosDevice[TC_MAX_PATH];
                   8048:        char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
                   8049:        LARGE_INTEGER headerOffset;
1.1.1.19  root     8050:        DWORD dwResult;
1.1.1.17  root     8051: 
                   8052:        context->VolumeIsOpen = FALSE;
                   8053:        context->CryptoInfo = NULL;
                   8054:        context->HostFileHandle = INVALID_HANDLE_VALUE;
                   8055:        context->TimestampsValid = FALSE;
                   8056: 
                   8057:        CreateFullVolumePath (szDiskFile, volumePath, &context->IsDevice);
                   8058: 
                   8059:        if (context->IsDevice)
                   8060:        {
                   8061:                status = FakeDosNameForDevice (szDiskFile, szDosDevice, szCFDevice, FALSE);
                   8062:                if (status != 0)
                   8063:                        return status;
                   8064: 
                   8065:                preserveTimestamps = FALSE;
                   8066:        }
                   8067:        else
                   8068:                strcpy (szCFDevice, szDiskFile);
                   8069: 
                   8070:        if (preserveTimestamps)
                   8071:                write = TRUE;
                   8072: 
                   8073:        context->HostFileHandle = CreateFile (szCFDevice, GENERIC_READ | (write ? GENERIC_WRITE : 0), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   8074: 
                   8075:        if (context->HostFileHandle == INVALID_HANDLE_VALUE)
                   8076:        {
                   8077:                status = ERR_OS_ERROR;
                   8078:                goto error;
                   8079:        }
                   8080: 
1.1.1.19  root     8081:        if (context->IsDevice)
                   8082:        {
                   8083:                // Try to gain "raw" access to the partition in case there is a live filesystem on it (otherwise, 
                   8084:                // the NTFS driver guards hidden sectors and prevents e.g. header backup restore after the user 
                   8085:                // accidentally quick-formats a dismounted partition-hosted TrueCrypt volume as NTFS, etc.)
                   8086: 
                   8087:                DeviceIoControl (context->HostFileHandle, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwResult, NULL);
                   8088:        }
                   8089: 
1.1.1.17  root     8090:        context->VolumeIsOpen = TRUE;
                   8091: 
                   8092:        // Remember the container modification/creation date and time
                   8093:        if (!context->IsDevice && preserveTimestamps)
                   8094:        {
                   8095:                if (GetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime) == 0)
                   8096:                {
                   8097:                        context->TimestampsValid = FALSE;
                   8098:                        Warning ("GETFILETIME_FAILED_GENERIC");
                   8099:                }
                   8100:                else
                   8101:                        context->TimestampsValid = TRUE;
                   8102:        }
                   8103: 
                   8104:        // Determine host size
                   8105:        if (context->IsDevice)
                   8106:        {
                   8107:                PARTITION_INFORMATION diskInfo;
                   8108: 
                   8109:                if (GetPartitionInfo (volumePath, &diskInfo))
                   8110:                {
                   8111:                        context->HostSize = diskInfo.PartitionLength.QuadPart;
                   8112:                }
                   8113:                else
                   8114:                {
                   8115:                        DISK_GEOMETRY driveInfo;
                   8116: 
                   8117:                        if (!DeviceIoControl (context->HostFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL))
1.1.1.19  root     8118:                        {
                   8119:                                status = ERR_OS_ERROR;
1.1.1.17  root     8120:                                goto error;
1.1.1.19  root     8121:                        }
1.1.1.17  root     8122: 
                   8123:                        context->HostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector * driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder;
                   8124:                }
                   8125: 
                   8126:                if (context->HostSize == 0)
                   8127:                {
                   8128:                        status = ERR_VOL_SIZE_WRONG;
                   8129:                        goto error;
                   8130:                }
                   8131:        }
                   8132:        else
                   8133:        {
                   8134:                LARGE_INTEGER fileSize;
                   8135:                if (!GetFileSizeEx (context->HostFileHandle, &fileSize))
                   8136:                {
                   8137:                        status = ERR_OS_ERROR;
                   8138:                        goto error;
                   8139:                }
                   8140: 
                   8141:                context->HostSize = fileSize.QuadPart;
                   8142:        }
                   8143: 
                   8144:        for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++)
                   8145:        {
                   8146:                // Seek the volume header
                   8147:                switch (volumeType)
                   8148:                {
                   8149:                case TC_VOLUME_TYPE_NORMAL:
                   8150:                        headerOffset.QuadPart = useBackupHeader ? context->HostSize - TC_VOLUME_HEADER_GROUP_SIZE : TC_VOLUME_HEADER_OFFSET;
                   8151:                        break;
                   8152: 
                   8153:                case TC_VOLUME_TYPE_HIDDEN:
                   8154:                        if (TC_HIDDEN_VOLUME_HEADER_OFFSET + TC_VOLUME_HEADER_SIZE > context->HostSize)
                   8155:                                continue;
                   8156: 
                   8157:                        headerOffset.QuadPart = useBackupHeader ? context->HostSize - TC_VOLUME_HEADER_SIZE : TC_HIDDEN_VOLUME_HEADER_OFFSET;
                   8158:                        break;
                   8159: 
                   8160:                case TC_VOLUME_TYPE_HIDDEN_LEGACY:
                   8161:                        if (useBackupHeader)
                   8162:                        {
                   8163:                                status = ERR_PASSWORD_WRONG;
                   8164:                                goto error;
                   8165:                        }
                   8166: 
                   8167:                        headerOffset.QuadPart = context->HostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
                   8168:                        break;
                   8169:                }
                   8170: 
                   8171:                if (!SetFilePointerEx ((HANDLE) context->HostFileHandle, headerOffset, NULL, FILE_BEGIN))
                   8172:                {
                   8173:                        status = ERR_OS_ERROR;
                   8174:                        goto error;
                   8175:                }
                   8176: 
                   8177:                // Read volume header
                   8178:                DWORD bytesRead;
                   8179:                if (!ReadFile (context->HostFileHandle, buffer, sizeof (buffer), &bytesRead, NULL))
                   8180:                {
                   8181:                        status = ERR_OS_ERROR;
                   8182:                        goto error;
                   8183:                }
                   8184: 
1.1.1.19  root     8185:                if (bytesRead != sizeof (buffer)
                   8186:                        && context->IsDevice)
1.1.1.17  root     8187:                {
1.1.1.19  root     8188:                        // If FSCTL_ALLOW_EXTENDED_DASD_IO failed and there is a live filesystem on the partition, then the
                   8189:                        // filesystem driver may report EOF when we are reading hidden sectors (when the filesystem is 
                   8190:                        // shorter than the partition). This can happen for example after the user quick-formats a dismounted
                   8191:                        // partition-hosted TrueCrypt volume and then tries to read the embedded backup header.
                   8192: 
                   8193:                        memset (buffer, 0, sizeof (buffer));
1.1.1.17  root     8194:                }
                   8195: 
                   8196:                // Decrypt volume header
1.1.1.19  root     8197:                status = ReadVolumeHeader (FALSE, buffer, password, &context->CryptoInfo, NULL);
1.1.1.17  root     8198: 
                   8199:                if (status == ERR_PASSWORD_WRONG)
                   8200:                        continue;               // Try next volume type
                   8201: 
                   8202:                break;
                   8203:        }
                   8204: 
                   8205:        if (status == ERR_SUCCESS)
                   8206:                return status;
                   8207: 
                   8208: error:
                   8209:        DWORD sysError = GetLastError ();
                   8210: 
                   8211:        CloseVolume (context);
                   8212: 
                   8213:        SetLastError (sysError);
                   8214:        return status;
                   8215: }
                   8216: 
                   8217: 
                   8218: void CloseVolume (OpenVolumeContext *context)
                   8219: {
                   8220:        if (!context->VolumeIsOpen)
                   8221:                return;
                   8222: 
                   8223:        if (context->HostFileHandle != INVALID_HANDLE_VALUE)
                   8224:        {
                   8225:                // Restore the container timestamp (to preserve plausible deniability of possible hidden volume). 
                   8226:                if (context->TimestampsValid)
                   8227:                {
                   8228:                        if (!SetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime))
                   8229:                        {
                   8230:                                handleWin32Error (NULL);
                   8231:                                Warning ("SETFILETIME_FAILED_PW");
                   8232:                        }
                   8233:                }
                   8234: 
                   8235:                CloseHandle (context->HostFileHandle);
                   8236:                context->HostFileHandle = INVALID_HANDLE_VALUE;
                   8237:        }
                   8238: 
                   8239:        if (context->CryptoInfo)
                   8240:        {
                   8241:                crypto_close (context->CryptoInfo);
                   8242:                context->CryptoInfo = NULL;
                   8243:        }
                   8244: 
                   8245:        context->VolumeIsOpen = FALSE;
                   8246: }
                   8247: 
                   8248: 
                   8249: int ReEncryptVolumeHeader (char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, BOOL wipeMode)
                   8250: {
                   8251:        CRYPTO_INFO *newCryptoInfo = NULL;
                   8252:        
                   8253:        RandSetHashFunction (cryptoInfo->pkcs5);
                   8254: 
                   8255:        if (Randinit() != ERR_SUCCESS)
                   8256:                return ERR_PARAMETER_INCORRECT;
                   8257: 
1.1.1.21  root     8258:        UserEnrichRandomPool (NULL);
                   8259: 
1.1.1.19  root     8260:        int status = CreateVolumeHeaderInMemory (bBoot,
1.1.1.17  root     8261:                buffer,
                   8262:                cryptoInfo->ea,
                   8263:                cryptoInfo->mode,
                   8264:                password,
                   8265:                cryptoInfo->pkcs5,
                   8266:                (char *) cryptoInfo->master_keydata,
                   8267:                &newCryptoInfo,
                   8268:                cryptoInfo->VolumeSize.Value,
                   8269:                cryptoInfo->hiddenVolume ? cryptoInfo->hiddenVolumeSize : 0,
                   8270:                cryptoInfo->EncryptedAreaStart.Value,
                   8271:                cryptoInfo->EncryptedAreaLength.Value,
                   8272:                cryptoInfo->RequiredProgramVersion,
                   8273:                cryptoInfo->HeaderFlags,
                   8274:                wipeMode);
                   8275: 
                   8276:        if (newCryptoInfo != NULL)
                   8277:                crypto_close (newCryptoInfo);
                   8278: 
                   8279:        return status;
                   8280: }
                   8281: 
                   8282: #endif // !SETUP
                   8283: 
                   8284: 
1.1.1.19  root     8285: BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
1.1.1.17  root     8286: {
                   8287:        // GlobalMemoryStatusEx() cannot be used to determine if a paging file is active
                   8288: 
                   8289:        char data[65536];
                   8290:        DWORD size = sizeof (data);
                   8291:        
1.1.1.21  root     8292:        if (IsPagingFileWildcardActive())
                   8293:                return TRUE;
                   8294: 
1.1.1.17  root     8295:        if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", data, &size)
1.1.1.19  root     8296:                && size > 12 && !checkNonWindowsPartitionsOnly)
1.1.1.17  root     8297:                return TRUE;
                   8298: 
1.1.1.19  root     8299:        if (!IsAdmin())
1.1.1.21  root     8300:                AbortProcess ("UAC_INIT_ERROR");
1.1.1.19  root     8301: 
1.1.1.17  root     8302:        for (char drive = 'C'; drive <= 'Z'; ++drive)
                   8303:        {
1.1.1.18  root     8304:                // Query geometry of the drive first to prevent "no medium" pop-ups
                   8305:                string drivePath = "\\\\.\\X:";
                   8306:                drivePath[4] = drive;
1.1.1.19  root     8307: 
                   8308:                if (checkNonWindowsPartitionsOnly)
                   8309:                {
                   8310:                        char sysDir[MAX_PATH];
                   8311:                        if (GetSystemDirectory (sysDir, sizeof (sysDir)) != 0 && toupper (sysDir[0]) == drive)
                   8312:                                continue;
                   8313:                }
                   8314: 
1.1.1.18  root     8315:                HANDLE handle = CreateFile (drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
                   8316:                
                   8317:                if (handle == INVALID_HANDLE_VALUE)
                   8318:                        continue;
                   8319: 
                   8320:                DISK_GEOMETRY driveInfo;
                   8321:                DWORD dwResult;
                   8322: 
                   8323:                if (!DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL))
                   8324:                {
                   8325:                        CloseHandle (handle);
                   8326:                        continue;
                   8327:                }
                   8328: 
                   8329:                CloseHandle (handle);
                   8330: 
                   8331:                // Test if a paging file exists and is locked by another process
1.1.1.17  root     8332:                string path = "X:\\pagefile.sys";
                   8333:                path[0] = drive;
                   8334: 
1.1.1.18  root     8335:                handle = CreateFile (path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.17  root     8336:                
                   8337:                if (handle != INVALID_HANDLE_VALUE)
                   8338:                        CloseHandle (handle);
                   8339:                else if (GetLastError() == ERROR_SHARING_VIOLATION)
                   8340:                        return TRUE;
                   8341:        }
                   8342: 
                   8343:        return FALSE;
                   8344: }
                   8345: 
                   8346: 
1.1.1.21  root     8347: BOOL IsPagingFileWildcardActive ()
                   8348: {
                   8349:        char pagingFiles[65536];
                   8350:        DWORD size = sizeof (pagingFiles);
                   8351:        char *mmKey = "System\\CurrentControlSet\\Control\\Session Manager\\Memory Management";
                   8352: 
                   8353:        if (!ReadLocalMachineRegistryString (mmKey, "PagingFiles", pagingFiles, &size))
                   8354:        {
                   8355:                size = sizeof (pagingFiles);
                   8356:                if (!ReadLocalMachineRegistryMultiString (mmKey, "PagingFiles", pagingFiles, &size))
                   8357:                        size = 0;
                   8358:        }
                   8359: 
                   8360:        return size > 0 && strstr (pagingFiles, "?:\\") == pagingFiles;
                   8361: }
                   8362: 
                   8363: 
1.1.1.17  root     8364: BOOL DisablePagingFile ()
                   8365: {
                   8366:        char empty[] = { 0, 0 };
                   8367:        return WriteLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", empty, sizeof (empty));
                   8368: }
1.1.1.19  root     8369: 
                   8370: 
                   8371: std::wstring SingleStringToWide (const std::string &singleString)
                   8372: {
                   8373:        if (singleString.empty())
                   8374:                return std::wstring();
                   8375: 
                   8376:        WCHAR wbuf[65536];
                   8377:        int wideLen = MultiByteToWideChar (CP_ACP, 0, singleString.c_str(), -1, wbuf, array_capacity (wbuf) - 1);
                   8378:        throw_sys_if (wideLen == 0);
                   8379: 
                   8380:        wbuf[wideLen] = 0;
                   8381:        return wbuf;
                   8382: }
                   8383: 
                   8384: 
                   8385: std::wstring Utf8StringToWide (const std::string &utf8String)
                   8386: {
                   8387:        if (utf8String.empty())
                   8388:                return std::wstring();
                   8389: 
                   8390:        WCHAR wbuf[65536];
                   8391:        int wideLen = MultiByteToWideChar (CP_UTF8, 0, utf8String.c_str(), -1, wbuf, array_capacity (wbuf) - 1);
                   8392:        throw_sys_if (wideLen == 0);
                   8393: 
                   8394:        wbuf[wideLen] = 0;
                   8395:        return wbuf;
                   8396: }
                   8397: 
                   8398: 
                   8399: std::string WideToUtf8String (const std::wstring &wideString)
                   8400: {
                   8401:        if (wideString.empty())
                   8402:                return std::string();
                   8403: 
                   8404:        char buf[65536];
                   8405:        int len = WideCharToMultiByte (CP_UTF8, 0, wideString.c_str(), -1, buf, array_capacity (buf) - 1, NULL, NULL);
                   8406:        throw_sys_if (len == 0);
                   8407: 
                   8408:        buf[len] = 0;
                   8409:        return buf;
                   8410: }
                   8411: 
                   8412: 
                   8413: std::string WideToSingleString (const std::wstring &wideString)
                   8414: {
                   8415:        if (wideString.empty())
                   8416:                return std::string();
                   8417: 
                   8418:        char buf[65536];
                   8419:        int len = WideCharToMultiByte (CP_ACP, 0, wideString.c_str(), -1, buf, array_capacity (buf) - 1, NULL, NULL);
                   8420:        throw_sys_if (len == 0);
                   8421: 
                   8422:        buf[len] = 0;
                   8423:        return buf;
                   8424: }
                   8425: 
                   8426: 
                   8427: #ifndef SETUP
                   8428: 
                   8429: BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                   8430: {
                   8431:        WORD lw = LOWORD (wParam);
                   8432:        static string *password;        
                   8433: 
                   8434:        switch (msg)
                   8435:        {
                   8436:        case WM_INITDIALOG:
                   8437:                {
                   8438:                        password = (string *) lParam;
                   8439:                        LocalizeDialog (hwndDlg, "IDD_TOKEN_PASSWORD");
                   8440: 
                   8441:                        wchar_t s[1024];
                   8442:                        wsprintfW (s, GetString ("ENTER_TOKEN_PASSWORD"), Utf8StringToWide (password->c_str()).c_str());
                   8443:                        SetWindowTextW (GetDlgItem (hwndDlg, IDT_TOKEN_PASSWORD_INFO), s);
                   8444: 
                   8445:                        SendMessage (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), EM_LIMITTEXT, SecurityToken::MaxPasswordLength, 0);
                   8446: 
                   8447:                        SetForegroundWindow (hwndDlg);
                   8448:                        SetFocus (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD));
                   8449:                }
                   8450:                return 0;
                   8451: 
                   8452:        case WM_COMMAND:
                   8453:                if (lw == IDCANCEL || lw == IDOK)
                   8454:                {
                   8455:                        if (lw == IDOK)
                   8456:                        {
                   8457:                                wchar_t passwordWide[SecurityToken::MaxPasswordLength + 1];
                   8458: 
                   8459:                                if (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), passwordWide, SecurityToken::MaxPasswordLength + 1) == 0)
                   8460:                                {
                   8461:                                        handleWin32Error (hwndDlg);
                   8462:                                        break;
                   8463:                                }
                   8464: 
                   8465:                                char passwordUtf8[SecurityToken::MaxPasswordLength + 1];
                   8466: 
                   8467:                                int len = WideCharToMultiByte (CP_UTF8, 0, passwordWide, -1, passwordUtf8, array_capacity (passwordUtf8) - 1, nullptr, nullptr);
                   8468:                                passwordUtf8[len] = 0;
                   8469:                                *password = passwordUtf8;
                   8470: 
                   8471:                                burn (passwordWide, sizeof (passwordWide));
                   8472:                                burn (passwordUtf8, sizeof (passwordUtf8));
                   8473:                        }
                   8474: 
                   8475:                        // Attempt to wipe password stored in the input field buffer
                   8476:                        char tmp[SecurityToken::MaxPasswordLength+1];
                   8477:                        memset (tmp, 'X', SecurityToken::MaxPasswordLength);
                   8478:                        tmp[SecurityToken::MaxPasswordLength] = 0;
                   8479:                        SetWindowText (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), tmp);  
                   8480: 
                   8481:                        EndDialog (hwndDlg, lw);
                   8482:                }
                   8483:                return 1;
                   8484:        }
                   8485: 
                   8486:        return 0;
                   8487: }
                   8488: 
                   8489: 
                   8490: struct NewSecurityTokenKeyfileDlgProcParams
                   8491: {
                   8492:        CK_SLOT_ID SlotId;
                   8493:        string Name;
                   8494: };
                   8495: 
                   8496: static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                   8497: {
                   8498:        static NewSecurityTokenKeyfileDlgProcParams *newParams;
                   8499: 
                   8500:        WORD lw = LOWORD (wParam);
                   8501:        switch (msg)
                   8502:        {
                   8503:        case WM_INITDIALOG:
                   8504:                {
1.1.1.23! root     8505:                        LocalizeDialog (hwndDlg, "IDD_NEW_TOKEN_KEYFILE");
        !          8506: 
1.1.1.19  root     8507:                        newParams = (NewSecurityTokenKeyfileDlgProcParams *) lParam;
                   8508: 
                   8509:                        WaitCursor();
                   8510:                        finally_do ({ NormalCursor(); });
                   8511: 
                   8512:                        list <SecurityTokenInfo> tokens;
                   8513: 
                   8514:                        try
                   8515:                        {
                   8516:                                tokens = SecurityToken::GetAvailableTokens();
                   8517:                        }
                   8518:                        catch (Exception &e)
                   8519:                        {
                   8520:                                e.Show (hwndDlg);
                   8521:                        }
                   8522: 
                   8523:                        if (tokens.empty())
                   8524:                        {
                   8525:                                Error ("NO_TOKENS_FOUND");
                   8526:                                EndDialog (hwndDlg, IDCANCEL);
                   8527:                                return 1;
                   8528:                        }
                   8529: 
                   8530:                        foreach (const SecurityTokenInfo &token, tokens)
                   8531:                        {
                   8532:                                wstringstream tokenLabel;
                   8533:                                tokenLabel << L"[" << token.SlotId << L"] " << token.Label;
                   8534: 
                   8535:                                AddComboPairW (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token.SlotId);
                   8536:                        }
                   8537: 
                   8538:                        ComboBox_SetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), 0);
                   8539: 
                   8540:                        SetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), Utf8StringToWide (newParams->Name).c_str());
                   8541:                        return 1;
                   8542:                }
                   8543: 
                   8544:        case WM_COMMAND:
                   8545:                switch (lw)
                   8546:                {
                   8547:                case IDOK:
                   8548:                        {
                   8549:                                int selectedToken = ComboBox_GetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN));
                   8550:                                if (selectedToken == CB_ERR)
                   8551:                                {
                   8552:                                        EndDialog (hwndDlg, IDCANCEL);
                   8553:                                        return 1;
                   8554:                                }
                   8555: 
                   8556:                                newParams->SlotId = ComboBox_GetItemData (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), selectedToken);
                   8557: 
                   8558:                                wchar_t name[1024];
                   8559:                                if (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), name, array_capacity (name)) != 0)
                   8560:                                {
                   8561:                                        try
                   8562:                                        {
                   8563:                                                newParams->Name = WideToUtf8String (name);
                   8564:                                        }
                   8565:                                        catch (...) { }
                   8566:                                }
                   8567: 
                   8568:                                EndDialog (hwndDlg, IDOK);
                   8569:                                return 1;
                   8570:                        }
                   8571: 
                   8572:                case IDCANCEL:
                   8573:                        EndDialog (hwndDlg, IDCANCEL);
                   8574:                        return 1;
                   8575:                }
                   8576: 
                   8577:                if (HIWORD (wParam) == EN_CHANGE)
                   8578:                {
                   8579:                        wchar_t name[2];
                   8580:                        EnableWindow (GetDlgItem (hwndDlg, IDOK), (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), name, array_capacity (name)) != 0));
                   8581:                        return 1;
                   8582:                }
                   8583:        }
                   8584: 
                   8585:        return 0;
                   8586: }
                   8587: 
                   8588: 
                   8589: static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
                   8590: {
                   8591:        HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
                   8592:        LVITEMW lvItem;
                   8593:        int line = 0;
                   8594: 
                   8595:        ListView_DeleteAllItems (tokenListControl);
                   8596: 
                   8597:        foreach (const SecurityTokenKeyfile &keyfile, keyfiles)
                   8598:        {
                   8599:                memset (&lvItem, 0, sizeof(lvItem));
                   8600:                lvItem.mask = LVIF_TEXT;   
                   8601:                lvItem.iItem = line++;   
                   8602: 
                   8603:                stringstream s;
                   8604:                s << keyfile.SlotId;
                   8605: 
                   8606:                ListItemAdd (tokenListControl, lvItem.iItem, (char *) s.str().c_str());
                   8607:                ListSubItemSetW (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile.Token.Label.c_str());
                   8608:                ListSubItemSetW (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile.Id.c_str());
                   8609:        }
                   8610: 
                   8611:        BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
                   8612:        EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected);
                   8613:        EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected);
                   8614: }
                   8615: 
                   8616: 
                   8617: static list <SecurityTokenKeyfile> SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
                   8618: {
                   8619:        HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
                   8620:        list <SecurityTokenKeyfile> selectedKeyfiles;
                   8621: 
                   8622:        int itemId = -1;
                   8623:        while ((itemId = ListView_GetNextItem (tokenListControl, itemId, LVIS_SELECTED)) != -1)
                   8624:        {
                   8625:                selectedKeyfiles.push_back (keyfiles[itemId]);
                   8626:        }
                   8627: 
                   8628:        return selectedKeyfiles;
                   8629: }
                   8630: 
                   8631: 
                   8632: BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                   8633: {
                   8634:        static list <SecurityTokenKeyfilePath> *selectedTokenKeyfiles;
                   8635:        static vector <SecurityTokenKeyfile> keyfiles;
                   8636: 
                   8637:        WORD lw = LOWORD (wParam);
                   8638: 
                   8639:        switch (msg)
                   8640:        {
                   8641:        case WM_INITDIALOG:
                   8642:                {
                   8643:                        selectedTokenKeyfiles = (list <SecurityTokenKeyfilePath> *) lParam;
                   8644: 
                   8645:                        LVCOLUMNW LvCol;
                   8646:                        HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
                   8647: 
                   8648:                        LocalizeDialog (hwndDlg, selectedTokenKeyfiles ? "SELECT_TOKEN_KEYFILES" : "IDD_TOKEN_KEYFILES");
                   8649: 
                   8650:                        SendMessage (tokenListControl,LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
                   8651:                                LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_TWOCLICKACTIVATE|LVS_EX_LABELTIP 
                   8652:                                ); 
                   8653: 
                   8654:                        memset (&LvCol, 0, sizeof(LvCol));               
                   8655:                        LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;  
                   8656:                        LvCol.pszText = GetString ("TOKEN_SLOT_ID");
                   8657:                        LvCol.cx = CompensateXDPI (40);
                   8658:                        LvCol.fmt = LVCFMT_CENTER;
                   8659:                        SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 1, (LPARAM)&LvCol);
                   8660: 
                   8661:                        LvCol.pszText = GetString ("TOKEN_NAME");
                   8662:                        LvCol.cx = CompensateXDPI (128);
                   8663:                        LvCol.fmt = LVCFMT_LEFT;
                   8664:                        SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 2, (LPARAM)&LvCol);
                   8665: 
                   8666:                        LvCol.pszText = GetString ("TOKEN_DATA_OBJECT_LABEL");
                   8667:                        LvCol.cx = CompensateXDPI (180);
                   8668:                        LvCol.fmt = LVCFMT_LEFT;
                   8669:                        SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 3, (LPARAM)&LvCol);
                   8670: 
                   8671:                        keyfiles.clear();
                   8672: 
                   8673:                        try
                   8674:                        {
                   8675:                                WaitCursor();
                   8676:                                finally_do ({ NormalCursor(); });
                   8677: 
                   8678:                                keyfiles = SecurityToken::GetAvailableKeyfiles();
                   8679:                        }
                   8680:                        catch (UserAbort&)
                   8681:                        {
                   8682:                                EndDialog (hwndDlg, IDCANCEL);
                   8683:                                return 1;
                   8684:                        }
                   8685:                        catch (Exception &e)
                   8686:                        {
                   8687:                                e.Show (hwndDlg);
                   8688: 
                   8689:                                if (keyfiles.empty())
                   8690:                                {
                   8691:                                        EndDialog (hwndDlg, IDCANCEL);
                   8692:                                        return 1;
                   8693:                                }
                   8694:                        }
                   8695:  
                   8696:                        SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
                   8697:                        return 1;
                   8698:                }
                   8699: 
                   8700:        case WM_COMMAND:
                   8701:        case WM_NOTIFY:
                   8702:                if (msg == WM_COMMAND && lw == IDOK || msg == WM_NOTIFY && ((NMHDR *)lParam)->code == LVN_ITEMACTIVATE)
                   8703:                {
                   8704:                        if (selectedTokenKeyfiles)
                   8705:                        {
                   8706:                                foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
                   8707:                                {
                   8708:                                        selectedTokenKeyfiles->push_back (SecurityTokenKeyfilePath (keyfile));
                   8709:                                } 
                   8710:                        }
                   8711: 
                   8712:                        EndDialog (hwndDlg, IDOK);
                   8713:                        return 1;
                   8714:                }
                   8715: 
                   8716:                if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
                   8717:                {
                   8718:                        BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
                   8719:                        EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected);
                   8720:                        EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected);
                   8721:                        return 1;
                   8722:                }
                   8723: 
                   8724:                switch (lw)
                   8725:                {
                   8726:                case IDCANCEL:
                   8727:                        EndDialog (hwndDlg, IDCANCEL);
                   8728:                        return 1;
                   8729: 
                   8730:                case IDC_IMPORT_KEYFILE:
                   8731:                        {
                   8732:                                char keyfilePath[TC_MAX_PATH];
                   8733: 
                   8734:                                if (BrowseFiles (hwndDlg, "SELECT_KEYFILE", keyfilePath, bHistory, FALSE, NULL))
                   8735:                                {
                   8736:                                        DWORD keyfileSize;
                   8737:                                        byte *keyfileData = (byte *) LoadFile (keyfilePath, &keyfileSize);
                   8738:                                        if (!keyfileData)
                   8739:                                        {
                   8740:                                                handleWin32Error (hwndDlg);
                   8741:                                                return 1;
                   8742:                                        }
                   8743: 
                   8744:                                        if (keyfileSize != 0)
                   8745:                                        {
                   8746:                                                NewSecurityTokenKeyfileDlgProcParams newParams;
                   8747:                                                newParams.Name = WideToUtf8String (SingleStringToWide (keyfilePath));
                   8748: 
                   8749:                                                size_t lastBackSlash = newParams.Name.find_last_of ('\\');
                   8750:                                                if (lastBackSlash != string::npos)
                   8751:                                                        newParams.Name = newParams.Name.substr (lastBackSlash + 1);
                   8752: 
                   8753:                                                if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_NEW_TOKEN_KEYFILE), hwndDlg, (DLGPROC) NewSecurityTokenKeyfileDlgProc, (LPARAM) &newParams) == IDOK)
                   8754:                                                {
                   8755:                                                        vector <byte> keyfileDataVector (keyfileSize);
                   8756:                                                        memcpy (&keyfileDataVector.front(), keyfileData, keyfileSize);
                   8757: 
                   8758:                                                        try
                   8759:                                                        {
                   8760:                                                                WaitCursor();
                   8761:                                                                finally_do ({ NormalCursor(); });
                   8762: 
                   8763:                                                                SecurityToken::CreateKeyfile (newParams.SlotId, keyfileDataVector, newParams.Name);
                   8764: 
                   8765:                                                                keyfiles = SecurityToken::GetAvailableKeyfiles();
                   8766:                                                                SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
                   8767:                                                        }
                   8768:                                                        catch (Exception &e)
                   8769:                                                        {
                   8770:                                                                e.Show (hwndDlg);
                   8771:                                                        }
                   8772: 
                   8773:                                                        burn (&keyfileDataVector.front(), keyfileSize);
                   8774:                                                }
                   8775:                                        }
1.1.1.21  root     8776:                                        else
                   8777:                                        {
                   8778:                                                SetLastError (ERROR_HANDLE_EOF);
                   8779:                                                handleWin32Error (hwndDlg);
                   8780:                                        }
1.1.1.19  root     8781: 
                   8782:                                        burn (keyfileData, keyfileSize);
                   8783:                                        TCfree (keyfileData);
                   8784:                                }
                   8785: 
                   8786:                                return 1;
                   8787:                        }
                   8788: 
                   8789:                case IDC_EXPORT:
                   8790:                        {
                   8791:                                try
                   8792:                                {
                   8793:                                        foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
                   8794:                                        {
                   8795:                                                char keyfilePath[TC_MAX_PATH];
                   8796: 
                   8797:                                                if (!BrowseFiles (hwndDlg, "OPEN_TITLE", keyfilePath, bHistory, TRUE, NULL))
                   8798:                                                        break;
                   8799: 
                   8800:                                                {
                   8801:                                                        WaitCursor();
                   8802:                                                        finally_do ({ NormalCursor(); });
                   8803: 
                   8804:                                                        vector <byte> keyfileData;
                   8805: 
                   8806:                                                        SecurityToken::GetKeyfileData (keyfile, keyfileData);
1.1.1.21  root     8807: 
                   8808:                                                        if (keyfileData.empty())
                   8809:                                                        {
                   8810:                                                                SetLastError (ERROR_HANDLE_EOF);
                   8811:                                                                handleWin32Error (hwndDlg);
                   8812:                                                                return 1;
                   8813:                                                        }
                   8814: 
1.1.1.19  root     8815:                                                        finally_do_arg (vector <byte> *, &keyfileData, { burn (&finally_arg->front(), finally_arg->size()); });
                   8816: 
                   8817:                                                        if (!SaveBufferToFile ((char *) &keyfileData.front(), keyfilePath, keyfileData.size(), FALSE))
                   8818:                                                                throw SystemException ();
                   8819:                                                }
                   8820: 
                   8821:                                                Info ("KEYFILE_EXPORTED");
                   8822:                                        }
                   8823:                                }
                   8824:                                catch (Exception &e)
                   8825:                                {
                   8826:                                        e.Show (hwndDlg);
                   8827:                                }
                   8828: 
                   8829:                                return 1;
                   8830:                        }
                   8831: 
                   8832:                case IDC_DELETE:
                   8833:                        {
                   8834:                                if (AskNoYes ("CONFIRM_SEL_FILES_DELETE") == IDNO)
                   8835:                                        return 1;
                   8836: 
                   8837:                                try
                   8838:                                {
                   8839:                                        WaitCursor();
                   8840:                                        finally_do ({ NormalCursor(); });
                   8841: 
                   8842:                                        foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
                   8843:                                        {
                   8844:                                                SecurityToken::DeleteKeyfile (keyfile);
                   8845:                                        }
                   8846: 
                   8847:                                        keyfiles = SecurityToken::GetAvailableKeyfiles();
                   8848:                                        SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
                   8849:                                }
                   8850:                                catch (Exception &e)
                   8851:                                {
                   8852:                                        e.Show (hwndDlg);
                   8853:                                }
                   8854: 
                   8855:                                return 1;
                   8856:                        }
                   8857:                }
                   8858: 
                   8859:                return 0;
                   8860:        }
                   8861:        return 0;
                   8862: }
                   8863: 
                   8864: 
                   8865: BOOL InitSecurityTokenLibrary ()
                   8866: {
                   8867:        if (SecurityTokenLibraryPath[0] == 0)
                   8868:        {
                   8869:                Error ("NO_PKCS11_MODULE_SPECIFIED");
                   8870:                return FALSE;
                   8871:        }
                   8872: 
                   8873:        struct PinRequestHandler : public GetPinFunctor
                   8874:        {
                   8875:                virtual void operator() (string &str)
                   8876:                {
                   8877:                        if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PASSWORD), MainDlg, (DLGPROC) SecurityTokenPasswordDlgProc, (LPARAM) &str) == IDCANCEL)
                   8878:                                throw UserAbort (SRC_POS);
1.1.1.21  root     8879: 
                   8880:                        if (hCursor != NULL)
                   8881:                                SetCursor (hCursor);
1.1.1.19  root     8882:                }
                   8883:        };
                   8884: 
                   8885:        struct WarningHandler : public SendExceptionFunctor
                   8886:        {
                   8887:                virtual void operator() (const Exception &e)
                   8888:                {
                   8889:                        e.Show (NULL);
                   8890:                }
                   8891:        };
                   8892: 
                   8893:        try
                   8894:        {
                   8895:                SecurityToken::InitLibrary (SecurityTokenLibraryPath, auto_ptr <GetPinFunctor> (new PinRequestHandler), auto_ptr <SendExceptionFunctor> (new WarningHandler));
                   8896:        }
                   8897:        catch (Exception &e)
                   8898:        {
                   8899:                e.Show (NULL);
                   8900:                Error ("PKCS11_MODULE_INIT_FAILED");
                   8901:                return FALSE;
                   8902:        }
                   8903: 
                   8904:        return TRUE;
                   8905: }
                   8906: 
                   8907: #endif // !SETUP
                   8908: 
1.1.1.22  root     8909: std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties, bool singleList, bool noFloppy, bool detectUnencryptedFilesystems)
1.1.1.19  root     8910: {
                   8911:        vector <HostDevice> devices;
1.1.1.23! root     8912:        size_t device0Index;
1.1.1.19  root     8913: 
                   8914:        for (int devNumber = 0; devNumber < 64; devNumber++)
                   8915:        {
                   8916:                for (int partNumber = 0; partNumber < 32; partNumber++)
                   8917:                {
                   8918:                        stringstream strm;
                   8919:                        strm << "\\Device\\Harddisk" << devNumber << "\\Partition" << partNumber;
                   8920:                        string devPathStr (strm.str());
                   8921:                        const char *devPath = devPathStr.c_str();
                   8922: 
                   8923:                        OPEN_TEST_STRUCT openTest;
1.1.1.22  root     8924:                        if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems && partNumber != 0))
1.1.1.19  root     8925:                        {
                   8926:                                if (partNumber == 0)
                   8927:                                        break;
                   8928: 
                   8929:                                continue;
                   8930:                        }
                   8931: 
                   8932:                        HostDevice device;
                   8933:                        device.SystemNumber = devNumber;
                   8934:                        device.Path = devPath;
                   8935: 
                   8936:                        PARTITION_INFORMATION partInfo;
                   8937: 
                   8938:                        if (GetPartitionInfo (devPath, &partInfo))
                   8939:                                device.Size = partInfo.PartitionLength.QuadPart;
                   8940: 
1.1.1.22  root     8941:                        device.HasUnencryptedFilesystem = (detectUnencryptedFilesystems && openTest.FilesystemDetected) ? true : false;
1.1.1.21  root     8942: 
1.1.1.19  root     8943:                        if (!noDeviceProperties)
                   8944:                        {
                   8945:                                DISK_GEOMETRY geometry;
                   8946: 
                   8947:                                wstringstream ws;
                   8948:                                ws << devPathStr.c_str();
                   8949:                                int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str());
                   8950: 
                   8951:                                if (driveNumber >= 0)
                   8952:                                {
                   8953:                                        device.MountPoint += (char) (driveNumber + 'A');
                   8954:                                        device.MountPoint += ":";
                   8955: 
                   8956:                                        wchar_t name[64];
                   8957:                                        if (GetDriveLabel (driveNumber, name, sizeof (name)))
                   8958:                                                device.Name = name;
                   8959: 
                   8960:                                        if (GetSystemDriveLetter() == 'A' + driveNumber)
                   8961:                                                device.ContainsSystem = true;
                   8962:                                }
                   8963: 
                   8964:                                if (partNumber == 0 && GetDriveGeometry (devPath, &geometry))
                   8965:                                        device.Removable = (geometry.MediaType == RemovableMedia);
                   8966:                        }
                   8967: 
                   8968:                        if (partNumber == 0)
                   8969:                        {
                   8970:                                devices.push_back (device);
1.1.1.23! root     8971:                                device0Index = devices.size() - 1;
1.1.1.19  root     8972:                        }
                   8973:                        else
                   8974:                        {
1.1.1.23! root     8975:                                HostDevice *device0 = &devices[device0Index];
1.1.1.19  root     8976: 
                   8977:                                // System creates a virtual partition1 for some storage devices without
                   8978:                                // partition table. We try to detect this case by comparing sizes of
                   8979:                                // partition0 and partition1. If they match, no partition of the device
                   8980:                                // is displayed to the user to avoid confusion. Drive letter assigned by
                   8981:                                // system to partition1 is assigned partition0
1.1.1.23! root     8982:                                if (partNumber == 1 && device0->Size == device.Size)
1.1.1.19  root     8983:                                {
1.1.1.23! root     8984:                                        device0->IsVirtualPartition = true;
        !          8985:                                        device0->MountPoint = device.MountPoint;
        !          8986:                                        device0->Name = device.Name;
        !          8987:                                        device0->Path = device.Path;
        !          8988:                                        device0->HasUnencryptedFilesystem = device.HasUnencryptedFilesystem;
1.1.1.19  root     8989:                                        break;
                   8990:                                }
                   8991: 
                   8992:                                device.IsPartition = true;
                   8993:                                device.SystemNumber = partNumber;
1.1.1.23! root     8994:                                device.Removable = device0->Removable;
1.1.1.19  root     8995: 
                   8996:                                if (device.ContainsSystem)
1.1.1.23! root     8997:                                        device0->ContainsSystem = true;
1.1.1.19  root     8998: 
                   8999:                                if (singleList)
                   9000:                                        devices.push_back (device);
1.1.1.23! root     9001:                                else
        !          9002:                                        device0->Partitions.push_back (device);
1.1.1.19  root     9003:                        }
                   9004:                }
                   9005:        }
                   9006: 
                   9007:        // Vista does not create partition links for dynamic volumes so it is necessary to scan \\Device\\HarddiskVolumeX devices
                   9008:        if (CurrentOSMajor >= 6)
                   9009:        {
                   9010:                for (int devNumber = 0; devNumber < 256; devNumber++)
                   9011:                {
                   9012:                        stringstream strm;
                   9013:                        strm << "\\Device\\HarddiskVolume" << devNumber;
                   9014:                        string devPathStr (strm.str());
                   9015:                        const char *devPath = devPathStr.c_str();
                   9016: 
                   9017:                        OPEN_TEST_STRUCT openTest;
1.1.1.22  root     9018:                        if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems))
1.1.1.19  root     9019:                                continue;
                   9020: 
                   9021:                        DISK_PARTITION_INFO_STRUCT info;
                   9022:                        if (GetDeviceInfo (devPath, &info) && info.IsDynamic)
                   9023:                        {
                   9024:                                HostDevice device;
                   9025:                                device.DynamicVolume = true;
                   9026:                                device.IsPartition = true;
                   9027:                                device.SystemNumber = devNumber;
                   9028:                                device.Path = devPath;
                   9029:                                device.Size = info.partInfo.PartitionLength.QuadPart;
1.1.1.22  root     9030:                                device.HasUnencryptedFilesystem = (detectUnencryptedFilesystems && openTest.FilesystemDetected) ? true : false;
1.1.1.19  root     9031: 
                   9032:                                if (!noDeviceProperties)
                   9033:                                {
                   9034:                                        wstringstream ws;
                   9035:                                        ws << devPathStr.c_str();
                   9036:                                        int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str());
                   9037: 
                   9038:                                        if (driveNumber >= 0)
                   9039:                                        {
                   9040:                                                device.MountPoint += (char) (driveNumber + 'A');
                   9041:                                                device.MountPoint += ":";
                   9042: 
                   9043:                                                wchar_t name[64];
                   9044:                                                if (GetDriveLabel (driveNumber, name, sizeof (name)))
                   9045:                                                        device.Name = name;
                   9046: 
                   9047:                                                if (GetSystemDriveLetter() == 'A' + driveNumber)
                   9048:                                                        device.ContainsSystem = true;
                   9049:                                        }
                   9050:                                }
                   9051: 
                   9052:                                devices.push_back (device);
                   9053:                        }
                   9054:                }
                   9055:        }
                   9056: 
                   9057:        // Floppy drives
                   9058:        if (!noFloppy)
                   9059:        {
                   9060:                HostDevice floppy;
                   9061:                floppy.Floppy = true;
                   9062: 
                   9063:                char path[TC_MAX_PATH];
                   9064: 
                   9065:                if (QueryDosDevice ("A:", path, sizeof (path)) != 0 && GetDriveType ("A:\\") == DRIVE_REMOVABLE)
                   9066:                {
                   9067:                        floppy.MountPoint = "A:";
                   9068:                        floppy.Path = "\\Device\\Floppy0";
                   9069:                        devices.push_back (floppy);
                   9070:                }
                   9071: 
                   9072:                if (QueryDosDevice ("B:", path, sizeof (path)) != 0 && GetDriveType ("B:\\") == DRIVE_REMOVABLE)
                   9073:                {
                   9074:                        floppy.MountPoint = "B:";
                   9075:                        floppy.Path = "\\Device\\Floppy1";
                   9076:                        devices.push_back (floppy);
                   9077:                }
                   9078:        }
                   9079: 
                   9080:        return devices;
                   9081: }
                   9082: 
                   9083: 
1.1.1.20  root     9084: BOOL FileHasReadOnlyAttribute (const char *path)
                   9085: {
                   9086:        DWORD attributes = GetFileAttributes (path);
                   9087:        return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_READONLY) != 0;
                   9088: }
                   9089: 
                   9090: 
1.1.1.19  root     9091: BOOL IsFileOnReadOnlyFilesystem (const char *path)
                   9092: {
                   9093:        char root[MAX_PATH];
                   9094:        if (!GetVolumePathName (path, root, sizeof (root)))
                   9095:                return FALSE;
                   9096: 
                   9097:        DWORD flags, d;
                   9098:        if (!GetVolumeInformation (root, NULL, 0,  NULL, &d, &flags, NULL, 0))
                   9099:                return FALSE;
                   9100: 
                   9101:        return (flags & FILE_READ_ONLY_VOLUME) ? TRUE : FALSE;
                   9102: }
                   9103: 
                   9104: 
                   9105: void CheckFilesystem (int driveNo, BOOL fixErrors)
                   9106: {
                   9107:        wchar_t msg[1024], param[1024];
1.1.1.23! root     9108:        char driveRoot[] = { 'A' + (char) driveNo, ':', 0 };
1.1.1.19  root     9109: 
1.1.1.22  root     9110:        if (fixErrors && AskWarnYesNo ("FILESYS_REPAIR_CONFIRM_BACKUP") == IDNO)
                   9111:                return;
                   9112: 
1.1.1.19  root     9113:        wsprintfW (msg, GetString (fixErrors ? "REPAIRING_FS" : "CHECKING_FS"), driveRoot);
                   9114:        wsprintfW (param, fixErrors ? L"/C echo %s & chkdsk %hs /F /X & pause" : L"/C echo %s & chkdsk %hs & pause", msg, driveRoot);
                   9115: 
                   9116:        ShellExecuteW (NULL, (!IsAdmin() && IsUacSupported()) ? L"runas" : L"open", L"cmd.exe", param, NULL, SW_SHOW);
                   9117: }
1.1.1.21  root     9118: 
                   9119: 
                   9120: BOOL BufferContainsString (const byte *buffer, size_t bufferSize, const char *str)
                   9121: {
                   9122:        size_t strLen = strlen (str);
                   9123: 
                   9124:        if (bufferSize < strLen)
                   9125:                return FALSE;
                   9126: 
                   9127:        bufferSize -= strLen;
                   9128: 
                   9129:        for (size_t i = 0; i < bufferSize; ++i)
                   9130:        {
                   9131:                if (memcmp (buffer + i, str, strLen) == 0)
                   9132:                        return TRUE;
                   9133:        }
                   9134: 
                   9135:        return FALSE;
                   9136: }
                   9137: 
                   9138: 
                   9139: #ifndef SETUP
                   9140: 
                   9141: int AskNonSysInPlaceEncryptionResume ()
                   9142: {
                   9143:        if (AskWarnYesNo ("NONSYS_INPLACE_ENC_RESUME_PROMPT") == IDYES)
                   9144:                return IDYES;
                   9145: 
                   9146:        char *multiChoiceStr[] = { 0, "ASK_NONSYS_INPLACE_ENC_NOTIFICATION_REMOVAL", "DO_NOT_PROMPT_ME", "KEEP_PROMPTING_ME", 0 };
                   9147: 
                   9148:        switch (AskMultiChoice ((void **) multiChoiceStr, FALSE))
                   9149:        {
                   9150:        case 1:
                   9151:                RemoveNonSysInPlaceEncNotifications();
                   9152:                Warning ("NONSYS_INPLACE_ENC_NOTIFICATION_REMOVAL_NOTE");
                   9153:                break;
                   9154: 
                   9155:        default:
                   9156:                // NOP
                   9157:                break;
                   9158:        }
                   9159: 
                   9160:        return IDNO;
                   9161: }
                   9162: 
                   9163: #endif // !SETUP
                   9164: 
                   9165: 
                   9166: BOOL RemoveDeviceWriteProtection (HWND hwndDlg, char *devicePath)
                   9167: {
                   9168:        int driveNumber;
                   9169:        int partitionNumber;
                   9170: 
                   9171:        char temp[MAX_PATH*2];
                   9172:        char cmdBatch[MAX_PATH*2];
                   9173:        char diskpartScript[MAX_PATH*2];
                   9174: 
                   9175:        if (sscanf (devicePath, "\\Device\\Harddisk%d\\Partition%d", &driveNumber, &partitionNumber) != 2)
                   9176:                return FALSE;
                   9177: 
                   9178:        if (GetTempPath (sizeof (temp), temp) == 0)
                   9179:                return FALSE;
                   9180: 
                   9181:        _snprintf (cmdBatch, sizeof (cmdBatch), "%s\\TrueCrypt_Write_Protection_Removal.cmd", temp);
                   9182:        _snprintf (diskpartScript, sizeof (diskpartScript), "%s\\TrueCrypt_Write_Protection_Removal.diskpart", temp);
                   9183: 
                   9184:        FILE *f = fopen (cmdBatch, "w");
                   9185:        if (!f)
                   9186:        {
                   9187:                handleWin32Error (hwndDlg);
                   9188:                return FALSE;
                   9189:        }
                   9190: 
                   9191:        fprintf (f, "@diskpart /s \"%s\"\n@pause\n@del \"%s\" \"%s\"", diskpartScript, diskpartScript, cmdBatch);
                   9192:        fclose (f);
                   9193: 
                   9194:        f = fopen (diskpartScript, "w");
                   9195:        if (!f)
                   9196:        {
                   9197:                handleWin32Error (hwndDlg);
                   9198:                DeleteFile (cmdBatch);
                   9199:                return FALSE;
                   9200:        }
                   9201: 
                   9202:        fprintf (f, "select disk %d\nattributes disk clear readonly\n", driveNumber);
                   9203: 
                   9204:        if (partitionNumber != 0)
                   9205:                fprintf (f, "select partition %d\nattributes volume clear readonly\n", partitionNumber);
                   9206: 
                   9207:        fprintf (f, "exit\n");
                   9208:        fclose (f);
                   9209: 
                   9210:        ShellExecute (NULL, (!IsAdmin() && IsUacSupported()) ? "runas" : "open", cmdBatch, NULL, NULL, SW_SHOW);
                   9211: 
                   9212:        return TRUE;
                   9213: }
1.1.1.22  root     9214: 
                   9215: 
                   9216: static LRESULT CALLBACK EnableElevatedCursorChangeWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                   9217: {
                   9218:        return DefWindowProc (hWnd, message, wParam, lParam);
                   9219: }
                   9220: 
                   9221: 
                   9222: void EnableElevatedCursorChange (HWND parent)
                   9223: {
                   9224:        // Create a transparent window to work around a UAC issue preventing change of the cursor
                   9225:        if (UacElevated)
                   9226:        {
                   9227:                const char *className = "TrueCryptEnableElevatedCursorChange";
                   9228:                WNDCLASSEX winClass;
                   9229:                HWND hWnd;
                   9230: 
                   9231:                memset (&winClass, 0, sizeof (winClass));
                   9232:                winClass.cbSize = sizeof (WNDCLASSEX); 
                   9233:                winClass.lpfnWndProc = (WNDPROC) EnableElevatedCursorChangeWndProc;
                   9234:                winClass.hInstance = hInst;
                   9235:                winClass.lpszClassName = className;
                   9236:                RegisterClassEx (&winClass);
                   9237: 
                   9238:                hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_LAYERED, className, "TrueCrypt UAC", 0, 0, 0, GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN), parent, NULL, hInst, NULL);
                   9239:                SetLayeredWindowAttributes (hWnd, 0, 1, LWA_ALPHA);
                   9240:                ShowWindow (hWnd, SW_SHOWNORMAL);
                   9241: 
                   9242:                DestroyWindow (hWnd);
                   9243:                UnregisterClass (className, hInst);
                   9244:        }
                   9245: }
1.1.1.23! root     9246: 
        !          9247: 
        !          9248: BOOL DisableFileCompression (HANDLE file)
        !          9249: {
        !          9250:        USHORT format;
        !          9251:        DWORD bytesOut;
        !          9252: 
        !          9253:        if (!DeviceIoControl (file, FSCTL_GET_COMPRESSION, NULL, 0, &format, sizeof (format), &bytesOut, NULL))
        !          9254:                return FALSE;
        !          9255: 
        !          9256:        if (format == COMPRESSION_FORMAT_NONE)
        !          9257:                return TRUE;
        !          9258: 
        !          9259:        format = COMPRESSION_FORMAT_NONE;
        !          9260:        return DeviceIoControl (file, FSCTL_SET_COMPRESSION, &format, sizeof (format), NULL, 0, &bytesOut, NULL); 
        !          9261: }
        !          9262: 
        !          9263: 
        !          9264: BOOL VolumePathExists (char *volumePath)
        !          9265: {
        !          9266:        OPEN_TEST_STRUCT openTest;
        !          9267:        char upperCasePath[TC_MAX_PATH];
        !          9268: 
        !          9269:        UpperCaseCopy (upperCasePath, volumePath);
        !          9270: 
        !          9271:        if (strstr (upperCasePath, "\\DEVICE\\") == upperCasePath)
        !          9272:                return OpenDevice (volumePath, &openTest, FALSE);
        !          9273: 
        !          9274:        string path = volumePath;
        !          9275:        if (path.find ("\\\\?\\Volume{") == 0 && path.rfind ("}\\") == path.size() - 2)
        !          9276:        {
        !          9277:                char devicePath[TC_MAX_PATH];
        !          9278:                if (QueryDosDevice (path.substr (4, path.size() - 5).c_str(), devicePath, TC_MAX_PATH) != 0)
        !          9279:                        return TRUE;
        !          9280:        }
        !          9281: 
        !          9282:        return _access (volumePath, 0) == 0;
        !          9283: }
        !          9284: 
        !          9285: 
        !          9286: BOOL IsWindowsIsoBurnerAvailable ()
        !          9287: {
        !          9288:        char path[MAX_PATH*2] = { 0 };
        !          9289: 
        !          9290:        if (!IsOSAtLeast (WIN_7))
        !          9291:        {
        !          9292:                return FALSE;
        !          9293:        }
        !          9294: 
        !          9295:        if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_SYSTEM, NULL, 0, path)))
        !          9296:        {
        !          9297:                strcat (path, "\\" ISO_BURNER_TOOL);
        !          9298: 
        !          9299:                return (FileExists (path));
        !          9300:        }
        !          9301: 
        !          9302:        return FALSE;
        !          9303: }
        !          9304: 
        !          9305: 
        !          9306: BOOL LaunchWindowsIsoBurner (HWND hwnd, const char *isoPath)
        !          9307: {
        !          9308:        int r = (int) ShellExecute (hwnd, "open", ISO_BURNER_TOOL, (string ("\"") + isoPath + "\"").c_str(), NULL, SW_SHOWNORMAL);
        !          9309: 
        !          9310:        if (r <= 32)
        !          9311:        {
        !          9312:                SetLastError (r);
        !          9313:                handleWin32Error (hwnd);
        !          9314: 
        !          9315:                return FALSE;
        !          9316:        }
        !          9317: 
        !          9318:        return TRUE;
        !          9319: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.