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