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