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

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

unix.superglobalmegacorp.com

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