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

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

unix.superglobalmegacorp.com

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