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