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