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