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