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

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

unix.superglobalmegacorp.com

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