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