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