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

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

unix.superglobalmegacorp.com

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