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

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

unix.superglobalmegacorp.com

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