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