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