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