|
|
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: }
2074: }
1.1 root 2075:
2076: /* Get the attributes for the standard dialog class */
2077: if ((GetClassInfo (hInst, WINDOWS_DIALOG_CLASS, &wc)) == 0)
1.1.1.7 root 2078: AbortProcess ("INIT_REGISTER");
1.1 root 2079:
2080: #ifndef SETUP
2081: wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_TRUECRYPT_ICON));
2082: #else
2083: #include "../setup/resource.h"
2084: wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_SETUP));
2085: #endif
2086: wc.lpszClassName = TC_DLG_CLASS;
2087: wc.lpfnWndProc = &CustomDlgProc;
2088: wc.hCursor = LoadCursor (NULL, IDC_ARROW);
2089: wc.cbWndExtra = DLGWINDOWEXTRA;
2090:
2091: hDlgClass = RegisterClass (&wc);
2092: if (hDlgClass == 0)
1.1.1.7 root 2093: AbortProcess ("INIT_REGISTER");
1.1 root 2094:
2095: wc.lpszClassName = TC_SPLASH_CLASS;
2096: wc.lpfnWndProc = &SplashDlgProc;
2097: wc.hCursor = LoadCursor (NULL, IDC_ARROW);
2098: wc.cbWndExtra = DLGWINDOWEXTRA;
2099:
2100: hSplashClass = RegisterClass (&wc);
2101: if (hSplashClass == 0)
1.1.1.7 root 2102: AbortProcess ("INIT_REGISTER");
2103:
1.1.1.19 root 2104: // Required for RichEdit text fields to work
2105: if (LoadLibrary("Riched20.dll") == NULL)
2106: {
2107: // This error is fatal e.g. because legal notices could not be displayed
2108: AbortProcess ("INIT_RICHEDIT");
2109: }
2110:
1.1.1.12 root 2111: // DPI and GUI aspect ratio
2112: DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_AUXILIARY_DLG), NULL,
2113: (DLGPROC) AuxiliaryDlgProc, (LPARAM) 1);
2114:
1.1.1.7 root 2115: InitHelpFileName ();
1.1.1.17 root 2116:
2117: #ifndef SETUP
2118: if (!EncryptionThreadPoolStart())
2119: {
2120: handleWin32Error (NULL);
2121: exit (1);
2122: }
2123: #endif
1.1.1.7 root 2124: }
2125:
2126: void InitHelpFileName (void)
2127: {
2128: char *lpszTmp;
1.1 root 2129:
2130: GetModuleFileName (NULL, szHelpFile, sizeof (szHelpFile));
2131: lpszTmp = strrchr (szHelpFile, '\\');
2132: if (lpszTmp)
2133: {
1.1.1.7 root 2134: char szTemp[TC_MAX_PATH];
1.1 root 2135:
1.1.1.7 root 2136: // Primary file name
2137: if (strcmp (GetPreferredLangId(), "en") == 0
2138: || GetPreferredLangId() == NULL)
1.1 root 2139: {
1.1.1.7 root 2140: strcpy (++lpszTmp, "TrueCrypt User Guide.pdf");
1.1 root 2141: }
2142: else
1.1.1.7 root 2143: {
2144: sprintf (szTemp, "TrueCrypt User Guide.%s.pdf", GetPreferredLangId());
2145: strcpy (++lpszTmp, szTemp);
2146: }
2147:
2148: // Secondary file name (used when localized documentation is not found).
2149: GetModuleFileName (NULL, szHelpFile2, sizeof (szHelpFile2));
2150: lpszTmp = strrchr (szHelpFile2, '\\');
2151: if (lpszTmp)
2152: {
2153: strcpy (++lpszTmp, "TrueCrypt User Guide.pdf");
2154: }
1.1 root 2155: }
2156: }
2157:
1.1.1.19 root 2158: BOOL OpenDevice (const char *lpszPath, OPEN_TEST_STRUCT *driver)
1.1 root 2159: {
2160: DWORD dwResult;
2161: BOOL bResult;
2162:
2163: strcpy ((char *) &driver->wszFileName[0], lpszPath);
1.1.1.7 root 2164: ToUNICODE ((char *) &driver->wszFileName[0]);
1.1 root 2165:
1.1.1.15 root 2166: driver->bDetectTCBootLoader = FALSE;
2167:
1.1.1.13 root 2168: bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
1.1 root 2169: driver, sizeof (OPEN_TEST_STRUCT),
1.1.1.7 root 2170: NULL, 0,
1.1 root 2171: &dwResult, NULL);
2172:
2173: if (bResult == FALSE)
2174: {
2175: dwResult = GetLastError ();
1.1.1.7 root 2176:
1.1 root 2177: if (dwResult == ERROR_SHARING_VIOLATION)
2178: return TRUE;
2179: else
2180: return FALSE;
2181: }
1.1.1.7 root 2182:
2183: return TRUE;
1.1 root 2184: }
2185:
2186:
1.1.1.15 root 2187: // Tells the driver that it's running in traveler mode
2188: void NotifyDriverOfTravelerMode (void)
2189: {
2190: if (hDriver != INVALID_HANDLE_VALUE)
2191: {
2192: DWORD dwResult;
2193:
2194: DeviceIoControl (hDriver, TC_IOCTL_SET_TRAVELER_MODE_STATUS, NULL, 0, NULL, 0, &dwResult, NULL);
2195: }
2196: }
2197:
2198:
1.1.1.11 root 2199: BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize)
2200: {
2201: DWORD fileSystemFlags;
2202: wchar_t root[] = { L'A' + driveNo, L':', L'\\', 0 };
2203:
2204: return GetVolumeInformationW (root, label, labelSize / 2, NULL, NULL, &fileSystemFlags, NULL, 0);
2205: }
2206:
2207:
1.1.1.13 root 2208: /* Stores the device path of the system partition in SysPartitionDevicePath and the device path of the system drive
1.1.1.17 root 2209: in SysDriveDevicePath.
1.1.1.13 root 2210: IMPORTANT: As this may take a very long time if called for the first time, it should be called only before performing
2211: a dangerous operation (such as header backup restore or formatting a supposedly non-system device) never
2212: at WM_INITDIALOG or any other GUI events -- instead call IsSystemDevicePath (path, hwndDlg, FALSE) for
2213: very fast preliminary GUI checks; also note that right after the "Select Device" dialog exits with an OK
2214: return code, you can use the global flags bSysPartitionSelected and bSysDriveSelected to see if the user
2215: selected the system partition/device.
2216: After this function completes successfully, the results are cached for the rest of the session and repeated
2217: executions complete very fast. Returns TRUE if successful (otherwise FALSE). */
2218: BOOL GetSysDevicePaths (HWND hwndDlg)
2219: {
2220: if (!bCachedSysDevicePathsValid
2221: || strlen (SysPartitionDevicePath) <= 1
2222: || strlen (SysDriveDevicePath) <= 1)
2223: {
1.1.1.19 root 2224: foreach (const HostDevice &device, GetAvailableHostDevices (false, true))
2225: {
2226: if (device.ContainsSystem)
2227: strcpy_s (device.IsPartition ? SysPartitionDevicePath : SysDriveDevicePath, TC_MAX_PATH, device.Path.c_str());
2228: }
1.1.1.13 root 2229:
1.1.1.19 root 2230: bCachedSysDevicePathsValid = 1;
1.1.1.13 root 2231: }
2232:
2233: return (bCachedSysDevicePathsValid
2234: && strlen (SysPartitionDevicePath) > 1
2235: && strlen (SysDriveDevicePath) > 1);
2236: }
2237:
1.1.1.17 root 2238: /* Determines whether the device path is the path of the system partition or of the system drive (or neither).
1.1.1.13 root 2239: If bReliableRequired is TRUE, very fast execution is guaranteed, but the results cannot be relied upon.
2240: If it's FALSE and the function is called for the first time, execution may take up to one minute but the
2241: results are reliable.
2242: IMPORTANT: As the execution may take a very long time if called for the first time with bReliableRequired set
2243: to TRUE, it should be called with bReliableRequired set to TRUE only before performing a dangerous
2244: operation (such as header backup restore or formatting a supposedly non-system device) never at
2245: WM_INITDIALOG or any other GUI events (use IsSystemDevicePath(path, hwndDlg, FALSE) for fast
2246: preliminary GUI checks; also note that right after the "Select Device" dialog exits with an OK
2247: return code, you can use the global flags bSysPartitionSelected and bSysDriveSelected to see if the
2248: user selected the system partition/device).
2249: After this function completes successfully, the results are cached for the rest of the session, bReliableRequired
2250: is ignored (TRUE implied), repeated executions complete very fast, and the results are always reliable.
2251: Return codes:
2252: 1 - it is the system partition path (e.g. \Device\Harddisk0\Partition1)
2253: 2 - it is the system drive path (e.g. \Device\Harddisk0\Partition0)
2254: 0 - it's not the system partition/drive path
2255: -1 - the result can't be determined, isn't reliable, or there was an error. */
2256: int IsSystemDevicePath (char *path, HWND hwndDlg, BOOL bReliableRequired)
2257: {
2258: if (!bCachedSysDevicePathsValid
2259: && bReliableRequired)
2260: {
2261: if (!GetSysDevicePaths (hwndDlg))
2262: return -1;
2263: }
2264:
2265: if (strlen (SysPartitionDevicePath) <= 1 || strlen (SysDriveDevicePath) <= 1)
2266: return -1;
2267:
2268: if (strncmp (path, SysPartitionDevicePath, max (strlen(path), strlen(SysPartitionDevicePath))) == 0)
2269: return 1;
2270: else if (strncmp (path, SysDriveDevicePath, max (strlen(path), strlen(SysDriveDevicePath))) == 0)
2271: return 2;
2272:
2273: return 0;
2274: }
2275:
2276: BOOL TextInfoDialogBox (int nID)
2277: {
2278: return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TEXT_INFO_DIALOG_BOX_DLG), MainDlg, (DLGPROC) TextInfoDialogBoxDlgProc, (LPARAM) nID);
2279: }
2280:
2281: BOOL CALLBACK TextInfoDialogBoxDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1 root 2282: {
2283: WORD lw = LOWORD (wParam);
1.1.1.13 root 2284: static int nID = 0;
1.1 root 2285:
2286: switch (msg)
2287: {
2288: case WM_INITDIALOG:
2289: {
1.1.1.13 root 2290: nID = (int) lParam;
1.1.1.11 root 2291:
1.1.1.19 root 2292: // Left margin for rich edit text field
2293: SendMessage (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_SETMARGINS, (WPARAM) EC_LEFTMARGIN, (LPARAM) CompensateXDPI (4));
2294:
1.1.1.13 root 2295: ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_HIDE);
2296:
2297: switch (nID)
1.1.1.11 root 2298: {
1.1.1.13 root 2299: case TC_TBXID_LEGAL_NOTICES:
2300: LocalizeDialog (hwndDlg, "LEGAL_NOTICES_DLG_TITLE");
2301: break;
2302:
2303: case TC_TBXID_SYS_ENCRYPTION_PRETEST:
2304: LocalizeDialog (hwndDlg, NULL);
2305: ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
2306: break;
2307:
2308: case TC_TBXID_SYS_ENC_RESCUE_DISK:
2309: LocalizeDialog (hwndDlg, NULL);
2310: ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
2311: break;
1.1.1.19 root 2312:
2313: case TC_TBXID_DECOY_OS_INSTRUCTIONS:
2314: LocalizeDialog (hwndDlg, NULL);
2315: ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW);
2316: break;
1.1.1.11 root 2317: }
1.1.1.13 root 2318:
2319: SendMessage (hwndDlg, TC_APPMSG_LOAD_TEXT_BOX_CONTENT, 0, 0);
1.1.1.7 root 2320: }
1.1.1.13 root 2321: return 0;
1.1 root 2322:
1.1.1.7 root 2323: case WM_COMMAND:
2324: if (lw == IDOK || lw == IDCANCEL)
2325: {
1.1.1.13 root 2326: NormalCursor ();
1.1.1.7 root 2327: EndDialog (hwndDlg, 0);
2328: return 1;
2329: }
1.1 root 2330:
1.1.1.13 root 2331: if (lw == IDC_PRINT)
2332: {
2333: switch (nID)
2334: {
2335: case TC_TBXID_SYS_ENCRYPTION_PRETEST:
2336: PrintHardCopyTextUTF16 (GetString ("SYS_ENCRYPTION_PRETEST_INFO2"), "Pre-Boot Troubleshooting", wcslen (GetString ("SYS_ENCRYPTION_PRETEST_INFO2")) * 2);
2337: break;
2338:
2339: case TC_TBXID_SYS_ENC_RESCUE_DISK:
2340: PrintHardCopyTextUTF16 (GetString ("RESCUE_DISK_HELP"), "TrueCrypt Rescue Disk Help", wcslen (GetString ("RESCUE_DISK_HELP")) * 2);
2341: break;
2342:
1.1.1.19 root 2343: case TC_TBXID_DECOY_OS_INSTRUCTIONS:
2344: PrintHardCopyTextUTF16 (GetString ("DECOY_OS_INSTRUCTIONS"), "How to Create Decoy OS", wcslen (GetString ("DECOY_OS_INSTRUCTIONS")) * 2);
2345: break;
2346: }
1.1.1.7 root 2347: return 1;
2348: }
2349:
2350: return 0;
2351:
1.1.1.13 root 2352: case TC_APPMSG_LOAD_TEXT_BOX_CONTENT:
2353: {
2354: char *r = NULL;
2355:
2356: switch (nID)
2357: {
2358: case TC_TBXID_LEGAL_NOTICES:
2359: LocalizeDialog (hwndDlg, "LEGAL_NOTICES_DLG_TITLE");
2360: r = GetLegalNotices ();
2361: if (r != NULL)
2362: {
2363: SetWindowText (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), r);
2364: free (r);
2365: }
2366: break;
2367:
2368: case TC_TBXID_SYS_ENCRYPTION_PRETEST:
2369: LocalizeDialog (hwndDlg, NULL);
2370: SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), GetString ("SYS_ENCRYPTION_PRETEST_INFO2"));
2371: break;
2372:
2373: case TC_TBXID_SYS_ENC_RESCUE_DISK:
2374: LocalizeDialog (hwndDlg, NULL);
2375: SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), GetString ("RESCUE_DISK_HELP"));
2376: break;
1.1.1.19 root 2377:
2378: case TC_TBXID_DECOY_OS_INSTRUCTIONS:
2379: LocalizeDialog (hwndDlg, NULL);
2380: SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), GetString ("DECOY_OS_INSTRUCTIONS"));
2381: break;
1.1.1.13 root 2382: }
2383: }
2384: return 1;
2385:
1.1.1.7 root 2386: case WM_CLOSE:
1.1.1.13 root 2387: NormalCursor ();
1.1.1.7 root 2388: EndDialog (hwndDlg, 0);
2389: return 1;
2390: }
2391:
2392: return 0;
2393: }
2394:
2395:
2396: char * GetLegalNotices ()
2397: {
2398: static char *resource;
1.1.1.11 root 2399: static DWORD size;
1.1.1.15 root 2400: char *buf = NULL;
1.1.1.7 root 2401:
2402: if (resource == NULL)
1.1.1.15 root 2403: resource = (char *) MapResource ("Text", IDR_LICENSE, &size);
1.1.1.7 root 2404:
1.1.1.11 root 2405: if (resource != NULL)
2406: {
1.1.1.15 root 2407: buf = (char *) malloc (size + 1);
1.1.1.11 root 2408: if (buf != NULL)
2409: {
2410: memcpy (buf, resource, size);
2411: buf[size] = 0;
2412: }
2413: }
2414:
2415: return buf;
1.1.1.7 root 2416: }
2417:
2418:
1.1.1.19 root 2419: BOOL CALLBACK RawDevicesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1.1.7 root 2420: {
1.1.1.13 root 2421: static char *lpszFileName; // This is actually a pointer to a GLOBAL array
1.1.1.19 root 2422: static vector <HostDevice> devices;
2423: static map <int, HostDevice> itemToDeviceMap;
2424:
1.1.1.7 root 2425: WORD lw = LOWORD (wParam);
2426:
2427: switch (msg)
2428: {
2429: case WM_INITDIALOG:
2430: {
2431: LVCOLUMNW LvCol;
2432: HWND hList = GetDlgItem (hwndDlg, IDC_DEVICELIST);
2433:
2434: LocalizeDialog (hwndDlg, "IDD_RAWDEVICES_DLG");
2435:
2436: SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
2437: LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_TWOCLICKACTIVATE|LVS_EX_LABELTIP
2438: );
2439:
2440: memset (&LvCol,0,sizeof(LvCol));
2441: LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
2442: LvCol.pszText = GetString ("DEVICE");
1.1.1.12 root 2443: LvCol.cx = CompensateXDPI (186);
1.1.1.7 root 2444: LvCol.fmt = LVCFMT_LEFT;
2445: SendMessage (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&LvCol);
1.1.1.5 root 2446:
1.1.1.7 root 2447: LvCol.pszText = GetString ("DRIVE");
1.1.1.13 root 2448: LvCol.cx = CompensateXDPI (38);
1.1.1.11 root 2449: LvCol.fmt = LVCFMT_LEFT;
1.1.1.7 root 2450: SendMessage (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&LvCol);
1.1 root 2451:
1.1.1.13 root 2452: LvCol.pszText = GetString ("SIZE");
2453: LvCol.cx = CompensateXDPI (64);
1.1 root 2454: LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7 root 2455: SendMessage (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol);
1.1 root 2456:
1.1.1.13 root 2457: LvCol.pszText = GetString ("VOLUME_LABEL");
2458: LvCol.cx = CompensateXDPI (128);
1.1 root 2459: LvCol.fmt = LVCFMT_LEFT;
1.1.1.7 root 2460: SendMessage (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol);
1.1 root 2461:
1.1.1.19 root 2462: devices.clear();
2463: itemToDeviceMap.clear();
2464:
2465: WaitCursor();
2466: devices = GetAvailableHostDevices (false, true, false);
2467: NormalCursor();
1.1.1.13 root 2468:
1.1.1.19 root 2469: if (devices.empty())
1.1.1.13 root 2470: {
1.1.1.19 root 2471: MessageBoxW (hwndDlg, GetString ("RAWDEVICES"), lpszTitle, ICON_HAND);
1.1.1.13 root 2472: EndDialog (hwndDlg, IDCANCEL);
2473: return 1;
2474: }
2475:
1.1.1.19 root 2476: int line = 1;
2477: LVITEM item;
2478: memset (&item, 0, sizeof (item));
2479: item.mask = LVIF_TEXT;
1.1 root 2480:
1.1.1.19 root 2481: foreach (const HostDevice &device, devices)
1.1 root 2482: {
1.1.1.19 root 2483: item.iSubItem = 1;
2484:
2485: if (device.ContainsSystem)
2486: {
2487: if (device.IsPartition)
2488: strcpy_s (SysPartitionDevicePath, sizeof (SysPartitionDevicePath), device.Path.c_str());
2489: else
2490: strcpy_s (SysDriveDevicePath, sizeof (SysDriveDevicePath), device.Path.c_str());
2491: }
2492:
2493: // Path
2494: if (!device.IsPartition || device.DynamicVolume)
2495: {
2496: if (!device.Floppy && device.Size == 0)
2497: continue;
2498:
2499: if (line > 1)
2500: {
2501: ListItemAdd (hList, item.iItem, "");
2502: item.iItem = line++;
2503: }
2504:
2505: if (device.Floppy || device.DynamicVolume)
2506: {
2507: ListItemAdd (hList, item.iItem, (char *) device.Path.c_str());
2508: }
2509: else
2510: {
2511: wchar_t s[1024];
2512: if (device.Removable)
2513: wsprintfW (s, L"%s %d", GetString ("REMOVABLE_DISK"), device.SystemNumber);
2514: else
2515: wsprintfW (s, L"%s %d", GetString ("HARDDISK"), device.SystemNumber);
2516:
2517: if (!device.Partitions.empty())
2518: wcscat (s, L":");
2519:
2520: ListItemAddW (hList, item.iItem, s);
2521: }
2522: }
2523: else
2524: {
2525: ListItemAdd (hList, item.iItem, (char *) device.Path.c_str());
2526: }
2527:
2528: itemToDeviceMap[item.iItem] = device;
2529:
2530: // Size
2531: if (device.Size != 0)
2532: {
2533: wchar_t size[100] = { 0 };
2534: GetSizeString (device.Size, size);
2535: ListSubItemSetW (hList, item.iItem, 2, size);
2536: }
2537:
2538: // Mount point
2539: if (!device.MountPoint.empty())
2540: ListSubItemSet (hList, item.iItem, 1, (char *) device.MountPoint.c_str());
2541:
2542: // Label
2543: if (!device.Name.empty())
2544: ListSubItemSetW (hList, item.iItem, 3, (wchar_t *) device.Name.c_str());
2545:
2546: item.iItem = line++;
1.1 root 2547: }
2548:
2549: lpszFileName = (char *) lParam;
1.1.1.12 root 2550:
2551: #ifdef VOLFORMAT
2552: EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE);
2553: #endif
1.1 root 2554: return 1;
2555: }
2556:
2557: case WM_COMMAND:
2558: case WM_NOTIFY:
2559: // catch non-device line selected
2560: if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED ))
2561: {
2562: LVITEM LvItem;
2563: memset(&LvItem,0,sizeof(LvItem));
1.1.1.11 root 2564: LvItem.mask = LVIF_TEXT | LVIF_PARAM;
1.1 root 2565: LvItem.iItem = ((LPNMLISTVIEW) lParam)->iItem;
2566: LvItem.pszText = lpszFileName;
2567: LvItem.cchTextMax = TC_MAX_PATH;
2568:
1.1.1.11 root 2569: SendMessage (GetDlgItem (hwndDlg, IDC_DEVICELIST), LVM_GETITEM, LvItem.iItem, (LPARAM) &LvItem);
1.1 root 2570: EnableWindow (GetDlgItem ((HWND) hwndDlg, IDOK), lpszFileName[0] != 0 && lpszFileName[0] != ' ');
1.1.1.11 root 2571:
1.1 root 2572: return 1;
2573: }
2574:
2575: if (msg == WM_COMMAND && lw == IDOK || msg == WM_NOTIFY && ((NMHDR *)lParam)->code == LVN_ITEMACTIVATE)
2576: {
1.1.1.19 root 2577: int selectedItem = ListView_GetSelectionMark (GetDlgItem (hwndDlg, IDC_DEVICELIST));
1.1 root 2578:
1.1.1.19 root 2579: if (selectedItem == -1 || itemToDeviceMap.find (selectedItem) == itemToDeviceMap.end())
1.1.1.12 root 2580: return 1; // non-device line selected
2581:
1.1.1.19 root 2582: const HostDevice selectedDevice = itemToDeviceMap[selectedItem];
2583: strcpy_s (lpszFileName, TC_MAX_PATH, selectedDevice.Path.c_str());
2584:
1.1.1.12 root 2585: #ifdef VOLFORMAT
1.1.1.19 root 2586: if (selectedDevice.ContainsSystem && selectedDevice.IsPartition)
1.1.1.12 root 2587: {
1.1.1.13 root 2588: if (WizardMode != WIZARD_MODE_SYS_DEVICE)
2589: {
2590: if (AskYesNo ("CONFIRM_SYSTEM_ENCRYPTION_MODE") == IDNO)
2591: {
2592: EndDialog (hwndDlg, IDCANCEL);
2593: return 1;
2594: }
2595:
2596: bSysPartitionSelected = TRUE;
2597: bSysDriveSelected = FALSE;
2598: lpszFileName[0] = 0;
2599: SwitchWizardToSysEncMode ();
2600:
2601: NormalCursor ();
2602: EndDialog (hwndDlg, IDOK);
2603: return 1;
2604: }
2605: else
2606: {
2607: // This should never be the case because the Select Device dialog is not available in this wizard mode
2608: bSysPartitionSelected = TRUE;
2609: bSysDriveSelected = FALSE;
2610: lpszFileName[0] = 0;
2611: SwitchWizardToSysEncMode ();
2612: NormalCursor ();
2613: EndDialog (hwndDlg, IDCANCEL);
2614: return 1;
2615: }
1.1.1.12 root 2616: }
2617:
1.1.1.19 root 2618: if (!(selectedDevice.ContainsSystem && !selectedDevice.IsPartition))
1.1.1.13 root 2619: {
2620: if (bWarnDeviceFormatAdvanced
2621: && !bHiddenVolDirect
2622: && AskWarnNoYes("FORMAT_DEVICE_FOR_ADVANCED_ONLY") == IDNO)
2623: {
2624: if (AskNoYes("CONFIRM_CHANGE_WIZARD_MODE_TO_FILE_CONTAINER") == IDYES)
2625: {
2626: SwitchWizardToFileContainerMode ();
2627: }
2628: EndDialog (hwndDlg, IDCANCEL);
2629: return 1;
2630: }
1.1.1.12 root 2631:
1.1.1.13 root 2632: if (!bHiddenVolDirect)
2633: bWarnDeviceFormatAdvanced = FALSE;
2634: }
2635:
2636: #else // #ifdef VOLFORMAT
2637:
1.1.1.19 root 2638: bSysPartitionSelected = (selectedDevice.ContainsSystem && selectedDevice.IsPartition);
1.1.1.13 root 2639: bSysDriveSelected = FALSE;
2640:
2641: #endif // #ifdef VOLFORMAT
1.1 root 2642:
1.1.1.19 root 2643: if (!selectedDevice.IsPartition && !selectedDevice.Floppy)
1.1.1.5 root 2644: {
2645: // Whole device selected
1.1.1.11 root 2646:
1.1.1.5 root 2647: #ifdef VOLFORMAT
1.1.1.19 root 2648: if (selectedDevice.ContainsSystem && !selectedDevice.IsPartition)
1.1.1.13 root 2649: {
2650: if (WizardMode != WIZARD_MODE_SYS_DEVICE)
2651: {
2652: if (AskYesNo ("CONFIRM_SYSTEM_ENCRYPTION_MODE") == IDNO)
2653: {
2654: NormalCursor ();
2655: EndDialog (hwndDlg, IDCANCEL);
2656: return 1;
2657: }
2658:
2659: bSysDriveSelected = TRUE;
2660: bSysPartitionSelected = FALSE;
2661: lpszFileName[0] = 0;
2662: SwitchWizardToSysEncMode ();
2663:
2664: NormalCursor ();
2665: EndDialog (hwndDlg, IDOK);
2666: return 1;
2667: }
2668: else
2669: {
2670: // This should never be the case because the Select Device dialog is not available in this wizard mode
2671: bSysDriveSelected = TRUE;
2672: bSysPartitionSelected = FALSE;
2673: lpszFileName[0] = 0;
2674: SwitchWizardToSysEncMode ();
2675: NormalCursor ();
2676: EndDialog (hwndDlg, IDCANCEL);
2677: return 1;
2678: }
2679: }
2680:
2681: // Disallow format if the device contains partitions, but not if the partition is virtual or system
1.1.1.19 root 2682: if (!selectedDevice.IsVirtualPartition
1.1.1.11 root 2683: && !bHiddenVolDirect)
1.1.1.5 root 2684: {
1.1.1.19 root 2685: if (!selectedDevice.Partitions.empty())
1.1.1.7 root 2686: {
1.1.1.11 root 2687: EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE);
1.1.1.19 root 2688: Error ("DEVICE_PARTITIONS_ERR_W_INPLACE_ENC_NOTE");
1.1.1.11 root 2689: return 1;
2690: }
1.1.1.19 root 2691:
2692: if (AskWarnNoYes ("WHOLE_NONSYS_DEVICE_ENC_CONFIRM") == IDNO)
2693: return 1;
1.1.1.5 root 2694: }
1.1.1.13 root 2695: #else // #ifdef VOLFORMAT
2696:
1.1.1.19 root 2697: bSysDriveSelected = (selectedDevice.ContainsSystem && !selectedDevice.IsPartition);
1.1.1.13 root 2698: bSysPartitionSelected = FALSE;
2699:
2700: #endif // #ifdef VOLFORMAT
1.1.1.5 root 2701: }
1.1.1.13 root 2702: else
2703: bSysDriveSelected = FALSE;
1.1.1.5 root 2704:
1.1.1.12 root 2705: #ifdef VOLFORMAT
1.1.1.19 root 2706: bRemovableHostDevice = selectedDevice.Removable;
1.1.1.12 root 2707: #endif
1.1.1.13 root 2708: NormalCursor ();
1.1 root 2709: EndDialog (hwndDlg, IDOK);
1.1.1.7 root 2710: return 1;
1.1 root 2711: }
2712:
2713: if (lw == IDCANCEL)
2714: {
1.1.1.13 root 2715: NormalCursor ();
1.1 root 2716: EndDialog (hwndDlg, IDCANCEL);
1.1.1.7 root 2717: return 1;
1.1 root 2718: }
2719: return 0;
2720: }
2721: return 0;
2722: }
2723:
1.1.1.6 root 2724:
1.1.1.15 root 2725: BOOL DoDriverInstall (HWND hwndDlg)
2726: {
2727: #ifdef SETUP
2728: if (SystemEncryptionUpgrade)
2729: return TRUE;
2730: #endif
2731:
2732: SC_HANDLE hManager, hService = NULL;
2733: BOOL bOK = FALSE, bRet;
2734:
2735: hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
2736: if (hManager == NULL)
2737: goto error;
2738:
2739: #ifdef SETUP
2740: StatusMessage (hwndDlg, "INSTALLING_DRIVER");
2741: #endif
2742:
2743: hService = CreateService (hManager, "truecrypt", "truecrypt",
2744: SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_SYSTEM_START, SERVICE_ERROR_NORMAL,
2745: !Is64BitOs () ? "System32\\drivers\\truecrypt.sys" : "SysWOW64\\drivers\\truecrypt.sys",
2746: NULL, NULL, NULL, NULL, NULL);
2747:
2748: if (hService == NULL)
2749: goto error;
2750: else
2751: CloseServiceHandle (hService);
2752:
2753: hService = OpenService (hManager, "truecrypt", SERVICE_ALL_ACCESS);
2754: if (hService == NULL)
2755: goto error;
2756:
2757: #ifdef SETUP
2758: StatusMessage (hwndDlg, "STARTING_DRIVER");
2759: #endif
2760:
2761: bRet = StartService (hService, 0, NULL);
2762: if (bRet == FALSE)
2763: goto error;
2764:
2765: bOK = TRUE;
2766:
2767: error:
2768: if (bOK == FALSE && GetLastError () != ERROR_SERVICE_ALREADY_RUNNING)
2769: {
2770: handleWin32Error (hwndDlg);
2771: MessageBoxW (hwndDlg, GetString ("DRIVER_INSTALL_FAILED"), lpszTitle, MB_ICONHAND);
2772: }
2773: else
2774: bOK = TRUE;
2775:
2776: if (hService != NULL)
2777: CloseServiceHandle (hService);
2778:
2779: if (hManager != NULL)
2780: CloseServiceHandle (hManager);
2781:
2782: return bOK;
2783: }
2784:
2785:
1.1.1.6 root 2786: // Install and start driver service and mark it for removal (non-install mode)
2787: static int DriverLoad ()
2788: {
2789: HANDLE file;
2790: WIN32_FIND_DATA find;
2791: SC_HANDLE hManager, hService = NULL;
2792: char driverPath[TC_MAX_PATH*2];
2793: BOOL res;
2794: char *tmp;
2795:
2796: GetModuleFileName (NULL, driverPath, sizeof (driverPath));
2797: tmp = strrchr (driverPath, '\\');
2798: if (!tmp)
2799: {
2800: strcpy (driverPath, ".");
2801: tmp = driverPath + 1;
2802: }
2803:
1.1.1.7 root 2804: strcpy (tmp, !Is64BitOs () ? "\\truecrypt.sys" : "\\truecrypt-x64.sys");
1.1.1.6 root 2805:
2806: file = FindFirstFile (driverPath, &find);
2807:
2808: if (file == INVALID_HANDLE_VALUE)
2809: {
1.1.1.7 root 2810: MessageBoxW (0, GetString ("DRIVER_NOT_FOUND"), lpszTitle, ICON_HAND);
1.1.1.6 root 2811: return ERR_DONT_REPORT;
2812: }
2813:
2814: FindClose (file);
2815:
2816: hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
2817: if (hManager == NULL)
1.1.1.7 root 2818: {
2819: if (GetLastError () == ERROR_ACCESS_DENIED)
2820: {
2821: MessageBoxW (0, GetString ("ADMIN_PRIVILEGES_DRIVER"), lpszTitle, ICON_HAND);
2822: return ERR_DONT_REPORT;
2823: }
2824:
1.1.1.6 root 2825: return ERR_OS_ERROR;
1.1.1.7 root 2826: }
1.1.1.6 root 2827:
1.1.1.12 root 2828: hService = OpenService (hManager, "truecrypt", SERVICE_ALL_ACCESS);
2829: if (hService != NULL)
2830: {
2831: // Remove stale service (driver is not loaded but service exists)
2832: DeleteService (hService);
2833: CloseServiceHandle (hService);
2834: Sleep (500);
2835: }
2836:
1.1.1.6 root 2837: hService = CreateService (hManager, "truecrypt", "truecrypt",
2838: SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
2839: driverPath, NULL, NULL, NULL, NULL, NULL);
2840:
2841: if (hService == NULL)
2842: {
2843: CloseServiceHandle (hManager);
2844: return ERR_OS_ERROR;
2845: }
2846:
2847: res = StartService (hService, 0, NULL);
2848: DeleteService (hService);
1.1.1.12 root 2849:
1.1.1.6 root 2850: CloseServiceHandle (hManager);
2851: CloseServiceHandle (hService);
2852:
2853: return !res ? ERR_OS_ERROR : ERROR_SUCCESS;
2854: }
2855:
2856:
1.1.1.7 root 2857: BOOL DriverUnload ()
2858: {
2859: MOUNT_LIST_STRUCT driver;
2860: int refCount;
1.1.1.13 root 2861: int volumesMounted;
1.1.1.7 root 2862: DWORD dwResult;
2863: BOOL bResult;
2864:
2865: SC_HANDLE hManager, hService = NULL;
2866: BOOL bRet;
2867: SERVICE_STATUS status;
2868: int x;
2869:
2870: if (hDriver == INVALID_HANDLE_VALUE)
2871: return TRUE;
1.1.1.15 root 2872:
2873: try
2874: {
2875: if (BootEncryption (NULL).GetStatus().DeviceFilterActive)
2876: return FALSE;
2877: }
2878: catch (...) { }
1.1.1.7 root 2879:
2880: // Test for mounted volumes
1.1.1.13 root 2881: bResult = DeviceIoControl (hDriver, TC_IOCTL_IS_ANY_VOLUME_MOUNTED, NULL, 0, &volumesMounted, sizeof (volumesMounted), &dwResult, NULL);
2882:
2883: if (!bResult)
2884: {
2885: bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES, NULL, 0, &driver, sizeof (driver), &dwResult, NULL);
2886: if (bResult)
2887: volumesMounted = driver.ulMountedDrives;
2888: }
1.1.1.7 root 2889:
2890: if (bResult)
2891: {
1.1.1.13 root 2892: if (volumesMounted != 0)
1.1.1.7 root 2893: return FALSE;
2894: }
2895: else
2896: return TRUE;
2897:
2898: // Test for any applications attached to driver
2899: refCount = GetDriverRefCount ();
2900:
2901: if (refCount > 1)
2902: return FALSE;
2903:
2904: CloseHandle (hDriver);
1.1.1.12 root 2905: hDriver = INVALID_HANDLE_VALUE;
1.1.1.7 root 2906:
2907: // Stop driver service
2908:
2909: hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
2910: if (hManager == NULL)
2911: goto error;
2912:
2913: hService = OpenService (hManager, "truecrypt", SERVICE_ALL_ACCESS);
2914: if (hService == NULL)
2915: goto error;
2916:
2917: bRet = QueryServiceStatus (hService, &status);
2918: if (bRet != TRUE)
2919: goto error;
2920:
2921: if (status.dwCurrentState != SERVICE_STOPPED)
2922: {
2923: ControlService (hService, SERVICE_CONTROL_STOP, &status);
2924:
2925: for (x = 0; x < 5; x++)
2926: {
2927: bRet = QueryServiceStatus (hService, &status);
2928: if (bRet != TRUE)
2929: goto error;
2930:
2931: if (status.dwCurrentState == SERVICE_STOPPED)
2932: break;
2933:
2934: Sleep (200);
2935: }
2936: }
2937:
2938: error:
2939: if (hService != NULL)
2940: CloseServiceHandle (hService);
2941:
2942: if (hManager != NULL)
2943: CloseServiceHandle (hManager);
2944:
2945: if (status.dwCurrentState == SERVICE_STOPPED)
2946: {
2947: hDriver = INVALID_HANDLE_VALUE;
2948: return TRUE;
2949: }
2950:
2951: return FALSE;
2952: }
2953:
2954:
1.1.1.15 root 2955: int DriverAttach (void)
1.1 root 2956: {
1.1.1.6 root 2957: /* Try to open a handle to the device driver. It will be closed later. */
1.1 root 2958:
1.1.1.15 root 2959: #ifndef SETUP
2960:
2961: int nLoadRetryCount = 0;
2962: start:
2963:
2964: #endif
2965:
1.1.1.6 root 2966: hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1.1 root 2967:
2968: if (hDriver == INVALID_HANDLE_VALUE)
2969: {
1.1.1.6 root 2970: #ifndef SETUP
1.1.1.15 root 2971:
2972: LoadSysEncSettings (NULL);
2973:
2974: if (!CreateDriverSetupMutex ())
2975: {
2976: // Another instance is already attempting to install, register or start the driver
2977:
2978: while (!CreateDriverSetupMutex ())
2979: {
2980: Sleep (100); // Wait until the other instance finishes
2981: }
2982:
2983: // Try to open a handle to the driver again (keep the mutex in case the other instance failed)
2984: goto start;
2985: }
2986: else
1.1.1.8 root 2987: {
1.1.1.15 root 2988: // No other instance is currently attempting to install, register or start the driver
1.1.1.6 root 2989:
1.1.1.15 root 2990: if (SystemEncryptionStatus != SYSENC_STATUS_NONE)
2991: {
2992: // This is an inconsistent state. The config file indicates system encryption should be
2993: // active, but the driver is not running. This may happen e.g. when the pretest fails and
2994: // the user selects "Last Known Good Configuration" from the Windows boot menu.
2995: // To fix this, we're going to reinstall the driver, start it, and register it for boot.
2996:
2997: if (DoDriverInstall (NULL))
2998: {
2999: Sleep (1000);
1.1.1.19 root 3000: hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
3001:
3002: try
3003: {
3004: BootEncryption bootEnc (NULL);
3005: bootEnc.RegisterBootDriver (bootEnc.GetHiddenOSCreationPhase() != TC_HIDDEN_OS_CREATION_PHASE_NONE ? true : false);
3006: }
3007: catch (Exception &e)
3008: {
3009: e.Show (NULL);
3010: }
1.1.1.15 root 3011: }
3012:
3013: CloseDriverSetupMutex ();
3014: }
3015: else
3016: {
3017: // Attempt to load the driver (non-install/traveler mode)
3018: load:
3019: BOOL res = DriverLoad ();
3020:
3021: CloseDriverSetupMutex ();
3022:
3023: if (res != ERROR_SUCCESS)
3024: return res;
3025:
3026: bTravelerModeConfirmed = TRUE;
1.1.1.6 root 3027:
1.1.1.19 root 3028: hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
3029: }
1.1.1.15 root 3030:
3031: if (bTravelerModeConfirmed)
3032: NotifyDriverOfTravelerMode ();
1.1.1.8 root 3033: }
1.1.1.15 root 3034:
3035: #endif // #ifndef SETUP
3036:
1.1.1.6 root 3037: if (hDriver == INVALID_HANDLE_VALUE)
3038: return ERR_OS_ERROR;
1.1 root 3039: }
1.1.1.7 root 3040:
1.1.1.15 root 3041: CloseDriverSetupMutex ();
3042:
1.1.1.7 root 3043: if (hDriver != INVALID_HANDLE_VALUE)
1.1 root 3044: {
3045: DWORD dwResult;
3046:
1.1.1.13 root 3047: BOOL bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &DriverVersion, sizeof (DriverVersion), &dwResult, NULL);
3048:
3049: if (!bResult)
3050: bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_DRIVER_VERSION, NULL, 0, &DriverVersion, sizeof (DriverVersion), &dwResult, NULL);
1.1 root 3051:
1.1.1.11 root 3052: #ifndef SETUP // Don't check version during setup to allow removal of another version
1.1 root 3053: if (bResult == FALSE)
1.1.1.12 root 3054: {
1.1 root 3055: return ERR_OS_ERROR;
1.1.1.12 root 3056: }
1.1.1.11 root 3057: else if (DriverVersion != VERSION_NUM)
1.1.1.12 root 3058: {
3059: // Unload an incompatbile version of the driver loaded in non-install mode and load the required version
1.1.1.15 root 3060: if (IsNonInstallMode () && CreateDriverSetupMutex () && DriverUnload () && nLoadRetryCount++ < 3)
1.1.1.12 root 3061: goto load;
3062:
1.1.1.15 root 3063: CloseDriverSetupMutex ();
1.1.1.12 root 3064: CloseHandle (hDriver);
3065: hDriver = INVALID_HANDLE_VALUE;
1.1 root 3066: return ERR_DRIVER_VERSION;
1.1.1.12 root 3067: }
1.1.1.11 root 3068: #else
3069: if (!bResult)
3070: DriverVersion = 0;
1.1 root 3071: #endif
1.1.1.11 root 3072: }
1.1 root 3073:
3074: return 0;
3075: }
3076:
1.1.1.5 root 3077:
1.1.1.10 root 3078: void ResetCurrentDirectory ()
3079: {
3080: char p[MAX_PATH];
3081: if (!IsNonInstallMode () && SHGetFolderPath (NULL, CSIDL_PROFILE, NULL, 0, p) == ERROR_SUCCESS)
3082: {
3083: SetCurrentDirectory (p);
3084: }
3085: else
3086: {
1.1.1.11 root 3087: GetModPath (p, sizeof (p));
1.1.1.10 root 3088: SetCurrentDirectory (p);
3089: }
3090: }
3091:
3092:
1.1.1.19 root 3093: BOOL BrowseFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter)
1.1.1.11 root 3094: {
1.1.1.19 root 3095: return BrowseFilesInDir (hwndDlg, stringId, NULL, lpszFileName, keepHistory, saveMode, browseFilter);
1.1.1.11 root 3096: }
3097:
3098:
1.1.1.19 root 3099: BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, char *initialDir, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter)
1.1 root 3100: {
1.1.1.7 root 3101: OPENFILENAMEW ofn;
3102: wchar_t file[TC_MAX_PATH] = { 0 };
1.1.1.11 root 3103: wchar_t wInitialDir[TC_MAX_PATH] = { 0 };
1.1.1.7 root 3104: wchar_t filter[1024];
1.1.1.17 root 3105: BOOL status = FALSE;
3106:
3107: CoInitialize (NULL);
1.1.1.7 root 3108:
1.1.1.10 root 3109: ZeroMemory (&ofn, sizeof (ofn));
1.1.1.7 root 3110: *lpszFileName = 0;
1.1.1.11 root 3111:
3112: if (initialDir)
3113: {
3114: swprintf_s (wInitialDir, sizeof (wInitialDir) / 2, L"%hs", initialDir);
3115: ofn.lpstrInitialDir = wInitialDir;
3116: }
3117:
1.1.1.10 root 3118: ofn.lStructSize = sizeof (ofn);
3119: ofn.hwndOwner = hwndDlg;
1.1.1.19 root 3120:
1.1.1.10 root 3121: wsprintfW (filter, L"%ls (*.*)%c*.*%c%ls (*.tc)%c*.tc%c%c",
3122: GetString ("ALL_FILES"), 0, 0, GetString ("TC_VOLUMES"), 0, 0, 0);
1.1.1.19 root 3123: ofn.lpstrFilter = browseFilter ? browseFilter : filter;
1.1.1.10 root 3124: ofn.nFilterIndex = 1;
3125: ofn.lpstrFile = file;
3126: ofn.nMaxFile = sizeof (file) / sizeof (file[0]);
3127: ofn.lpstrTitle = GetString (stringId);
3128: ofn.Flags = OFN_HIDEREADONLY
1.1.1.8 root 3129: | OFN_PATHMUSTEXIST
3130: | (keepHistory ? 0 : OFN_DONTADDTORECENT)
3131: | (saveMode ? OFN_OVERWRITEPROMPT : 0);
3132:
1.1.1.11 root 3133: if (!keepHistory)
3134: CleanLastVisitedMRU ();
3135:
1.1.1.8 root 3136: if (!saveMode)
1.1.1.7 root 3137: {
1.1.1.8 root 3138: if (!GetOpenFileNameW (&ofn))
1.1.1.17 root 3139: goto ret;
1.1.1.7 root 3140: }
1.1 root 3141: else
1.1.1.7 root 3142: {
1.1.1.8 root 3143: if (!GetSaveFileNameW (&ofn))
1.1.1.17 root 3144: goto ret;
1.1.1.7 root 3145: }
1.1.1.8 root 3146:
3147: WideCharToMultiByte (CP_ACP, 0, file, -1, lpszFileName, MAX_PATH, NULL, NULL);
1.1.1.9 root 3148:
1.1.1.11 root 3149: if (!keepHistory)
3150: CleanLastVisitedMRU ();
1.1.1.9 root 3151:
1.1.1.11 root 3152: ResetCurrentDirectory ();
1.1.1.17 root 3153: status = TRUE;
1.1.1.9 root 3154:
1.1.1.17 root 3155: ret:
3156: CoUninitialize();
3157: return status;
1.1.1.9 root 3158: }
3159:
3160:
1.1.1.19 root 3161: static char SelectMultipleFilesPath[131072];
1.1.1.9 root 3162: static int SelectMultipleFilesOffset;
3163:
3164: BOOL SelectMultipleFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory)
3165: {
3166: OPENFILENAMEW ofn;
1.1.1.20! root 3167: wchar_t file[0xffff * 2] = { 0 }; // The size must not exceed 0xffff*2 due to a bug in Windows 2000 and XP SP1
1.1.1.9 root 3168: wchar_t filter[1024];
1.1.1.17 root 3169: BOOL status = FALSE;
3170:
3171: CoInitialize (NULL);
1.1.1.9 root 3172:
1.1.1.10 root 3173: ZeroMemory (&ofn, sizeof (ofn));
1.1.1.9 root 3174:
3175: *lpszFileName = 0;
1.1.1.10 root 3176: ofn.lStructSize = sizeof (ofn);
3177: ofn.hwndOwner = hwndDlg;
3178: wsprintfW (filter, L"%ls (*.*)%c*.*%c%ls (*.tc)%c*.tc%c%c",
3179: GetString ("ALL_FILES"), 0, 0, GetString ("TC_VOLUMES"), 0, 0, 0);
3180: ofn.lpstrFilter = filter;
3181: ofn.nFilterIndex = 1;
3182: ofn.lpstrFile = file;
3183: ofn.nMaxFile = sizeof (file) / sizeof (file[0]);
3184: ofn.lpstrTitle = GetString (stringId);
3185: ofn.Flags = OFN_HIDEREADONLY
1.1.1.9 root 3186: | OFN_EXPLORER
3187: | OFN_PATHMUSTEXIST
3188: | OFN_ALLOWMULTISELECT
3189: | (keepHistory ? 0 : OFN_DONTADDTORECENT);
3190:
3191: if (!keepHistory)
3192: CleanLastVisitedMRU ();
3193:
1.1.1.11 root 3194: if (!GetOpenFileNameW (&ofn))
1.1.1.17 root 3195: goto ret;
1.1.1.11 root 3196:
1.1.1.9 root 3197: if (file[ofn.nFileOffset - 1] != 0)
3198: {
3199: // Single file selected
3200: WideCharToMultiByte (CP_ACP, 0, file, -1, lpszFileName, MAX_PATH, NULL, NULL);
3201: SelectMultipleFilesOffset = 0;
3202: }
3203: else
3204: {
3205: // Multiple files selected
3206: int n;
3207: wchar_t *f = file;
3208: char *s = SelectMultipleFilesPath;
3209: while ((n = WideCharToMultiByte (CP_ACP, 0, f, -1, s, MAX_PATH, NULL, NULL)) > 1)
3210: {
3211: f += n;
3212: s += n;
3213: }
3214:
3215: SelectMultipleFilesOffset = ofn.nFileOffset;
3216: SelectMultipleFilesNext (lpszFileName);
3217: }
3218:
1.1.1.11 root 3219: if (!keepHistory)
3220: CleanLastVisitedMRU ();
1.1.1.9 root 3221:
1.1.1.11 root 3222: ResetCurrentDirectory ();
1.1.1.17 root 3223: status = TRUE;
3224:
3225: ret:
3226: CoUninitialize();
3227: return status;
1.1.1.9 root 3228: }
3229:
3230:
3231: BOOL SelectMultipleFilesNext (char *lpszFileName)
3232: {
3233: if (SelectMultipleFilesOffset == 0)
3234: return FALSE;
3235:
1.1.1.19 root 3236: strncpy (lpszFileName, SelectMultipleFilesPath, TC_MAX_PATH);
3237: lpszFileName[TC_MAX_PATH - 1] = 0;
1.1.1.9 root 3238:
3239: if (lpszFileName[strlen (lpszFileName) - 1] != '\\')
3240: strcat (lpszFileName, "\\");
3241:
3242: strcat (lpszFileName, SelectMultipleFilesPath + SelectMultipleFilesOffset);
3243:
3244: SelectMultipleFilesOffset += strlen (SelectMultipleFilesPath + SelectMultipleFilesOffset) + 1;
3245: if (SelectMultipleFilesPath[SelectMultipleFilesOffset] == 0)
3246: SelectMultipleFilesOffset = 0;
3247:
1.1.1.8 root 3248: return TRUE;
1.1 root 3249: }
3250:
3251:
1.1.1.19 root 3252: static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData)
1.1.1.6 root 3253: {
1.1.1.7 root 3254: switch(uMsg) {
3255: case BFFM_INITIALIZED:
3256: {
3257: /* WParam is TRUE since we are passing a path.
3258: It would be FALSE if we were passing a pidl. */
3259: SendMessage (hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)pData);
3260: break;
3261: }
3262:
3263: case BFFM_SELCHANGED:
3264: {
3265: char szDir[TC_MAX_PATH];
3266:
3267: /* Set the status window to the currently selected path. */
3268: if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szDir))
3269: {
3270: SendMessage (hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
3271: }
3272: break;
3273: }
3274:
3275: default:
3276: break;
3277: }
3278:
3279: return 0;
3280: }
1.1.1.6 root 3281:
3282:
1.1.1.19 root 3283: BOOL BrowseDirectories (HWND hwndDlg, char *lpszTitle, char *dirName)
1.1.1.7 root 3284: {
3285: BROWSEINFOW bi;
3286: LPITEMIDLIST pidl;
3287: LPMALLOC pMalloc;
3288: BOOL bOK = FALSE;
1.1.1.6 root 3289:
1.1.1.17 root 3290: CoInitialize (NULL);
3291:
1.1.1.15 root 3292: if (SUCCEEDED (SHGetMalloc (&pMalloc)))
1.1.1.6 root 3293: {
1.1.1.15 root 3294: ZeroMemory (&bi, sizeof(bi));
1.1.1.7 root 3295: bi.hwndOwner = hwndDlg;
3296: bi.pszDisplayName = 0;
3297: bi.lpszTitle = GetString (lpszTitle);
3298: bi.pidlRoot = 0;
1.1.1.15 root 3299: bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
1.1.1.7 root 3300: bi.lpfn = BrowseCallbackProc;
3301: bi.lParam = (LPARAM)dirName;
1.1.1.6 root 3302:
1.1.1.7 root 3303: pidl = SHBrowseForFolderW (&bi);
1.1.1.15 root 3304: if (pidl != NULL)
1.1.1.7 root 3305: {
3306: if (SHGetPathFromIDList(pidl, dirName))
3307: {
3308: bOK = TRUE;
3309: }
3310:
1.1.1.15 root 3311: pMalloc->Free (pidl);
3312: pMalloc->Release();
1.1.1.7 root 3313: }
1.1.1.6 root 3314: }
3315:
1.1.1.17 root 3316: CoUninitialize();
3317:
1.1.1.7 root 3318: return bOK;
1.1.1.6 root 3319: }
3320:
3321:
1.1.1.15 root 3322: void handleError (HWND hwndDlg, int code)
1.1 root 3323: {
1.1.1.11 root 3324: WCHAR szTmp[4096];
1.1.1.7 root 3325:
3326: if (Silent) return;
1.1 root 3327:
3328: switch (code)
3329: {
3330: case ERR_OS_ERROR:
3331: handleWin32Error (hwndDlg);
3332: break;
3333: case ERR_OUTOFMEMORY:
1.1.1.7 root 3334: MessageBoxW (hwndDlg, GetString ("OUTOFMEMORY"), lpszTitle, ICON_HAND);
1.1 root 3335: break;
1.1.1.7 root 3336:
1.1 root 3337: case ERR_PASSWORD_WRONG:
1.1.1.11 root 3338: swprintf (szTmp, GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_WRONG" : "PASSWORD_WRONG"));
1.1.1.7 root 3339: if (CheckCapsLock (hwndDlg, TRUE))
3340: wcscat (szTmp, GetString ("PASSWORD_WRONG_CAPSLOCK_ON"));
3341:
1.1.1.15 root 3342: #ifdef TCMOUNT
3343: if (TCBootLoaderOnInactiveSysEncDrive ())
3344: {
3345: swprintf (szTmp, GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_OR_MODE_WRONG" : "PASSWORD_OR_MODE_WRONG"));
3346:
3347: if (CheckCapsLock (hwndDlg, TRUE))
3348: wcscat (szTmp, GetString ("PASSWORD_WRONG_CAPSLOCK_ON"));
3349:
3350: wcscat (szTmp, GetString ("SYSENC_MOUNT_WITHOUT_PBA_NOTE"));
3351: }
3352: #endif
3353:
1.1.1.7 root 3354: MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONWARNING);
1.1 root 3355: break;
1.1.1.7 root 3356:
1.1 root 3357: case ERR_DRIVE_NOT_FOUND:
1.1.1.7 root 3358: MessageBoxW (hwndDlg, GetString ("NOT_FOUND"), lpszTitle, ICON_HAND);
1.1 root 3359: break;
3360: case ERR_FILES_OPEN:
1.1.1.7 root 3361: MessageBoxW (hwndDlg, GetString ("OPENFILES_DRIVER"), lpszTitle, ICON_HAND);
1.1 root 3362: break;
3363: case ERR_FILES_OPEN_LOCK:
1.1.1.7 root 3364: MessageBoxW (hwndDlg, GetString ("OPENFILES_LOCK"), lpszTitle, ICON_HAND);
1.1 root 3365: break;
3366: case ERR_VOL_SIZE_WRONG:
1.1.1.7 root 3367: MessageBoxW (hwndDlg, GetString ("VOL_SIZE_WRONG"), lpszTitle, ICON_HAND);
1.1 root 3368: break;
3369: case ERR_COMPRESSION_NOT_SUPPORTED:
1.1.1.7 root 3370: MessageBoxW (hwndDlg, GetString ("COMPRESSION_NOT_SUPPORTED"), lpszTitle, ICON_HAND);
1.1 root 3371: break;
3372: case ERR_PASSWORD_CHANGE_VOL_TYPE:
1.1.1.7 root 3373: MessageBoxW (hwndDlg, GetString ("WRONG_VOL_TYPE"), lpszTitle, ICON_HAND);
1.1 root 3374: break;
3375: case ERR_VOL_SEEKING:
1.1.1.7 root 3376: MessageBoxW (hwndDlg, GetString ("VOL_SEEKING"), lpszTitle, ICON_HAND);
1.1 root 3377: break;
1.1.1.7 root 3378: case ERR_CIPHER_INIT_FAILURE:
3379: MessageBoxW (hwndDlg, GetString ("ERR_CIPHER_INIT_FAILURE"), lpszTitle, ICON_HAND);
3380: break;
3381: case ERR_CIPHER_INIT_WEAK_KEY:
3382: MessageBoxW (hwndDlg, GetString ("ERR_CIPHER_INIT_WEAK_KEY"), lpszTitle, ICON_HAND);
1.1 root 3383: break;
3384: case ERR_VOL_ALREADY_MOUNTED:
1.1.1.7 root 3385: MessageBoxW (hwndDlg, GetString ("VOL_ALREADY_MOUNTED"), lpszTitle, ICON_HAND);
1.1 root 3386: break;
3387: case ERR_FILE_OPEN_FAILED:
1.1.1.7 root 3388: MessageBoxW (hwndDlg, GetString ("FILE_OPEN_FAILED"), lpszTitle, ICON_HAND);
1.1 root 3389: break;
3390: case ERR_VOL_MOUNT_FAILED:
1.1.1.7 root 3391: MessageBoxW (hwndDlg, GetString ("VOL_MOUNT_FAILED"), lpszTitle, ICON_HAND);
1.1 root 3392: break;
3393: case ERR_NO_FREE_DRIVES:
1.1.1.7 root 3394: MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
1.1 root 3395: break;
3396: case ERR_ACCESS_DENIED:
1.1.1.7 root 3397: MessageBoxW (hwndDlg, GetString ("ACCESS_DENIED"), lpszTitle, ICON_HAND);
1.1 root 3398: break;
3399:
3400: case ERR_DRIVER_VERSION:
1.1.1.7 root 3401: wsprintfW (szTmp, GetString ("DRIVER_VERSION"), VERSION_STRING);
3402: MessageBoxW (hwndDlg, szTmp, lpszTitle, ICON_HAND);
1.1 root 3403: break;
3404:
3405: case ERR_NEW_VERSION_REQUIRED:
1.1.1.7 root 3406: MessageBoxW (hwndDlg, GetString ("NEW_VERSION_REQUIRED"), lpszTitle, ICON_HAND);
3407: break;
3408:
3409: case ERR_SELF_TESTS_FAILED:
3410: Error ("ERR_SELF_TESTS_FAILED");
1.1 root 3411: break;
3412:
1.1.1.13 root 3413: case ERR_VOL_FORMAT_BAD:
3414: Error ("ERR_VOL_FORMAT_BAD");
3415: break;
3416:
1.1.1.15 root 3417: case ERR_ENCRYPTION_NOT_COMPLETED:
3418: Error ("ERR_ENCRYPTION_NOT_COMPLETED");
3419: break;
3420:
1.1.1.19 root 3421: case ERR_NONSYS_INPLACE_ENC_INCOMPLETE:
3422: Error ("ERR_NONSYS_INPLACE_ENC_INCOMPLETE");
3423: break;
3424:
1.1.1.17 root 3425: case ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG:
3426: Error ("ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG");
3427: break;
3428:
1.1.1.15 root 3429: case ERR_PARAMETER_INCORRECT:
3430: Error ("ERR_PARAMETER_INCORRECT");
3431: break;
3432:
1.1.1.19 root 3433: case ERR_USER_ABORT:
1.1.1.6 root 3434: case ERR_DONT_REPORT:
1.1.1.19 root 3435: // A non-error
1.1.1.6 root 3436: break;
3437:
1.1 root 3438: default:
1.1.1.7 root 3439: wsprintfW (szTmp, GetString ("ERR_UNKNOWN"), code);
3440: MessageBoxW (hwndDlg, szTmp, lpszTitle, ICON_HAND);
1.1 root 3441: }
3442: }
3443:
1.1.1.7 root 3444: static BOOL CALLBACK LocalizeDialogEnum( HWND hwnd, LPARAM font)
1.1 root 3445: {
1.1.1.7 root 3446: // Localization of controls
1.1 root 3447:
1.1.1.7 root 3448: if (LocalizationActive)
1.1 root 3449: {
1.1.1.7 root 3450: int ctrlId = GetDlgCtrlID (hwnd);
3451: if (ctrlId != 0)
3452: {
3453: char name[10] = { 0 };
3454: GetClassName (hwnd, name, sizeof (name));
1.1.1.5 root 3455:
1.1.1.7 root 3456: if (_stricmp (name, "Button") == 0 || _stricmp (name, "Static") == 0)
3457: {
1.1.1.15 root 3458: wchar_t *str = (wchar_t *) GetDictionaryValueByInt (ctrlId);
1.1.1.7 root 3459: if (str != NULL)
3460: SetWindowTextW (hwnd, str);
3461: }
3462: }
3463: }
1.1 root 3464:
1.1.1.7 root 3465: // Font
3466: SendMessage (hwnd, WM_SETFONT, (WPARAM) font, 0);
3467:
3468: return TRUE;
3469: }
1.1 root 3470:
1.1.1.7 root 3471: void LocalizeDialog (HWND hwnd, char *stringId)
3472: {
1.1.1.10 root 3473: LastDialogId = stringId;
1.1.1.7 root 3474: SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) 'TRUE');
1.1.1.8 root 3475: SendMessage (hwnd, WM_SETFONT, (WPARAM) hUserFont, 0);
1.1.1.5 root 3476:
1.1.1.11 root 3477: if (stringId == NULL)
3478: SetWindowText (hwnd, "TrueCrypt");
1.1.1.13 root 3479: else
1.1.1.7 root 3480: SetWindowTextW (hwnd, GetString (stringId));
1.1.1.11 root 3481:
1.1.1.7 root 3482: if (hUserFont != 0)
3483: EnumChildWindows (hwnd, LocalizeDialogEnum, (LPARAM) hUserFont);
1.1.1.5 root 3484: }
3485:
3486: void OpenVolumeExplorerWindow (int driveNo)
3487: {
3488: char dosName[5];
3489: SHFILEINFO fInfo;
3490:
3491: sprintf (dosName, "%c:\\", (char) driveNo + 'A');
3492:
3493: // Force explorer to discover the drive
3494: SHGetFileInfo (dosName, 0, &fInfo, sizeof (fInfo), 0);
3495:
3496: ShellExecute (NULL, "open", dosName, NULL, NULL, SW_SHOWNORMAL);
3497: }
3498:
3499: static BOOL explorerCloseSent;
1.1.1.11 root 3500: static HWND explorerTopLevelWindow;
1.1.1.5 root 3501:
1.1.1.11 root 3502: static BOOL CALLBACK CloseVolumeExplorerWindowsChildEnum (HWND hwnd, LPARAM driveStr)
1.1.1.5 root 3503: {
1.1.1.11 root 3504: char s[MAX_PATH];
3505: SendMessage (hwnd, WM_GETTEXT, sizeof (s), (LPARAM) s);
1.1.1.5 root 3506:
1.1.1.11 root 3507: if (strstr (s, (char *) driveStr) != NULL)
1.1.1.5 root 3508: {
1.1.1.11 root 3509: PostMessage (explorerTopLevelWindow, WM_CLOSE, 0, 0);
3510: explorerCloseSent = TRUE;
3511: return FALSE;
3512: }
1.1.1.5 root 3513:
1.1.1.11 root 3514: return TRUE;
3515: }
3516:
3517: static BOOL CALLBACK CloseVolumeExplorerWindowsEnum (HWND hwnd, LPARAM driveNo)
3518: {
3519: char driveStr[10];
3520: char s[MAX_PATH];
3521:
3522: sprintf (driveStr, "%c:\\", driveNo + 'A');
3523:
3524: GetClassName (hwnd, s, sizeof s);
3525: if (strcmp (s, "CabinetWClass") == 0)
3526: {
3527: GetWindowText (hwnd, s, sizeof s);
3528: if (strstr (s, driveStr) != NULL)
1.1.1.5 root 3529: {
3530: PostMessage (hwnd, WM_CLOSE, 0, 0);
3531: explorerCloseSent = TRUE;
1.1.1.12 root 3532: return TRUE;
1.1.1.5 root 3533: }
3534:
1.1.1.11 root 3535: explorerTopLevelWindow = hwnd;
3536: EnumChildWindows (hwnd, CloseVolumeExplorerWindowsChildEnum, (LPARAM) driveStr);
1.1.1.5 root 3537: }
1.1.1.11 root 3538:
1.1.1.5 root 3539: return TRUE;
3540: }
3541:
3542: BOOL CloseVolumeExplorerWindows (HWND hwnd, int driveNo)
3543: {
1.1.1.19 root 3544: if (driveNo >= 0)
3545: {
3546: explorerCloseSent = FALSE;
3547: EnumWindows (CloseVolumeExplorerWindowsEnum, (LPARAM) driveNo);
3548: }
1.1.1.5 root 3549:
3550: return explorerCloseSent;
3551: }
3552:
1.1.1.7 root 3553: void GetSizeString (unsigned __int64 size, wchar_t *str)
3554: {
3555: static wchar_t *b, *kb, *mb, *gb, *tb, *pb;
3556: static int serNo;
3557:
3558: if (b == NULL || serNo != LocalizationSerialNo)
3559: {
3560: serNo = LocalizationSerialNo;
3561: kb = GetString ("KB");
3562: mb = GetString ("MB");
3563: gb = GetString ("GB");
3564: tb = GetString ("TB");
3565: pb = GetString ("PB");
3566: b = GetString ("BYTE");
3567: }
3568:
3569: if (size > 1024I64*1024*1024*1024*1024*99)
3570: swprintf (str, L"%I64d %s", size/1024/1024/1024/1024/1024, pb);
3571: else if (size > 1024I64*1024*1024*1024*1024)
3572: swprintf (str, L"%.1f %s",(double)(size/1024.0/1024/1024/1024/1024), pb);
3573: else if (size > 1024I64*1024*1024*1024*99)
3574: swprintf (str, L"%I64d %s",size/1024/1024/1024/1024, tb);
3575: else if (size > 1024I64*1024*1024*1024)
3576: swprintf (str, L"%.1f %s",(double)(size/1024.0/1024/1024/1024), tb);
3577: else if (size > 1024I64*1024*1024*99)
3578: swprintf (str, L"%I64d %s",size/1024/1024/1024, gb);
3579: else if (size > 1024I64*1024*1024)
3580: swprintf (str, L"%.1f %s",(double)(size/1024.0/1024/1024), gb);
3581: else if (size > 1024I64*1024*99)
3582: swprintf (str, L"%I64d %s", size/1024/1024, mb);
3583: else if (size > 1024I64*1024)
3584: swprintf (str, L"%.1f %s",(double)(size/1024.0/1024), mb);
1.1.1.19 root 3585: else if (size >= 1024I64)
1.1.1.7 root 3586: swprintf (str, L"%I64d %s", size/1024, kb);
3587: else
3588: swprintf (str, L"%I64d %s", size, b);
3589: }
1.1.1.5 root 3590:
3591: #ifndef SETUP
1.1.1.7 root 3592: void GetSpeedString (unsigned __int64 speed, wchar_t *str)
1.1.1.5 root 3593: {
1.1.1.7 root 3594: static wchar_t *b, *kb, *mb, *gb, *tb, *pb;
3595: static int serNo;
3596:
3597: if (b == NULL || serNo != LocalizationSerialNo)
3598: {
3599: serNo = LocalizationSerialNo;
3600: kb = GetString ("KB_PER_SEC");
3601: mb = GetString ("MB_PER_SEC");
3602: gb = GetString ("GB_PER_SEC");
3603: tb = GetString ("TB_PER_SEC");
3604: pb = GetString ("PB_PER_SEC");
3605: b = GetString ("B_PER_SEC");
3606: }
3607:
1.1.1.5 root 3608: if (speed > 1024I64*1024*1024*1024*1024*99)
1.1.1.7 root 3609: swprintf (str, L"%I64d %s", speed/1024/1024/1024/1024/1024, pb);
1.1.1.5 root 3610: else if (speed > 1024I64*1024*1024*1024*1024)
1.1.1.7 root 3611: swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024/1024/1024/1024), pb);
1.1.1.5 root 3612: else if (speed > 1024I64*1024*1024*1024*99)
1.1.1.7 root 3613: swprintf (str, L"%I64d %s",speed/1024/1024/1024/1024, tb);
1.1.1.5 root 3614: else if (speed > 1024I64*1024*1024*1024)
1.1.1.7 root 3615: swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024/1024/1024), tb);
1.1.1.5 root 3616: else if (speed > 1024I64*1024*1024*99)
1.1.1.7 root 3617: swprintf (str, L"%I64d %s",speed/1024/1024/1024, gb);
1.1.1.5 root 3618: else if (speed > 1024I64*1024*1024)
1.1.1.7 root 3619: swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024/1024), gb);
1.1.1.5 root 3620: else if (speed > 1024I64*1024*99)
1.1.1.7 root 3621: swprintf (str, L"%I64d %s", speed/1024/1024, mb);
1.1.1.5 root 3622: else if (speed > 1024I64*1024)
1.1.1.7 root 3623: swprintf (str, L"%.1f %s",(double)(speed/1024.0/1024), mb);
3624: else if (speed > 1024I64)
3625: swprintf (str, L"%I64d %s", speed/1024, kb);
1.1.1.5 root 3626: else
1.1.1.7 root 3627: swprintf (str, L"%I64d %s", speed, b);
1.1.1.5 root 3628: }
3629:
3630: static void DisplayBenchmarkResults (HWND hwndDlg)
3631: {
1.1.1.7 root 3632: wchar_t item1[100]={0};
3633: LVITEMW LvItem;
1.1.1.5 root 3634: HWND hList = GetDlgItem (hwndDlg, IDC_RESULTS);
3635: int ea, i;
3636: BOOL unsorted = TRUE;
1.1.1.7 root 3637: BENCHMARK_REC tmp_line;
1.1.1.5 root 3638:
3639: /* Sort the list */
3640:
3641: switch (benchmarkSortMethod)
3642: {
3643: case BENCHMARK_SORT_BY_SPEED:
3644:
3645: while (unsorted)
3646: {
3647: unsorted = FALSE;
3648: for (i = 0; i < benchmarkTotalItems - 1; i++)
3649: {
3650: if (benchmarkTable[i].meanBytesPerSec < benchmarkTable[i+1].meanBytesPerSec)
3651: {
3652: unsorted = TRUE;
3653: memcpy (&tmp_line, &benchmarkTable[i], sizeof(BENCHMARK_REC));
3654: memcpy (&benchmarkTable[i], &benchmarkTable[i+1], sizeof(BENCHMARK_REC));
3655: memcpy (&benchmarkTable[i+1], &tmp_line, sizeof(BENCHMARK_REC));
3656: }
3657: }
3658: }
3659: break;
3660:
3661: case BENCHMARK_SORT_BY_NAME:
3662:
3663: while (unsorted)
3664: {
3665: unsorted = FALSE;
3666: for (i = 0; i < benchmarkTotalItems - 1; i++)
3667: {
3668: if (benchmarkTable[i].id > benchmarkTable[i+1].id)
3669: {
3670: unsorted = TRUE;
3671: memcpy (&tmp_line, &benchmarkTable[i], sizeof(BENCHMARK_REC));
3672: memcpy (&benchmarkTable[i], &benchmarkTable[i+1], sizeof(BENCHMARK_REC));
3673: memcpy (&benchmarkTable[i+1], &tmp_line, sizeof(BENCHMARK_REC));
3674: }
3675: }
3676: }
3677: break;
3678: }
3679:
3680: /* Render the results */
3681:
3682: SendMessage (hList,LVM_DELETEALLITEMS,0,(LPARAM)&LvItem);
3683:
3684: for (i = 0; i < benchmarkTotalItems; i++)
3685: {
3686: ea = benchmarkTable[i].id;
3687:
3688: memset (&LvItem,0,sizeof(LvItem));
3689: LvItem.mask = LVIF_TEXT;
1.1.1.7 root 3690: LvItem.iItem = i;
1.1.1.5 root 3691: LvItem.iSubItem = 0;
1.1.1.7 root 3692: LvItem.pszText = (LPWSTR) benchmarkTable[i].name;
3693: SendMessageW (hList, LVM_INSERTITEM, 0, (LPARAM)&LvItem);
1.1.1.5 root 3694:
1.1.1.7 root 3695: #if PKCS5_BENCHMARKS
3696: wcscpy (item1, L"-");
3697: #else
3698: GetSpeedString ((unsigned __int64) (benchmarkLastBufferSize / ((float) benchmarkTable[i].encSpeed / benchmarkPerformanceFrequency.QuadPart)), item1);
3699: #endif
1.1.1.5 root 3700: LvItem.iSubItem = 1;
3701: LvItem.pszText = item1;
3702:
1.1.1.7 root 3703: SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem);
3704:
3705: #if PKCS5_BENCHMARKS
3706: wcscpy (item1, L"-");
3707: #else
3708: GetSpeedString ((unsigned __int64) (benchmarkLastBufferSize / ((float) benchmarkTable[i].decSpeed / benchmarkPerformanceFrequency.QuadPart)), item1);
3709: #endif
1.1.1.5 root 3710: LvItem.iSubItem = 2;
3711: LvItem.pszText = item1;
3712:
1.1.1.7 root 3713: SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem);
1.1.1.5 root 3714:
1.1.1.7 root 3715: #if PKCS5_BENCHMARKS
3716: swprintf (item1, L"%d t", benchmarkTable[i].encSpeed);
3717: #else
3718: GetSpeedString (benchmarkTable[i].meanBytesPerSec, item1);
3719: #endif
1.1.1.5 root 3720: LvItem.iSubItem = 3;
3721: LvItem.pszText = item1;
3722:
1.1.1.7 root 3723: SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem);
1.1.1.5 root 3724: }
3725: }
3726:
3727: static BOOL PerformBenchmark(HWND hwndDlg)
3728: {
3729: LARGE_INTEGER performanceCountStart, performanceCountEnd;
3730: BYTE *lpTestBuffer;
1.1.1.8 root 3731: PCRYPTO_INFO ci = NULL;
1.1.1.17 root 3732: UINT64_STRUCT startDataUnitNo;
3733:
3734: startDataUnitNo.Value = 0;
3735:
1.1.1.7 root 3736: #if !(PKCS5_BENCHMARKS || HASH_FNC_BENCHMARKS)
1.1.1.8 root 3737: ci = crypto_open ();
3738: if (!ci)
3739: return FALSE;
1.1.1.7 root 3740: #endif
1.1.1.5 root 3741:
3742: if (QueryPerformanceFrequency (&benchmarkPerformanceFrequency) == 0)
3743: {
1.1.1.7 root 3744: MessageBoxW (hwndDlg, GetString ("ERR_PERF_COUNTER"), lpszTitle, ICON_HAND);
1.1.1.5 root 3745: return FALSE;
3746: }
3747:
1.1.1.15 root 3748: lpTestBuffer = (BYTE *) malloc(benchmarkBufferSize - (benchmarkBufferSize % 16));
1.1.1.5 root 3749: if (lpTestBuffer == NULL)
3750: {
1.1.1.7 root 3751: MessageBoxW (hwndDlg, GetString ("ERR_MEM_ALLOC"), lpszTitle, ICON_HAND);
1.1.1.5 root 3752: return FALSE;
3753: }
3754: VirtualLock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16));
3755:
1.1.1.11 root 3756: WaitCursor ();
1.1.1.5 root 3757: benchmarkTotalItems = 0;
1.1.1.7 root 3758:
1.1.1.13 root 3759: #if !(PKCS5_BENCHMARKS || HASH_FNC_BENCHMARKS)
1.1.1.11 root 3760: // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency
3761: // gradually changes depending on CPU load).
3762: ci->ea = EAGetFirst();
1.1.1.13 root 3763: if (!EAInit (ci->ea, ci->master_keydata, ci->ks))
1.1.1.11 root 3764: {
1.1.1.13 root 3765: ci->mode = FIRST_MODE_OF_OPERATION_ID;
1.1.1.11 root 3766: if (EAInitMode (ci))
3767: {
3768: int i;
3769:
3770: for (i = 0; i < 2; i++)
3771: {
1.1.1.17 root 3772: EncryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
3773: DecryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
1.1.1.11 root 3774: }
3775: }
3776: }
1.1.1.13 root 3777: #endif
1.1.1.11 root 3778:
1.1.1.7 root 3779: #if HASH_FNC_BENCHMARKS
3780:
3781: /* Measures the speed at which each of the hash algorithms processes the message to produce
3782: a single digest.
3783:
3784: The hash algorithm benchmarks are included here for development purposes only. Do not enable
3785: them when building a public release (the benchmark GUI strings wouldn't make sense). */
3786:
3787: {
3788: BYTE *digest [MAX_DIGESTSIZE];
3789: WHIRLPOOL_CTX wctx;
3790: RMD160_CTX rctx;
3791: sha1_ctx sctx;
1.1.1.13 root 3792: sha512_ctx s2ctx;
1.1.1.7 root 3793: int hid;
3794:
1.1.1.13 root 3795: for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
1.1.1.7 root 3796: {
3797: if (QueryPerformanceCounter (&performanceCountStart) == 0)
3798: goto counter_error;
3799:
3800: switch (hid)
3801: {
3802: case SHA1:
3803: sha1_begin (&sctx);
3804: sha1_hash (lpTestBuffer, benchmarkBufferSize, &sctx);
3805: sha1_end ((unsigned char *) digest, &sctx);
3806: break;
3807:
1.1.1.13 root 3808: case SHA512:
3809: sha512_begin (&s2ctx);
3810: sha512_hash (lpTestBuffer, benchmarkBufferSize, &s2ctx);
3811: sha512_end ((unsigned char *) digest, &s2ctx);
3812: break;
3813:
1.1.1.7 root 3814: case RIPEMD160:
3815: RMD160Init(&rctx);
3816: RMD160Update(&rctx, lpTestBuffer, benchmarkBufferSize);
3817: RMD160Final((unsigned char *) digest, &rctx);
3818: break;
3819:
3820: case WHIRLPOOL:
3821: WHIRLPOOL_init (&wctx);
3822: WHIRLPOOL_add (lpTestBuffer, benchmarkBufferSize * 8, &wctx);
3823: WHIRLPOOL_finalize (&wctx, (unsigned char *) digest);
3824: break;
3825: }
3826:
3827: if (QueryPerformanceCounter (&performanceCountEnd) == 0)
3828: goto counter_error;
3829:
3830: benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
3831:
3832: benchmarkTable[benchmarkTotalItems].decSpeed = benchmarkTable[benchmarkTotalItems].encSpeed;
3833: benchmarkTable[benchmarkTotalItems].id = hid;
3834: 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 3835: sprintf (benchmarkTable[benchmarkTotalItems].name, "%s", HashGetName(hid));
1.1.1.7 root 3836:
3837: benchmarkTotalItems++;
3838: }
3839: }
3840:
3841: #elif PKCS5_BENCHMARKS // #if HASH_FNC_BENCHMARKS
3842:
3843: /* Measures the time that it takes for the PKCS-5 routine to derive a header key using
3844: each of the implemented PRF algorithms.
3845:
3846: The PKCS-5 benchmarks are included here for development purposes only. Do not enable
3847: them when building a public release (the benchmark GUI strings wouldn't make sense). */
3848: {
3849: int thid, i;
1.1.1.13 root 3850: char dk[MASTER_KEYDATA_SIZE];
1.1.1.7 root 3851: 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"};
3852:
1.1.1.13 root 3853: for (thid = FIRST_PRF_ID; thid <= LAST_PRF_ID; thid++)
1.1.1.7 root 3854: {
3855: if (QueryPerformanceCounter (&performanceCountStart) == 0)
3856: goto counter_error;
3857:
3858: for (i = 1; i <= 5; i++)
3859: {
3860: switch (thid)
3861: {
3862: case SHA1:
3863: /* PKCS-5 test with HMAC-SHA-1 used as the PRF */
1.1.1.13 root 3864: derive_key_sha1 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
3865: break;
3866:
3867: case SHA512:
3868: /* PKCS-5 test with HMAC-SHA-512 used as the PRF */
3869: derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
1.1.1.7 root 3870: break;
3871:
3872: case RIPEMD160:
3873: /* PKCS-5 test with HMAC-RIPEMD-160 used as the PRF */
1.1.1.13 root 3874: derive_key_ripemd160 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
1.1.1.7 root 3875: break;
3876:
3877: case WHIRLPOOL:
3878: /* PKCS-5 test with HMAC-Whirlpool used as the PRF */
1.1.1.13 root 3879: derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE);
1.1.1.7 root 3880: break;
3881: }
3882: }
3883:
3884: if (QueryPerformanceCounter (&performanceCountEnd) == 0)
3885: goto counter_error;
3886:
3887: benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
3888: benchmarkTable[benchmarkTotalItems].id = thid;
3889: sprintf (benchmarkTable[benchmarkTotalItems].name, "%s", get_pkcs5_prf_name (thid));
3890:
3891: benchmarkTotalItems++;
3892: }
3893: }
3894:
3895: #else // #elif PKCS5_BENCHMARKS
3896:
3897: /* Encryption algorithm benchmarks */
1.1.1.8 root 3898:
3899: for (ci->ea = EAGetFirst(); ci->ea != 0; ci->ea = EAGetNext(ci->ea))
1.1.1.5 root 3900: {
1.1.1.11 root 3901: if (!EAIsFormatEnabled (ci->ea))
1.1.1.8 root 3902: continue;
3903:
1.1.1.13 root 3904: EAInit (ci->ea, ci->master_keydata, ci->ks);
1.1.1.8 root 3905:
1.1.1.13 root 3906: ci->mode = FIRST_MODE_OF_OPERATION_ID;
1.1.1.19 root 3907: EAInitMode (ci);
1.1.1.8 root 3908:
1.1.1.5 root 3909: if (QueryPerformanceCounter (&performanceCountStart) == 0)
3910: goto counter_error;
3911:
1.1.1.17 root 3912: EncryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
1.1.1.5 root 3913:
3914: if (QueryPerformanceCounter (&performanceCountEnd) == 0)
3915: goto counter_error;
3916:
3917: benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
3918:
3919: if (QueryPerformanceCounter (&performanceCountStart) == 0)
3920: goto counter_error;
3921:
1.1.1.17 root 3922: DecryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci);
1.1.1.8 root 3923:
1.1.1.5 root 3924: if (QueryPerformanceCounter (&performanceCountEnd) == 0)
3925: goto counter_error;
3926:
3927: benchmarkTable[benchmarkTotalItems].decSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
1.1.1.8 root 3928: benchmarkTable[benchmarkTotalItems].id = ci->ea;
1.1.1.5 root 3929: 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 3930: EAGetName (benchmarkTable[benchmarkTotalItems].name, ci->ea);
1.1.1.5 root 3931:
3932: benchmarkTotalItems++;
3933: }
3934:
1.1.1.7 root 3935: #endif // #elif PKCS5_BENCHMARKS (#else)
3936:
1.1.1.8 root 3937: if (ci)
3938: crypto_close (ci);
3939:
1.1.1.5 root 3940: VirtualUnlock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16));
3941:
3942: free(lpTestBuffer);
3943:
3944: benchmarkLastBufferSize = benchmarkBufferSize;
3945:
3946: DisplayBenchmarkResults(hwndDlg);
3947:
1.1.1.7 root 3948: EnableWindow (GetDlgItem (hwndDlg, IDC_PERFORM_BENCHMARK), TRUE);
1.1.1.5 root 3949: EnableWindow (GetDlgItem (hwndDlg, IDCLOSE), TRUE);
3950:
3951: NormalCursor ();
3952: return TRUE;
3953:
3954: counter_error:
1.1.1.8 root 3955:
3956: if (ci)
3957: crypto_close (ci);
1.1.1.5 root 3958:
3959: VirtualUnlock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16));
3960:
3961: free(lpTestBuffer);
3962:
3963: NormalCursor ();
3964:
1.1.1.7 root 3965: EnableWindow (GetDlgItem (hwndDlg, IDC_PERFORM_BENCHMARK), TRUE);
1.1.1.5 root 3966: EnableWindow (GetDlgItem (hwndDlg, IDCLOSE), TRUE);
3967:
1.1.1.7 root 3968: MessageBoxW (hwndDlg, GetString ("ERR_PERF_COUNTER"), lpszTitle, ICON_HAND);
1.1.1.5 root 3969: return FALSE;
3970: }
3971:
3972:
1.1.1.12 root 3973: BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
1.1.1.5 root 3974: {
3975: WORD lw = LOWORD (wParam);
3976: LPARAM nIndex;
3977: HWND hCboxSortMethod = GetDlgItem (hwndDlg, IDC_BENCHMARK_SORT_METHOD);
3978: HWND hCboxBufferSize = GetDlgItem (hwndDlg, IDC_BENCHMARK_BUFFER_SIZE);
3979:
3980: switch (msg)
3981: {
3982: case WM_INITDIALOG:
3983: {
1.1.1.7 root 3984: LVCOLUMNW LvCol;
3985: wchar_t s[128];
1.1.1.5 root 3986: HWND hList = GetDlgItem (hwndDlg, IDC_RESULTS);
3987:
1.1.1.7 root 3988: LocalizeDialog (hwndDlg, "IDD_BENCHMARK_DLG");
1.1.1.5 root 3989:
3990: benchmarkBufferSize = BENCHMARK_DEFAULT_BUF_SIZE;
3991: benchmarkSortMethod = BENCHMARK_SORT_BY_SPEED;
3992:
3993: SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
1.1.1.7 root 3994: LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP
1.1.1.5 root 3995: );
3996:
3997: memset (&LvCol,0,sizeof(LvCol));
3998: LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
1.1.1.12 root 3999: LvCol.pszText = GetString ("ALGORITHM");
4000: LvCol.cx = CompensateXDPI (114);
1.1.1.5 root 4001: LvCol.fmt = LVCFMT_LEFT;
1.1.1.7 root 4002: SendMessage (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&LvCol);
1.1.1.5 root 4003:
1.1.1.12 root 4004: LvCol.pszText = GetString ("ENCRYPTION");
4005: LvCol.cx = CompensateXDPI (80);
1.1.1.5 root 4006: LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7 root 4007: SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&LvCol);
1.1.1.5 root 4008:
1.1.1.12 root 4009: LvCol.pszText = GetString ("DECRYPTION");
4010: LvCol.cx = CompensateXDPI (80);
1.1.1.5 root 4011: LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7 root 4012: SendMessageW (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol);
1.1.1.5 root 4013:
1.1.1.12 root 4014: LvCol.pszText = GetString ("MEAN");
4015: LvCol.cx = CompensateXDPI (80);
1.1.1.5 root 4016: LvCol.fmt = LVCFMT_RIGHT;
1.1.1.7 root 4017: SendMessageW (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol);
1.1.1.5 root 4018:
4019: /* Combo boxes */
4020:
4021: // Sort method
4022:
4023: SendMessage (hCboxSortMethod, CB_RESETCONTENT, 0, 0);
4024:
1.1.1.7 root 4025: nIndex = SendMessageW (hCboxSortMethod, CB_ADDSTRING, 0, (LPARAM) GetString ("ALPHABETICAL_CATEGORIZED"));
1.1.1.5 root 4026: SendMessage (hCboxSortMethod, CB_SETITEMDATA, nIndex, (LPARAM) 0);
4027:
1.1.1.7 root 4028: nIndex = SendMessageW (hCboxSortMethod, CB_ADDSTRING, 0, (LPARAM) GetString ("MEAN_SPEED"));
1.1.1.5 root 4029: SendMessage (hCboxSortMethod, CB_SETITEMDATA, nIndex, (LPARAM) 0);
4030:
4031: SendMessage (hCboxSortMethod, CB_SETCURSEL, 1, 0); // Default sort method
4032:
4033: // Buffer size
4034:
4035: SendMessage (hCboxBufferSize, CB_RESETCONTENT, 0, 0);
4036:
1.1.1.7 root 4037: swprintf (s, L"100 %s", GetString ("KB"));
4038: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4039: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 100 * BYTES_PER_KB);
4040:
1.1.1.7 root 4041: swprintf (s, L"500 %s", GetString ("KB"));
4042: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4043: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 500 * BYTES_PER_KB);
4044:
1.1.1.7 root 4045: swprintf (s, L"1 %s", GetString ("MB"));
4046: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4047: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 1 * BYTES_PER_MB);
4048:
1.1.1.7 root 4049: swprintf (s, L"5 %s", GetString ("MB"));
4050: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4051: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 5 * BYTES_PER_MB);
4052:
1.1.1.7 root 4053: swprintf (s, L"10 %s", GetString ("MB"));
4054: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4055: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 10 * BYTES_PER_MB);
4056:
1.1.1.7 root 4057: swprintf (s, L"50 %s", GetString ("MB"));
4058: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4059: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 50 * BYTES_PER_MB);
4060:
1.1.1.7 root 4061: swprintf (s, L"100 %s", GetString ("MB"));
4062: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4063: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 100 * BYTES_PER_MB);
4064:
1.1.1.7 root 4065: swprintf (s, L"200 %s", GetString ("MB"));
4066: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4067: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 200 * BYTES_PER_MB);
4068:
1.1.1.7 root 4069: swprintf (s, L"500 %s", GetString ("MB"));
4070: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4071: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 500 * BYTES_PER_MB);
4072:
1.1.1.7 root 4073: swprintf (s, L"1 %s", GetString ("GB"));
4074: nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s);
1.1.1.5 root 4075: SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 1 * BYTES_PER_GB);
4076:
1.1.1.17 root 4077: SendMessage (hCboxBufferSize, CB_SETCURSEL, 3, 0); // Default buffer size
1.1.1.5 root 4078:
4079: return 1;
4080: }
4081: break;
4082:
4083: case WM_COMMAND:
4084: case WM_NOTIFY:
4085:
4086: if (lw == IDC_BENCHMARK_SORT_METHOD)
4087: {
4088: nIndex = SendMessage (hCboxSortMethod, CB_GETCURSEL, 0, 0);
4089: if (nIndex != benchmarkSortMethod)
4090: {
4091: benchmarkSortMethod = nIndex;
4092: DisplayBenchmarkResults (hwndDlg);
4093: }
1.1.1.7 root 4094: return 1;
1.1.1.5 root 4095: }
4096:
1.1.1.7 root 4097: if (lw == IDC_PERFORM_BENCHMARK)
1.1.1.5 root 4098: {
4099: nIndex = SendMessage (hCboxBufferSize, CB_GETCURSEL, 0, 0);
4100: benchmarkBufferSize = SendMessage (hCboxBufferSize, CB_GETITEMDATA, nIndex, 0);
4101:
1.1.1.11 root 4102: if (PerformBenchmark (hwndDlg) == FALSE)
1.1.1.5 root 4103: {
4104: EndDialog (hwndDlg, IDCLOSE);
4105: }
1.1.1.7 root 4106: return 1;
1.1.1.5 root 4107: }
1.1.1.7 root 4108: if (lw == IDCLOSE || lw == IDCANCEL)
1.1.1.5 root 4109: {
4110: EndDialog (hwndDlg, IDCLOSE);
1.1.1.7 root 4111: return 1;
1.1.1.5 root 4112: }
4113: return 0;
4114:
4115: break;
4116:
4117: case WM_CLOSE:
4118: EndDialog (hwndDlg, IDCLOSE);
1.1.1.7 root 4119: return 1;
1.1.1.5 root 4120:
4121: break;
4122:
4123: }
4124: return 0;
4125: }
4126:
4127:
1.1.1.7 root 4128:
4129: /* Except in response to the WM_INITDIALOG message, the dialog box procedure
4130: should return nonzero if it processes the message, and zero if it does
4131: not. - see DialogProc */
1.1.1.12 root 4132: BOOL CALLBACK
1.1.1.7 root 4133: KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
4134: {
4135: WORD lw = LOWORD (wParam);
4136: WORD hw = HIWORD (wParam);
4137: static unsigned char randPool [RNG_POOL_SIZE];
4138: static unsigned char lastRandPool [RNG_POOL_SIZE];
1.1.1.13 root 4139: static char outputDispBuffer [RNG_POOL_SIZE * 3 + RANDPOOL_DISPLAY_ROWS + 2];
1.1.1.10 root 4140: static BOOL bDisplayPoolContents = TRUE;
1.1.1.13 root 4141: static BOOL bRandPoolDispAscii = FALSE;
1.1.1.7 root 4142: int hash_algo = RandGetHashFunction();
4143: int hid;
4144:
4145: switch (msg)
4146: {
4147: case WM_INITDIALOG:
1.1.1.5 root 4148: {
1.1.1.7 root 4149: HWND hComboBox = GetDlgItem (hwndDlg, IDC_PRF_ID);
4150:
4151: VirtualLock (randPool, sizeof(randPool));
4152: VirtualLock (lastRandPool, sizeof(lastRandPool));
4153: VirtualLock (outputDispBuffer, sizeof(outputDispBuffer));
4154:
4155: LocalizeDialog (hwndDlg, "IDD_KEYFILE_GENERATOR_DLG");
4156:
4157: SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
1.1.1.13 root 4158: for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++)
1.1.1.7 root 4159: {
1.1.1.13 root 4160: if (!HashIsDeprecated (hid))
4161: AddComboPair (hComboBox, HashGetName(hid), hid);
1.1.1.7 root 4162: }
4163: SelectAlgo (hComboBox, &hash_algo);
4164:
4165: SetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS, bDisplayPoolContents);
4166:
4167: #ifndef VOLFORMAT
4168: if (Randinit ())
4169: {
4170: Error ("INIT_RAND");
4171: EndDialog (hwndDlg, IDCLOSE);
4172: }
4173: #endif
1.1.1.13 root 4174: SetTimer (hwndDlg, 0xfd, RANDPOOL_DISPLAY_REFRESH_INTERVAL, NULL);
1.1.1.7 root 4175: SendMessage (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE);
4176: return 1;
4177: }
4178:
4179: case WM_TIMER:
4180: {
4181: char tmp[4];
1.1.1.13 root 4182: unsigned char tmpByte;
1.1.1.7 root 4183: int col, row;
4184:
4185: if (bDisplayPoolContents)
4186: {
4187: RandpeekBytes (randPool, sizeof (randPool));
4188:
4189: if (memcmp (lastRandPool, randPool, sizeof(lastRandPool)) != 0)
4190: {
4191: outputDispBuffer[0] = 0;
4192:
1.1.1.13 root 4193: for (row = 0; row < RANDPOOL_DISPLAY_ROWS; row++)
1.1.1.7 root 4194: {
1.1.1.13 root 4195: for (col = 0; col < RANDPOOL_DISPLAY_COLUMNS; col++)
1.1.1.7 root 4196: {
1.1.1.13 root 4197: tmpByte = randPool[row * RANDPOOL_DISPLAY_COLUMNS + col];
4198:
4199: sprintf (tmp, bRandPoolDispAscii ? ((tmpByte >= 32 && tmpByte < 255 && tmpByte != '&') ? " %c " : " . ") : "%02X ", tmpByte);
1.1.1.7 root 4200: strcat (outputDispBuffer, tmp);
4201: }
4202: strcat (outputDispBuffer, "\n");
4203: }
4204: SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), outputDispBuffer);
4205:
4206: memcpy (lastRandPool, randPool, sizeof(lastRandPool));
4207: }
4208: }
4209: return 1;
4210: }
4211:
4212: case WM_COMMAND:
4213:
4214: if (lw == IDCLOSE || lw == IDCANCEL)
4215: {
4216: goto exit;
4217: }
4218:
4219: if (lw == IDC_PRF_ID && hw == CBN_SELCHANGE)
4220: {
4221: hid = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETCURSEL, 0, 0);
4222: hash_algo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETITEMDATA, hid, 0);
4223: RandSetHashFunction (hash_algo);
4224: return 1;
4225: }
4226:
4227: if (lw == IDC_DISPLAY_POOL_CONTENTS)
4228: {
4229: if (!(bDisplayPoolContents = GetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS)))
1.1.1.13 root 4230: {
4231: char tmp[RNG_POOL_SIZE+1];
4232:
4233: memset (tmp, ' ', sizeof(tmp));
4234: tmp [RNG_POOL_SIZE] = 0;
4235: SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp);
4236: }
1.1.1.7 root 4237: }
4238:
4239: if (lw == IDC_GENERATE_AND_SAVE_KEYFILE)
4240: {
4241: char szFileName [TC_MAX_PATH];
4242: unsigned char keyfile [MAX_PASSWORD];
4243: int fhKeyfile = -1;
4244:
4245: /* Select filename */
1.1.1.19 root 4246: if (!BrowseFiles (hwndDlg, "OPEN_TITLE", szFileName, bHistory, TRUE, NULL))
1.1.1.7 root 4247: return 1;
4248:
4249: /* Conceive the file */
4250: if ((fhKeyfile = _open(szFileName, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) == -1)
4251: {
1.1.1.10 root 4252: handleWin32Error (hwndDlg);
1.1.1.7 root 4253: return 1;
4254: }
4255:
4256: /* Generate the keyfile */
4257: WaitCursor();
1.1.1.10 root 4258: if (!RandgetBytes (keyfile, sizeof(keyfile), TRUE))
4259: {
4260: _close (fhKeyfile);
4261: DeleteFile (szFileName);
4262: NormalCursor();
4263: return 1;
4264: }
1.1.1.7 root 4265: NormalCursor();
4266:
4267: /* Write the keyfile */
4268: if (_write (fhKeyfile, keyfile, sizeof(keyfile)) == -1)
4269: handleWin32Error (hwndDlg);
4270: else
4271: Info("KEYFILE_CREATED");
4272:
1.1.1.13 root 4273: burn (keyfile, sizeof(keyfile));
1.1.1.7 root 4274: _close (fhKeyfile);
4275: return 1;
4276: }
4277: return 0;
4278:
4279: case WM_CLOSE:
4280: {
4281: char tmp[RNG_POOL_SIZE+1];
4282: exit:
1.1.1.13 root 4283: WaitCursor();
1.1.1.7 root 4284: KillTimer (hwndDlg, 0xfd);
4285:
4286: #ifndef VOLFORMAT
4287: Randfree ();
4288: #endif
4289: /* Cleanup */
4290:
1.1.1.13 root 4291: burn (randPool, sizeof(randPool));
4292: burn (lastRandPool, sizeof(lastRandPool));
4293: burn (outputDispBuffer, sizeof(outputDispBuffer));
1.1.1.7 root 4294:
4295: // Attempt to wipe the pool contents in the GUI text area
4296: memset (tmp, 'X', RNG_POOL_SIZE);
4297: tmp [RNG_POOL_SIZE] = 0;
4298: SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp);
4299:
4300: EndDialog (hwndDlg, IDCLOSE);
1.1.1.13 root 4301: NormalCursor ();
1.1.1.7 root 4302: return 1;
1.1.1.5 root 4303: }
4304: }
1.1.1.7 root 4305: return 0;
1.1.1.5 root 4306: }
4307:
4308:
1.1.1.7 root 4309:
4310: /* Except in response to the WM_INITDIALOG message, the dialog box procedure
4311: should return nonzero if it processes the message, and zero if it does
4312: not. - see DialogProc */
4313: BOOL CALLBACK
4314: CipherTestDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1.1.1.5 root 4315: {
1.1.1.8 root 4316: static int idTestCipher = -1; /* Currently selected cipher for the test vector facility (none = -1). */
1.1.1.13 root 4317: static BOOL bXTSTestEnabled = FALSE;
1.1.1.8 root 4318:
4319: PCRYPTO_INFO ci;
1.1.1.7 root 4320: WORD lw = LOWORD (wParam);
4321: WORD hw = HIWORD (wParam);
4322:
4323: switch (uMsg)
1.1.1.5 root 4324: {
1.1.1.7 root 4325: case WM_INITDIALOG:
4326: {
4327: int ea;
4328: char buf[100];
4329:
4330: LocalizeDialog (hwndDlg, "IDD_CIPHER_TEST_DLG");
4331:
4332: SendMessage(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), WM_SETFONT, (WPARAM)hBoldFont, MAKELPARAM(TRUE,0));
4333: SendMessage(GetDlgItem(hwndDlg, IDC_KEY), EM_LIMITTEXT, 128,0);
4334: SendMessage(GetDlgItem(hwndDlg, IDC_KEY), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
1.1.1.13 root 4335: SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT), EM_LIMITTEXT,64,0);
1.1.1.7 root 4336: SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
1.1.1.13 root 4337: SendMessage(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), EM_LIMITTEXT,64,0);
1.1.1.7 root 4338: SendMessage(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
1.1.1.13 root 4339: SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), EM_LIMITTEXT, 128,0);
4340: SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
4341: SendMessage(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), EM_LIMITTEXT,32,0);
4342: SendMessage(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0));
4343: SetCheckBox (hwndDlg, IDC_XTS_MODE_ENABLED, bXTSTestEnabled);
4344: EnableWindow (GetDlgItem (hwndDlg, IDC_SECONDARY_KEY), bXTSTestEnabled);
4345: EnableWindow (GetDlgItem (hwndDlg, IDT_SECONDARY_KEY), bXTSTestEnabled);
4346: EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), bXTSTestEnabled);
4347: EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_BLOCK_NUMBER), bXTSTestEnabled);
4348: EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
4349: EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
1.1.1.7 root 4350:
4351: if (idTestCipher == -1)
4352: idTestCipher = (int) lParam;
4353:
4354: SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_RESETCONTENT, 0, 0);
4355: for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
4356: {
1.1.1.11 root 4357: if (EAGetCipherCount (ea) == 1 && EAIsFormatEnabled (ea))
1.1.1.12 root 4358: AddComboPair (GetDlgItem (hwndDlg, IDC_CIPHER), EAGetName (buf, ea), EAGetFirstCipher (ea));
1.1.1.7 root 4359: }
4360:
4361: ResetCipherTest(hwndDlg, idTestCipher);
4362:
4363: SelectAlgo (GetDlgItem (hwndDlg, IDC_CIPHER), &idTestCipher);
4364:
4365: return 1;
4366: }
4367:
4368: case WM_COMMAND:
4369:
4370: if (hw == CBN_SELCHANGE && lw == IDC_CIPHER)
4371: {
4372: idTestCipher = (int) SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_GETCURSEL, 0, 0), 0);
4373: ResetCipherTest(hwndDlg, idTestCipher);
4374: SendMessage (hwndDlg, WM_INITDIALOG, 0, 0);
4375: return 1;
4376: }
4377:
4378: if (hw == CBN_SELCHANGE && lw == IDC_KEY_SIZE)
4379: {
4380: // NOP
4381: return 1;
4382: }
4383:
4384: if (lw == IDC_RESET)
4385: {
4386: ResetCipherTest(hwndDlg, idTestCipher);
4387:
4388: return 1;
4389: }
4390:
4391: if (lw == IDC_AUTO)
4392: {
1.1.1.13 root 4393: WaitCursor ();
1.1.1.7 root 4394: if (!AutoTestAlgorithms())
4395: {
4396: ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_SHOWNORMAL);
4397: SetWindowTextW(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), GetString ("TESTS_FAILED"));
4398: }
4399: else
4400: {
4401: ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_SHOWNORMAL);
4402: SetWindowTextW(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), GetString ("TESTS_PASSED"));
4403: ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_SHOWNORMAL);
4404: }
1.1.1.13 root 4405: NormalCursor ();
1.1.1.7 root 4406:
4407: return 1;
4408:
4409: }
4410:
1.1.1.13 root 4411: if (lw == IDC_XTS_MODE_ENABLED)
1.1.1.8 root 4412: {
1.1.1.13 root 4413: bXTSTestEnabled = GetCheckBox (hwndDlg, IDC_XTS_MODE_ENABLED);
4414: EnableWindow (GetDlgItem (hwndDlg, IDC_SECONDARY_KEY), bXTSTestEnabled);
4415: EnableWindow (GetDlgItem (hwndDlg, IDT_SECONDARY_KEY), bXTSTestEnabled);
4416: EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), bXTSTestEnabled);
4417: EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_BLOCK_NUMBER), bXTSTestEnabled);
4418: EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
4419: EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled);
4420: if (bXTSTestEnabled)
1.1.1.9 root 4421: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, 0,0);
1.1.1.8 root 4422: }
4423:
1.1.1.7 root 4424: if (lw == IDOK || lw == IDC_ENCRYPT || lw == IDC_DECRYPT)
4425: {
1.1.1.13 root 4426: char key[128+1], inputtext[128+1], secondaryKey[64+1], dataUnitNo[16+1], szTmp[128+1];
4427: int ks, pt, n, tlen, blockNo = 0;
1.1.1.7 root 4428: BOOL bEncrypt;
4429:
4430: ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_HIDE);
4431: ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_HIDE);
4432:
4433: ks = (int) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_GETCURSEL, 0,0);
4434: ks = (int) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_GETITEMDATA, ks,0);
4435: pt = (int) SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_GETITEMDATA, 0,0);
4436:
4437: bEncrypt = lw == IDC_ENCRYPT;
4438:
4439: memset(key,0,sizeof(key));
4440: memset(szTmp,0,sizeof(szTmp));
4441: n = GetWindowText(GetDlgItem(hwndDlg, IDC_KEY), szTmp, sizeof(szTmp));
4442: if (n != ks * 2)
4443: {
1.1.1.13 root 4444: Warning ("TEST_KEY_SIZE");
1.1.1.7 root 4445: return 1;
4446: }
4447:
4448: for (n = 0; n < ks; n ++)
4449: {
4450: char szTmp2[3], *ptr;
4451: long x;
4452:
4453: szTmp2[2] = 0;
4454: szTmp2[0] = szTmp[n * 2];
4455: szTmp2[1] = szTmp[n * 2 + 1];
4456:
4457: x = strtol(szTmp2, &ptr, 16);
4458:
4459: key[n] = (char) x;
4460: }
4461:
1.1.1.8 root 4462: memset(inputtext, 0, sizeof(inputtext));
1.1.1.13 root 4463: memset(secondaryKey, 0, sizeof(secondaryKey));
4464: memset(dataUnitNo, 0, sizeof(dataUnitNo));
1.1.1.8 root 4465: memset(szTmp, 0, sizeof(szTmp));
1.1.1.7 root 4466:
4467: if (bEncrypt)
4468: {
4469: n = GetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), szTmp, sizeof(szTmp));
4470: }
4471: else
4472: {
4473: n = GetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), szTmp, sizeof(szTmp));
4474: }
4475:
4476: if (n != pt * 2)
4477: {
4478: if (bEncrypt)
4479: {
1.1.1.13 root 4480: Warning ("TEST_PLAINTEXT_SIZE");
1.1.1.7 root 4481: return 1;
4482: }
4483: else
4484: {
1.1.1.13 root 4485: Warning ("TEST_CIPHERTEXT_SIZE");
1.1.1.7 root 4486: return 1;
4487: }
4488: }
1.1.1.8 root 4489:
1.1.1.7 root 4490: for (n = 0; n < pt; n ++)
4491: {
4492: char szTmp2[3], *ptr;
4493: long x;
4494:
4495: szTmp2[2] = 0;
4496: szTmp2[0] = szTmp[n * 2];
4497: szTmp2[1] = szTmp[n * 2 + 1];
4498:
4499: x = strtol(szTmp2, &ptr, 16);
4500:
4501: inputtext[n] = (char) x;
4502: }
4503:
1.1.1.13 root 4504: // XTS
4505: if (bXTSTestEnabled)
1.1.1.7 root 4506: {
1.1.1.13 root 4507: // Secondary key
4508:
4509: if (GetWindowText(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), szTmp, sizeof(szTmp)) != 64)
1.1.1.8 root 4510: {
1.1.1.13 root 4511: Warning ("TEST_INCORRECT_SECONDARY_KEY_SIZE");
1.1.1.8 root 4512: return 1;
4513: }
1.1.1.7 root 4514:
1.1.1.13 root 4515: for (n = 0; n < 64; n ++)
1.1.1.7 root 4516: {
1.1.1.8 root 4517: char szTmp2[3], *ptr;
4518: long x;
4519:
4520: szTmp2[2] = 0;
4521: szTmp2[0] = szTmp[n * 2];
4522: szTmp2[1] = szTmp[n * 2 + 1];
4523:
4524: x = strtol(szTmp2, &ptr, 16);
4525:
1.1.1.13 root 4526: secondaryKey[n] = (char) x;
1.1.1.7 root 4527: }
4528:
1.1.1.13 root 4529: // Data unit number
1.1.1.7 root 4530:
1.1.1.13 root 4531: tlen = GetWindowText(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), szTmp, sizeof(szTmp));
4532:
4533: if (tlen > 16 || tlen < 1)
1.1.1.7 root 4534: {
1.1.1.13 root 4535: Warning ("TEST_INCORRECT_TEST_DATA_UNIT_SIZE");
1.1.1.8 root 4536: return 1;
1.1.1.7 root 4537: }
1.1.1.13 root 4538:
4539: LeftPadString (szTmp, tlen, 16, '0');
4540:
4541: for (n = 0; n < 16; n ++)
1.1.1.7 root 4542: {
1.1.1.8 root 4543: char szTmp2[3], *ptr;
4544: long x;
4545:
4546: szTmp2[2] = 0;
4547: szTmp2[0] = szTmp[n * 2];
4548: szTmp2[1] = szTmp[n * 2 + 1];
4549:
4550: x = strtol(szTmp2, &ptr, 16);
4551:
1.1.1.13 root 4552: dataUnitNo[n] = (char) x;
1.1.1.7 root 4553: }
1.1.1.9 root 4554:
1.1.1.13 root 4555: // Block number
4556:
4557: blockNo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_GETCURSEL, 0, 0), 0);
4558: } // if (bXTSTestEnabled)
1.1.1.7 root 4559:
1.1.1.8 root 4560:
4561: /* Perform the actual tests */
4562:
4563: if (ks != CB_ERR && pt != CB_ERR)
4564: {
4565: char tmp[128];
1.1.1.9 root 4566: int tmpRetVal;
1.1.1.8 root 4567:
4568: /* Copy the plain/ciphertext */
4569: memcpy(tmp,inputtext, pt);
4570:
1.1.1.13 root 4571: if (bXTSTestEnabled)
1.1.1.7 root 4572: {
1.1.1.13 root 4573: UINT64_STRUCT structDataUnitNo;
4574:
4575: /* XTS mode */
1.1.1.8 root 4576:
4577: ci = crypto_open ();
4578: if (!ci)
4579: return 1;
4580:
1.1.1.13 root 4581: ci->mode = XTS;
1.1.1.12 root 4582:
4583: for (ci->ea = EAGetFirst (); ci->ea != 0 ; ci->ea = EAGetNext (ci->ea))
4584: if (EAGetCipherCount (ci->ea) == 1 && EAGetFirstCipher (ci->ea) == idTestCipher)
4585: break;
1.1.1.8 root 4586:
1.1.1.15 root 4587: if ((tmpRetVal = EAInit (ci->ea, (unsigned char *) key, ci->ks)) != ERR_SUCCESS)
1.1.1.9 root 4588: {
4589: handleError (hwndDlg, tmpRetVal);
1.1.1.8 root 4590: return 1;
1.1.1.9 root 4591: }
1.1.1.8 root 4592:
1.1.1.13 root 4593: memcpy (&ci->k2, secondaryKey, sizeof (secondaryKey));
1.1.1.8 root 4594: if (!EAInitMode (ci))
4595: return 1;
4596:
1.1.1.13 root 4597: structDataUnitNo.Value = BE64(((unsigned __int64 *)dataUnitNo)[0]);
1.1.1.12 root 4598:
1.1.1.13 root 4599: if (bEncrypt)
1.1.1.15 root 4600: EncryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher);
1.1.1.13 root 4601: else
1.1.1.15 root 4602: DecryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher);
1.1.1.9 root 4603:
1.1.1.8 root 4604: crypto_close (ci);
1.1.1.7 root 4605: }
1.1.1.8 root 4606: else
4607: {
4608: if (idTestCipher == BLOWFISH)
4609: {
1.1.1.12 root 4610: /* Deprecated/legacy */
4611:
1.1.1.8 root 4612: /* Convert to little-endian, this is needed here and not in
4613: above auto-tests because BF_ecb_encrypt above correctly converts
4614: from big to little endian, and EncipherBlock does not! */
1.1.1.15 root 4615: LongReverse((unsigned int *) tmp, pt);
1.1.1.8 root 4616: }
4617:
4618: CipherInit2(idTestCipher, key, ks_tmp, ks);
4619:
4620: if (bEncrypt)
4621: {
4622: EncipherBlock(idTestCipher, tmp, ks_tmp);
4623: }
4624: else
4625: {
4626: DecipherBlock(idTestCipher, tmp, ks_tmp);
4627: }
1.1.1.7 root 4628:
1.1.1.8 root 4629: if (idTestCipher == BLOWFISH)
4630: {
1.1.1.12 root 4631: /* Deprecated/legacy */
4632:
1.1.1.8 root 4633: /* Convert back to big-endian */
1.1.1.15 root 4634: LongReverse((unsigned int *) tmp, pt);
1.1.1.8 root 4635: }
4636: }
1.1.1.7 root 4637: *szTmp = 0;
4638:
1.1.1.8 root 4639: for (n = 0; n < pt; n ++)
1.1.1.7 root 4640: {
4641: char szTmp2[3];
4642: sprintf(szTmp2, "%02x", (int)((unsigned char)tmp[n]));
4643: strcat(szTmp, szTmp2);
4644: }
4645:
4646: if (bEncrypt)
4647: SetWindowText(GetDlgItem(hwndDlg,IDC_CIPHERTEXT), szTmp);
4648: else
4649: SetWindowText(GetDlgItem(hwndDlg,IDC_PLAINTEXT), szTmp);
4650: }
1.1.1.8 root 4651:
1.1.1.7 root 4652: return 1;
4653: }
4654:
4655: if (lw == IDCLOSE || lw == IDCANCEL)
4656: {
4657: idTestCipher = -1;
4658: EndDialog (hwndDlg, 0);
4659: return 1;
4660: }
4661: break;
4662:
4663: case WM_CLOSE:
4664: idTestCipher = -1;
4665: EndDialog (hwndDlg, 0);
4666: return 1;
1.1.1.5 root 4667: }
1.1.1.7 root 4668:
4669: return 0;
4670: }
4671:
4672: void
4673: ResetCipherTest(HWND hwndDlg, int idTestCipher)
4674: {
4675: int ndx;
4676:
4677: ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_HIDE);
4678: ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_HIDE);
4679:
1.1.1.11 root 4680: EnableWindow(GetDlgItem(hwndDlg,IDC_KEY_SIZE), FALSE);
1.1.1.7 root 4681:
4682: /* Setup the keysize and plaintext sizes for the selected cipher */
4683:
4684: SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_RESETCONTENT, 0,0);
4685: SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_RESETCONTENT, 0,0);
1.1.1.13 root 4686: SendMessage (GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_RESETCONTENT, 0,0);
1.1.1.7 root 4687:
4688: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_ADDSTRING, 0,(LPARAM) "64");
4689: SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 8);
4690: SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETCURSEL, ndx,0);
4691:
1.1.1.13 root 4692: for (ndx = 0; ndx < BLOCKS_PER_XTS_DATA_UNIT; ndx++)
4693: {
4694: char tmpStr [16];
4695:
4696: sprintf (tmpStr, "%d", ndx);
4697:
4698: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_ADDSTRING, 0,(LPARAM) tmpStr);
4699: SendMessage(GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_SETITEMDATA, ndx,(LPARAM) ndx);
4700: }
4701:
4702: SendMessage(GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_SETCURSEL, 0, 0);
4703:
4704: SetWindowText(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), "0000000000000000000000000000000000000000000000000000000000000000");
4705: SetWindowText(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), "0");
1.1.1.8 root 4706:
1.1.1.7 root 4707: if (idTestCipher == BLOWFISH)
4708: {
1.1.1.12 root 4709: /* Deprecated/legacy */
4710:
1.1.1.7 root 4711: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "448");
4712: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 56);
4713: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "256");
4714: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 32);
4715: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "128");
4716: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16);
4717: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "64");
4718: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 8);
4719: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, 0,0);
4720: SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
4721: }
4722:
4723:
4724: if (idTestCipher == CAST)
4725: {
1.1.1.12 root 4726: /* Deprecated/legacy */
4727:
1.1.1.7 root 4728: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "128");
4729: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16);
4730: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0);
4731: SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "00000000000000000000000000000000");
4732: }
4733:
4734: if (idTestCipher == TRIPLEDES)
4735: {
1.1.1.12 root 4736: /* Deprecated/legacy */
4737:
1.1.1.7 root 4738: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "168");
4739: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 24);
4740: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0);
4741: SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "000000000000000000000000000000000000000000000000");
4742: }
4743:
4744: SetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), "0000000000000000");
4745: SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), "0000000000000000");
4746:
4747: if (idTestCipher == AES || idTestCipher == SERPENT || idTestCipher == TWOFISH)
4748: {
4749: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "256");
4750: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 32);
4751: SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0);
4752:
4753: SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_RESETCONTENT, 0,0);
4754: ndx = SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_ADDSTRING, 0,(LPARAM) "128");
4755: SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16);
4756: SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETCURSEL, ndx,0);
4757:
4758: SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "0000000000000000000000000000000000000000000000000000000000000000");
4759: SetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), "00000000000000000000000000000000");
4760: SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), "00000000000000000000000000000000");
4761: }
4762: }
4763:
4764: #endif // #ifndef SETUP
4765:
4766:
1.1.1.11 root 4767: BOOL CALLBACK MultiChoiceDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
4768: {
4769: int nChoiceIDs [MAX_MULTI_CHOICES+1] = { IDC_MULTI_CHOICE_MSG, IDC_CHOICE1, IDC_CHOICE2, IDC_CHOICE3,
4770: IDC_CHOICE4, IDC_CHOICE5, IDC_CHOICE6, IDC_CHOICE7, IDC_CHOICE8, IDC_CHOICE9, IDC_CHOICE10 };
4771: int nBaseButtonWidth = 0;
4772: int nBaseButtonHeight = 0;
4773: int nActiveChoices = -1;
4774: int nStr = 0;
4775: int vertSubOffset, horizSubOffset, vertMsgHeightOffset;
4776: int vertOffset = 0;
4777: int nLongestButtonCaptionWidth = 6;
1.1.1.17 root 4778: int nLongestButtonCaptionCharLen = 1;
1.1.1.11 root 4779: int nTextGfxLineHeight = 0;
1.1.1.17 root 4780: int nMainTextLenInChars = 0;
1.1.1.19 root 4781: int newLineSeqCount = 0;
1.1.1.11 root 4782: RECT rec, wrec, wtrec, trec;
4783: BOOL bResolve;
4784:
4785: WORD lw = LOWORD (wParam);
4786:
4787: switch (uMsg)
4788: {
4789: case WM_INITDIALOG:
4790: {
1.1.1.19 root 4791: char **pStr = (char **) ((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->strings;
4792: char **pStrOrig = pStr;
4793: wchar_t **pwStr = (wchar_t **) ((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->strings;
4794: wchar_t **pwStrOrig = pwStr;
4795:
4796: LocalizeDialog (hwndDlg, NULL);
1.1.1.11 root 4797:
4798: SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
4799: SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
4800:
4801: bResolve = (*pStr == NULL);
4802:
1.1.1.19 root 4803: // Style
4804: if (((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->bold)
4805: {
4806: SendMessage (GetDlgItem (hwndDlg, IDC_MULTI_CHOICE_MSG), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
4807: }
4808:
1.1.1.11 root 4809: // Process the strings
4810: pStr++;
4811: pwStr++;
4812:
4813: do
4814: {
4815: if (*pStr != 0)
4816: {
4817: SetWindowTextW (GetDlgItem(hwndDlg, nChoiceIDs[nStr]), bResolve ? GetString(*pStr) : *pwStr);
4818:
4819: if (nStr > 0)
4820: {
4821: nLongestButtonCaptionWidth = max (
4822: GetTextGfxWidth (GetDlgItem(hwndDlg, IDC_CHOICE1),
4823: bResolve ? GetString(*pStr) : *pwStr,
4824: hUserFont),
4825: nLongestButtonCaptionWidth);
1.1.1.17 root 4826:
4827: nLongestButtonCaptionCharLen = max (nLongestButtonCaptionCharLen,
4828: (int) wcslen ((const wchar_t *) (bResolve ? GetString(*pStr) : *pwStr)));
1.1.1.11 root 4829: }
4830:
4831: nActiveChoices++;
4832: pStr++;
4833: pwStr++;
4834: }
4835: else
4836: {
4837: ShowWindow(GetDlgItem(hwndDlg, nChoiceIDs[nStr]), SW_HIDE);
4838: }
4839: nStr++;
4840:
4841: } while (nStr < MAX_MULTI_CHOICES+1);
4842:
1.1.1.17 root 4843: // Length of main message in characters (not bytes)
4844: nMainTextLenInChars = wcslen ((const wchar_t *) (bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1)));
4845:
1.1.1.19 root 4846: if (nMainTextLenInChars > 200
1.1.1.17 root 4847: && nMainTextLenInChars / nLongestButtonCaptionCharLen >= 10)
4848: {
1.1.1.19 root 4849: // As the main text is longer than 200 characters, we will "pad" the widest button caption with
1.1.1.17 root 4850: // spaces (if it is not wide enough) so as to increase the width of the whole dialog window.
4851: // Otherwise, it would look too tall (dialog boxes look better when they are more wide than tall).
4852: nLongestButtonCaptionWidth = CompensateXDPI (max (
4853: nLongestButtonCaptionWidth,
4854: min (350, nMainTextLenInChars)));
4855: }
4856:
1.1.1.11 root 4857: // Get the window coords
4858: GetWindowRect(hwndDlg, &wrec);
4859:
4860: // Get the base button size
4861: GetClientRect(GetDlgItem(hwndDlg, IDC_CHOICE1), &rec);
4862: nBaseButtonWidth = rec.right + 2;
4863: nBaseButtonHeight = rec.bottom + 2;
4864:
4865: // Increase in width based on the gfx length of the widest button caption
1.1.1.12 root 4866: horizSubOffset = min (CompensateXDPI (500), max (0, nLongestButtonCaptionWidth + CompensateXDPI (50) - nBaseButtonWidth));
1.1.1.11 root 4867:
4868: // Vertical "title bar" offset
4869: GetClientRect(hwndDlg, &wtrec);
4870: vertOffset = wrec.bottom - wrec.top - wtrec.bottom - GetSystemMetrics(SM_CYFIXEDFRAME);
4871:
4872: // Height/width of the message text
4873: GetClientRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &trec);
4874:
1.1.1.19 root 4875: // Determine the number of newlines contained in the message text
4876: {
4877: int64 offset = -1;
4878:
4879: do
4880: {
4881: offset = FindString ((char *) (bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1)),
4882: (char *) L"\n",
4883: nMainTextLenInChars * 2,
4884: wcslen (L"\n") * 2,
4885: offset + 1);
4886:
4887: newLineSeqCount++;
4888:
4889: } while (offset != -1);
4890: }
4891:
1.1.1.11 root 4892: nTextGfxLineHeight = GetTextGfxHeight (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG),
4893: bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1),
4894: hUserFont);
4895:
4896: vertMsgHeightOffset = ((GetTextGfxWidth (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG),
4897: bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1),
4898: hUserFont) / (trec.right + horizSubOffset) + 1) * nTextGfxLineHeight) - trec.bottom;
4899:
1.1.1.19 root 4900: 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 4901:
4902: // Reduction in height according to the number of shown buttons
4903: vertSubOffset = ((MAX_MULTI_CHOICES - nActiveChoices) * nBaseButtonHeight);
4904:
4905: if (horizSubOffset > 0
4906: || vertMsgHeightOffset > 0
4907: || vertOffset > 0)
4908: {
4909: // Resize/move each button if necessary
4910: for (nStr = 1; nStr < MAX_MULTI_CHOICES+1; nStr++)
4911: {
4912: GetWindowRect(GetDlgItem(hwndDlg, nChoiceIDs[nStr]), &rec);
4913:
4914: MoveWindow (GetDlgItem(hwndDlg, nChoiceIDs[nStr]),
4915: rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
4916: rec.top - wrec.top - vertOffset + vertMsgHeightOffset,
4917: nBaseButtonWidth + horizSubOffset,
4918: nBaseButtonHeight,
4919: TRUE);
4920: }
4921:
4922: // Resize/move the remaining GUI elements
4923: GetWindowRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &rec);
4924: GetClientRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &trec);
4925: MoveWindow (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG),
4926: rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
4927: rec.top - wrec.top - vertOffset,
4928: trec.right + 2 + horizSubOffset,
4929: trec.bottom + 2 + vertMsgHeightOffset,
4930: TRUE);
4931:
4932: GetWindowRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), &rec);
4933: GetClientRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), &trec);
4934: MoveWindow (GetDlgItem(hwndDlg, IDC_MC_DLG_HR1),
4935: rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
4936: rec.top - wrec.top - vertOffset,
4937: trec.right + 2 + horizSubOffset,
4938: trec.bottom + 2,
4939: TRUE);
4940:
4941: GetWindowRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), &rec);
4942: GetClientRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), &trec);
4943: MoveWindow (GetDlgItem(hwndDlg, IDC_MC_DLG_HR2),
4944: rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME),
4945: rec.top - wrec.top - vertOffset + vertMsgHeightOffset,
4946: trec.right + 2 + horizSubOffset,
4947: trec.bottom + 2,
4948: TRUE);
4949: }
4950:
4951: // Resize the window according to number of shown buttons and the longest button caption
4952: MoveWindow (hwndDlg,
4953: wrec.left - horizSubOffset / 2,
4954: wrec.top + vertSubOffset / 2 - vertMsgHeightOffset / 2,
4955: wrec.right - wrec.left + horizSubOffset,
4956: wrec.bottom - wrec.top - vertSubOffset + 1 + vertMsgHeightOffset,
4957: TRUE);
4958:
4959: return 1;
4960: }
4961:
4962: case WM_COMMAND:
4963:
4964: if (lw == IDCLOSE || lw == IDCANCEL)
4965: {
4966: EndDialog (hwndDlg, 0);
4967: return 1;
4968: }
4969:
4970: for (nStr = 1; nStr < MAX_MULTI_CHOICES+1; nStr++)
4971: {
4972: if (lw == nChoiceIDs[nStr])
4973: {
4974: EndDialog (hwndDlg, nStr);
4975: return 1;
4976: }
4977: }
4978: break;
4979:
4980: case WM_CLOSE:
4981: EndDialog (hwndDlg, 0);
4982: return 1;
4983: }
4984:
4985: return 0;
4986: }
4987:
4988:
1.1.1.7 root 4989: BOOL CheckCapsLock (HWND hwnd, BOOL quiet)
4990: {
4991: if ((GetKeyState(VK_CAPITAL) & 1) != 0)
4992: {
4993: if (!quiet)
4994: {
4995: MessageBoxW (hwnd, GetString ("CAPSLOCK_ON"), lpszTitle, MB_ICONEXCLAMATION);
4996: }
4997: return TRUE;
4998: }
4999: return FALSE;
1.1.1.5 root 5000: }
5001:
5002:
1.1.1.13 root 5003: // Checks whether the file extension is not used for executable files or similarly problematic, which often
5004: // causes Windows and antivirus software to interfere with the container
1.1.1.11 root 5005: BOOL CheckFileExtension (char *fileName)
5006: {
1.1.1.13 root 5007: int i = 0;
1.1.1.12 root 5008: char *ext = strrchr (fileName, '.');
1.1.1.13 root 5009: static char *problemFileExt[] = {
5010: // These are protected by the Windows Resource Protection
5011: ".asa", ".asp", ".aspx", ".ax", ".bas", ".bat", ".bin", ".cer", ".chm", ".clb", ".cmd", ".cnt", ".cnv",
5012: ".com", ".cpl", ".cpx", ".crt", ".csh", ".dll", ".drv", ".dtd", ".exe", ".fxp", ".grp", ".h1s", ".hlp",
5013: ".hta", ".ime", ".inf", ".ins", ".isp", ".its", ".js", ".jse", ".ksh", ".lnk", ".mad", ".maf", ".mag",
5014: ".mam", ".man", ".maq", ".mar", ".mas", ".mat", ".mau", ".mav", ".maw", ".mda", ".mdb", ".mde", ".mdt",
5015: ".mdw", ".mdz", ".msc", ".msi", ".msp", ".mst", ".mui", ".nls", ".ocx", ".ops", ".pal", ".pcd", ".pif",
5016: ".prf", ".prg", ".pst", ".reg", ".scf", ".scr", ".sct", ".shb", ".shs", ".sys", ".tlb", ".tsp", ".url",
5017: ".vb", ".vbe", ".vbs", ".vsmacros", ".vss", ".vst", ".vsw", ".ws", ".wsc", ".wsf", ".wsh", ".xsd", ".xsl",
5018: // These additional file extensions are usually watched by antivirus programs
1.1.1.17 root 5019: ".386", ".acm", ".ade", ".adp", ".ani", ".app", ".asd", ".asf", ".asx", ".awx", ".ax", ".boo", ".bz2", ".cdf",
5020: ".class", ".dhtm", ".dhtml",".dlo", ".emf", ".eml", ".flt", ".fot", ".gz", ".hlp", ".htm", ".html", ".ini",
1.1.1.13 root 5021: ".j2k", ".jar", ".jff", ".jif", ".jmh", ".jng", ".jp2", ".jpe", ".jpeg", ".jpg", ".lsp", ".mod", ".nws",
5022: ".obj", ".olb", ".osd", ".ov1", ".ov2", ".ov3", ".ovl", ".ovl", ".ovr", ".pdr", ".pgm", ".php", ".pkg",
5023: ".pl", ".png", ".pot", ".pps", ".ppt", ".rar", ".rpl", ".rtf", ".sbf", ".script", ".sh", ".sha", ".shtm",
1.1.1.17 root 5024: ".shtml", ".spl", ".swf", ".tar", ".tgz", ".tmp", ".ttf", ".vcs", ".vlm", ".vxd", ".vxo", ".wiz", ".wll", ".wmd",
5025: ".wmf", ".wms", ".wmz", ".wpc", ".wsc", ".wsh", ".wwk", ".xhtm", ".xhtml", ".xl", ".xml", ".zip", ".7z", 0};
1.1.1.11 root 5026:
1.1.1.13 root 5027: if (!ext)
5028: return FALSE;
5029:
5030: while (problemFileExt[i])
5031: {
5032: if (!_stricmp (ext, problemFileExt[i++]))
5033: return TRUE;
5034: }
1.1.1.11 root 5035:
5036: return FALSE;
5037: }
5038:
5039:
1.1.1.17 root 5040: void IncreaseWrongPwdRetryCount (int count)
5041: {
5042: WrongPwdRetryCounter += count;
5043: }
5044:
5045:
5046: void ResetWrongPwdRetryCount (void)
5047: {
5048: WrongPwdRetryCounter = 0;
5049: }
5050:
5051:
5052: BOOL WrongPwdRetryCountOverLimit (void)
5053: {
5054: return (WrongPwdRetryCounter > TC_TRY_HEADER_BAK_AFTER_NBR_WRONG_PWD_TRIES);
5055: }
5056:
5057:
1.1.1.5 root 5058: int GetFirstAvailableDrive ()
5059: {
5060: DWORD dwUsedDrives = GetLogicalDrives();
5061: int i;
5062:
5063: for (i = 3; i < 26; i++)
5064: {
5065: if (!(dwUsedDrives & 1 << i))
5066: return i;
5067: }
5068:
5069: return -1;
5070: }
5071:
5072:
5073: int GetLastAvailableDrive ()
5074: {
5075: DWORD dwUsedDrives = GetLogicalDrives();
5076: int i;
5077:
5078: for (i = 25; i > 2; i--)
5079: {
5080: if (!(dwUsedDrives & 1 << i))
5081: return i;
5082: }
5083:
5084: return -1;
5085: }
5086:
5087:
5088: BOOL IsDriveAvailable (int driveNo)
5089: {
5090: return (GetLogicalDrives() & (1 << driveNo)) == 0;
5091: }
5092:
5093:
1.1.1.11 root 5094: BOOL IsDeviceMounted (char *deviceName)
5095: {
5096: BOOL bResult = FALSE;
5097: DWORD dwResult;
5098: HANDLE dev = INVALID_HANDLE_VALUE;
5099:
5100: if ((dev = CreateFile (deviceName,
1.1.1.12 root 5101: GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1.1.1.11 root 5102: NULL,
5103: OPEN_EXISTING,
5104: 0,
5105: NULL)) != INVALID_HANDLE_VALUE)
5106: {
5107: bResult = DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL);
5108: CloseHandle (dev);
5109: }
5110:
5111: return bResult;
5112: }
5113:
5114:
1.1.1.5 root 5115: int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced)
5116: {
5117: UNMOUNT_STRUCT unmount;
5118: DWORD dwResult;
5119:
5120: BOOL bResult;
5121:
5122: unmount.nDosDriveNo = nDosDriveNo;
5123: unmount.ignoreOpenFiles = forced;
5124:
1.1.1.13 root 5125: bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_VOLUME, &unmount,
1.1.1.5 root 5126: sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL);
5127:
5128: if (bResult == FALSE)
5129: {
5130: handleWin32Error (hwndDlg);
5131: return 1;
5132: }
5133:
1.1.1.17 root 5134: #ifdef TCMOUNT
5135:
5136: if (unmount.nReturnCode == ERR_SUCCESS
5137: && unmount.HiddenVolumeProtectionTriggered
5138: && !VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo])
5139: {
5140: wchar_t msg[4096];
5141:
5142: VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo] = TRUE;
5143: swprintf (msg, GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), nDosDriveNo + 'A');
5144: SetForegroundWindow (hwndDlg);
5145: MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
5146: }
5147:
5148: #endif // #ifdef TCMOUNT
5149:
1.1.1.5 root 5150: return unmount.nReturnCode;
5151: }
5152:
5153:
1.1.1.6 root 5154: void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap)
1.1.1.5 root 5155: {
5156: DEV_BROADCAST_VOLUME dbv;
1.1.1.6 root 5157: DWORD dwResult;
1.1.1.11 root 5158: LONG eventId = 0;
1.1.1.7 root 5159: int i;
1.1.1.6 root 5160:
1.1.1.10 root 5161: if (message == DBT_DEVICEARRIVAL)
1.1.1.11 root 5162: eventId = SHCNE_DRIVEADD;
1.1.1.10 root 5163: else if (message == DBT_DEVICEREMOVECOMPLETE)
1.1.1.11 root 5164: eventId = SHCNE_DRIVEREMOVED;
1.1.1.5 root 5165:
1.1.1.7 root 5166: if (driveMap == 0)
1.1.1.10 root 5167: driveMap = (1 << nDosDriveNo);
5168:
1.1.1.11 root 5169: if (eventId != 0)
1.1.1.7 root 5170: {
1.1.1.11 root 5171: for (i = 0; i < 26; i++)
1.1.1.7 root 5172: {
1.1.1.11 root 5173: if (driveMap & (1 << i))
1.1.1.7 root 5174: {
1.1.1.11 root 5175: char root[] = {i + 'A', ':', '\\', 0 };
5176: SHChangeNotify (eventId, SHCNF_PATH, root, NULL);
1.1.1.10 root 5177:
1.1.1.11 root 5178: if (nCurrentOS == WIN_2000 && RemoteSession)
5179: {
5180: char target[32];
5181: wsprintf (target, "%ls%c", TC_MOUNT_PREFIX, i + 'A');
5182: root[2] = 0;
5183:
5184: if (message == DBT_DEVICEARRIVAL)
5185: DefineDosDevice (DDD_RAW_TARGET_PATH, root, target);
5186: else if (message == DBT_DEVICEREMOVECOMPLETE)
5187: DefineDosDevice (DDD_RAW_TARGET_PATH| DDD_REMOVE_DEFINITION
1.1.1.10 root 5188: | DDD_EXACT_MATCH_ON_REMOVE, root, target);
1.1.1.11 root 5189: }
1.1.1.7 root 5190: }
5191: }
5192: }
1.1.1.5 root 5193:
1.1.1.11 root 5194: dbv.dbcv_size = sizeof (dbv);
1.1.1.5 root 5195: dbv.dbcv_devicetype = DBT_DEVTYP_VOLUME;
5196: dbv.dbcv_reserved = 0;
1.1.1.10 root 5197: dbv.dbcv_unitmask = driveMap;
1.1.1.5 root 5198: dbv.dbcv_flags = 0;
5199:
1.1.1.17 root 5200: UINT timeOut = 1000;
5201:
5202: // SHChangeNotify() works on Vista, so the Explorer does not require WM_DEVICECHANGE
5203: if (CurrentOSMajor >= 6)
5204: timeOut = 100;
5205:
1.1.1.12 root 5206: IgnoreWmDeviceChange = TRUE;
1.1.1.17 root 5207: SendMessageTimeout (HWND_BROADCAST, WM_DEVICECHANGE, message, (LPARAM)(&dbv), 0, timeOut, &dwResult);
1.1.1.12 root 5208:
1.1.1.17 root 5209: // Explorer prior Vista sometimes fails to register a new drive
5210: if (CurrentOSMajor < 6 && message == DBT_DEVICEARRIVAL)
1.1.1.12 root 5211: SendMessageTimeout (HWND_BROADCAST, WM_DEVICECHANGE, message, (LPARAM)(&dbv), 0, 200, &dwResult);
1.1.1.17 root 5212:
1.1.1.12 root 5213: IgnoreWmDeviceChange = FALSE;
1.1.1.5 root 5214: }
5215:
5216:
1.1.1.7 root 5217: // Use only cached passwords if password = NULL
5218: //
1.1.1.5 root 5219: // Returns:
5220: // -1 = user aborted mount / error
5221: // 0 = mount failed
5222: // 1 = mount OK
5223: // 2 = mount OK in shared mode
5224:
5225: int MountVolume (HWND hwndDlg,
5226: int driveNo,
5227: char *volumePath,
1.1.1.7 root 5228: Password *password,
1.1.1.5 root 5229: BOOL cachePassword,
5230: BOOL sharedAccess,
1.1.1.6 root 5231: MountOptions *mountOptions,
1.1.1.7 root 5232: BOOL quiet,
5233: BOOL bReportWrongPassword)
1.1.1.5 root 5234: {
1.1.1.7 root 5235: MOUNT_STRUCT mount;
1.1.1.5 root 5236: DWORD dwResult;
5237: BOOL bResult, bDevice;
1.1.1.11 root 5238: char root[MAX_PATH];
1.1.1.5 root 5239:
1.1.1.15 root 5240: #ifdef TCMOUNT
5241: if (mountOptions->PartitionInInactiveSysEncScope)
5242: {
5243: if (!CheckSysEncMountWithoutPBA (volumePath, quiet))
5244: return -1;
5245: }
5246: #endif
5247:
1.1.1.5 root 5248: if (IsMountedVolume (volumePath))
5249: {
5250: if (!quiet)
1.1.1.11 root 5251: Error ("VOL_ALREADY_MOUNTED");
1.1.1.5 root 5252: return -1;
5253: }
5254:
5255: if (!IsDriveAvailable (driveNo))
1.1.1.10 root 5256: {
1.1.1.17 root 5257: if (!quiet)
5258: Error ("DRIVE_LETTER_UNAVAILABLE");
5259:
1.1.1.5 root 5260: return -1;
1.1.1.10 root 5261: }
1.1.1.5 root 5262:
5263: // If using cached passwords, check cache status first
1.1.1.7 root 5264: if (password == NULL && IsPasswordCacheEmpty ())
1.1.1.5 root 5265: return 0;
5266:
1.1.1.7 root 5267: ZeroMemory (&mount, sizeof (mount));
5268: mount.bExclusiveAccess = sharedAccess ? FALSE : TRUE;
1.1.1.17 root 5269: mount.UseBackupHeader = mountOptions->UseBackupHeader;
1.1.1.19 root 5270: mount.RecoveryMode = mountOptions->RecoveryMode;
1.1.1.17 root 5271:
1.1.1.5 root 5272: retry:
1.1.1.7 root 5273: mount.nDosDriveNo = driveNo;
5274: mount.bCache = cachePassword;
5275:
1.1.1.15 root 5276: mount.bPartitionInInactiveSysEncScope = FALSE;
5277:
1.1.1.7 root 5278: if (password != NULL)
5279: mount.VolumePassword = *password;
5280: else
5281: mount.VolumePassword.Length = 0;
5282:
5283: if (!mountOptions->ReadOnly && mountOptions->ProtectHiddenVolume)
5284: {
5285: mount.ProtectedHidVolPassword = mountOptions->ProtectedHidVolPassword;
5286: mount.bProtectHiddenVolume = TRUE;
5287: }
5288: else
5289: mount.bProtectHiddenVolume = FALSE;
5290:
5291: mount.bMountReadOnly = mountOptions->ReadOnly;
5292: mount.bMountRemovable = mountOptions->Removable;
5293: mount.bPreserveTimestamp = mountOptions->PreserveTimestamp;
5294:
5295: mount.bMountManager = TRUE;
1.1.1.5 root 5296:
5297: // Windows 2000 mount manager causes problems with remounted volumes
5298: if (CurrentOSMajor == 5 && CurrentOSMinor == 0)
1.1.1.7 root 5299: mount.bMountManager = FALSE;
1.1.1.5 root 5300:
1.1.1.7 root 5301: CreateFullVolumePath ((char *) mount.wszVolume, volumePath, &bDevice);
1.1.1.5 root 5302:
1.1.1.11 root 5303: if (!bDevice)
1.1.1.7 root 5304: {
1.1.1.11 root 5305: // UNC path
5306: if (volumePath[0] == '\\' && volumePath[1] == '\\')
5307: {
5308: _snprintf ((char *)mount.wszVolume, MAX_PATH, "UNC%s", volumePath + 1);
5309: }
5310:
5311: if (GetVolumePathName (volumePath, root, sizeof (root) - 1))
5312: {
5313: DWORD bps, flags, d;
5314: if (GetDiskFreeSpace (root, &d, &bps, &d, &d))
5315: mount.BytesPerSector = bps;
5316:
5317: // Read-only host filesystem
5318: if (!mount.bMountReadOnly && GetVolumeInformation (root, NULL, 0, NULL, &d, &flags, NULL, 0))
5319: mount.bMountReadOnly = (flags & FILE_READ_ONLY_VOLUME) != 0;
5320: }
1.1.1.7 root 5321: }
5322:
5323: ToUNICODE ((char *) mount.wszVolume);
1.1.1.5 root 5324:
1.1.1.15 root 5325: if (mountOptions->PartitionInInactiveSysEncScope)
5326: {
5327: if (mount.wszVolume == NULL || swscanf_s ((const wchar_t *) mount.wszVolume,
5328: WIDE("\\Device\\Harddisk%d\\Partition"),
5329: &mount.nPartitionInInactiveSysEncScopeDriveNo,
5330: sizeof(mount.nPartitionInInactiveSysEncScopeDriveNo)) != 1)
5331: {
5332: return -1;
5333: }
5334:
5335: mount.bPartitionInInactiveSysEncScope = TRUE;
5336: }
5337:
1.1.1.13 root 5338: bResult = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, &mount,
1.1.1.7 root 5339: sizeof (mount), &mount, sizeof (mount), &dwResult, NULL);
5340:
5341: burn (&mount.VolumePassword, sizeof (mount.VolumePassword));
5342: burn (&mount.ProtectedHidVolPassword, sizeof (mount.ProtectedHidVolPassword));
1.1.1.5 root 5343:
5344: if (bResult == FALSE)
5345: {
5346: // Volume already open by another process
1.1.1.8 root 5347: if (GetLastError () == ERROR_SHARING_VIOLATION)
1.1.1.5 root 5348: {
1.1.1.7 root 5349: if (mount.bExclusiveAccess == FALSE)
1.1.1.5 root 5350: {
5351: if (!quiet)
1.1.1.7 root 5352: MessageBoxW (hwndDlg, GetString ("FILE_IN_USE_FAILED"),
1.1.1.5 root 5353: lpszTitle, MB_ICONSTOP);
5354:
5355: return -1;
5356: }
5357: else
5358: {
5359: if (quiet)
5360: {
1.1.1.7 root 5361: mount.bExclusiveAccess = FALSE;
1.1.1.5 root 5362: goto retry;
5363: }
5364:
5365: // Ask user
1.1.1.7 root 5366: if (IDYES == MessageBoxW (hwndDlg, GetString ("FILE_IN_USE"),
1.1.1.5 root 5367: lpszTitle, MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION))
5368: {
1.1.1.7 root 5369: mount.bExclusiveAccess = FALSE;
1.1.1.5 root 5370: goto retry;
5371: }
5372: }
5373:
5374: return -1;
5375: }
5376:
5377: if (!quiet)
5378: handleWin32Error (hwndDlg);
5379:
5380: return -1;
5381: }
5382:
1.1.1.7 root 5383: if (mount.nReturnCode != 0)
1.1.1.5 root 5384: {
1.1.1.7 root 5385: if (mount.nReturnCode == ERR_PASSWORD_WRONG)
5386: {
5387: // Do not report wrong password, if not instructed to
5388: if (bReportWrongPassword)
1.1.1.17 root 5389: {
5390: IncreaseWrongPwdRetryCount (1); // We increase the count here only if bReportWrongPassword is TRUE, because "Auto-Mount All Devices" and other callers do it separately
5391:
5392: if (WrongPwdRetryCountOverLimit ()
5393: && !mount.UseBackupHeader)
5394: {
5395: // Retry using embedded header backup (if any)
5396: mount.UseBackupHeader = TRUE;
5397: goto retry;
5398: }
5399:
1.1.1.7 root 5400: handleError (hwndDlg, mount.nReturnCode);
1.1.1.17 root 5401: }
1.1.1.7 root 5402:
5403: return 0;
5404: }
1.1.1.5 root 5405:
1.1.1.7 root 5406: if (!quiet)
5407: handleError (hwndDlg, mount.nReturnCode);
1.1.1.5 root 5408:
5409: return 0;
5410: }
5411:
1.1.1.17 root 5412: // Mount successful
5413:
5414: if (mount.UseBackupHeader != mountOptions->UseBackupHeader
5415: && mount.UseBackupHeader)
5416: {
1.1.1.20! root 5417: if (bReportWrongPassword && !Silent)
1.1.1.17 root 5418: Warning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK");
5419: }
1.1.1.19 root 5420:
5421: if (mount.FilesystemDirty)
5422: {
5423: wchar_t msg[1024];
5424: wchar_t mountPoint[] = { L'A' + driveNo, L':', 0 };
5425: wsprintfW (msg, GetString ("MOUNTED_VOLUME_DIRTY"), mountPoint);
5426:
5427: if (AskWarnYesNoString (msg) == IDYES)
5428: CheckFilesystem (driveNo, TRUE);
5429: }
1.1.1.17 root 5430:
1.1.1.20! root 5431: if (mount.VolumeMountedReadOnlyAfterAccessDenied
! 5432: && !Silent
! 5433: && !bDevice
! 5434: && !FileHasReadOnlyAttribute (volumePath)
! 5435: && !IsFileOnReadOnlyFilesystem (volumePath))
! 5436: {
! 5437: wchar_t msg[1024];
! 5438: wchar_t mountPoint[] = { L'A' + driveNo, L':', 0 };
! 5439: wsprintfW (msg, GetString ("MOUNTED_CONTAINER_FORCED_READ_ONLY"), mountPoint);
! 5440:
! 5441: WarningDirect (msg);
! 5442: }
! 5443:
! 5444: if (mount.VolumeMountedReadOnlyAfterAccessDenied
! 5445: && !Silent
! 5446: && bDevice)
! 5447: {
! 5448: wchar_t msg[1024];
! 5449: wchar_t mountPoint[] = { L'A' + driveNo, L':', 0 };
! 5450: wsprintfW (msg, GetString ("MOUNTED_DEVICE_FORCED_READ_ONLY"), mountPoint);
! 5451:
! 5452: WarningDirect (msg);
! 5453: }
! 5454:
1.1.1.17 root 5455: ResetWrongPwdRetryCount ();
5456:
1.1.1.6 root 5457: BroadcastDeviceChange (DBT_DEVICEARRIVAL, driveNo, 0);
1.1.1.5 root 5458:
1.1.1.7 root 5459: if (mount.bExclusiveAccess == FALSE)
1.1.1.5 root 5460: return 2;
5461:
5462: return 1;
5463: }
5464:
5465:
1.1.1.11 root 5466: BOOL UnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount)
1.1.1.5 root 5467: {
5468: int result;
5469: BOOL forced = forceUnmount;
1.1.1.6 root 5470: int dismountMaxRetries = UNMOUNT_MAX_AUTO_RETRIES;
1.1.1.5 root 5471:
5472: retry:
1.1.1.11 root 5473: BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, nDosDriveNo, 0);
5474:
1.1.1.6 root 5475: do
5476: {
5477: result = DriverUnmountVolume (hwndDlg, nDosDriveNo, forced);
5478:
5479: if (result == ERR_FILES_OPEN)
5480: Sleep (UNMOUNT_AUTO_RETRY_DELAY);
5481: else
5482: break;
5483:
5484: } while (--dismountMaxRetries > 0);
1.1.1.5 root 5485:
5486: if (result != 0)
5487: {
1.1.1.7 root 5488: if (result == ERR_FILES_OPEN && !Silent)
1.1.1.5 root 5489: {
1.1.1.12 root 5490: if (IDYES == AskWarnNoYes ("UNMOUNT_LOCK_FAILED"))
1.1.1.5 root 5491: {
5492: forced = TRUE;
5493: goto retry;
5494: }
5495:
5496: return FALSE;
5497: }
5498:
1.1.1.7 root 5499: Error ("UNMOUNT_FAILED");
1.1.1.5 root 5500:
5501: return FALSE;
5502: }
5503:
1.1.1.6 root 5504: BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0);
1.1.1.5 root 5505:
5506: return TRUE;
5507: }
5508:
5509:
5510: BOOL IsPasswordCacheEmpty (void)
5511: {
5512: DWORD dw;
1.1.1.13 root 5513: return !DeviceIoControl (hDriver, TC_IOCTL_GET_PASSWORD_CACHE_STATUS, 0, 0, 0, 0, &dw, 0);
1.1.1.5 root 5514: }
5515:
1.1.1.15 root 5516:
1.1.1.19 root 5517: BOOL IsMountedVolume (const char *volname)
1.1.1.5 root 5518: {
5519: MOUNT_LIST_STRUCT mlist;
5520: DWORD dwResult;
5521: int i;
5522: char volume[TC_MAX_PATH*2+16];
5523:
5524: strcpy (volume, volname);
1.1.1.7 root 5525:
5526: if (strstr (volname, "\\Device\\") != volname)
5527: sprintf(volume, "\\??\\%s", volname);
5528: ToUNICODE (volume);
1.1.1.5 root 5529:
5530: memset (&mlist, 0, sizeof (mlist));
1.1.1.13 root 5531: DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
1.1.1.5 root 5532: sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
5533: NULL);
5534:
5535: for (i=0 ; i<26; i++)
1.1.1.19 root 5536: if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume))
1.1.1.5 root 5537: return TRUE;
5538:
5539: return FALSE;
5540: }
5541:
5542:
1.1.1.12 root 5543: int GetMountedVolumeDriveNo (char *volname)
5544: {
5545: MOUNT_LIST_STRUCT mlist;
5546: DWORD dwResult;
5547: int i;
5548: char volume[TC_MAX_PATH*2+16];
5549:
5550: if (volname == NULL)
5551: return -1;
5552:
5553: strcpy (volume, volname);
5554:
5555: if (strstr (volname, "\\Device\\") != volname)
5556: sprintf(volume, "\\??\\%s", volname);
5557: ToUNICODE (volume);
5558:
5559: memset (&mlist, 0, sizeof (mlist));
1.1.1.13 root 5560: DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
1.1.1.12 root 5561: sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
5562: NULL);
5563:
5564: for (i=0 ; i<26; i++)
1.1.1.19 root 5565: if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume))
1.1.1.12 root 5566: return i;
5567:
5568: return -1;
5569: }
5570:
5571:
1.1.1.5 root 5572: BOOL IsAdmin (void)
5573: {
1.1.1.11 root 5574: return IsUserAnAdmin ();
5575: }
1.1.1.5 root 5576:
5577:
1.1.1.11 root 5578: BOOL IsUacSupported ()
5579: {
5580: HKEY hkey;
5581: DWORD value = 1, size = sizeof (DWORD);
1.1.1.5 root 5582:
1.1.1.11 root 5583: if (nCurrentOS != WIN_VISTA_OR_LATER)
1.1.1.5 root 5584: return FALSE;
5585:
1.1.1.11 root 5586: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
1.1.1.5 root 5587: {
1.1.1.11 root 5588: if (RegQueryValueEx (hkey, "EnableLUA", 0, 0, (LPBYTE) &value, &size) != ERROR_SUCCESS)
5589: value = 1;
1.1.1.5 root 5590:
1.1.1.11 root 5591: RegCloseKey (hkey);
1.1.1.5 root 5592: }
5593:
1.1.1.11 root 5594: return value != 0;
1.1.1.5 root 5595: }
5596:
5597:
5598: BOOL ResolveSymbolicLink (PWSTR symLinkName, PWSTR targetName)
5599: {
5600: BOOL bResult;
5601: DWORD dwResult;
5602: RESOLVE_SYMLINK_STRUCT resolve;
5603:
5604: memset (&resolve, 0, sizeof(resolve));
5605: wcscpy ((PWSTR) &resolve.symLinkName, symLinkName);
5606:
1.1.1.13 root 5607: bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_RESOLVED_SYMLINK, &resolve,
1.1.1.5 root 5608: sizeof (resolve), &resolve, sizeof (resolve), &dwResult,
5609: NULL);
5610:
5611: wcscpy (targetName, (PWSTR) &resolve.targetName);
5612:
5613: return bResult;
5614: }
5615:
5616:
1.1.1.19 root 5617: BOOL GetPartitionInfo (const char *deviceName, PPARTITION_INFORMATION rpartInfo)
1.1.1.11 root 5618: {
5619: BOOL bResult;
5620: DWORD dwResult;
5621: DISK_PARTITION_INFO_STRUCT dpi;
5622:
5623: memset (&dpi, 0, sizeof(dpi));
5624: wsprintfW ((PWSTR) &dpi.deviceName, L"%hs", deviceName);
5625:
1.1.1.13 root 5626: bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_PARTITION_INFO, &dpi,
1.1.1.11 root 5627: sizeof (dpi), &dpi, sizeof (dpi), &dwResult, NULL);
5628:
5629: memcpy (rpartInfo, &dpi.partInfo, sizeof (PARTITION_INFORMATION));
5630: return bResult;
5631: }
5632:
5633:
1.1.1.19 root 5634: BOOL GetDeviceInfo (const char *deviceName, DISK_PARTITION_INFO_STRUCT *info)
5635: {
5636: DWORD dwResult;
5637:
5638: memset (info, 0, sizeof(*info));
5639: wsprintfW ((PWSTR) &info->deviceName, L"%hs", deviceName);
5640:
5641: return DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_PARTITION_INFO, info, sizeof (*info), info, sizeof (*info), &dwResult, NULL);
5642: }
5643:
5644:
5645: BOOL GetDriveGeometry (const char *deviceName, PDISK_GEOMETRY diskGeometry)
1.1.1.11 root 5646: {
5647: BOOL bResult;
5648: DWORD dwResult;
5649: DISK_GEOMETRY_STRUCT dg;
5650:
5651: memset (&dg, 0, sizeof(dg));
5652: wsprintfW ((PWSTR) &dg.deviceName, L"%hs", deviceName);
5653:
1.1.1.13 root 5654: bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_GEOMETRY, &dg,
1.1.1.11 root 5655: sizeof (dg), &dg, sizeof (dg), &dwResult, NULL);
5656:
5657: memcpy (diskGeometry, &dg.diskGeometry, sizeof (DISK_GEOMETRY));
5658: return bResult;
5659: }
5660:
5661:
1.1.1.5 root 5662: // Returns drive letter number assigned to device (-1 if none)
5663: int GetDiskDeviceDriveLetter (PWSTR deviceName)
5664: {
5665: int i;
5666: WCHAR link[MAX_PATH];
5667: WCHAR target[MAX_PATH];
5668: WCHAR device[MAX_PATH];
5669:
5670: if (!ResolveSymbolicLink (deviceName, device))
5671: wcscpy (device, deviceName);
5672:
5673: for (i = 0; i < 26; i++)
5674: {
5675: WCHAR drive[] = { i + 'A', ':', 0 };
5676:
5677: wcscpy (link, L"\\DosDevices\\");
5678: wcscat (link, drive);
5679:
5680: ResolveSymbolicLink (link, target);
5681:
5682: if (wcscmp (device, target) == 0)
5683: return i;
5684: }
5685:
5686: return -1;
5687: }
5688:
5689:
1.1.1.19 root 5690: // WARNING: This function does NOT provide 100% reliable results -- do NOT use it for critical/dangerous operations!
5691: // Return values: 0 - filesystem does not appear empty, 1 - filesystem appears empty, -1 - an error occurred
5692: int FileSystemAppearsEmpty (const char *devicePath)
5693: {
5694: float percentFreeSpace = 0.0;
5695: __int64 occupiedBytes = 0;
5696:
5697: if (GetStatsFreeSpaceOnPartition (devicePath, &percentFreeSpace, &occupiedBytes, TRUE) != -1)
5698: {
5699: 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.
5700: || percentFreeSpace < 88) // A 24-MB NTFS filesystem has 11.5% of space in use even if there are no files stored on it.
5701: {
5702: return 0;
5703: }
5704: else
5705: return 1;
5706: }
5707: else
5708: return -1;
5709: }
5710:
5711:
5712: // Returns the free space on the specified partition (volume) in bytes. If the 'occupiedBytes' pointer
5713: // is not NULL, size of occupied space (in bytes) is written to the pointed location. In addition, if the
5714: // 'percent' pointer is not NULL, % of free space is stored in the pointed location. If there's an error,
5715: // returns -1.
5716: __int64 GetStatsFreeSpaceOnPartition (const char *devicePath, float *percentFree, __int64 *occupiedBytes, BOOL silent)
5717: {
5718: WCHAR devPath [MAX_PATH];
5719: int driveLetterNo = -1;
5720: char szRootPath[4] = {0, ':', '\\', 0};
5721: ULARGE_INTEGER freeSpaceSize;
5722: ULARGE_INTEGER totalNumberOfBytes;
5723: ULARGE_INTEGER totalNumberOfFreeBytes;
5724:
5725: strcpy ((char *) devPath, devicePath);
5726: ToUNICODE ((char *) devPath);
5727:
5728: driveLetterNo = GetDiskDeviceDriveLetter (devPath);
5729: szRootPath[0] = driveLetterNo + 'A';
5730:
5731:
5732: if (!GetDiskFreeSpaceEx (szRootPath, &freeSpaceSize, &totalNumberOfBytes, &totalNumberOfFreeBytes))
5733: {
5734: if (!silent)
5735: {
5736: handleWin32Error (MainDlg);
5737: Error ("CANNOT_CALC_SPACE");
5738: }
5739:
5740: return -1;
5741: }
5742:
5743:
5744: if (percentFree != NULL || occupiedBytes != NULL)
5745: {
5746: // Determine occupied space and % of free space
5747:
5748: PARTITION_INFORMATION partitionInfo;
5749:
5750: if (!GetPartitionInfo (devicePath, &partitionInfo))
5751: {
5752: if (!silent)
5753: {
5754: handleWin32Error (MainDlg);
5755: Error ("CANT_GET_VOLSIZE");
5756: }
5757: return -1;
5758: }
5759:
5760: if (occupiedBytes != NULL)
5761: *occupiedBytes = partitionInfo.PartitionLength.QuadPart - freeSpaceSize.QuadPart;
5762:
5763: if (percentFree != NULL)
5764: *percentFree = (float) ((double) freeSpaceSize.QuadPart / (double) partitionInfo.PartitionLength.QuadPart * 100.0);
5765: }
5766:
5767: return freeSpaceSize.QuadPart;
5768: }
5769:
5770:
5771: // Returns -1 if there's an error.
5772: __int64 GetDeviceSize (const char *devicePath)
5773: {
5774: PARTITION_INFORMATION partitionInfo;
5775:
5776: if (!GetPartitionInfo (devicePath, &partitionInfo))
5777: return -1;
5778:
5779: return partitionInfo.PartitionLength.QuadPart;
5780: }
5781:
5782:
5783: HANDLE DismountDrive (char *devName, char *devicePath)
1.1.1.5 root 5784: {
5785: DWORD dwResult;
5786: HANDLE hVolume;
1.1.1.11 root 5787: BOOL bResult = FALSE;
1.1.1.19 root 5788: int attempt = UNMOUNT_MAX_AUTO_RETRIES;
5789: int driveLetterNo = -1;
5790: WCHAR devPath [MAX_PATH];
5791:
5792: strcpy ((char *) devPath, devicePath);
5793: ToUNICODE ((char *) devPath);
5794: driveLetterNo = GetDiskDeviceDriveLetter (devPath);
5795:
1.1.1.5 root 5796:
1.1.1.11 root 5797: hVolume = CreateFile (devName, GENERIC_READ | GENERIC_WRITE,
5798: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.5 root 5799:
1.1.1.11 root 5800: if (hVolume == INVALID_HANDLE_VALUE)
5801: return INVALID_HANDLE_VALUE;
1.1.1.5 root 5802:
1.1.1.19 root 5803:
5804: // Try to lock the volume first so that dismount is not forced.
5805: // If we fail, we will dismount anyway even if it needs to be forced.
5806:
5807: CloseVolumeExplorerWindows (MainDlg, driveLetterNo);
5808:
5809: while (!(bResult = DeviceIoControl (hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL))
5810: && attempt > 0)
5811: {
5812: Sleep (UNMOUNT_AUTO_RETRY_DELAY);
5813: attempt--;
5814: }
5815:
5816:
5817: // Try to dismount the volume
5818:
5819: attempt = UNMOUNT_MAX_AUTO_RETRIES;
5820:
1.1.1.11 root 5821: while (!(bResult = DeviceIoControl (hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL))
5822: && attempt > 0)
5823: {
5824: Sleep (UNMOUNT_AUTO_RETRY_DELAY);
5825: attempt--;
5826: }
1.1.1.5 root 5827:
1.1.1.11 root 5828: if (!bResult)
5829: CloseHandle (hVolume);
1.1.1.5 root 5830:
1.1.1.11 root 5831: return (bResult ? hVolume : INVALID_HANDLE_VALUE);
1.1.1.6 root 5832: }
5833:
1.1.1.19 root 5834: // Returns -1 if the specified string is not found in the buffer. Otherwise, returns the
5835: // offset of the first occurrence of the string. The string and the buffer may contain zeroes,
5836: // which do NOT terminate them.
5837: int64 FindString (const char *buf, const char *str, int64 bufLen, size_t strLen, int64 startOffset)
5838: {
5839: if (buf == NULL
5840: || str == NULL
5841: || strLen > bufLen
5842: || bufLen < 1
5843: || strLen < 1
5844: || startOffset > bufLen - strLen)
5845: {
5846: return -1;
5847: }
5848:
5849: for (int64 i = startOffset; i < bufLen - strLen; i++)
5850: {
5851: if (memcmp (buf + i, str, strLen) == 0)
5852: return i;
5853: }
5854:
5855: return -1;
5856: }
5857:
1.1.1.13 root 5858: // Returns TRUE if the file exists (otherwise FALSE).
5859: BOOL FileExists (const char *filePathPtr)
5860: {
5861: char filePath [TC_MAX_PATH];
5862:
5863: // Strip quotation marks (if any)
5864: if (filePathPtr [0] == '"')
5865: {
5866: strcpy (filePath, filePathPtr + 1);
5867: }
5868: else
5869: {
5870: strcpy (filePath, filePathPtr);
5871: }
5872:
5873: // Strip quotation marks (if any)
5874: if (filePath [strlen (filePath) - 1] == '"')
5875: filePath [strlen (filePath) - 1] = 0;
5876:
5877: return (_access (filePath, 0) != -1);
5878: }
5879:
5880: // Searches the file from its end for the LAST occurrence of the string str.
5881: // The string may contain zeroes, which do NOT terminate the string.
5882: // If the string is found, its offset from the start of the file is returned.
5883: // If the string isn't found or if any error occurs, -1 is returned.
1.1.1.19 root 5884: __int64 FindStringInFile (const char *filePath, const char* str, int strLen)
1.1.1.13 root 5885: {
5886: int bufSize = 64 * BYTES_PER_KB;
1.1.1.15 root 5887: char *buffer = (char *) malloc (bufSize);
1.1.1.13 root 5888: HANDLE src = NULL;
5889: DWORD bytesRead;
5890: BOOL readRetVal;
5891: __int64 filePos = GetFileSize64 (filePath);
5892: int bufPos = 0;
5893: LARGE_INTEGER seekOffset, seekOffsetNew;
5894: BOOL bExit = FALSE;
5895: int filePosStep;
5896: __int64 retVal = -1;
5897:
5898: if (filePos <= 0
5899: || buffer == NULL
5900: || strLen > bufSize
5901: || strLen < 1)
5902: return -1;
5903:
5904: src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
5905:
5906: if (src == INVALID_HANDLE_VALUE)
5907: {
5908: free (buffer);
5909: return -1;
5910: }
5911:
5912: filePosStep = bufSize - strLen + 1;
5913:
5914: do
5915: {
5916: filePos -= filePosStep;
5917:
5918: if (filePos < 0)
5919: {
5920: filePos = 0;
5921: bExit = TRUE;
5922: }
5923:
5924: seekOffset.QuadPart = filePos;
5925:
5926: if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
5927: goto fsif_end;
5928:
5929: if ((readRetVal = ReadFile (src, buffer, bufSize, &bytesRead, NULL)) == 0
5930: || bytesRead == 0)
5931: goto fsif_end;
5932:
5933: bufPos = bytesRead - strLen;
5934:
5935: while (bufPos > 0)
5936: {
5937: if (memcmp (buffer + bufPos, str, strLen) == 0)
5938: {
5939: // String found
5940: retVal = filePos + bufPos;
5941: goto fsif_end;
5942: }
5943: bufPos--;
5944: }
5945:
5946: } while (!bExit);
5947:
5948: fsif_end:
5949: CloseHandle (src);
5950: free (buffer);
5951:
5952: return retVal;
5953: }
1.1.1.11 root 5954:
1.1.1.6 root 5955: // System CopyFile() copies source file attributes (like FILE_ATTRIBUTE_ENCRYPTED)
5956: // so we need to use our own copy function
5957: BOOL TCCopyFile (char *sourceFileName, char *destinationFile)
5958: {
5959: __int8 *buffer;
5960: HANDLE src, dst;
5961: FILETIME fileTime;
5962: DWORD bytesRead, bytesWritten;
5963: BOOL res;
5964:
5965: src = CreateFile (sourceFileName,
5966: GENERIC_READ,
5967: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
5968:
5969: if (src == INVALID_HANDLE_VALUE)
5970: return FALSE;
5971:
5972: dst = CreateFile (destinationFile,
5973: GENERIC_WRITE,
5974: 0, NULL, CREATE_ALWAYS, 0, NULL);
5975:
5976: if (dst == INVALID_HANDLE_VALUE)
5977: {
5978: CloseHandle (src);
5979: return FALSE;
5980: }
5981:
1.1.1.15 root 5982: buffer = (char *) malloc (64 * 1024);
1.1.1.6 root 5983: if (!buffer)
5984: {
5985: CloseHandle (src);
5986: CloseHandle (dst);
5987: return FALSE;
5988: }
5989:
5990: while (res = ReadFile (src, buffer, 64 * 1024, &bytesRead, NULL))
5991: {
5992: if (bytesRead == 0)
5993: {
5994: res = 1;
5995: break;
5996: }
5997:
5998: if (!WriteFile (dst, buffer, bytesRead, &bytesWritten, NULL)
5999: || bytesRead != bytesWritten)
6000: {
6001: res = 0;
6002: break;
6003: }
6004: }
6005:
6006: GetFileTime (src, NULL, NULL, &fileTime);
6007: SetFileTime (dst, NULL, NULL, &fileTime);
6008:
6009: CloseHandle (src);
6010: CloseHandle (dst);
6011:
6012: free (buffer);
6013: return res != 0;
6014: }
6015:
1.1.1.15 root 6016: // If bAppend is TRUE, the buffer is appended to an existing file. If bAppend is FALSE, any existing file
6017: // is replaced. If an error occurs, the incomplete file is deleted (provided that bAppend is FALSE).
1.1.1.13 root 6018: BOOL SaveBufferToFile (char *inputBuffer, char *destinationFile, DWORD inputLength, BOOL bAppend)
6019: {
6020: HANDLE dst;
6021: DWORD bytesWritten;
6022: BOOL res = TRUE;
6023:
6024: dst = CreateFile (destinationFile,
6025: GENERIC_WRITE,
6026: FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
6027:
6028: if (dst == INVALID_HANDLE_VALUE)
6029: {
6030: handleWin32Error (MainDlg);
6031: return FALSE;
6032: }
6033:
6034: if (bAppend)
6035: SetFilePointer (dst, 0, NULL, FILE_END);
6036:
6037: if (!WriteFile (dst, inputBuffer, inputLength, &bytesWritten, NULL)
6038: || inputLength != bytesWritten)
6039: {
6040: res = FALSE;
6041: }
6042:
6043: if (!res)
6044: {
6045: // If CREATE_ALWAYS is used, ERROR_ALREADY_EXISTS is returned after successful overwrite
6046: // of an existing file (it's not an error)
6047: if (! (GetLastError() == ERROR_ALREADY_EXISTS && !bAppend) )
6048: handleWin32Error (MainDlg);
6049: }
6050:
6051: CloseHandle (dst);
6052: FlushFileBuffers (dst);
6053:
6054: if (!res && !bAppend)
6055: remove (destinationFile);
6056:
6057: return res;
6058: }
6059:
1.1.1.17 root 6060:
6061: // Proper flush for Windows systems. Returns TRUE if successful.
6062: BOOL TCFlushFile (FILE *f)
6063: {
6064: HANDLE hf = (HANDLE) _get_osfhandle (_fileno (f));
6065:
6066: fflush (f);
6067:
6068: if (hf == INVALID_HANDLE_VALUE)
6069: return FALSE;
6070:
6071: return FlushFileBuffers (hf) != 0;
6072: }
6073:
6074:
1.1.1.13 root 6075: // Prints a UTF-16 text (note that this involves a real printer, not a screen).
6076: // textByteLen - length of the text in bytes
6077: // title - printed as part of the page header and used as the filename for a temporary file
6078: BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, int textByteLen)
6079: {
6080: char cl [MAX_PATH*3] = {"/p \""};
6081: char path [MAX_PATH * 2] = { 0 };
6082: char filename [MAX_PATH + 1] = { 0 };
6083:
6084: strcpy (filename, title);
6085: //strcat (filename, ".txt");
6086:
6087: GetTempPath (sizeof (path), path);
6088:
6089: if (!FileExists (path))
6090: {
6091: strcpy (path, GetConfigPath (filename));
6092:
6093: if (strlen(path) < 2)
6094: return FALSE;
6095: }
6096: else
6097: {
6098: strcat (path, filename);
6099: }
6100:
6101: // Write the Unicode signature
6102: if (!SaveBufferToFile ("\xFF\xFE", path, 2, FALSE))
6103: {
6104: remove (path);
6105: return FALSE;
6106: }
6107:
6108: // Write the actual text
6109: if (!SaveBufferToFile ((char *) text, path, textByteLen, TRUE))
6110: {
6111: remove (path);
6112: return FALSE;
6113: }
6114:
6115: strcat (cl, path);
6116: strcat (cl, "\"");
6117:
6118: WaitCursor ();
6119: ShellExecute (NULL, "open", PRINT_TOOL, cl, NULL, SW_HIDE);
6120: Sleep (6000);
6121: NormalCursor();
6122:
6123: remove (path);
6124:
6125: return TRUE;
6126: }
6127:
6128:
1.1.1.17 root 6129: BOOL IsNonInstallMode ()
1.1.1.7 root 6130: {
1.1.1.17 root 6131: HKEY hkey;
6132: DWORD dw;
1.1.1.13 root 6133:
1.1.1.17 root 6134: if (bTravelerModeConfirmed)
6135: return TRUE;
1.1.1.7 root 6136:
1.1.1.17 root 6137: if (hDriver != INVALID_HANDLE_VALUE)
1.1.1.7 root 6138: {
1.1.1.17 root 6139: // The driver is running
6140: if (DeviceIoControl (hDriver, TC_IOCTL_GET_TRAVELER_MODE_STATUS, NULL, 0, NULL, 0, &dw, 0))
6141: {
6142: bTravelerModeConfirmed = TRUE;
6143: return TRUE;
6144: }
6145: else
6146: {
6147: // This is also returned if we fail to determine the status (it does not mean that traveler mode is disproved).
6148: return FALSE;
6149: }
1.1.1.7 root 6150: }
1.1.1.17 root 6151: else
6152: {
6153: // The tests in this block are necessary because this function is in some cases called before DriverAttach().
1.1.1.7 root 6154:
1.1.1.17 root 6155: HANDLE hDriverTmp = CreateFile (WIN32_ROOT_PREFIX, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.7 root 6156:
1.1.1.17 root 6157: if (hDriverTmp == INVALID_HANDLE_VALUE)
6158: {
6159: // The driver was not found in the system path
1.1.1.7 root 6160:
1.1.1.17 root 6161: char path[MAX_PATH * 2] = { 0 };
1.1.1.7 root 6162:
1.1.1.17 root 6163: // We can't use GetConfigPath() here because it would call us back (indirect recursion)
1.1.1.18 root 6164: if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path)))
1.1.1.17 root 6165: {
6166: strcat (path, "\\TrueCrypt\\");
1.1.1.19 root 6167: strcat (path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION);
1.1.1.7 root 6168:
1.1.1.17 root 6169: if (FileExists (path))
6170: {
6171: // To maintain consistency and safety, if the system encryption config file exits, we cannot
6172: // allow traveler mode. (This happens e.g. when the pretest fails and the user selects
6173: // "Last Known Good Configuration" from the Windows boot menu.)
1.1.1.7 root 6174:
1.1.1.17 root 6175: // However, if UAC elevation is needed, we have to confirm traveler mode first (after we are elevated, we won't).
6176: if (!IsAdmin () && IsUacSupported ())
6177: return TRUE;
1.1.1.7 root 6178:
1.1.1.17 root 6179: return FALSE;
6180: }
6181: }
1.1.1.7 root 6182:
1.1.1.17 root 6183: // As the driver was not found in the system path, we can predict that we will run in traveler mode
6184: return TRUE;
6185: }
6186: else
6187: CloseHandle (hDriverTmp);
1.1.1.7 root 6188: }
6189:
1.1.1.17 root 6190: // The following test may be unreliable in some cases (e.g. after the user selects restore "Last Known Good
6191: // Configuration" from the Windows boot menu).
6192: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\TrueCrypt", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
1.1.1.7 root 6193: {
1.1.1.11 root 6194: RegCloseKey (hkey);
6195: return FALSE;
1.1.1.7 root 6196: }
1.1.1.15 root 6197: else
6198: return TRUE;
1.1.1.6 root 6199: }
6200:
6201:
1.1.1.7 root 6202: LRESULT SetCheckBox (HWND hwndDlg, int dlgItem, BOOL state)
1.1.1.6 root 6203: {
1.1.1.7 root 6204: return SendDlgItemMessage (hwndDlg, dlgItem, BM_SETCHECK, state ? BST_CHECKED : BST_UNCHECKED, 0);
6205: }
1.1.1.6 root 6206:
1.1.1.7 root 6207:
6208: BOOL GetCheckBox (HWND hwndDlg, int dlgItem)
6209: {
6210: return IsButtonChecked (GetDlgItem (hwndDlg, dlgItem));
6211: }
6212:
6213:
1.1.1.13 root 6214: // Adds or removes TrueCrypt.exe to/from the system startup sequence (with appropriate command line arguments)
6215: void ManageStartupSeq (void)
6216: {
6217: if (!IsNonInstallMode ())
6218: {
6219: char regk [64];
6220:
6221: // Split the string in order to prevent some antivirus packages from falsely reporting
6222: // TrueCrypt.exe to contain a possible Trojan horse because of this string (heuristic scan).
6223: sprintf (regk, "%s%s", "Software\\Microsoft\\Windows\\Curren", "tVersion\\Run");
6224:
1.1.1.19 root 6225: if (bStartOnLogon || bMountDevicesOnLogon || bMountFavoritesOnLogon)
1.1.1.13 root 6226: {
6227: char exe[MAX_PATH * 2] = { '"' };
6228:
6229: GetModuleFileName (NULL, exe + 1, sizeof (exe) - 1);
6230:
6231: #ifdef VOLFORMAT
6232: {
6233: char *tmp = NULL;
6234:
6235: if (tmp = strrchr (exe, '\\'))
6236: strcpy (++tmp, "TrueCrypt.exe");
6237: }
6238: #endif
6239: strcat (exe, "\" /q preferences");
6240:
6241: if (bMountDevicesOnLogon) strcat (exe, " /a devices");
6242: if (bMountFavoritesOnLogon) strcat (exe, " /a favorites");
6243:
6244: WriteRegistryString (regk, "TrueCrypt", exe);
6245: }
6246: else
6247: DeleteRegistryValue (regk, "TrueCrypt");
6248: }
6249: }
6250:
6251:
1.1.1.11 root 6252: // Delete the last used Windows file selector path for TrueCrypt from the registry
1.1.1.7 root 6253: void CleanLastVisitedMRU (void)
6254: {
6255: WCHAR exeFilename[MAX_PATH];
6256: WCHAR *strToMatch;
6257:
1.1.1.11 root 6258: WCHAR strTmp[4096];
6259: char regPath[128];
6260: char key[64];
6261: int id, len;
1.1.1.7 root 6262:
1.1.1.15 root 6263: GetModuleFileNameW (NULL, exeFilename, sizeof (exeFilename) / sizeof(exeFilename[0]));
1.1.1.7 root 6264: strToMatch = wcsrchr (exeFilename, '\\') + 1;
6265:
1.1.1.11 root 6266: sprintf (regPath, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisited%sMRU", nCurrentOS == WIN_VISTA_OR_LATER ? "Pidl" : "");
6267:
6268: for (id = (nCurrentOS == WIN_VISTA_OR_LATER ? 0 : 'a'); id <= (nCurrentOS == WIN_VISTA_OR_LATER ? 1000 : 'z'); id++)
1.1.1.6 root 6269: {
1.1.1.7 root 6270: *strTmp = 0;
1.1.1.11 root 6271: sprintf (key, (nCurrentOS == WIN_VISTA_OR_LATER ? "%d" : "%c"), id);
6272:
6273: if ((len = ReadRegistryBytes (regPath, key, (char *) strTmp, sizeof (strTmp))) > 0)
1.1.1.6 root 6274: {
1.1.1.11 root 6275: if (_wcsicmp (strTmp, strToMatch) == 0)
1.1.1.7 root 6276: {
1.1.1.11 root 6277: char buf[65536], bufout[sizeof (buf)];
6278:
1.1.1.7 root 6279: // Overwrite the entry with zeroes while keeping its original size
6280: memset (strTmp, 0, len);
1.1.1.11 root 6281: if (!WriteRegistryBytes (regPath, key, (char *) strTmp, len))
1.1.1.7 root 6282: MessageBoxW (NULL, GetString ("CLEAN_WINMRU_FAILED"), lpszTitle, ICON_HAND);
6283:
1.1.1.11 root 6284: DeleteRegistryValue (regPath, key);
6285:
6286: // Remove ID from MRUList
6287: if (nCurrentOS == WIN_VISTA_OR_LATER)
6288: {
6289: int *p = (int *)buf;
6290: int *pout = (int *)bufout;
6291: int l;
6292:
6293: l = len = ReadRegistryBytes ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", "MRUListEx", buf, sizeof (buf));
6294: while (l > 0)
6295: {
6296: l -= sizeof (int);
6297:
6298: if (*p == id)
6299: {
6300: p++;
6301: len -= sizeof (int);
6302: continue;
6303: }
6304: *pout++ = *p++;
6305: }
6306:
6307: WriteRegistryBytes ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", "MRUListEx", bufout, len);
6308: }
6309: else
6310: {
6311: char *p = buf;
6312: char *pout = bufout;
6313:
6314: ReadRegistryString ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", "MRUList", "", buf, sizeof (buf));
6315: while (*p)
6316: {
6317: if (*p == id)
6318: {
6319: p++;
6320: continue;
6321: }
6322: *pout++ = *p++;
6323: }
6324: *pout++ = 0;
6325:
6326: WriteRegistryString ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", "MRUList", bufout);
6327: }
6328:
6329: break;
1.1.1.7 root 6330: }
6331: }
6332: }
6333: }
1.1.1.6 root 6334:
6335:
1.1.1.11 root 6336: #ifndef SETUP
6337: void ClearHistory (HWND hwndDlgItem)
6338: {
6339: ArrowWaitCursor ();
6340:
6341: ClearCombo (hwndDlgItem);
6342: DumpCombo (hwndDlgItem, TRUE);
6343:
6344: CleanLastVisitedMRU ();
6345:
6346: NormalCursor ();
6347: }
6348: #endif // #ifndef SETUP
6349:
6350:
1.1.1.7 root 6351: LRESULT ListItemAdd (HWND list, int index, char *string)
6352: {
6353: LVITEM li;
6354: memset (&li, 0, sizeof(li));
1.1.1.6 root 6355:
1.1.1.7 root 6356: li.mask = LVIF_TEXT;
6357: li.pszText = string;
6358: li.iItem = index;
6359: li.iSubItem = 0;
6360: return ListView_InsertItem (list, &li);
6361: }
1.1.1.6 root 6362:
1.1.1.7 root 6363:
6364: LRESULT ListItemAddW (HWND list, int index, wchar_t *string)
6365: {
6366: LVITEMW li;
6367: memset (&li, 0, sizeof(li));
6368:
6369: li.mask = LVIF_TEXT;
6370: li.pszText = string;
6371: li.iItem = index;
6372: li.iSubItem = 0;
6373: return SendMessageW (list, LVM_INSERTITEMW, 0, (LPARAM)(&li));
6374: }
6375:
6376:
6377: LRESULT ListSubItemSet (HWND list, int index, int subIndex, char *string)
6378: {
6379: LVITEM li;
6380: memset (&li, 0, sizeof(li));
6381:
6382: li.mask = LVIF_TEXT;
6383: li.pszText = string;
6384: li.iItem = index;
6385: li.iSubItem = subIndex;
6386: return ListView_SetItem (list, &li);
6387: }
6388:
6389:
6390: LRESULT ListSubItemSetW (HWND list, int index, int subIndex, wchar_t *string)
6391: {
6392: LVITEMW li;
6393: memset (&li, 0, sizeof(li));
6394:
6395: li.mask = LVIF_TEXT;
6396: li.pszText = string;
6397: li.iItem = index;
6398: li.iSubItem = subIndex;
6399: return SendMessageW (list, LVM_SETITEMW, 0, (LPARAM)(&li));
6400: }
6401:
6402:
6403: BOOL GetMountList (MOUNT_LIST_STRUCT *list)
6404: {
6405: DWORD dwResult;
6406:
6407: memset (list, 0, sizeof (*list));
1.1.1.13 root 6408: return DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, list,
1.1.1.7 root 6409: sizeof (*list), list, sizeof (*list), &dwResult,
6410: NULL);
6411: }
6412:
6413:
6414: int GetDriverRefCount ()
6415: {
6416: DWORD dwResult;
6417: BOOL bResult;
6418: int refCount;
6419:
1.1.1.13 root 6420: bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DEVICE_REFCOUNT, &refCount, sizeof (refCount), &refCount,
1.1.1.7 root 6421: sizeof (refCount), &dwResult, NULL);
6422:
6423: if (bResult)
6424: return refCount;
6425: else
6426: return -1;
6427: }
6428:
1.1.1.13 root 6429: // Loads a 32-bit integer from the file at the specified file offset. The saved value is assumed to have been
6430: // processed by mputLong(). The result is stored in *result. Returns TRUE if successful (otherwise FALSE).
6431: BOOL LoadInt32 (char *filePath, unsigned __int32 *result, __int64 fileOffset)
6432: {
6433: int bufSize = sizeof(__int32);
1.1.1.15 root 6434: unsigned char *buffer = (unsigned char *) malloc (bufSize);
1.1.1.13 root 6435: unsigned char *bufferPtr = buffer;
6436: HANDLE src = NULL;
6437: DWORD bytesRead;
6438: LARGE_INTEGER seekOffset, seekOffsetNew;
6439: BOOL retVal = FALSE;
6440:
6441: if (buffer == NULL)
6442: return -1;
6443:
6444: src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
6445:
6446: if (src == INVALID_HANDLE_VALUE)
6447: {
6448: free (buffer);
6449: return FALSE;
6450: }
6451:
6452: seekOffset.QuadPart = fileOffset;
6453:
6454: if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
6455: goto fsif_end;
6456:
6457: if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0
6458: || bytesRead != bufSize)
6459: goto fsif_end;
6460:
6461:
6462: retVal = TRUE;
6463:
6464: *result = mgetLong(bufferPtr);
6465:
6466: fsif_end:
6467: CloseHandle (src);
6468: free (buffer);
6469:
6470: return retVal;
6471: }
6472:
6473: // Loads a 16-bit integer from the file at the specified file offset. The saved value is assumed to have been
6474: // processed by mputWord(). The result is stored in *result. Returns TRUE if successful (otherwise FALSE).
6475: BOOL LoadInt16 (char *filePath, int *result, __int64 fileOffset)
6476: {
6477: int bufSize = sizeof(__int16);
1.1.1.15 root 6478: unsigned char *buffer = (unsigned char *) malloc (bufSize);
1.1.1.13 root 6479: unsigned char *bufferPtr = buffer;
6480: HANDLE src = NULL;
6481: DWORD bytesRead;
6482: LARGE_INTEGER seekOffset, seekOffsetNew;
6483: BOOL retVal = FALSE;
6484:
6485: if (buffer == NULL)
6486: return -1;
6487:
6488: src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
6489:
6490: if (src == INVALID_HANDLE_VALUE)
6491: {
6492: free (buffer);
6493: return FALSE;
6494: }
6495:
6496: seekOffset.QuadPart = fileOffset;
6497:
6498: if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
6499: goto fsif_end;
6500:
6501: if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0
6502: || bytesRead != bufSize)
6503: goto fsif_end;
6504:
1.1.1.7 root 6505:
1.1.1.13 root 6506: retVal = TRUE;
6507:
6508: *result = mgetWord(bufferPtr);
6509:
6510: fsif_end:
6511: CloseHandle (src);
6512: free (buffer);
6513:
6514: return retVal;
6515: }
6516:
1.1.1.19 root 6517: // Returns NULL if there's any error. Although the buffer can contain binary data, it is always null-terminated.
6518: char *LoadFile (const char *fileName, DWORD *size)
1.1.1.7 root 6519: {
6520: char *buf;
1.1.1.13 root 6521: HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.7 root 6522: if (h == INVALID_HANDLE_VALUE)
6523: return NULL;
6524:
6525: *size = GetFileSize (h, NULL);
1.1.1.15 root 6526: buf = (char *) malloc (*size + 1);
1.1.1.13 root 6527:
6528: if (buf == NULL)
6529: {
6530: CloseHandle (h);
6531: return NULL;
6532: }
6533:
1.1.1.7 root 6534: ZeroMemory (buf, *size + 1);
6535:
1.1.1.13 root 6536: if (!ReadFile (h, buf, *size, size, NULL))
6537: {
6538: free (buf);
6539: buf = NULL;
6540: }
6541:
6542: CloseHandle (h);
6543: return buf;
6544: }
6545:
6546:
6547: // Returns NULL if there's any error.
6548: char *LoadFileBlock (char *fileName, __int64 fileOffset, int count)
6549: {
6550: char *buf;
6551: DWORD bytesRead = 0;
6552: LARGE_INTEGER seekOffset, seekOffsetNew;
6553:
6554: HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
6555: if (h == INVALID_HANDLE_VALUE)
6556: return NULL;
6557:
6558: seekOffset.QuadPart = fileOffset;
6559:
6560: if (SetFilePointerEx (h, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0)
6561: {
6562: CloseHandle (h);
6563: return NULL;
6564: }
6565:
1.1.1.15 root 6566: buf = (char *) malloc (count);
1.1.1.13 root 6567:
6568: if (buf == NULL)
6569: {
6570: CloseHandle (h);
6571: return NULL;
6572: }
6573:
6574: ZeroMemory (buf, count);
6575:
1.1.1.7 root 6576: if (buf != NULL)
1.1.1.13 root 6577: ReadFile (h, buf, count, &bytesRead, NULL);
1.1.1.7 root 6578:
6579: CloseHandle (h);
1.1.1.13 root 6580:
6581: if (bytesRead != count)
6582: {
6583: free (buf);
6584: return NULL;
6585: }
6586:
1.1.1.7 root 6587: return buf;
6588: }
6589:
6590:
1.1.1.13 root 6591: // Returns -1 if there is an error, or the size of the file.
1.1.1.19 root 6592: __int64 GetFileSize64 (const char *path)
1.1.1.13 root 6593: {
6594: HANDLE h = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
6595: LARGE_INTEGER size;
6596:
6597: if (h == INVALID_HANDLE_VALUE)
6598: return -1;
6599:
6600: if (GetFileSizeEx (h, &size) == 0)
6601: return -1;
6602:
6603: CloseHandle (h);
6604:
6605: return size.QuadPart;
6606: }
6607:
6608:
1.1.1.11 root 6609: char *GetModPath (char *path, int maxSize)
1.1.1.10 root 6610: {
6611: GetModuleFileName (NULL, path, maxSize);
6612: strrchr (path, '\\')[1] = 0;
6613: return path;
6614: }
6615:
6616:
1.1.1.7 root 6617: char *GetConfigPath (char *fileName)
6618: {
1.1.1.10 root 6619: static char path[MAX_PATH * 2] = { 0 };
1.1.1.11 root 6620:
6621: if (IsNonInstallMode ())
1.1.1.12 root 6622: {
6623: GetModPath (path, sizeof (path));
6624: strcat (path, fileName);
6625:
1.1.1.11 root 6626: return path;
1.1.1.12 root 6627: }
1.1.1.7 root 6628:
1.1.1.12 root 6629: if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path)))
1.1.1.7 root 6630: {
6631: strcat (path, "\\TrueCrypt\\");
6632: CreateDirectory (path, NULL);
6633: strcat (path, fileName);
6634: }
6635: else
1.1.1.12 root 6636: path[0] = 0;
1.1.1.7 root 6637:
6638: return path;
6639: }
6640:
1.1.1.13 root 6641: // Returns 0 if an error occurs or the drive letter (as an upper-case char) of the system partition (e.g. 'C');
6642: char GetSystemDriveLetter (void)
6643: {
6644: char systemDir [MAX_PATH];
6645:
6646: if (GetSystemDirectory (systemDir, sizeof (systemDir)))
6647: return (toupper (systemDir [0]));
6648: else
6649: return 0;
6650: }
1.1.1.7 root 6651:
6652: int Info (char *stringId)
6653: {
6654: if (Silent) return 0;
1.1.1.17 root 6655: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONINFORMATION);
6656: }
6657:
6658:
1.1.1.20! root 6659: int InfoTopMost (char *stringId)
! 6660: {
! 6661: if (Silent) return 0;
! 6662: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
! 6663: }
! 6664:
! 6665:
1.1.1.17 root 6666: int InfoDirect (const wchar_t *msg)
6667: {
6668: if (Silent) return 0;
6669: return MessageBoxW (MainDlg, msg, lpszTitle, MB_ICONINFORMATION);
1.1.1.7 root 6670: }
6671:
6672:
6673: int Warning (char *stringId)
6674: {
6675: if (Silent) return 0;
1.1.1.17 root 6676: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING);
6677: }
6678:
6679:
6680: int WarningTopMost (char *stringId)
6681: {
6682: if (Silent) return 0;
1.1.1.7 root 6683: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
6684: }
6685:
6686:
1.1.1.17 root 6687: int WarningDirect (const wchar_t *warnMsg)
6688: {
6689: if (Silent) return 0;
1.1.1.19 root 6690: return MessageBoxW (MainDlg, warnMsg, lpszTitle, MB_ICONWARNING);
1.1.1.17 root 6691: }
6692:
6693:
1.1.1.7 root 6694: int Error (char *stringId)
6695: {
6696: if (Silent) return 0;
1.1.1.17 root 6697: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR);
6698: }
6699:
6700:
6701: int ErrorTopMost (char *stringId)
6702: {
6703: if (Silent) return 0;
1.1.1.7 root 6704: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
6705: }
6706:
6707:
1.1.1.17 root 6708: int ErrorDirect (const wchar_t *errMsg)
6709: {
6710: if (Silent) return 0;
6711: return MessageBoxW (MainDlg, errMsg, lpszTitle, MB_ICONERROR);
6712: }
6713:
6714:
1.1.1.7 root 6715: int AskYesNo (char *stringId)
6716: {
6717: if (Silent) return 0;
1.1.1.17 root 6718: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1);
1.1.1.7 root 6719: }
6720:
6721:
6722: int AskNoYes (char *stringId)
6723: {
6724: if (Silent) return 0;
1.1.1.17 root 6725: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
1.1.1.7 root 6726: }
6727:
6728:
1.1.1.13 root 6729: int AskOkCancel (char *stringId)
6730: {
6731: if (Silent) return 0;
1.1.1.17 root 6732: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_OKCANCEL | MB_DEFBUTTON1);
1.1.1.13 root 6733: }
6734:
6735:
1.1.1.7 root 6736: int AskWarnYesNo (char *stringId)
6737: {
6738: if (Silent) return 0;
1.1.1.17 root 6739: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1);
1.1.1.7 root 6740: }
6741:
6742:
6743: int AskWarnNoYes (char *stringId)
6744: {
6745: if (Silent) return 0;
1.1.1.17 root 6746: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
1.1.1.7 root 6747: }
6748:
6749:
1.1.1.12 root 6750: int AskWarnNoYesString (wchar_t *string)
6751: {
6752: if (Silent) return 0;
1.1.1.17 root 6753: return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);
1.1.1.12 root 6754: }
6755:
6756:
1.1.1.19 root 6757: int AskWarnYesNoString (wchar_t *string)
6758: {
6759: if (Silent) return 0;
6760: return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1);
6761: }
6762:
6763:
6764: int AskWarnOkCancel (char *stringId)
6765: {
6766: if (Silent) return 0;
6767: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON1);
6768: }
6769:
6770:
1.1.1.7 root 6771: int AskWarnCancelOk (char *stringId)
6772: {
6773: if (Silent) return 0;
1.1.1.17 root 6774: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2);
1.1.1.7 root 6775: }
6776:
6777:
1.1.1.13 root 6778: int AskErrYesNo (char *stringId)
6779: {
6780: if (Silent) return 0;
1.1.1.17 root 6781: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_YESNO | MB_DEFBUTTON1);
1.1.1.13 root 6782: }
6783:
6784:
6785: int AskErrNoYes (char *stringId)
6786: {
6787: if (Silent) return 0;
1.1.1.17 root 6788: return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_YESNO | MB_DEFBUTTON2);
1.1.1.13 root 6789: }
6790:
6791:
1.1.1.11 root 6792: // The function accepts two input formats:
6793: // Input format 1: {0, "MESSAGE_STRING_ID", "BUTTON_1_STRING_ID", ... "LAST_BUTTON_STRING_ID", 0};
6794: // Input format 2: {L"", L"Message text", L"Button caption 1", ... L"Last button caption", 0};
6795: // The second format is to be used if any of the strings contains format specification (e.g. %s, %d) or
6796: // in any other cases where a string needs to be resolved before calling this function.
6797: // If the returned value is 0, the user closed the dialog window without making a choice.
6798: // 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 6799: int AskMultiChoice (void *strings[], BOOL bBold)
1.1.1.11 root 6800: {
1.1.1.19 root 6801: MULTI_CHOICE_DLGPROC_PARAMS params;
6802:
6803: params.strings = &strings[0];
6804: params.bold = bBold;
6805:
1.1.1.11 root 6806: return DialogBoxParamW (hInst,
6807: MAKEINTRESOURCEW (IDD_MULTI_CHOICE_DLG), MainDlg,
1.1.1.19 root 6808: (DLGPROC) MultiChoiceDialogProc, (LPARAM) ¶ms);
1.1.1.11 root 6809: }
6810:
6811:
1.1.1.7 root 6812: BOOL ConfigWriteBegin ()
6813: {
6814: DWORD size;
1.1.1.13 root 6815: if (ConfigFileHandle != NULL)
6816: return FALSE;
1.1.1.7 root 6817:
6818: if (ConfigBuffer == NULL)
1.1.1.19 root 6819: ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size);
1.1.1.7 root 6820:
1.1.1.19 root 6821: ConfigFileHandle = fopen (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), "w");
1.1.1.7 root 6822: if (ConfigFileHandle == NULL)
6823: {
6824: free (ConfigBuffer);
6825: ConfigBuffer = NULL;
6826: return FALSE;
6827: }
6828: XmlWriteHeader (ConfigFileHandle);
6829: fputs ("\n\t<configuration>", ConfigFileHandle);
6830:
6831: return TRUE;
6832: }
6833:
6834:
6835: BOOL ConfigWriteEnd ()
6836: {
6837: char *xml = ConfigBuffer;
6838: char key[128], value[2048];
6839:
6840: if (ConfigFileHandle == NULL) return FALSE;
6841:
6842: // Write unmodified values
6843: while (xml && (xml = XmlFindElement (xml, "config")))
6844: {
1.1.1.11 root 6845: XmlGetAttributeText (xml, "key", key, sizeof (key));
6846: XmlGetNodeText (xml, value, sizeof (value));
1.1.1.7 root 6847:
6848: fprintf (ConfigFileHandle, "\n\t\t<config key=\"%s\">%s</config>", key, value);
6849: xml++;
6850: }
6851:
6852: fputs ("\n\t</configuration>", ConfigFileHandle);
6853: XmlWriteFooter (ConfigFileHandle);
6854:
1.1.1.17 root 6855: TCFlushFile (ConfigFileHandle);
1.1.1.16 root 6856:
1.1.1.7 root 6857: fclose (ConfigFileHandle);
6858: ConfigFileHandle = NULL;
6859:
6860: if (ConfigBuffer != NULL)
6861: {
6862: DWORD size;
6863: free (ConfigBuffer);
1.1.1.19 root 6864: ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size);
1.1.1.7 root 6865: }
6866:
6867: return TRUE;
6868: }
6869:
6870:
6871: BOOL ConfigWriteString (char *configKey, char *configValue)
6872: {
6873: char *c;
6874: if (ConfigFileHandle == NULL)
6875: return FALSE;
6876:
6877: // Mark previous config value as updated
6878: if (ConfigBuffer != NULL)
6879: {
6880: c = XmlFindElementByAttributeValue (ConfigBuffer, "config", "key", configKey);
6881: if (c != NULL)
6882: c[1] = '!';
6883: }
6884:
6885: return 0 != fprintf (
6886: ConfigFileHandle, "\n\t\t<config key=\"%s\">%s</config>",
6887: configKey, configValue);
6888: }
6889:
6890:
6891: BOOL ConfigWriteInt (char *configKey, int configValue)
6892: {
6893: char val[32];
6894: sprintf (val, "%d", configValue);
6895: return ConfigWriteString (configKey, val);
6896: }
6897:
6898:
6899: static BOOL ConfigRead (char *configKey, char *configValue, int maxValueSize)
6900: {
6901: DWORD size;
6902: char *xml;
6903:
6904: if (ConfigBuffer == NULL)
1.1.1.19 root 6905: ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size);
1.1.1.7 root 6906:
6907: xml = ConfigBuffer;
6908: if (xml != NULL)
6909: {
6910: xml = XmlFindElementByAttributeValue (xml, "config", "key", configKey);
6911: if (xml != NULL)
1.1.1.6 root 6912: {
1.1.1.11 root 6913: XmlGetNodeText (xml, configValue, maxValueSize);
1.1.1.7 root 6914: return TRUE;
1.1.1.6 root 6915: }
1.1.1.7 root 6916: }
6917:
6918: return FALSE;
6919: }
6920:
6921:
6922: int ConfigReadInt (char *configKey, int defaultValue)
6923: {
6924: char s[32];
6925:
6926: if (ConfigRead (configKey, s, sizeof (s)))
6927: return atoi (s);
6928: else
6929: return defaultValue;
6930: }
6931:
6932:
6933: char *ConfigReadString (char *configKey, char *defaultValue, char *str, int maxLen)
6934: {
6935: if (ConfigRead (configKey, str, maxLen))
6936: return str;
6937: else
6938: return defaultValue;
6939: }
6940:
6941:
6942: void OpenPageHelp (HWND hwndDlg, int nPage)
6943: {
6944: int r = (int)ShellExecute (NULL, "open", szHelpFile, NULL, NULL, SW_SHOWNORMAL);
1.1.1.6 root 6945:
1.1.1.7 root 6946: if (r == ERROR_FILE_NOT_FOUND)
6947: {
6948: // Try the secondary help file
6949: r = (int)ShellExecute (NULL, "open", szHelpFile2, NULL, NULL, SW_SHOWNORMAL);
6950:
6951: if (r == ERROR_FILE_NOT_FOUND)
1.1.1.10 root 6952: {
6953: OpenOnlineHelp ();
6954: return;
6955: }
1.1.1.7 root 6956: }
1.1.1.10 root 6957:
1.1.1.7 root 6958: if (r == SE_ERR_NOASSOC)
1.1.1.10 root 6959: {
6960: if (AskYesNo ("HELP_READER_ERROR") == IDYES)
6961: OpenOnlineHelp ();
6962: }
6963: }
6964:
6965:
6966: void OpenOnlineHelp ()
6967: {
1.1.1.11 root 6968: Applink ("help", TRUE, "");
1.1.1.7 root 6969: }
6970:
6971:
6972: #ifndef SETUP
6973:
6974: void RestoreDefaultKeyFilesParam (void)
6975: {
6976: KeyFileRemoveAll (&FirstKeyFile);
6977: if (defaultKeyFilesParam.FirstKeyFile != NULL)
6978: {
6979: FirstKeyFile = KeyFileCloneAll (defaultKeyFilesParam.FirstKeyFile);
6980: KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles;
6981: }
6982: else
6983: KeyFilesEnable = FALSE;
6984: }
6985:
6986:
6987: BOOL LoadDefaultKeyFilesParam (void)
6988: {
6989: BOOL status = TRUE;
6990: DWORD size;
1.1.1.19 root 6991: char *defaultKeyfilesFile = LoadFile (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES), &size);
1.1.1.7 root 6992: char *xml = defaultKeyfilesFile;
6993: KeyFile *kf;
6994:
6995: if (xml == NULL)
6996: return FALSE;
6997:
6998: KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile);
6999:
7000: while (xml = XmlFindElement (xml, "keyfile"))
7001: {
1.1.1.15 root 7002: kf = (KeyFile *) malloc (sizeof (KeyFile));
1.1.1.7 root 7003:
1.1.1.11 root 7004: if (XmlGetNodeText (xml, kf->FileName, sizeof (kf->FileName)) != NULL)
1.1.1.7 root 7005: defaultKeyFilesParam.FirstKeyFile = KeyFileAdd (defaultKeyFilesParam.FirstKeyFile, kf);
7006: else
7007: free (kf);
7008:
7009: xml++;
7010: }
7011:
7012: free (defaultKeyfilesFile);
7013: KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles;
7014:
7015: return status;
7016: }
7017:
7018: #endif /* #ifndef SETUP */
7019:
7020:
7021: void Debug (char *format, ...)
7022: {
7023: char buf[1024];
7024: va_list val;
7025:
7026: va_start(val, format);
7027: _vsnprintf (buf, sizeof (buf), format, val);
7028: va_end(val);
7029:
7030: OutputDebugString (buf);
7031: }
7032:
7033:
7034: void DebugMsgBox (char *format, ...)
7035: {
7036: char buf[1024];
7037: va_list val;
7038:
7039: va_start(val, format);
7040: _vsnprintf (buf, sizeof (buf), format, val);
7041: va_end(val);
7042:
7043: MessageBox (MainDlg, buf, "TrueCrypt debug", 0);
7044: }
7045:
7046:
7047: BOOL Is64BitOs ()
7048: {
7049: static BOOL isWow64 = FALSE;
7050: static BOOL valid = FALSE;
7051: typedef BOOL (__stdcall *LPFN_ISWOW64PROCESS ) (HANDLE hProcess,PBOOL Wow64Process);
7052: LPFN_ISWOW64PROCESS fnIsWow64Process;
7053:
7054: if (valid)
7055: return isWow64;
7056:
7057: fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle("kernel32"), "IsWow64Process");
7058:
7059: if (fnIsWow64Process != NULL)
7060: if (!fnIsWow64Process (GetCurrentProcess(), &isWow64))
7061: isWow64 = FALSE;
7062:
7063: valid = TRUE;
7064: return isWow64;
7065: }
7066:
7067:
1.1.1.17 root 7068: // Returns TRUE, if the currently running operating system is installed in a hidden volume. If it's not, or if
7069: // there's an error, returns FALSE.
7070: BOOL IsHiddenOSRunning (void)
7071: {
7072: static BOOL statusCached = FALSE;
7073: static BOOL hiddenOSRunning;
7074:
7075: if (!statusCached)
7076: {
7077: try
7078: {
7079: hiddenOSRunning = BootEncryption (MainDlg).IsHiddenSystemRunning();
7080: }
7081: catch (...)
7082: {
7083: hiddenOSRunning = FALSE;
7084: }
7085:
7086: statusCached = TRUE;
7087: }
7088:
7089: return hiddenOSRunning;
7090: }
7091:
7092:
7093: BOOL RestartComputer (void)
7094: {
7095: TOKEN_PRIVILEGES tokenPrivil;
7096: HANDLE hTkn;
7097:
7098: if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hTkn))
7099: {
7100: return false;
7101: }
7102:
7103: LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &tokenPrivil.Privileges[0].Luid);
7104: tokenPrivil.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
7105: tokenPrivil.PrivilegeCount = 1;
7106:
7107: AdjustTokenPrivileges (hTkn, false, &tokenPrivil, 0, (PTOKEN_PRIVILEGES) NULL, 0);
7108: if (GetLastError() != ERROR_SUCCESS)
7109: return false;
7110:
7111: if (!ExitWindowsEx (EWX_REBOOT | EWX_FORCE,
7112: SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED))
7113: return false;
7114:
7115: return true;
7116: }
7117:
7118:
1.1.1.11 root 7119: void Applink (char *dest, BOOL bSendOS, char *extraOutput)
7120: {
7121: char url [MAX_URL_LENGTH];
7122: char osname [200];
7123:
7124: if (bSendOS)
7125: {
1.1.1.17 root 7126: /* The type and version of the operating system are (or will be, in future) used to redirect users to website
7127: pages that are appropriate in regards to the OS (such as an OS-specific version of the online documentation). */
7128:
1.1.1.11 root 7129: OSVERSIONINFOEXA os;
7130:
7131: os.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXA);
7132:
7133: GetVersionExA ((LPOSVERSIONINFOA) &os);
7134:
7135: strcpy (osname, "&os=");
7136:
7137: switch (nCurrentOS)
7138: {
1.1.1.17 root 7139:
1.1.1.11 root 7140: case WIN_2000:
7141: strcat (osname, "win2000");
7142: break;
7143:
7144: case WIN_XP:
7145: case WIN_XP64:
7146: strcat (osname, "winxp");
1.1.1.17 root 7147: strcat (osname, (os.wSuiteMask & VER_SUITE_PERSONAL) ? "-home" : "-pro");
1.1.1.11 root 7148: break;
7149:
7150: case WIN_SERVER_2003:
7151: strcat (osname, "win2003");
7152: break;
7153:
7154: case WIN_VISTA_OR_LATER:
1.1.1.13 root 7155: if (CurrentOSMajor == 6 && CurrentOSMinor == 0)
1.1.1.11 root 7156: {
1.1.1.13 root 7157: if (os.wProductType != VER_NT_SERVER && os.wProductType != VER_NT_DOMAIN_CONTROLLER)
1.1.1.11 root 7158: {
1.1.1.13 root 7159: strcat (osname, "winvista");
7160:
7161: if (os.wSuiteMask & VER_SUITE_PERSONAL)
7162: strcat (osname, "-home");
7163: else
1.1.1.11 root 7164: {
1.1.1.13 root 7165: HKEY hkey = 0;
7166: char str[300] = {0};
7167: DWORD size = sizeof (str);
7168:
7169: ZeroMemory (str, sizeof (str));
7170: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
7171: 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS
7172: && (RegQueryValueEx (hkey, "ProductName", 0, 0, (LPBYTE) &str, &size) == ERROR_SUCCESS))
7173: {
7174: if (strstr (str, "Enterprise") != 0)
7175: strcat (osname, "-enterprise");
7176: else if (strstr (str, "Business") != 0)
7177: strcat (osname, "-business");
7178: else if (strstr (str, "Ultimate") != 0)
7179: strcat (osname, "-ultimate");
7180: }
7181: RegCloseKey (hkey);
1.1.1.11 root 7182: }
1.1.1.13 root 7183: }
7184: else
7185: {
7186: strcat (osname, "win2008");
1.1.1.11 root 7187: }
7188: }
1.1.1.12 root 7189: else
7190: {
7191: sprintf (osname + strlen (osname), "win%d.%d", CurrentOSMajor, CurrentOSMinor);
7192: }
7193:
7194: if (os.wProductType == VER_NT_SERVER || os.wProductType == VER_NT_DOMAIN_CONTROLLER)
7195: strcat (osname, "-server");
7196:
1.1.1.11 root 7197: break;
7198:
7199: default:
1.1.1.12 root 7200: sprintf (osname + strlen (osname), "win%d.%d", CurrentOSMajor, CurrentOSMinor);
7201: break;
1.1.1.11 root 7202: }
7203:
7204: if (Is64BitOs())
7205: strcat (osname, "-x64");
7206:
7207: if (CurrentOSServicePack > 0)
1.1.1.12 root 7208: sprintf (osname + strlen (osname), "-sp%d", CurrentOSServicePack);
1.1.1.11 root 7209: }
7210: else
7211: osname[0] = 0;
7212:
7213: ArrowWaitCursor ();
7214:
7215: sprintf (url, TC_APPLINK "%s%s&dest=%s", osname, extraOutput, dest);
7216: ShellExecute (NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
7217:
7218: Sleep (200);
7219: NormalCursor ();
7220: }
7221:
7222:
1.1.1.7 root 7223: char *RelativePath2Absolute (char *szFileName)
7224: {
7225: if (szFileName[0] != '\\'
7226: && strchr (szFileName, ':') == 0
7227: && strstr (szFileName, "Volume{") != szFileName)
7228: {
7229: char path[MAX_PATH*2];
7230: GetCurrentDirectory (MAX_PATH, path);
7231:
7232: if (path[strlen (path) - 1] != '\\')
7233: strcat (path, "\\");
7234:
7235: strcat (path, szFileName);
7236: strncpy (szFileName, path, MAX_PATH-1);
7237: }
7238:
7239: return szFileName;
7240: }
7241:
7242:
7243: void CheckSystemAutoMount ()
7244: {
7245: HKEY hkey = 0;
7246: DWORD value = 0, size = sizeof (DWORD);
7247:
7248: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\ControlSet001\\Services\\MountMgr",
7249: 0, KEY_READ, &hkey) != ERROR_SUCCESS)
7250: return;
7251:
7252: if (RegQueryValueEx (hkey, "NoAutoMount", 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS
7253: && value != 0)
7254: Warning ("SYS_AUTOMOUNT_DISABLED");
1.1.1.11 root 7255: else if (nCurrentOS == WIN_VISTA_OR_LATER)
7256: Warning ("SYS_ASSIGN_DRIVE_LETTER");
7257:
1.1.1.7 root 7258: RegCloseKey (hkey);
7259: }
7260:
7261:
1.1.1.8 root 7262: BOOL CALLBACK CloseTCWindowsEnum (HWND hwnd, LPARAM lParam)
1.1.1.7 root 7263: {
7264: if (GetWindowLongPtr (hwnd, GWLP_USERDATA) == (LONG_PTR) 'TRUE')
7265: {
1.1.1.12 root 7266: char name[1024] = { 0 };
1.1.1.7 root 7267: GetWindowText (hwnd, name, sizeof (name) - 1);
1.1.1.12 root 7268: if (hwnd != MainDlg && strstr (name, "TrueCrypt"))
1.1.1.6 root 7269: {
1.1.1.13 root 7270: PostMessage (hwnd, TC_APPMSG_CLOSE_BKG_TASK, 0, 0);
1.1.1.11 root 7271:
7272: if (DriverVersion < 0x0430)
7273: PostMessage (hwnd, WM_ENDSESSION, 0, 0);
7274:
1.1.1.7 root 7275: PostMessage (hwnd, WM_CLOSE, 0, 0);
1.1.1.6 root 7276:
1.1.1.7 root 7277: if (lParam != 0)
7278: *((BOOL *)lParam) = TRUE;
1.1.1.6 root 7279: }
7280: }
1.1.1.7 root 7281: return TRUE;
1.1.1.6 root 7282: }
1.1.1.7 root 7283:
1.1.1.8 root 7284: BOOL CALLBACK FindTCWindowEnum (HWND hwnd, LPARAM lParam)
7285: {
7286: if (*(HWND *)lParam == hwnd)
7287: return TRUE;
7288:
7289: if (GetWindowLongPtr (hwnd, GWLP_USERDATA) == (LONG_PTR) 'TRUE')
7290: {
7291: char name[32] = { 0 };
7292: GetWindowText (hwnd, name, sizeof (name) - 1);
1.1.1.9 root 7293: if (hwnd != MainDlg && strcmp (name, "TrueCrypt") == 0)
1.1.1.8 root 7294: {
7295: if (lParam != 0)
7296: *((HWND *)lParam) = hwnd;
7297: }
7298: }
7299: return TRUE;
7300: }
7301:
7302:
1.1.1.7 root 7303: BYTE *MapResource (char *resourceType, int resourceId, PDWORD size)
7304: {
7305: HGLOBAL hResL;
7306: HRSRC hRes;
7307:
7308: hRes = FindResource (NULL, MAKEINTRESOURCE(resourceId), resourceType);
7309: hResL = LoadResource (NULL, hRes);
7310:
7311: if (size != NULL)
7312: *size = SizeofResource (NULL, hRes);
7313:
7314: return (BYTE *) LockResource (hResL);
1.1.1.13 root 7315: }
7316:
7317:
7318: void InconsistencyResolved (char *techInfo)
7319: {
7320: wchar_t finalMsg[8024];
7321:
7322: wsprintfW (finalMsg, GetString ("INCONSISTENCY_RESOLVED"), techInfo);
7323: MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
7324: }
1.1.1.17 root 7325:
7326:
1.1.1.19 root 7327: void ReportUnexpectedState (char *techInfo)
7328: {
7329: wchar_t finalMsg[8024];
7330:
7331: wsprintfW (finalMsg, GetString ("UNEXPECTED_STATE"), techInfo);
7332: MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
7333: }
7334:
7335:
1.1.1.17 root 7336: #ifndef SETUP
7337:
1.1.1.19 root 7338: int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader)
1.1.1.17 root 7339: {
1.1.1.19 root 7340: int status = ERR_PARAMETER_INCORRECT;
1.1.1.17 root 7341: int volumeType;
7342: char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH];
7343: char szDosDevice[TC_MAX_PATH];
7344: char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
7345: LARGE_INTEGER headerOffset;
1.1.1.19 root 7346: DWORD dwResult;
1.1.1.17 root 7347:
7348: context->VolumeIsOpen = FALSE;
7349: context->CryptoInfo = NULL;
7350: context->HostFileHandle = INVALID_HANDLE_VALUE;
7351: context->TimestampsValid = FALSE;
7352:
7353: CreateFullVolumePath (szDiskFile, volumePath, &context->IsDevice);
7354:
7355: if (context->IsDevice)
7356: {
7357: status = FakeDosNameForDevice (szDiskFile, szDosDevice, szCFDevice, FALSE);
7358: if (status != 0)
7359: return status;
7360:
7361: preserveTimestamps = FALSE;
7362: }
7363: else
7364: strcpy (szCFDevice, szDiskFile);
7365:
7366: if (preserveTimestamps)
7367: write = TRUE;
7368:
7369: context->HostFileHandle = CreateFile (szCFDevice, GENERIC_READ | (write ? GENERIC_WRITE : 0), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
7370:
7371: if (context->HostFileHandle == INVALID_HANDLE_VALUE)
7372: {
7373: status = ERR_OS_ERROR;
7374: goto error;
7375: }
7376:
1.1.1.19 root 7377: if (context->IsDevice)
7378: {
7379: // Try to gain "raw" access to the partition in case there is a live filesystem on it (otherwise,
7380: // the NTFS driver guards hidden sectors and prevents e.g. header backup restore after the user
7381: // accidentally quick-formats a dismounted partition-hosted TrueCrypt volume as NTFS, etc.)
7382:
7383: DeviceIoControl (context->HostFileHandle, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwResult, NULL);
7384: }
7385:
1.1.1.17 root 7386: context->VolumeIsOpen = TRUE;
7387:
7388: // Remember the container modification/creation date and time
7389: if (!context->IsDevice && preserveTimestamps)
7390: {
7391: if (GetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime) == 0)
7392: {
7393: context->TimestampsValid = FALSE;
7394: Warning ("GETFILETIME_FAILED_GENERIC");
7395: }
7396: else
7397: context->TimestampsValid = TRUE;
7398: }
7399:
7400: // Determine host size
7401: if (context->IsDevice)
7402: {
7403: PARTITION_INFORMATION diskInfo;
7404:
7405: if (GetPartitionInfo (volumePath, &diskInfo))
7406: {
7407: context->HostSize = diskInfo.PartitionLength.QuadPart;
7408: }
7409: else
7410: {
7411: DISK_GEOMETRY driveInfo;
7412:
7413: if (!DeviceIoControl (context->HostFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL))
1.1.1.19 root 7414: {
7415: status = ERR_OS_ERROR;
1.1.1.17 root 7416: goto error;
1.1.1.19 root 7417: }
1.1.1.17 root 7418:
7419: context->HostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector * driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder;
7420: }
7421:
7422: if (context->HostSize == 0)
7423: {
7424: status = ERR_VOL_SIZE_WRONG;
7425: goto error;
7426: }
7427: }
7428: else
7429: {
7430: LARGE_INTEGER fileSize;
7431: if (!GetFileSizeEx (context->HostFileHandle, &fileSize))
7432: {
7433: status = ERR_OS_ERROR;
7434: goto error;
7435: }
7436:
7437: context->HostSize = fileSize.QuadPart;
7438: }
7439:
7440: for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++)
7441: {
7442: // Seek the volume header
7443: switch (volumeType)
7444: {
7445: case TC_VOLUME_TYPE_NORMAL:
7446: headerOffset.QuadPart = useBackupHeader ? context->HostSize - TC_VOLUME_HEADER_GROUP_SIZE : TC_VOLUME_HEADER_OFFSET;
7447: break;
7448:
7449: case TC_VOLUME_TYPE_HIDDEN:
7450: if (TC_HIDDEN_VOLUME_HEADER_OFFSET + TC_VOLUME_HEADER_SIZE > context->HostSize)
7451: continue;
7452:
7453: headerOffset.QuadPart = useBackupHeader ? context->HostSize - TC_VOLUME_HEADER_SIZE : TC_HIDDEN_VOLUME_HEADER_OFFSET;
7454: break;
7455:
7456: case TC_VOLUME_TYPE_HIDDEN_LEGACY:
7457: if (useBackupHeader)
7458: {
7459: status = ERR_PASSWORD_WRONG;
7460: goto error;
7461: }
7462:
7463: headerOffset.QuadPart = context->HostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
7464: break;
7465: }
7466:
7467: if (!SetFilePointerEx ((HANDLE) context->HostFileHandle, headerOffset, NULL, FILE_BEGIN))
7468: {
7469: status = ERR_OS_ERROR;
7470: goto error;
7471: }
7472:
7473: // Read volume header
7474: DWORD bytesRead;
7475: if (!ReadFile (context->HostFileHandle, buffer, sizeof (buffer), &bytesRead, NULL))
7476: {
7477: status = ERR_OS_ERROR;
7478: goto error;
7479: }
7480:
1.1.1.19 root 7481: if (bytesRead != sizeof (buffer)
7482: && context->IsDevice)
1.1.1.17 root 7483: {
1.1.1.19 root 7484: // If FSCTL_ALLOW_EXTENDED_DASD_IO failed and there is a live filesystem on the partition, then the
7485: // filesystem driver may report EOF when we are reading hidden sectors (when the filesystem is
7486: // shorter than the partition). This can happen for example after the user quick-formats a dismounted
7487: // partition-hosted TrueCrypt volume and then tries to read the embedded backup header.
7488:
7489: memset (buffer, 0, sizeof (buffer));
1.1.1.17 root 7490: }
7491:
7492: // Decrypt volume header
1.1.1.19 root 7493: status = ReadVolumeHeader (FALSE, buffer, password, &context->CryptoInfo, NULL);
1.1.1.17 root 7494:
7495: if (status == ERR_PASSWORD_WRONG)
7496: continue; // Try next volume type
7497:
7498: break;
7499: }
7500:
7501: if (status == ERR_SUCCESS)
7502: return status;
7503:
7504: error:
7505: DWORD sysError = GetLastError ();
7506:
7507: CloseVolume (context);
7508:
7509: SetLastError (sysError);
7510: return status;
7511: }
7512:
7513:
7514: void CloseVolume (OpenVolumeContext *context)
7515: {
7516: if (!context->VolumeIsOpen)
7517: return;
7518:
7519: if (context->HostFileHandle != INVALID_HANDLE_VALUE)
7520: {
7521: // Restore the container timestamp (to preserve plausible deniability of possible hidden volume).
7522: if (context->TimestampsValid)
7523: {
7524: if (!SetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime))
7525: {
7526: handleWin32Error (NULL);
7527: Warning ("SETFILETIME_FAILED_PW");
7528: }
7529: }
7530:
7531: CloseHandle (context->HostFileHandle);
7532: context->HostFileHandle = INVALID_HANDLE_VALUE;
7533: }
7534:
7535: if (context->CryptoInfo)
7536: {
7537: crypto_close (context->CryptoInfo);
7538: context->CryptoInfo = NULL;
7539: }
7540:
7541: context->VolumeIsOpen = FALSE;
7542: }
7543:
7544:
7545: int ReEncryptVolumeHeader (char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, BOOL wipeMode)
7546: {
7547: CRYPTO_INFO *newCryptoInfo = NULL;
7548:
7549: RandSetHashFunction (cryptoInfo->pkcs5);
7550:
7551: if (Randinit() != ERR_SUCCESS)
7552: return ERR_PARAMETER_INCORRECT;
7553:
1.1.1.19 root 7554: int status = CreateVolumeHeaderInMemory (bBoot,
1.1.1.17 root 7555: buffer,
7556: cryptoInfo->ea,
7557: cryptoInfo->mode,
7558: password,
7559: cryptoInfo->pkcs5,
7560: (char *) cryptoInfo->master_keydata,
7561: &newCryptoInfo,
7562: cryptoInfo->VolumeSize.Value,
7563: cryptoInfo->hiddenVolume ? cryptoInfo->hiddenVolumeSize : 0,
7564: cryptoInfo->EncryptedAreaStart.Value,
7565: cryptoInfo->EncryptedAreaLength.Value,
7566: cryptoInfo->RequiredProgramVersion,
7567: cryptoInfo->HeaderFlags,
7568: wipeMode);
7569:
7570: if (newCryptoInfo != NULL)
7571: crypto_close (newCryptoInfo);
7572:
7573: return status;
7574: }
7575:
7576: #endif // !SETUP
7577:
7578:
1.1.1.19 root 7579: BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
1.1.1.17 root 7580: {
7581: // GlobalMemoryStatusEx() cannot be used to determine if a paging file is active
7582:
7583: char data[65536];
7584: DWORD size = sizeof (data);
7585:
7586: if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", data, &size)
1.1.1.19 root 7587: && size > 12 && !checkNonWindowsPartitionsOnly)
1.1.1.17 root 7588: return TRUE;
7589:
1.1.1.19 root 7590: if (!IsAdmin())
7591: TC_THROW_FATAL_EXCEPTION;
7592:
1.1.1.17 root 7593: for (char drive = 'C'; drive <= 'Z'; ++drive)
7594: {
1.1.1.18 root 7595: // Query geometry of the drive first to prevent "no medium" pop-ups
7596: string drivePath = "\\\\.\\X:";
7597: drivePath[4] = drive;
1.1.1.19 root 7598:
7599: if (checkNonWindowsPartitionsOnly)
7600: {
7601: char sysDir[MAX_PATH];
7602: if (GetSystemDirectory (sysDir, sizeof (sysDir)) != 0 && toupper (sysDir[0]) == drive)
7603: continue;
7604: }
7605:
1.1.1.18 root 7606: HANDLE handle = CreateFile (drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
7607:
7608: if (handle == INVALID_HANDLE_VALUE)
7609: continue;
7610:
7611: DISK_GEOMETRY driveInfo;
7612: DWORD dwResult;
7613:
7614: if (!DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL))
7615: {
7616: CloseHandle (handle);
7617: continue;
7618: }
7619:
7620: CloseHandle (handle);
7621:
7622: // Test if a paging file exists and is locked by another process
1.1.1.17 root 7623: string path = "X:\\pagefile.sys";
7624: path[0] = drive;
7625:
1.1.1.18 root 7626: handle = CreateFile (path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1.1.1.17 root 7627:
7628: if (handle != INVALID_HANDLE_VALUE)
7629: CloseHandle (handle);
7630: else if (GetLastError() == ERROR_SHARING_VIOLATION)
7631: return TRUE;
7632: }
7633:
7634: return FALSE;
7635: }
7636:
7637:
7638: BOOL DisablePagingFile ()
7639: {
7640: char empty[] = { 0, 0 };
7641: return WriteLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", empty, sizeof (empty));
7642: }
1.1.1.19 root 7643:
7644:
7645: std::wstring SingleStringToWide (const std::string &singleString)
7646: {
7647: if (singleString.empty())
7648: return std::wstring();
7649:
7650: WCHAR wbuf[65536];
7651: int wideLen = MultiByteToWideChar (CP_ACP, 0, singleString.c_str(), -1, wbuf, array_capacity (wbuf) - 1);
7652: throw_sys_if (wideLen == 0);
7653:
7654: wbuf[wideLen] = 0;
7655: return wbuf;
7656: }
7657:
7658:
7659: std::wstring Utf8StringToWide (const std::string &utf8String)
7660: {
7661: if (utf8String.empty())
7662: return std::wstring();
7663:
7664: WCHAR wbuf[65536];
7665: int wideLen = MultiByteToWideChar (CP_UTF8, 0, utf8String.c_str(), -1, wbuf, array_capacity (wbuf) - 1);
7666: throw_sys_if (wideLen == 0);
7667:
7668: wbuf[wideLen] = 0;
7669: return wbuf;
7670: }
7671:
7672:
7673: std::string WideToUtf8String (const std::wstring &wideString)
7674: {
7675: if (wideString.empty())
7676: return std::string();
7677:
7678: char buf[65536];
7679: int len = WideCharToMultiByte (CP_UTF8, 0, wideString.c_str(), -1, buf, array_capacity (buf) - 1, NULL, NULL);
7680: throw_sys_if (len == 0);
7681:
7682: buf[len] = 0;
7683: return buf;
7684: }
7685:
7686:
7687: std::string WideToSingleString (const std::wstring &wideString)
7688: {
7689: if (wideString.empty())
7690: return std::string();
7691:
7692: char buf[65536];
7693: int len = WideCharToMultiByte (CP_ACP, 0, wideString.c_str(), -1, buf, array_capacity (buf) - 1, NULL, NULL);
7694: throw_sys_if (len == 0);
7695:
7696: buf[len] = 0;
7697: return buf;
7698: }
7699:
7700:
7701: #ifndef SETUP
7702:
7703: BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
7704: {
7705: WORD lw = LOWORD (wParam);
7706: static string *password;
7707:
7708: switch (msg)
7709: {
7710: case WM_INITDIALOG:
7711: {
7712: password = (string *) lParam;
7713: LocalizeDialog (hwndDlg, "IDD_TOKEN_PASSWORD");
7714:
7715: wchar_t s[1024];
7716: wsprintfW (s, GetString ("ENTER_TOKEN_PASSWORD"), Utf8StringToWide (password->c_str()).c_str());
7717: SetWindowTextW (GetDlgItem (hwndDlg, IDT_TOKEN_PASSWORD_INFO), s);
7718:
7719: SendMessage (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), EM_LIMITTEXT, SecurityToken::MaxPasswordLength, 0);
7720:
7721: SetForegroundWindow (hwndDlg);
7722: SetFocus (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD));
7723: }
7724: return 0;
7725:
7726: case WM_COMMAND:
7727: if (lw == IDCANCEL || lw == IDOK)
7728: {
7729: if (lw == IDOK)
7730: {
7731: wchar_t passwordWide[SecurityToken::MaxPasswordLength + 1];
7732:
7733: if (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), passwordWide, SecurityToken::MaxPasswordLength + 1) == 0)
7734: {
7735: handleWin32Error (hwndDlg);
7736: break;
7737: }
7738:
7739: char passwordUtf8[SecurityToken::MaxPasswordLength + 1];
7740:
7741: int len = WideCharToMultiByte (CP_UTF8, 0, passwordWide, -1, passwordUtf8, array_capacity (passwordUtf8) - 1, nullptr, nullptr);
7742: passwordUtf8[len] = 0;
7743: *password = passwordUtf8;
7744:
7745: burn (passwordWide, sizeof (passwordWide));
7746: burn (passwordUtf8, sizeof (passwordUtf8));
7747: }
7748:
7749: // Attempt to wipe password stored in the input field buffer
7750: char tmp[SecurityToken::MaxPasswordLength+1];
7751: memset (tmp, 'X', SecurityToken::MaxPasswordLength);
7752: tmp[SecurityToken::MaxPasswordLength] = 0;
7753: SetWindowText (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), tmp);
7754:
7755: EndDialog (hwndDlg, lw);
7756: }
7757: return 1;
7758: }
7759:
7760: return 0;
7761: }
7762:
7763:
7764: struct NewSecurityTokenKeyfileDlgProcParams
7765: {
7766: CK_SLOT_ID SlotId;
7767: string Name;
7768: };
7769:
7770: static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
7771: {
7772: static NewSecurityTokenKeyfileDlgProcParams *newParams;
7773:
7774: WORD lw = LOWORD (wParam);
7775: switch (msg)
7776: {
7777: case WM_INITDIALOG:
7778: {
7779: newParams = (NewSecurityTokenKeyfileDlgProcParams *) lParam;
7780:
7781: WaitCursor();
7782: finally_do ({ NormalCursor(); });
7783:
7784: list <SecurityTokenInfo> tokens;
7785:
7786: try
7787: {
7788: tokens = SecurityToken::GetAvailableTokens();
7789: }
7790: catch (Exception &e)
7791: {
7792: e.Show (hwndDlg);
7793: }
7794:
7795: if (tokens.empty())
7796: {
7797: Error ("NO_TOKENS_FOUND");
7798: EndDialog (hwndDlg, IDCANCEL);
7799: return 1;
7800: }
7801:
7802: foreach (const SecurityTokenInfo &token, tokens)
7803: {
7804: wstringstream tokenLabel;
7805: tokenLabel << L"[" << token.SlotId << L"] " << token.Label;
7806:
7807: AddComboPairW (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token.SlotId);
7808: }
7809:
7810: ComboBox_SetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), 0);
7811:
7812: SetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), Utf8StringToWide (newParams->Name).c_str());
7813: return 1;
7814: }
7815:
7816: case WM_COMMAND:
7817: switch (lw)
7818: {
7819: case IDOK:
7820: {
7821: int selectedToken = ComboBox_GetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN));
7822: if (selectedToken == CB_ERR)
7823: {
7824: EndDialog (hwndDlg, IDCANCEL);
7825: return 1;
7826: }
7827:
7828: newParams->SlotId = ComboBox_GetItemData (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), selectedToken);
7829:
7830: wchar_t name[1024];
7831: if (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), name, array_capacity (name)) != 0)
7832: {
7833: try
7834: {
7835: newParams->Name = WideToUtf8String (name);
7836: }
7837: catch (...) { }
7838: }
7839:
7840: EndDialog (hwndDlg, IDOK);
7841: return 1;
7842: }
7843:
7844: case IDCANCEL:
7845: EndDialog (hwndDlg, IDCANCEL);
7846: return 1;
7847: }
7848:
7849: if (HIWORD (wParam) == EN_CHANGE)
7850: {
7851: wchar_t name[2];
7852: EnableWindow (GetDlgItem (hwndDlg, IDOK), (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), name, array_capacity (name)) != 0));
7853: return 1;
7854: }
7855: }
7856:
7857: return 0;
7858: }
7859:
7860:
7861: static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
7862: {
7863: HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
7864: LVITEMW lvItem;
7865: int line = 0;
7866:
7867: ListView_DeleteAllItems (tokenListControl);
7868:
7869: foreach (const SecurityTokenKeyfile &keyfile, keyfiles)
7870: {
7871: memset (&lvItem, 0, sizeof(lvItem));
7872: lvItem.mask = LVIF_TEXT;
7873: lvItem.iItem = line++;
7874:
7875: stringstream s;
7876: s << keyfile.SlotId;
7877:
7878: ListItemAdd (tokenListControl, lvItem.iItem, (char *) s.str().c_str());
7879: ListSubItemSetW (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile.Token.Label.c_str());
7880: ListSubItemSetW (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile.Id.c_str());
7881: }
7882:
7883: BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
7884: EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected);
7885: EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected);
7886: }
7887:
7888:
7889: static list <SecurityTokenKeyfile> SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
7890: {
7891: HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
7892: list <SecurityTokenKeyfile> selectedKeyfiles;
7893:
7894: int itemId = -1;
7895: while ((itemId = ListView_GetNextItem (tokenListControl, itemId, LVIS_SELECTED)) != -1)
7896: {
7897: selectedKeyfiles.push_back (keyfiles[itemId]);
7898: }
7899:
7900: return selectedKeyfiles;
7901: }
7902:
7903:
7904: BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
7905: {
7906: static list <SecurityTokenKeyfilePath> *selectedTokenKeyfiles;
7907: static vector <SecurityTokenKeyfile> keyfiles;
7908:
7909: WORD lw = LOWORD (wParam);
7910:
7911: switch (msg)
7912: {
7913: case WM_INITDIALOG:
7914: {
7915: selectedTokenKeyfiles = (list <SecurityTokenKeyfilePath> *) lParam;
7916:
7917: LVCOLUMNW LvCol;
7918: HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
7919:
7920: LocalizeDialog (hwndDlg, selectedTokenKeyfiles ? "SELECT_TOKEN_KEYFILES" : "IDD_TOKEN_KEYFILES");
7921:
7922: SendMessage (tokenListControl,LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
7923: LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_TWOCLICKACTIVATE|LVS_EX_LABELTIP
7924: );
7925:
7926: memset (&LvCol, 0, sizeof(LvCol));
7927: LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
7928: LvCol.pszText = GetString ("TOKEN_SLOT_ID");
7929: LvCol.cx = CompensateXDPI (40);
7930: LvCol.fmt = LVCFMT_CENTER;
7931: SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 1, (LPARAM)&LvCol);
7932:
7933: LvCol.pszText = GetString ("TOKEN_NAME");
7934: LvCol.cx = CompensateXDPI (128);
7935: LvCol.fmt = LVCFMT_LEFT;
7936: SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 2, (LPARAM)&LvCol);
7937:
7938: LvCol.pszText = GetString ("TOKEN_DATA_OBJECT_LABEL");
7939: LvCol.cx = CompensateXDPI (180);
7940: LvCol.fmt = LVCFMT_LEFT;
7941: SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 3, (LPARAM)&LvCol);
7942:
7943: keyfiles.clear();
7944:
7945: try
7946: {
7947: WaitCursor();
7948: finally_do ({ NormalCursor(); });
7949:
7950: keyfiles = SecurityToken::GetAvailableKeyfiles();
7951: }
7952: catch (UserAbort&)
7953: {
7954: EndDialog (hwndDlg, IDCANCEL);
7955: return 1;
7956: }
7957: catch (Exception &e)
7958: {
7959: e.Show (hwndDlg);
7960:
7961: if (keyfiles.empty())
7962: {
7963: EndDialog (hwndDlg, IDCANCEL);
7964: return 1;
7965: }
7966: }
7967:
7968: SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
7969: return 1;
7970: }
7971:
7972: case WM_COMMAND:
7973: case WM_NOTIFY:
7974: if (msg == WM_COMMAND && lw == IDOK || msg == WM_NOTIFY && ((NMHDR *)lParam)->code == LVN_ITEMACTIVATE)
7975: {
7976: if (selectedTokenKeyfiles)
7977: {
7978: foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
7979: {
7980: selectedTokenKeyfiles->push_back (SecurityTokenKeyfilePath (keyfile));
7981: }
7982: }
7983:
7984: EndDialog (hwndDlg, IDOK);
7985: return 1;
7986: }
7987:
7988: if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
7989: {
7990: BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
7991: EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected);
7992: EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected);
7993: return 1;
7994: }
7995:
7996: switch (lw)
7997: {
7998: case IDCANCEL:
7999: EndDialog (hwndDlg, IDCANCEL);
8000: return 1;
8001:
8002: case IDC_IMPORT_KEYFILE:
8003: {
8004: char keyfilePath[TC_MAX_PATH];
8005:
8006: if (BrowseFiles (hwndDlg, "SELECT_KEYFILE", keyfilePath, bHistory, FALSE, NULL))
8007: {
8008: DWORD keyfileSize;
8009: byte *keyfileData = (byte *) LoadFile (keyfilePath, &keyfileSize);
8010: if (!keyfileData)
8011: {
8012: handleWin32Error (hwndDlg);
8013: return 1;
8014: }
8015:
8016: if (keyfileSize != 0)
8017: {
8018: NewSecurityTokenKeyfileDlgProcParams newParams;
8019: newParams.Name = WideToUtf8String (SingleStringToWide (keyfilePath));
8020:
8021: size_t lastBackSlash = newParams.Name.find_last_of ('\\');
8022: if (lastBackSlash != string::npos)
8023: newParams.Name = newParams.Name.substr (lastBackSlash + 1);
8024:
8025: if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_NEW_TOKEN_KEYFILE), hwndDlg, (DLGPROC) NewSecurityTokenKeyfileDlgProc, (LPARAM) &newParams) == IDOK)
8026: {
8027: vector <byte> keyfileDataVector (keyfileSize);
8028: memcpy (&keyfileDataVector.front(), keyfileData, keyfileSize);
8029:
8030: try
8031: {
8032: WaitCursor();
8033: finally_do ({ NormalCursor(); });
8034:
8035: SecurityToken::CreateKeyfile (newParams.SlotId, keyfileDataVector, newParams.Name);
8036:
8037: keyfiles = SecurityToken::GetAvailableKeyfiles();
8038: SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
8039: }
8040: catch (Exception &e)
8041: {
8042: e.Show (hwndDlg);
8043: }
8044:
8045: burn (&keyfileDataVector.front(), keyfileSize);
8046: }
8047: }
8048:
8049: burn (keyfileData, keyfileSize);
8050: TCfree (keyfileData);
8051: }
8052:
8053: return 1;
8054: }
8055:
8056: case IDC_EXPORT:
8057: {
8058: try
8059: {
8060: foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
8061: {
8062: char keyfilePath[TC_MAX_PATH];
8063:
8064: if (!BrowseFiles (hwndDlg, "OPEN_TITLE", keyfilePath, bHistory, TRUE, NULL))
8065: break;
8066:
8067: {
8068: WaitCursor();
8069: finally_do ({ NormalCursor(); });
8070:
8071: vector <byte> keyfileData;
8072:
8073: SecurityToken::GetKeyfileData (keyfile, keyfileData);
8074: finally_do_arg (vector <byte> *, &keyfileData, { burn (&finally_arg->front(), finally_arg->size()); });
8075:
8076: if (!SaveBufferToFile ((char *) &keyfileData.front(), keyfilePath, keyfileData.size(), FALSE))
8077: throw SystemException ();
8078: }
8079:
8080: Info ("KEYFILE_EXPORTED");
8081: }
8082: }
8083: catch (Exception &e)
8084: {
8085: e.Show (hwndDlg);
8086: }
8087:
8088: return 1;
8089: }
8090:
8091: case IDC_DELETE:
8092: {
8093: if (AskNoYes ("CONFIRM_SEL_FILES_DELETE") == IDNO)
8094: return 1;
8095:
8096: try
8097: {
8098: WaitCursor();
8099: finally_do ({ NormalCursor(); });
8100:
8101: foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
8102: {
8103: SecurityToken::DeleteKeyfile (keyfile);
8104: }
8105:
8106: keyfiles = SecurityToken::GetAvailableKeyfiles();
8107: SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
8108: }
8109: catch (Exception &e)
8110: {
8111: e.Show (hwndDlg);
8112: }
8113:
8114: return 1;
8115: }
8116: }
8117:
8118: return 0;
8119: }
8120: return 0;
8121: }
8122:
8123:
8124: BOOL InitSecurityTokenLibrary ()
8125: {
8126: if (SecurityTokenLibraryPath[0] == 0)
8127: {
8128: Error ("NO_PKCS11_MODULE_SPECIFIED");
8129: return FALSE;
8130: }
8131:
8132: struct PinRequestHandler : public GetPinFunctor
8133: {
8134: virtual void operator() (string &str)
8135: {
8136: if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PASSWORD), MainDlg, (DLGPROC) SecurityTokenPasswordDlgProc, (LPARAM) &str) == IDCANCEL)
8137: throw UserAbort (SRC_POS);
8138: }
8139: };
8140:
8141: struct WarningHandler : public SendExceptionFunctor
8142: {
8143: virtual void operator() (const Exception &e)
8144: {
8145: e.Show (NULL);
8146: }
8147: };
8148:
8149: try
8150: {
8151: SecurityToken::InitLibrary (SecurityTokenLibraryPath, auto_ptr <GetPinFunctor> (new PinRequestHandler), auto_ptr <SendExceptionFunctor> (new WarningHandler));
8152: }
8153: catch (Exception &e)
8154: {
8155: e.Show (NULL);
8156: Error ("PKCS11_MODULE_INIT_FAILED");
8157: return FALSE;
8158: }
8159:
8160: return TRUE;
8161: }
8162:
8163: #endif // !SETUP
8164:
8165: std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties, bool singleList, bool noFloppy)
8166: {
8167: vector <HostDevice> devices;
8168:
8169: for (int devNumber = 0; devNumber < 64; devNumber++)
8170: {
8171: for (int partNumber = 0; partNumber < 32; partNumber++)
8172: {
8173: stringstream strm;
8174: strm << "\\Device\\Harddisk" << devNumber << "\\Partition" << partNumber;
8175: string devPathStr (strm.str());
8176: const char *devPath = devPathStr.c_str();
8177:
8178: OPEN_TEST_STRUCT openTest;
8179: if (!OpenDevice (devPath, &openTest))
8180: {
8181: if (partNumber == 0)
8182: break;
8183:
8184: continue;
8185: }
8186:
8187: HostDevice device;
8188: device.SystemNumber = devNumber;
8189: device.Path = devPath;
8190:
8191: PARTITION_INFORMATION partInfo;
8192:
8193: if (GetPartitionInfo (devPath, &partInfo))
8194: device.Size = partInfo.PartitionLength.QuadPart;
8195:
8196: if (!noDeviceProperties)
8197: {
8198: DISK_GEOMETRY geometry;
8199:
8200: wstringstream ws;
8201: ws << devPathStr.c_str();
8202: int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str());
8203:
8204: if (driveNumber >= 0)
8205: {
8206: device.MountPoint += (char) (driveNumber + 'A');
8207: device.MountPoint += ":";
8208:
8209: wchar_t name[64];
8210: if (GetDriveLabel (driveNumber, name, sizeof (name)))
8211: device.Name = name;
8212:
8213: if (GetSystemDriveLetter() == 'A' + driveNumber)
8214: device.ContainsSystem = true;
8215: }
8216:
8217: if (partNumber == 0 && GetDriveGeometry (devPath, &geometry))
8218: device.Removable = (geometry.MediaType == RemovableMedia);
8219: }
8220:
8221: if (partNumber == 0)
8222: {
8223: devices.push_back (device);
8224: }
8225: else
8226: {
8227: HostDevice &dev0 = *--devices.end();
8228:
8229: // System creates a virtual partition1 for some storage devices without
8230: // partition table. We try to detect this case by comparing sizes of
8231: // partition0 and partition1. If they match, no partition of the device
8232: // is displayed to the user to avoid confusion. Drive letter assigned by
8233: // system to partition1 is assigned partition0
8234: if (partNumber == 1 && dev0.Size == device.Size)
8235: {
8236: dev0.IsVirtualPartition = true;
8237: dev0.MountPoint = device.MountPoint;
8238: dev0.Name = device.Name;
8239: dev0.Path = device.Path;
8240: break;
8241: }
8242:
8243: device.IsPartition = true;
8244: device.SystemNumber = partNumber;
8245: device.Removable = dev0.Removable;
8246:
8247: if (device.ContainsSystem)
8248: dev0.ContainsSystem = true;
8249:
8250: dev0.Partitions.push_back (device);
8251:
8252: if (singleList)
8253: devices.push_back (device);
8254: }
8255: }
8256: }
8257:
8258: // Vista does not create partition links for dynamic volumes so it is necessary to scan \\Device\\HarddiskVolumeX devices
8259: if (CurrentOSMajor >= 6)
8260: {
8261: for (int devNumber = 0; devNumber < 256; devNumber++)
8262: {
8263: stringstream strm;
8264: strm << "\\Device\\HarddiskVolume" << devNumber;
8265: string devPathStr (strm.str());
8266: const char *devPath = devPathStr.c_str();
8267:
8268: OPEN_TEST_STRUCT openTest;
8269: if (!OpenDevice (devPath, &openTest))
8270: continue;
8271:
8272: DISK_PARTITION_INFO_STRUCT info;
8273: if (GetDeviceInfo (devPath, &info) && info.IsDynamic)
8274: {
8275: HostDevice device;
8276: device.DynamicVolume = true;
8277: device.IsPartition = true;
8278: device.SystemNumber = devNumber;
8279: device.Path = devPath;
8280: device.Size = info.partInfo.PartitionLength.QuadPart;
8281:
8282: if (!noDeviceProperties)
8283: {
8284: wstringstream ws;
8285: ws << devPathStr.c_str();
8286: int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str());
8287:
8288: if (driveNumber >= 0)
8289: {
8290: device.MountPoint += (char) (driveNumber + 'A');
8291: device.MountPoint += ":";
8292:
8293: wchar_t name[64];
8294: if (GetDriveLabel (driveNumber, name, sizeof (name)))
8295: device.Name = name;
8296:
8297: if (GetSystemDriveLetter() == 'A' + driveNumber)
8298: device.ContainsSystem = true;
8299: }
8300: }
8301:
8302: devices.push_back (device);
8303: }
8304: }
8305: }
8306:
8307: // Floppy drives
8308: if (!noFloppy)
8309: {
8310: HostDevice floppy;
8311: floppy.Floppy = true;
8312:
8313: char path[TC_MAX_PATH];
8314:
8315: if (QueryDosDevice ("A:", path, sizeof (path)) != 0 && GetDriveType ("A:\\") == DRIVE_REMOVABLE)
8316: {
8317: floppy.MountPoint = "A:";
8318: floppy.Path = "\\Device\\Floppy0";
8319: devices.push_back (floppy);
8320: }
8321:
8322: if (QueryDosDevice ("B:", path, sizeof (path)) != 0 && GetDriveType ("B:\\") == DRIVE_REMOVABLE)
8323: {
8324: floppy.MountPoint = "B:";
8325: floppy.Path = "\\Device\\Floppy1";
8326: devices.push_back (floppy);
8327: }
8328: }
8329:
8330: return devices;
8331: }
8332:
8333:
1.1.1.20! root 8334: BOOL FileHasReadOnlyAttribute (const char *path)
! 8335: {
! 8336: DWORD attributes = GetFileAttributes (path);
! 8337: return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_READONLY) != 0;
! 8338: }
! 8339:
! 8340:
1.1.1.19 root 8341: BOOL IsFileOnReadOnlyFilesystem (const char *path)
8342: {
8343: char root[MAX_PATH];
8344: if (!GetVolumePathName (path, root, sizeof (root)))
8345: return FALSE;
8346:
8347: DWORD flags, d;
8348: if (!GetVolumeInformation (root, NULL, 0, NULL, &d, &flags, NULL, 0))
8349: return FALSE;
8350:
8351: return (flags & FILE_READ_ONLY_VOLUME) ? TRUE : FALSE;
8352: }
8353:
8354:
8355: void CheckFilesystem (int driveNo, BOOL fixErrors)
8356: {
8357: wchar_t msg[1024], param[1024];
8358: char driveRoot[] = { 'A' + driveNo, ':', 0};
8359:
8360: wsprintfW (msg, GetString (fixErrors ? "REPAIRING_FS" : "CHECKING_FS"), driveRoot);
8361: wsprintfW (param, fixErrors ? L"/C echo %s & chkdsk %hs /F /X & pause" : L"/C echo %s & chkdsk %hs & pause", msg, driveRoot);
8362:
8363: ShellExecuteW (NULL, (!IsAdmin() && IsUacSupported()) ? L"runas" : L"open", L"cmd.exe", param, NULL, SW_SHOW);
8364: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.