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

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

unix.superglobalmegacorp.com

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