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