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

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

unix.superglobalmegacorp.com

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