/* Legal Notice: Some portions of the source code contained in this file were derived from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses'. Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2003-2012 TrueCrypt Developers Association and are governed by the TrueCrypt License 3.0 the full text of which is contained in the file License.txt included in TrueCrypt binary and source code distribution packages. */ #include "Tcdefs.h" #include #include #include #include #include #include #include #include #include #include #include "Resource.h" #include "Platform/Finally.h" #include "Platform/ForEach.h" #include "Apidrvr.h" #include "BootEncryption.h" #include "Combo.h" #include "Crc.h" #include "Crypto.h" #include "Dictionary.h" #include "Dlgcode.h" #include "EncryptionThreadPool.h" #include "Endian.h" #include "Format/Inplace.h" #include "Language.h" #include "Keyfiles.h" #include "Pkcs5.h" #include "Random.h" #include "Registry.h" #include "SecurityToken.h" #include "Tests.h" #include "Volumes.h" #include "Wipe.h" #include "Xml.h" #include "Xts.h" #include "Boot/Windows/BootCommon.h" #ifdef TCMOUNT #include "Mount/Mount.h" #endif #ifdef VOLFORMAT #include "Format/Tcformat.h" #endif #ifdef SETUP #include "Setup/Setup.h" #endif #include using namespace VeraCrypt; LONG DriverVersion; char *LastDialogId; char szHelpFile[TC_MAX_PATH]; char szHelpFile2[TC_MAX_PATH]; char SecurityTokenLibraryPath[TC_MAX_PATH]; HFONT hFixedDigitFont = NULL; HFONT hBoldFont = NULL; HFONT hTitleFont = NULL; HFONT hFixedFont = NULL; HFONT hUserFont = NULL; HFONT hUserUnderlineFont = NULL; HFONT hUserBoldFont = NULL; HFONT hUserUnderlineBoldFont = NULL; HFONT WindowTitleBarFont; int ScreenDPI = USER_DEFAULT_SCREEN_DPI; double DPIScaleFactorX = 1; double DPIScaleFactorY = 1; double DlgAspectRatio = 1; HWND MainDlg = NULL; wchar_t *lpszTitle = NULL; BOOL Silent = FALSE; BOOL bPreserveTimestamp = TRUE; BOOL bStartOnLogon = FALSE; BOOL bMountDevicesOnLogon = FALSE; BOOL bMountFavoritesOnLogon = FALSE; BOOL bHistory = FALSE; // Status of detection of hidden sectors (whole-system-drive encryption). // 0 - Unknown/undetermined/completed, 1: Detection is or was in progress (but did not complete e.g. due to system crash). int HiddenSectorDetectionStatus = 0; OSVersionEnum nCurrentOS = WIN_UNKNOWN; int CurrentOSMajor = 0; int CurrentOSMinor = 0; int CurrentOSServicePack = 0; BOOL RemoteSession = FALSE; BOOL UacElevated = FALSE; BOOL bPortableModeConfirmed = FALSE; // TRUE if it is certain that the instance is running in portable mode 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. /* Globals used by Mount and Format (separately per instance) */ BOOL KeyFilesEnable = FALSE; KeyFile *FirstKeyFile = NULL; KeyFilesDlgParam defaultKeyFilesParam; BOOL IgnoreWmDeviceChange = FALSE; BOOL DeviceChangeBroadcastDisabled = FALSE; BOOL LastMountedVolumeDirty; BOOL MountVolumesAsSystemFavorite = FALSE; BOOL FavoriteMountOnArrivalInProgress = FALSE; BOOL MultipleMountOperationInProgress = FALSE; /* Handle to the device driver */ HANDLE hDriver = INVALID_HANDLE_VALUE; /* This mutex is used to prevent multiple instances of the wizard or main app from dealing with system encryption */ volatile HANDLE hSysEncMutex = NULL; /* This mutex is used for non-system in-place encryption but only for informative (non-blocking) purposes, such as whether an app should prompt the user whether to resume scheduled process. */ volatile HANDLE hNonSysInplaceEncMutex = NULL; /* This mutex is used to prevent multiple instances of the wizard or main app from trying to install or register the driver or from trying to launch it in portable mode at the same time. */ volatile HANDLE hDriverSetupMutex = NULL; /* This mutex is used to prevent users from running the main TrueCrypt app or the wizard while an instance of the TrueCrypt installer is running (which is also useful for enforcing restart before the apps can be used). */ volatile HANDLE hAppSetupMutex = NULL; HINSTANCE hInst = NULL; HCURSOR hCursor = NULL; ATOM hDlgClass, hSplashClass; /* This value may changed only by calling ChangeSystemEncryptionStatus(). Only the wizard can change it (others may still read it though). */ int SystemEncryptionStatus = SYSENC_STATUS_NONE; /* Only the wizard can change this value (others may only read it). */ WipeAlgorithmId nWipeMode = TC_WIPE_NONE; BOOL bSysPartitionSelected = FALSE; /* TRUE if the user selected the system partition via the Select Device dialog */ BOOL bSysDriveSelected = FALSE; /* TRUE if the user selected the system drive via the Select Device dialog */ /* To populate these arrays, call GetSysDevicePaths(). If they contain valid paths, bCachedSysDevicePathsValid is TRUE. */ char SysPartitionDevicePath [TC_MAX_PATH]; char SysDriveDevicePath [TC_MAX_PATH]; string ExtraBootPartitionDevicePath; char bCachedSysDevicePathsValid = FALSE; BOOL bHyperLinkBeingTracked = FALSE; int WrongPwdRetryCounter = 0; static FILE *ConfigFileHandle; char *ConfigBuffer; BOOL SystemFileSelectorCallPending = FALSE; DWORD SystemFileSelectorCallerThreadId; #define RANDPOOL_DISPLAY_REFRESH_INTERVAL 30 #define RANDPOOL_DISPLAY_ROWS 16 #define RANDPOOL_DISPLAY_COLUMNS 20 /* Windows dialog class */ #define WINDOWS_DIALOG_CLASS "#32770" /* Custom class names */ #define TC_DLG_CLASS "CustomDlg" #define TC_SPLASH_CLASS "SplashDlg" /* Benchmarks */ #ifndef SETUP #define BENCHMARK_MAX_ITEMS 100 #define BENCHMARK_DEFAULT_BUF_SIZE BYTES_PER_MB #define HASH_FNC_BENCHMARKS FALSE // For development purposes only. Must be FALSE when building a public release. #define PKCS5_BENCHMARKS FALSE // For development purposes only. Must be FALSE when building a public release. #if PKCS5_BENCHMARKS && HASH_FNC_BENCHMARKS #error PKCS5_BENCHMARKS and HASH_FNC_BENCHMARKS are both TRUE (at least one of them should be FALSE). #endif enum { BENCHMARK_SORT_BY_NAME = 0, BENCHMARK_SORT_BY_SPEED }; typedef struct { int id; char name[100]; unsigned __int64 encSpeed; unsigned __int64 decSpeed; unsigned __int64 meanBytesPerSec; } BENCHMARK_REC; BENCHMARK_REC benchmarkTable [BENCHMARK_MAX_ITEMS]; int benchmarkTotalItems = 0; int benchmarkBufferSize = BENCHMARK_DEFAULT_BUF_SIZE; int benchmarkLastBufferSize = BENCHMARK_DEFAULT_BUF_SIZE; int benchmarkSortMethod = BENCHMARK_SORT_BY_SPEED; LARGE_INTEGER benchmarkPerformanceFrequency; #endif // #ifndef SETUP typedef struct { void *strings; BOOL bold; } MULTI_CHOICE_DLGPROC_PARAMS; void cleanup () { /* Cleanup the GDI fonts */ if (hFixedFont != NULL) DeleteObject (hFixedFont); if (hFixedDigitFont != NULL) DeleteObject (hFixedDigitFont); if (hBoldFont != NULL) DeleteObject (hBoldFont); if (hTitleFont != NULL) DeleteObject (hTitleFont); if (hUserFont != NULL) DeleteObject (hUserFont); if (hUserUnderlineFont != NULL) DeleteObject (hUserUnderlineFont); if (hUserBoldFont != NULL) DeleteObject (hUserBoldFont); if (hUserUnderlineBoldFont != NULL) DeleteObject (hUserUnderlineBoldFont); /* Cleanup our dialog class */ if (hDlgClass) UnregisterClass (TC_DLG_CLASS, hInst); if (hSplashClass) UnregisterClass (TC_SPLASH_CLASS, hInst); /* Close the device driver handle */ if (hDriver != INVALID_HANDLE_VALUE) { // Unload driver mode if possible (non-install mode) if (IsNonInstallMode ()) { // If a dismount was forced in the lifetime of the driver, Windows may later prevent it to be loaded again from // the same path. Therefore, the driver will not be unloaded even though it was loaded in non-install mode. int driverUnloadDisabled; DWORD dwResult; if (!DeviceIoControl (hDriver, TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED, NULL, 0, &driverUnloadDisabled, sizeof (driverUnloadDisabled), &dwResult, NULL)) driverUnloadDisabled = 0; if (!driverUnloadDisabled) DriverUnload (); else { CloseHandle (hDriver); hDriver = INVALID_HANDLE_VALUE; } } else { CloseHandle (hDriver); hDriver = INVALID_HANDLE_VALUE; } } if (ConfigBuffer != NULL) { free (ConfigBuffer); ConfigBuffer = NULL; } CoUninitialize (); CloseSysEncMutex (); #ifndef SETUP try { if (SecurityToken::IsInitialized()) SecurityToken::CloseLibrary(); } catch (...) { } EncryptionThreadPoolStop(); #endif } void LowerCaseCopy (char *lpszDest, const char *lpszSource) { int i = strlen (lpszSource); lpszDest[i] = 0; while (--i >= 0) { lpszDest[i] = (char) tolower (lpszSource[i]); } } void UpperCaseCopy (char *lpszDest, size_t cbDest, const char *lpszSource) { if (lpszDest && cbDest) { int i = strlen (lpszSource); if (i >= (int) cbDest) i = cbDest - 1; lpszDest[i] = 0; while (--i >= 0) { lpszDest[i] = (char) toupper (lpszSource[i]); } } } std::string ToUpperCase (const std::string &str) { string u; foreach (char c, str) { u += (char) toupper (c); } return u; } size_t TrimWhiteSpace(char *str) { char *end, *ptr = str; size_t out_size; if(!str || *str == 0) return 0; // Trim leading space while(isspace(*ptr)) ptr++; if(*ptr == 0) // All spaces? { *str = 0; return 0; } // Trim trailing space end = str + strlen(str) - 1; while(end > ptr && isspace(*end)) end--; end++; // Set output size to trimmed string length out_size = (end - ptr); // Copy trimmed string and add null terminator memmove(str, ptr, out_size); str[out_size] = 0; return out_size; } // check the validity of a file name BOOL IsValidFileName(const char* str) { static char invalidChars[9] = {'<', '>', ':', '"', '/', '\\', '|', '?', '*'}; char c; int i; BOOL bNotDotOnly = FALSE; while ((c = *str)) { if (c != '.') bNotDotOnly = TRUE; for (i= 0; i < sizeof(invalidChars); i++) if (c == invalidChars[i]) return FALSE; str++; } return bNotDotOnly; } BOOL IsVolumeDeviceHosted (const char *lpszDiskFile) { return strstr (lpszDiskFile, "\\Device\\") == lpszDiskFile || strstr (lpszDiskFile, "\\DEVICE\\") == lpszDiskFile; } void CreateFullVolumePath (char *lpszDiskFile, size_t cbDiskFile, const char *lpszFileName, BOOL * bDevice) { UpperCaseCopy (lpszDiskFile, cbDiskFile, lpszFileName); *bDevice = FALSE; if (memcmp (lpszDiskFile, "\\DEVICE", sizeof (char) * 7) == 0) { *bDevice = TRUE; } StringCbCopyA (lpszDiskFile, cbDiskFile, lpszFileName); #if _DEBUG OutputDebugString ("CreateFullVolumePath: "); OutputDebugString (lpszDiskFile); OutputDebugString ("\n"); #endif } int FakeDosNameForDevice (const char *lpszDiskFile , char *lpszDosDevice , size_t cbDosDevice, char *lpszCFDevice , size_t cbCFDevice, BOOL bNameOnly) { BOOL bDosLinkCreated = TRUE; StringCbPrintfA (lpszDosDevice, cbDosDevice,"veracrypt%lu", GetCurrentProcessId ()); if (bNameOnly == FALSE) bDosLinkCreated = DefineDosDevice (DDD_RAW_TARGET_PATH, lpszDosDevice, lpszDiskFile); if (bDosLinkCreated == FALSE) return ERR_OS_ERROR; else StringCbPrintfA (lpszCFDevice, cbCFDevice,"\\\\.\\%s", lpszDosDevice); return 0; } int RemoveFakeDosName (char *lpszDiskFile, char *lpszDosDevice) { BOOL bDosLinkRemoved = DefineDosDevice (DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE | DDD_REMOVE_DEFINITION, lpszDosDevice, lpszDiskFile); if (bDosLinkRemoved == FALSE) { return ERR_OS_ERROR; } return 0; } void AbortProcess (char *stringId) { // Note that this function also causes localcleanup() to be called (see atexit()) MessageBeep (MB_ICONEXCLAMATION); MessageBoxW (NULL, GetString (stringId), lpszTitle, ICON_HAND); exit (1); } void AbortProcessSilent (void) { // Note that this function also causes localcleanup() to be called (see atexit()) exit (1); } #pragma warning(push) #pragma warning(disable:4702) void *err_malloc (size_t size) { void *z = (void *) TCalloc (size); if (z) return z; AbortProcess ("OUTOFMEMORY"); return 0; } #pragma warning(pop) char *err_strdup (char *lpszText) { int j = (strlen (lpszText) + 1) * sizeof (char); char *z = (char *) err_malloc (j); memmove (z, lpszText, j); return z; } BOOL IsDiskReadError (DWORD error) { return (error == ERROR_CRC || error == ERROR_IO_DEVICE || error == ERROR_BAD_CLUSTERS || error == ERROR_SECTOR_NOT_FOUND || error == ERROR_READ_FAULT || error == ERROR_INVALID_FUNCTION // I/O error may be reported as ERROR_INVALID_FUNCTION by buggy chipset drivers || error == ERROR_SEM_TIMEOUT); // I/O operation timeout may be reported as ERROR_SEM_TIMEOUT } BOOL IsDiskWriteError (DWORD error) { return (error == ERROR_IO_DEVICE || error == ERROR_BAD_CLUSTERS || error == ERROR_SECTOR_NOT_FOUND || error == ERROR_WRITE_FAULT || error == ERROR_INVALID_FUNCTION // I/O error may be reported as ERROR_INVALID_FUNCTION by buggy chipset drivers || error == ERROR_SEM_TIMEOUT); // I/O operation timeout may be reported as ERROR_SEM_TIMEOUT } BOOL IsDiskError (DWORD error) { return IsDiskReadError (error) || IsDiskWriteError (error); } DWORD handleWin32Error (HWND hwndDlg) { PWSTR lpMsgBuf; DWORD dwError = GetLastError (); if (Silent || dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE) return dwError; // Access denied if (dwError == ERROR_ACCESS_DENIED && !IsAdmin ()) { Error ("ERR_ACCESS_DENIED"); SetLastError (dwError); // Preserve the original error code return dwError; } FormatMessageW ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ (PWSTR) &lpMsgBuf, 0, NULL ); MessageBoxW (hwndDlg, lpMsgBuf, lpszTitle, ICON_HAND); LocalFree (lpMsgBuf); // User-friendly hardware error explanation if (IsDiskError (dwError)) Error ("ERR_HARDWARE_ERROR"); // Device not ready if (dwError == ERROR_NOT_READY) HandleDriveNotReadyError(); SetLastError (dwError); // Preserve the original error code return dwError; } BOOL translateWin32Error (wchar_t *lpszMsgBuf, int nWSizeOfBuf) { DWORD dwError = GetLastError (); if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ lpszMsgBuf, nWSizeOfBuf, NULL)) { SetLastError (dwError); // Preserve the original error code return TRUE; } SetLastError (dwError); // Preserve the original error code return FALSE; } // If the user has a non-default screen DPI, all absolute font sizes must be // converted using this function. int CompensateDPIFont (int val) { if (ScreenDPI == USER_DEFAULT_SCREEN_DPI) return val; else { double tmpVal = (double) val * DPIScaleFactorY * DlgAspectRatio * 0.999; if (tmpVal > 0) return (int) floor(tmpVal); else return (int) ceil(tmpVal); } } // If the user has a non-default screen DPI, some screen coordinates and sizes must // be converted using this function int CompensateXDPI (int val) { if (ScreenDPI == USER_DEFAULT_SCREEN_DPI) return val; else { double tmpVal = (double) val * DPIScaleFactorX; if (tmpVal > 0) return (int) floor(tmpVal); else return (int) ceil(tmpVal); } } // If the user has a non-default screen DPI, some screen coordinates and sizes must // be converted using this function int CompensateYDPI (int val) { if (ScreenDPI == USER_DEFAULT_SCREEN_DPI) return val; else { double tmpVal = (double) val * DPIScaleFactorY; if (tmpVal > 0) return (int) floor(tmpVal); else return (int) ceil(tmpVal); } } int GetTextGfxWidth (HWND hwndDlgItem, const wchar_t *text, HFONT hFont) { SIZE sizes; TEXTMETRIC textMetrics; HDC hdc = GetDC (hwndDlgItem); SelectObject(hdc, (HGDIOBJ) hFont); GetTextExtentPoint32W (hdc, text, wcslen (text), &sizes); GetTextMetrics(hdc, &textMetrics); // Necessary for non-TrueType raster fonts (tmOverhang) ReleaseDC (hwndDlgItem, hdc); return ((int) sizes.cx - (int) textMetrics.tmOverhang); } int GetTextGfxHeight (HWND hwndDlgItem, const wchar_t *text, HFONT hFont) { SIZE sizes; HDC hdc = GetDC (hwndDlgItem); SelectObject(hdc, (HGDIOBJ) hFont); GetTextExtentPoint32W (hdc, text, wcslen (text), &sizes); ReleaseDC (hwndDlgItem, hdc); return ((int) sizes.cy); } std::string FitPathInGfxWidth (HWND hwnd, HFONT hFont, LONG width, const std::string &path) { string newPath; RECT rect; rect.left = 0; rect.top = 0; rect.right = width; rect.bottom = LONG_MAX; HDC hdc = GetDC (hwnd); SelectObject (hdc, (HGDIOBJ) hFont); char pathBuf[TC_MAX_PATH]; strcpy_s (pathBuf, sizeof (pathBuf), path.c_str()); if (DrawText (hdc, pathBuf, path.size(), &rect, DT_CALCRECT | DT_MODIFYSTRING | DT_PATH_ELLIPSIS | DT_SINGLELINE) != 0) newPath = pathBuf; ReleaseDC (hwnd, hdc); return newPath; } static LRESULT CALLBACK HyperlinkProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { WNDPROC wp = (WNDPROC) GetWindowLongPtr (hwnd, GWLP_USERDATA); switch (message) { case WM_SETCURSOR: if (!bHyperLinkBeingTracked) { TRACKMOUSEEVENT trackMouseEvent; trackMouseEvent.cbSize = sizeof(trackMouseEvent); trackMouseEvent.dwFlags = TME_LEAVE; trackMouseEvent.hwndTrack = hwnd; bHyperLinkBeingTracked = TrackMouseEvent(&trackMouseEvent); HandCursor(); } return 0; case WM_MOUSELEAVE: bHyperLinkBeingTracked = FALSE; NormalCursor(); return 0; } return CallWindowProc (wp, hwnd, message, wParam, lParam); } BOOL ToHyperlink (HWND hwndDlg, UINT ctrlId) { return ToCustHyperlink (hwndDlg, ctrlId, hUserUnderlineFont); } BOOL ToCustHyperlink (HWND hwndDlg, UINT ctrlId, HFONT hFont) { HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); SendMessage (hwndCtrl, WM_SETFONT, (WPARAM) hFont, 0); SetWindowLongPtr (hwndCtrl, GWLP_USERDATA, (LONG_PTR) GetWindowLongPtr (hwndCtrl, GWLP_WNDPROC)); SetWindowLongPtr (hwndCtrl, GWLP_WNDPROC, (LONG_PTR) HyperlinkProc); // Resize the field according to its actual size in pixels and move it if centered or right-aligned. // This should be done again if the link text changes. AccommodateTextField (hwndDlg, ctrlId, TRUE, hFont); return TRUE; } // Resizes a text field according to its actual width and height in pixels (font size is taken into account) and moves // it accordingly if the field is centered or right-aligned. Should be used on all hyperlinks upon dialog init // after localization (bFirstUpdate should be TRUE) and later whenever a hyperlink text changes (bFirstUpdate // must be FALSE). void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT hFont) { RECT rec, wrec, trec; HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); int width, origWidth, height, origHeight; int horizSubOffset, vertSubOffset, vertOffset, alignPosDiff = 0; wchar_t text [MAX_URL_LENGTH]; WINDOWINFO windowInfo; BOOL bBorderlessWindow = !(GetWindowLongPtr (hwndDlg, GWL_STYLE) & (WS_BORDER | WS_DLGFRAME)); // Resize the field according to its length and font size and move if centered or right-aligned GetWindowTextW (hwndCtrl, text, sizeof (text) / sizeof (wchar_t)); width = GetTextGfxWidth (hwndCtrl, text, hFont); height = GetTextGfxHeight (hwndCtrl, text, hFont); GetClientRect (hwndCtrl, &rec); origWidth = rec.right; origHeight = rec.bottom; if (width >= 0 && (!bFirstUpdate || origWidth > width)) // The original width of the field is the maximum allowed size { horizSubOffset = origWidth - width; vertSubOffset = origHeight - height; // Window coords GetWindowRect(hwndDlg, &wrec); GetClientRect(hwndDlg, &trec); // Vertical "title bar" offset vertOffset = wrec.bottom - wrec.top - trec.bottom - (bBorderlessWindow ? 0 : GetSystemMetrics(SM_CYFIXEDFRAME)); // Text field coords GetWindowRect(hwndCtrl, &rec); // Alignment offset windowInfo.cbSize = sizeof(windowInfo); GetWindowInfo (hwndCtrl, &windowInfo); if (windowInfo.dwStyle & SS_CENTER) alignPosDiff = horizSubOffset / 2; else if (windowInfo.dwStyle & SS_RIGHT) alignPosDiff = horizSubOffset; // Resize/move if (alignPosDiff > 0) { // Resize and move the text field MoveWindow (hwndCtrl, rec.left - wrec.left - (bBorderlessWindow ? 0 : GetSystemMetrics(SM_CXFIXEDFRAME)) + alignPosDiff, rec.top - wrec.top - vertOffset, origWidth - horizSubOffset, origHeight - vertSubOffset, TRUE); } else { // Resize the text field SetWindowPos (hwndCtrl, 0, 0, 0, origWidth - horizSubOffset, origHeight - vertSubOffset, SWP_NOMOVE | SWP_NOZORDER); } SetWindowPos (hwndCtrl, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); InvalidateRect (hwndCtrl, NULL, TRUE); } } // Protects an input field from having its content updated by a Paste action (call ToBootPwdField() to use this). static LRESULT CALLBACK BootPwdFieldProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { WNDPROC wp = (WNDPROC) GetWindowLongPtr (hwnd, GWLP_USERDATA); switch (message) { case WM_PASTE: return 1; } return CallWindowProc (wp, hwnd, message, wParam, lParam); } // Protects an input field from having its content updated by a Paste action. Used for pre-boot password // input fields (only the US keyboard layout is supported in pre-boot environment so we must prevent the // user from pasting a password typed using a non-US keyboard layout). void ToBootPwdField (HWND hwndDlg, UINT ctrlId) { HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId); SetWindowLongPtr (hwndCtrl, GWLP_USERDATA, (LONG_PTR) GetWindowLongPtr (hwndCtrl, GWLP_WNDPROC)); SetWindowLongPtr (hwndCtrl, GWLP_WNDPROC, (LONG_PTR) BootPwdFieldProc); } // This function currently serves the following purposes: // - Determines scaling factors for current screen DPI and GUI aspect ratio. // - Determines how Windows skews the GUI aspect ratio (which happens when the user has a non-default DPI). // The determined values must be used when performing some GUI operations and calculations. BOOL CALLBACK AuxiliaryDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { HDC hDC = GetDC (hwndDlg); if (hDC) { ScreenDPI = GetDeviceCaps (hDC, LOGPIXELSY); ReleaseDC (hwndDlg, hDC); } DPIScaleFactorX = 1; DPIScaleFactorY = 1; DlgAspectRatio = 1; if (ScreenDPI != USER_DEFAULT_SCREEN_DPI) { // Windows skews the GUI aspect ratio if the user has a non-default DPI. Hence, working with // actual screen DPI is redundant and leads to incorrect results. What really matters here is // how Windows actually renders our GUI. This is determined by comparing the expected and current // sizes of a hidden calibration text field. RECT trec; trec.right = 0; trec.bottom = 0; GetClientRect (GetDlgItem (hwndDlg, IDC_ASPECT_RATIO_CALIBRATION_BOX), &trec); if (trec.right != 0 && trec.bottom != 0) { // The size of the 282x282 IDC_ASPECT_RATIO_CALIBRATION_BOX rendered at the default DPI (96) is 423x458 DPIScaleFactorX = (double) trec.right / 423; DPIScaleFactorY = (double) trec.bottom / 458; DlgAspectRatio = DPIScaleFactorX / DPIScaleFactorY; } } EndDialog (hwndDlg, 0); return 1; } case WM_CLOSE: EndDialog (hwndDlg, 0); return 1; } return 0; } /* Except in response to the WM_INITDIALOG message, the dialog box procedure should return nonzero if it processes the message, and zero if it does not. - see DialogProc */ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); static HBITMAP hbmTextualLogoBitmapRescaled = NULL; switch (msg) { case WM_INITDIALOG: { char szTmp[100]; RECT rec; LocalizeDialog (hwndDlg, "IDD_ABOUT_DLG"); // Hyperlink SetWindowText (GetDlgItem (hwndDlg, IDC_HOMEPAGE), "www.idrix.fr"); ToHyperlink (hwndDlg, IDC_HOMEPAGE); // Logo area background (must not keep aspect ratio; must retain Windows-imposed distortion) GetClientRect (GetDlgItem (hwndDlg, IDC_ABOUT_LOGO_AREA), &rec); SetWindowPos (GetDlgItem (hwndDlg, IDC_ABOUT_BKG), HWND_TOP, 0, 0, rec.right, rec.bottom, SWP_NOMOVE); // Resize the logo bitmap if the user has a non-default DPI if (ScreenDPI != USER_DEFAULT_SCREEN_DPI) { // Logo (must recreate and keep the original aspect ratio as Windows distorts it) hbmTextualLogoBitmapRescaled = RenderBitmap (MAKEINTRESOURCE (IDB_TEXTUAL_LOGO_288DPI), GetDlgItem (hwndDlg, IDC_TEXTUAL_LOGO_IMG), 0, 0, 0, 0, FALSE, TRUE); SetWindowPos (GetDlgItem (hwndDlg, IDC_ABOUT_BKG), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } // Version SendMessage (GetDlgItem (hwndDlg, IDT_ABOUT_VERSION), WM_SETFONT, (WPARAM) hUserBoldFont, 0); StringCbPrintfA (szTmp, sizeof(szTmp), "VeraCrypt %s", VERSION_STRING); #if (defined(_DEBUG) || defined(DEBUG)) StringCbCatA (szTmp, sizeof(szTmp), " (debug)"); #endif SetDlgItemText (hwndDlg, IDT_ABOUT_VERSION, szTmp); SetDlgItemText (hwndDlg, IDT_ABOUT_RELEASE, TC_STR_RELEASED_BY); // Credits SendMessage (GetDlgItem (hwndDlg, IDC_ABOUT_CREDITS), WM_SETFONT, (WPARAM) hUserFont, (LPARAM) 0); SendMessage (hwndDlg, WM_APP, 0, 0); return 1; } case WM_APP: SetWindowText (GetDlgItem (hwndDlg, IDC_ABOUT_CREDITS), "Based on TrueCrypt, freely available at http://www.truecrypt.org/ .\r\n\r\n" "Portions of this software:\r\n" "Copyright \xA9 2003-2012 TrueCrypt Developers Association. All Rights Reserved.\r\n" "Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\r\n" "Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\r\n" "Copyright \xA9 2002-2004 Mark Adler. All Rights Reserved.\r\n\r\n" "This software as a whole:\r\n" "Copyright \xA9 2013 IDRIX. All rights reserved.\r\n\r\n" "An IDRIX Release"); return 1; case WM_COMMAND: if (lw == IDOK || lw == IDCANCEL) { PostMessage (hwndDlg, WM_CLOSE, 0, 0); return 1; } if (lw == IDC_HOMEPAGE) { Applink ("main", TRUE, ""); return 1; } // Disallow modification of credits if (HIWORD (wParam) == EN_UPDATE) { SendMessage (hwndDlg, WM_APP, 0, 0); return 1; } return 0; case WM_CLOSE: /* Delete buffered bitmaps (if any) */ if (hbmTextualLogoBitmapRescaled != NULL) { DeleteObject ((HGDIOBJ) hbmTextualLogoBitmapRescaled); hbmTextualLogoBitmapRescaled = NULL; } EndDialog (hwndDlg, 0); return 1; } return 0; } static HWND StaticModelessWaitDlgHandle = NULL; // Call DisplayStaticModelessWaitDlg() to open this dialog and CloseStaticModelessWaitDlg() to close it. static BOOL CALLBACK StaticModelessWaitDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); switch (msg) { case WM_INITDIALOG: { LocalizeDialog (hwndDlg, NULL); return 0; } case WM_COMMAND: if (lw == IDOK || lw == IDCANCEL) return 1; return 0; case WM_CLOSE: StaticModelessWaitDlgHandle = NULL; EndDialog (hwndDlg, 0); return 1; } return 0; } // Opens a dialog window saying "Please wait..." which is not modal and does not need any GUI refresh after initialization. void DisplayStaticModelessWaitDlg (HWND parent) { if (StaticModelessWaitDlgHandle != NULL) return; // Already shown StaticModelessWaitDlgHandle = CreateDialogParamW (hInst, MAKEINTRESOURCEW (IDD_STATIC_MODELESS_WAIT_DLG), parent, (DLGPROC) StaticModelessWaitDlgProc, (LPARAM) 0); ShowWindow (StaticModelessWaitDlgHandle, SW_SHOWNORMAL); // Allow synchronous use with the GUI being instantly and fully rendered ProcessPaintMessages (StaticModelessWaitDlgHandle, 500); } void CloseStaticModelessWaitDlg (void) { if (StaticModelessWaitDlgHandle == NULL) return; // Not shown DestroyWindow (StaticModelessWaitDlgHandle); } BOOL IsButtonChecked (HWND hButton) { if (SendMessage (hButton, BM_GETCHECK, 0, 0) == BST_CHECKED) return TRUE; else return FALSE; } void CheckButton (HWND hButton) { SendMessage (hButton, BM_SETCHECK, BST_CHECKED, 0); } void LeftPadString (char *szTmp, int len, int targetLen, char filler) { int i; if (targetLen <= len) return; for (i = targetLen-1; i >= (targetLen-len); i--) szTmp [i] = szTmp [i-(targetLen-len)]; memset (szTmp, filler, targetLen-len); szTmp [targetLen] = 0; } /***************************************************************************** ToSBCS: converts a unicode string to Single Byte Character String (SBCS). ***************************************************************************/ void ToSBCS (LPWSTR lpszText, size_t cbSize) { if (lpszText) { int j = wcslen (lpszText); if (j == 0) { *((char *) lpszText) = 0; return; } else { char *lpszNewText = (char *) err_malloc (j + 1); j = WideCharToMultiByte (CP_ACP, 0L, lpszText, -1, lpszNewText, j + 1, NULL, NULL); if (j > 0) StringCbCopyA ((char *) lpszText, cbSize, lpszNewText); else *((char *) lpszText) = 0; free (lpszNewText); } } } /***************************************************************************** ToUNICODE: converts a SBCS string to a UNICODE string. ***************************************************************************/ void ToUNICODE (char *lpszText, size_t cbSize) { int j = (int) strlen (lpszText); if (j == 0) { StringCbCopyW ((LPWSTR) lpszText, cbSize, (LPWSTR) WIDE ("")); return; } else { LPWSTR lpszNewText = (LPWSTR) err_malloc ((j + 1) * 2); j = MultiByteToWideChar (CP_ACP, 0L, lpszText, -1, lpszNewText, j + 1); if (j > 0) StringCbCopyW ((LPWSTR) lpszText, cbSize, lpszNewText); else StringCbCopyW ((LPWSTR) lpszText, cbSize, (LPWSTR) WIDE ("")); free (lpszNewText); } } /* InitDialog - initialize the applications main dialog, this function should be called only once in the dialogs WM_INITDIALOG message handler */ void InitDialog (HWND hwndDlg) { NONCLIENTMETRICSW metric; static BOOL aboutMenuAppended = FALSE; int nHeight; LOGFONTW lf; HMENU hMenu; Font *font; /* Fonts */ memset (&lf, 0, sizeof(lf)); // Normal font = GetFont ("font_normal"); metric.cbSize = sizeof (metric); SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof(metric), &metric, 0); WindowTitleBarFont = CreateFontIndirectW (&metric.lfCaptionFont); metric.lfMessageFont.lfHeight = CompensateDPIFont (!font ? -11 : -font->Size); metric.lfMessageFont.lfWidth = 0; if (font && wcscmp (font->FaceName, L"default") != 0) { StringCbCopyW ((WCHAR *)metric.lfMessageFont.lfFaceName, sizeof (metric.lfMessageFont.lfFaceName), font->FaceName); } else if (IsOSAtLeast (WIN_VISTA)) { // Vista's new default font (size and spacing) breaks compatibility with Windows 2k/XP applications. // Force use of Tahoma (as Microsoft does in many dialogs) until a native Vista look is implemented. StringCbCopyW ((WCHAR *)metric.lfMessageFont.lfFaceName, sizeof (metric.lfMessageFont.lfFaceName), L"Tahoma"); } hUserFont = CreateFontIndirectW (&metric.lfMessageFont); metric.lfMessageFont.lfUnderline = TRUE; hUserUnderlineFont = CreateFontIndirectW (&metric.lfMessageFont); metric.lfMessageFont.lfUnderline = FALSE; metric.lfMessageFont.lfWeight = FW_BOLD; hUserBoldFont = CreateFontIndirectW (&metric.lfMessageFont); metric.lfMessageFont.lfUnderline = TRUE; metric.lfMessageFont.lfWeight = FW_BOLD; hUserUnderlineBoldFont = CreateFontIndirectW (&metric.lfMessageFont); // Fixed-size (hexadecimal digits) nHeight = CompensateDPIFont (-12); lf.lfHeight = nHeight; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = FW_NORMAL; lf.lfItalic = FALSE; lf.lfUnderline = FALSE; lf.lfStrikeOut = FALSE; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = FF_DONTCARE; StringCbCopyW (lf.lfFaceName, sizeof(lf.lfFaceName), L"Courier New"); hFixedDigitFont = CreateFontIndirectW (&lf); if (hFixedDigitFont == NULL) { handleWin32Error (hwndDlg); AbortProcess ("NOFONT"); } // Bold font = GetFont ("font_bold"); nHeight = CompensateDPIFont (!font ? -13 : -font->Size); lf.lfHeight = nHeight; lf.lfWeight = FW_BLACK; StringCbCopyW (lf.lfFaceName, sizeof(lf.lfFaceName), !font ? L"Arial" : font->FaceName); hBoldFont = CreateFontIndirectW (&lf); if (hBoldFont == NULL) { handleWin32Error (hwndDlg); AbortProcess ("NOFONT"); } // Title font = GetFont ("font_title"); nHeight = CompensateDPIFont (!font ? -21 : -font->Size); lf.lfHeight = nHeight; lf.lfWeight = FW_REGULAR; StringCbCopyW (lf.lfFaceName, sizeof(lf.lfFaceName),!font ? L"Times New Roman" : font->FaceName); hTitleFont = CreateFontIndirectW (&lf); if (hTitleFont == NULL) { handleWin32Error (hwndDlg); AbortProcess ("NOFONT"); } // Fixed-size font = GetFont ("font_fixed"); nHeight = CompensateDPIFont (!font ? -12 : -font->Size); lf.lfHeight = nHeight; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = FW_NORMAL; lf.lfItalic = FALSE; lf.lfUnderline = FALSE; lf.lfStrikeOut = FALSE; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = FF_DONTCARE; StringCbCopyW (lf.lfFaceName, sizeof(lf.lfFaceName),!font ? L"Lucida Console" : font->FaceName); hFixedFont = CreateFontIndirectW (&lf); if (hFixedFont == NULL) { handleWin32Error (hwndDlg); AbortProcess ("NOFONT"); } if (!aboutMenuAppended) { hMenu = GetSystemMenu (hwndDlg, FALSE); AppendMenu (hMenu, MF_SEPARATOR, 0, ""); AppendMenuW (hMenu, MF_ENABLED | MF_STRING, IDC_ABOUT, GetString ("ABOUTBOX")); aboutMenuAppended = TRUE; } } // The parameter maxMessagesToProcess prevents endless processing of paint messages void ProcessPaintMessages (HWND hwnd, int maxMessagesToProcess) { MSG paintMsg; int msgCounter = maxMessagesToProcess; while (PeekMessage (&paintMsg, hwnd, 0, 0, PM_REMOVE | PM_QS_PAINT) != 0 && msgCounter-- > 0) { DispatchMessage (&paintMsg); } } HDC CreateMemBitmap (HINSTANCE hInstance, HWND hwnd, char *resource) { HBITMAP picture = LoadBitmap (hInstance, resource); HDC viewDC = GetDC (hwnd), dcMem; dcMem = CreateCompatibleDC (viewDC); SetMapMode (dcMem, MM_TEXT); SelectObject (dcMem, picture); DeleteObject (picture); ReleaseDC (hwnd, viewDC); return dcMem; } /* Renders the specified bitmap at the specified location and stretches it to fit (anti-aliasing is applied). If bDirectRender is FALSE and both nWidth and nHeight are zero, the width and height of hwndDest are retrieved and adjusted according to screen DPI (the width and height of the resultant image are adjusted the same way); furthermore, if bKeepAspectRatio is TRUE, the smaller DPI factor of the two (i.e. horiz. or vert.) is used both for horiz. and vert. scaling (note that the overall GUI aspect ratio changes irregularly in both directions depending on the DPI). If bDirectRender is TRUE, bKeepAspectRatio is ignored. This function returns a handle to the scaled bitmap. When the bitmap is no longer needed, it should be deleted by calling DeleteObject() with the handle passed as the parameter. Known Windows issues: - For some reason, anti-aliasing is not applied if the source bitmap contains less than 16K pixels. - Windows 2000 may produce slightly inaccurate colors even when source, buffer, and target are 24-bit true color. */ HBITMAP RenderBitmap (char *resource, HWND hwndDest, int x, int y, int nWidth, int nHeight, BOOL bDirectRender, BOOL bKeepAspectRatio) { LRESULT lResult = 0; HDC hdcSrc = CreateMemBitmap (hInst, hwndDest, resource); if (!hdcSrc) return NULL; HGDIOBJ picture = GetCurrentObject (hdcSrc, OBJ_BITMAP); HBITMAP hbmpRescaled = NULL; BITMAP bitmap; HDC hdcRescaled; if (!bDirectRender && nWidth == 0 && nHeight == 0) { RECT rec; GetClientRect (hwndDest, &rec); if (bKeepAspectRatio) { if (DlgAspectRatio > 1) { // Do not fix this, it's correct. We use the Y scale factor intentionally for both // directions to maintain aspect ratio (see above for more info). nWidth = CompensateYDPI (rec.right); nHeight = CompensateYDPI (rec.bottom); } else { // Do not fix this, it's correct. We use the X scale factor intentionally for both // directions to maintain aspect ratio (see above for more info). nWidth = CompensateXDPI (rec.right); nHeight = CompensateXDPI (rec.bottom); } } else { nWidth = CompensateXDPI (rec.right); nHeight = CompensateYDPI (rec.bottom); } } GetObject (picture, sizeof (BITMAP), &bitmap); hdcRescaled = CreateCompatibleDC (hdcSrc); if (hdcRescaled) { hbmpRescaled = CreateCompatibleBitmap (hdcSrc, nWidth, nHeight); SelectObject (hdcRescaled, hbmpRescaled); /* Anti-aliasing mode (HALFTONE is the only anti-aliasing algorithm natively supported by Windows 2000. TODO: GDI+ offers higher quality -- InterpolationModeHighQualityBicubic) */ SetStretchBltMode (hdcRescaled, HALFTONE); StretchBlt (hdcRescaled, 0, 0, nWidth, nHeight, hdcSrc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY); DeleteDC (hdcSrc); if (bDirectRender) { HDC hdcDest = GetDC (hwndDest); if (hdcDest) { BitBlt (hdcDest, x, y, nWidth, nHeight, hdcRescaled, 0, 0, SRCCOPY); ReleaseDC (hwndDest, hdcDest); } } else { lResult = SendMessage (hwndDest, (UINT) STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) (HANDLE) hbmpRescaled); } if ((HGDIOBJ) lResult != NULL && (HGDIOBJ) lResult != (HGDIOBJ) hbmpRescaled) DeleteObject ((HGDIOBJ) lResult); DeleteDC (hdcRescaled); } return hbmpRescaled; } LRESULT CALLBACK RedTick (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_CREATE) { } else if (uMsg == WM_DESTROY) { } else if (uMsg == WM_TIMER) { } else if (uMsg == WM_PAINT) { PAINTSTRUCT tmp; HPEN hPen; HDC hDC; BOOL bEndPaint; RECT Rect; if (GetUpdateRect (hwnd, NULL, FALSE)) { hDC = BeginPaint (hwnd, &tmp); bEndPaint = TRUE; if (hDC == NULL) return DefWindowProc (hwnd, uMsg, wParam, lParam); } else { hDC = GetDC (hwnd); bEndPaint = FALSE; } GetClientRect (hwnd, &Rect); hPen = CreatePen (PS_SOLID, 2, RGB (0, 255, 0)); if (hPen != NULL) { HGDIOBJ hObj = SelectObject (hDC, hPen); WORD bx = LOWORD (GetDialogBaseUnits ()); WORD by = HIWORD (GetDialogBaseUnits ()); MoveToEx (hDC, (Rect.right - Rect.left) / 2, Rect.bottom, NULL); LineTo (hDC, Rect.right, Rect.top); MoveToEx (hDC, (Rect.right - Rect.left) / 2, Rect.bottom, NULL); LineTo (hDC, (3 * bx) / 4, (2 * by) / 8); SelectObject (hDC, hObj); DeleteObject (hPen); } if (bEndPaint) EndPaint (hwnd, &tmp); else ReleaseDC (hwnd, hDC); return TRUE; } return DefWindowProc (hwnd, uMsg, wParam, lParam); } BOOL RegisterRedTick (HINSTANCE hInstance) { WNDCLASS wc; ULONG rc; memset(&wc, 0 , sizeof wc); wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 4; wc.hInstance = hInstance; wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); wc.hCursor = NULL; wc.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH); wc.lpszClassName = "REDTICK"; wc.lpfnWndProc = &RedTick; rc = (ULONG) RegisterClass (&wc); return rc == 0 ? FALSE : TRUE; } BOOL UnregisterRedTick (HINSTANCE hInstance) { return UnregisterClass ("REDTICK", hInstance); } LRESULT CALLBACK SplashDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefDlgProc (hwnd, uMsg, wParam, lParam); } void WaitCursor () { static HCURSOR hcWait; if (hcWait == NULL) hcWait = LoadCursor (NULL, IDC_WAIT); SetCursor (hcWait); hCursor = hcWait; } void NormalCursor () { static HCURSOR hcArrow; if (hcArrow == NULL) hcArrow = LoadCursor (NULL, IDC_ARROW); SetCursor (hcArrow); hCursor = NULL; } void ArrowWaitCursor () { static HCURSOR hcArrowWait; if (hcArrowWait == NULL) hcArrowWait = LoadCursor (NULL, IDC_APPSTARTING); SetCursor (hcArrowWait); hCursor = hcArrowWait; } void HandCursor () { static HCURSOR hcHand; if (hcHand == NULL) hcHand = LoadCursor (NULL, IDC_HAND); SetCursor (hcHand); hCursor = hcHand; } void AddComboPair (HWND hComboBox, const char *lpszItem, int value) { LPARAM nIndex; nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) lpszItem); nIndex = SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) value); } void AddComboPairW (HWND hComboBox, const wchar_t *lpszItem, int value) { LPARAM nIndex; nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) lpszItem); nIndex = SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) value); } void SelectAlgo (HWND hComboBox, int *algo_id) { LPARAM nCount = SendMessage (hComboBox, CB_GETCOUNT, 0, 0); LPARAM x, i; for (i = 0; i < nCount; i++) { x = SendMessage (hComboBox, CB_GETITEMDATA, i, 0); if (x == (LPARAM) *algo_id) { SendMessage (hComboBox, CB_SETCURSEL, i, 0); return; } } /* Something went wrong ; couldn't find the requested algo id so we drop back to a default */ *algo_id = SendMessage (hComboBox, CB_GETITEMDATA, 0, 0); SendMessage (hComboBox, CB_SETCURSEL, 0, 0); } void PopulateWipeModeCombo (HWND hComboBox, BOOL bNA, BOOL bInPlaceEncryption, BOOL bHeaderWipe) { if (bNA) { AddComboPairW (hComboBox, GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"), TC_WIPE_NONE); } else { if (!bHeaderWipe) { if (bInPlaceEncryption) AddComboPairW (hComboBox, GetString ("WIPE_MODE_NONE"), TC_WIPE_NONE); else AddComboPairW (hComboBox, GetString ("WIPE_MODE_1_RAND"), TC_WIPE_1_RAND); } AddComboPairW (hComboBox, GetString ("WIPE_MODE_3_DOD_5220"), TC_WIPE_3_DOD_5220); AddComboPairW (hComboBox, GetString ("WIPE_MODE_7_DOD_5220"), TC_WIPE_7_DOD_5220); AddComboPairW (hComboBox, GetString ("WIPE_MODE_35_GUTMANN"), TC_WIPE_35_GUTMANN); if (bHeaderWipe) AddComboPairW (hComboBox, GetString ("WIPE_MODE_256"), TC_WIPE_256); // paranoid wipe for volume header } } wchar_t *GetWipeModeName (WipeAlgorithmId modeId) { switch (modeId) { case TC_WIPE_NONE: return GetString ("WIPE_MODE_NONE"); case TC_WIPE_1_RAND: return GetString ("WIPE_MODE_1_RAND"); case TC_WIPE_3_DOD_5220: return GetString ("WIPE_MODE_3_DOD_5220"); case TC_WIPE_7_DOD_5220: return GetString ("WIPE_MODE_7_DOD_5220"); case TC_WIPE_35_GUTMANN: return GetString ("WIPE_MODE_35_GUTMANN"); case TC_WIPE_256: return GetString ("WIPE_MODE_256"); default: return GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"); } } wchar_t *GetPathType (const char *path, BOOL bUpperCase, BOOL *bIsPartition) { if (strstr (path, "Partition") && strstr (path, "Partition0") == NULL) { *bIsPartition = TRUE; return GetString (bUpperCase ? "PARTITION_UPPER_CASE" : "PARTITION_LOWER_CASE"); } else if (strstr (path, "HarddiskVolume")) { *bIsPartition = TRUE; return GetString (bUpperCase ? "VOLUME_UPPER_CASE" : "VOLUME_LOWER_CASE"); } *bIsPartition = FALSE; return GetString (bUpperCase ? "DEVICE_UPPER_CASE" : "DEVICE_LOWER_CASE"); } LRESULT CALLBACK CustomDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_SETCURSOR && hCursor != NULL) { SetCursor (hCursor); return TRUE; } return DefDlgProc (hwnd, uMsg, wParam, lParam); } /* static BOOL IsReturnAddress (DWORD64 address) { static size_t codeEnd = 0; byte *sp = (byte *) address; if (codeEnd == 0) { MEMORY_BASIC_INFORMATION mi; if (VirtualQuery ((LPCVOID) 0x401000, &mi, sizeof (mi)) >= sizeof (mi)) codeEnd = (size_t) mi.BaseAddress + mi.RegionSize; } if (address < 0x401000 + 8 || address > codeEnd) return FALSE; return sp[-5] == 0xe8 // call ADDR || (sp[-6] == 0xff && sp[-5] == 0x15) // call [ADDR] || (sp[-2] == 0xff && (sp[-1] & 0xf0) == 0xd0); // call REG } */ typedef struct { EXCEPTION_POINTERS *ExceptionPointers; HANDLE ExceptionThread; } ExceptionHandlerThreadArgs; void ExceptionHandlerThread (void *threadArg) { ExceptionHandlerThreadArgs *args = (ExceptionHandlerThreadArgs *) threadArg; EXCEPTION_POINTERS *ep = args->ExceptionPointers; //DWORD addr; DWORD exCode = ep->ExceptionRecord->ExceptionCode; // SYSTEM_INFO si; // wchar_t msg[8192]; // char modPath[MAX_PATH]; // int crc = 0; // char url[MAX_URL_LENGTH]; // char lpack[128]; // stringstream callStack; // addr = (DWORD) ep->ExceptionRecord->ExceptionAddress; // PDWORD sp = (PDWORD) ep->ContextRecord->Esp; // int frameNumber = 0; switch (exCode) { case STATUS_IN_PAGE_ERROR: case 0xeedfade: // Exception not caused by VeraCrypt MessageBoxW (0, GetString ("EXCEPTION_REPORT_EXT"), GetString ("EXCEPTION_REPORT_TITLE"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); return; } // Call stack /* HMODULE dbgDll = LoadLibrary ("dbghelp.dll"); if (dbgDll) { typedef DWORD (__stdcall *SymGetOptions_t) (); typedef DWORD (__stdcall *SymSetOptions_t) (DWORD SymOptions); typedef BOOL (__stdcall *SymInitialize_t) (HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess); typedef BOOL (__stdcall *StackWalk64_t) (DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); typedef BOOL (__stdcall * SymFromAddr_t) (HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol); SymGetOptions_t DbgHelpSymGetOptions = (SymGetOptions_t) GetProcAddress (dbgDll, "SymGetOptions"); SymSetOptions_t DbgHelpSymSetOptions = (SymSetOptions_t) GetProcAddress (dbgDll, "SymSetOptions"); SymInitialize_t DbgHelpSymInitialize = (SymInitialize_t) GetProcAddress (dbgDll, "SymInitialize"); PFUNCTION_TABLE_ACCESS_ROUTINE64 DbgHelpSymFunctionTableAccess64 = (PFUNCTION_TABLE_ACCESS_ROUTINE64) GetProcAddress (dbgDll, "SymFunctionTableAccess64"); PGET_MODULE_BASE_ROUTINE64 DbgHelpSymGetModuleBase64 = (PGET_MODULE_BASE_ROUTINE64) GetProcAddress (dbgDll, "SymGetModuleBase64"); StackWalk64_t DbgHelpStackWalk64 = (StackWalk64_t) GetProcAddress (dbgDll, "StackWalk64"); SymFromAddr_t DbgHelpSymFromAddr = (SymFromAddr_t) GetProcAddress (dbgDll, "SymFromAddr"); if (DbgHelpSymGetOptions && DbgHelpSymSetOptions && DbgHelpSymInitialize && DbgHelpSymFunctionTableAccess64 && DbgHelpSymGetModuleBase64 && DbgHelpStackWalk64 && DbgHelpSymFromAddr) { DbgHelpSymSetOptions (DbgHelpSymGetOptions() | SYMOPT_DEFERRED_LOADS | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS | SYMOPT_NO_CPP); if (DbgHelpSymInitialize (GetCurrentProcess(), NULL, TRUE)) { STACKFRAME64 frame; memset (&frame, 0, sizeof (frame)); frame.AddrPC.Offset = ep->ContextRecord->Eip; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Offset = ep->ContextRecord->Esp; frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Offset = ep->ContextRecord->Ebp; frame.AddrFrame.Mode = AddrModeFlat; string lastSymbol; while (frameNumber < 32 && DbgHelpStackWalk64 (IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), args->ExceptionThread, &frame, ep->ContextRecord, NULL, DbgHelpSymFunctionTableAccess64, DbgHelpSymGetModuleBase64, NULL)) { if (!frame.AddrPC.Offset) continue; ULONG64 symbolBuffer[(sizeof (SYMBOL_INFO) + MAX_SYM_NAME * sizeof (TCHAR) + sizeof (ULONG64) - 1) / sizeof (ULONG64)]; memset (symbolBuffer, 0, sizeof (symbolBuffer)); PSYMBOL_INFO symbol = (PSYMBOL_INFO) symbolBuffer; symbol->SizeOfStruct = sizeof (SYMBOL_INFO); symbol->MaxNameLen = MAX_SYM_NAME; if (DbgHelpSymFromAddr (GetCurrentProcess(), frame.AddrPC.Offset, NULL, symbol) && symbol->NameLen > 0) { for (size_t i = 0; i < symbol->NameLen; ++i) { if (!isalnum (symbol->Name[i])) symbol->Name[i] = '_'; } if (symbol->Name != lastSymbol) callStack << "&st" << frameNumber++ << "=" << symbol->Name; lastSymbol = symbol->Name; } else if (frameNumber == 0 || IsReturnAddress (frame.AddrPC.Offset)) { callStack << "&st" << frameNumber++ << "=0x" << hex << frame.AddrPC.Offset << dec; } } } } } // StackWalk64() may fail due to missing frame pointers list retAddrs; if (frameNumber == 0) retAddrs.push_back (ep->ContextRecord->Eip); retAddrs.push_back (0); MEMORY_BASIC_INFORMATION mi; VirtualQuery (sp, &mi, sizeof (mi)); PDWORD stackTop = (PDWORD)((byte *) mi.BaseAddress + mi.RegionSize); int i = 0; while (retAddrs.size() < 16 && &sp[i] < stackTop) { if (IsReturnAddress (sp[i])) { bool duplicate = false; foreach (DWORD prevAddr, retAddrs) { if (sp[i] == prevAddr) { duplicate = true; break; } } if (!duplicate) retAddrs.push_back (sp[i]); } i++; } if (retAddrs.size() > 1) { foreach (DWORD addr, retAddrs) { callStack << "&st" << frameNumber++ << "=0x" << hex << addr << dec; } } // Checksum of the module if (GetModuleFileName (NULL, modPath, sizeof (modPath))) { HANDLE h = CreateFile (modPath, FILE_READ_DATA | FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (h != INVALID_HANDLE_VALUE) { BY_HANDLE_FILE_INFORMATION fi; if (GetFileInformationByHandle (h, &fi)) { char *buf = (char *) malloc (fi.nFileSizeLow); if (buf) { DWORD bytesRead; if (ReadFile (h, buf, fi.nFileSizeLow, &bytesRead, NULL) && bytesRead == fi.nFileSizeLow) crc = GetCrc32 ((unsigned char *) buf, fi.nFileSizeLow); free (buf); } } CloseHandle (h); } } GetSystemInfo (&si); if (LocalizationActive) sprintf_s (lpack, sizeof (lpack), "&langpack=%s_%s", GetPreferredLangId (), GetActiveLangPackVersion ()); else lpack[0] = 0; sprintf (url, TC_APPLINK_SECURE "&dest=err-report%s&os=%s&osver=%d.%d.%d&arch=%s&cpus=%d&app=%s&cksum=%x&dlg=%s&err=%x&addr=%x" , lpack , GetWindowsEdition().c_str() , CurrentOSMajor , CurrentOSMinor , CurrentOSServicePack , Is64BitOs () ? "x64" : "x86" , si.dwNumberOfProcessors #ifdef TCMOUNT ,"main" #endif #ifdef VOLFORMAT ,"format" #endif #ifdef SETUP ,"setup" #endif , crc , LastDialogId ? LastDialogId : "-" , exCode , addr); string urlStr = url + callStack.str(); _snwprintf (msg, array_capacity (msg), GetString ("EXCEPTION_REPORT"), urlStr.c_str()); if (IDYES == MessageBoxW (0, msg, GetString ("EXCEPTION_REPORT_TITLE"), MB_ICONERROR | MB_YESNO | MB_DEFBUTTON1)) ShellExecute (NULL, "open", urlStr.c_str(), NULL, NULL, SW_SHOWNORMAL); else */ UnhandledExceptionFilter (ep); } LONG __stdcall ExceptionHandler (EXCEPTION_POINTERS *ep) { SetUnhandledExceptionFilter (NULL); if (SystemFileSelectorCallPending && SystemFileSelectorCallerThreadId == GetCurrentThreadId()) { MessageBoxW (NULL, GetString ("EXCEPTION_REPORT_EXT_FILESEL"), GetString ("EXCEPTION_REPORT_TITLE"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TOPMOST); UnhandledExceptionFilter (ep); return EXCEPTION_EXECUTE_HANDLER; } ExceptionHandlerThreadArgs args; args.ExceptionPointers = ep; args.ExceptionThread = GetCurrentThread(); WaitForSingleObject ((HANDLE) _beginthread (ExceptionHandlerThread, 0, &args), INFINITE); return EXCEPTION_EXECUTE_HANDLER; } void InvalidParameterHandler (const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t reserved) { TC_THROW_FATAL_EXCEPTION; } static LRESULT CALLBACK NonInstallUacWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { return DefWindowProc (hWnd, message, wParam, lParam); } // Mutex handling to prevent multiple instances of the wizard or main app from dealing with system encryption. // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). BOOL CreateSysEncMutex (void) { return TCCreateMutex (&hSysEncMutex, TC_MUTEX_NAME_SYSENC); } BOOL InstanceHasSysEncMutex (void) { return (hSysEncMutex != NULL); } // Mutex handling to prevent multiple instances of the wizard from dealing with system encryption void CloseSysEncMutex (void) { TCCloseMutex (&hSysEncMutex); } // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). BOOL CreateNonSysInplaceEncMutex (void) { return TCCreateMutex (&hNonSysInplaceEncMutex, TC_MUTEX_NAME_NONSYS_INPLACE_ENC); } BOOL InstanceHasNonSysInplaceEncMutex (void) { return (hNonSysInplaceEncMutex != NULL); } void CloseNonSysInplaceEncMutex (void) { TCCloseMutex (&hNonSysInplaceEncMutex); } // Returns TRUE if another instance of the wizard is preparing, resuming or performing non-system in-place encryption BOOL NonSysInplaceEncInProgressElsewhere (void) { return (!InstanceHasNonSysInplaceEncMutex () && MutexExistsOnSystem (TC_MUTEX_NAME_NONSYS_INPLACE_ENC)); } // Mutex handling to prevent multiple instances of the wizard or main app from trying to install // or register the driver or from trying to launch it in portable mode at the same time. // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). BOOL CreateDriverSetupMutex (void) { return TCCreateMutex (&hDriverSetupMutex, TC_MUTEX_NAME_DRIVER_SETUP); } void CloseDriverSetupMutex (void) { TCCloseMutex (&hDriverSetupMutex); } BOOL CreateAppSetupMutex (void) { return TCCreateMutex (&hAppSetupMutex, TC_MUTEX_NAME_APP_SETUP); } void CloseAppSetupMutex (void) { TCCloseMutex (&hAppSetupMutex); } BOOL IsTrueCryptInstallerRunning (void) { return (MutexExistsOnSystem (TC_MUTEX_NAME_APP_SETUP)); } // Returns TRUE if the mutex is (or had been) successfully acquired (otherwise FALSE). BOOL TCCreateMutex (volatile HANDLE *hMutex, char *name) { if (*hMutex != NULL) return TRUE; // This instance already has the mutex *hMutex = CreateMutex (NULL, TRUE, name); if (*hMutex == NULL) { // In multi-user configurations, the OS returns "Access is denied" here when a user attempts // to acquire the mutex if another user already has. However, on Vista, "Access is denied" is // returned also if the mutex is owned by a process with admin rights while we have none. return FALSE; } if (GetLastError () == ERROR_ALREADY_EXISTS) { ReleaseMutex (*hMutex); CloseHandle (*hMutex); *hMutex = NULL; return FALSE; } return TRUE; } void TCCloseMutex (volatile HANDLE *hMutex) { if (*hMutex != NULL) { if (ReleaseMutex (*hMutex) && CloseHandle (*hMutex)) *hMutex = NULL; } } // Returns TRUE if a process running on the system has the specified mutex (otherwise FALSE). BOOL MutexExistsOnSystem (char *name) { if (name[0] == 0) return FALSE; HANDLE hMutex = OpenMutex (MUTEX_ALL_ACCESS, FALSE, name); if (hMutex == NULL) { if (GetLastError () == ERROR_FILE_NOT_FOUND) return FALSE; if (GetLastError () == ERROR_ACCESS_DENIED) // On Vista, this is returned if the owner of the mutex is elevated while we are not return TRUE; // The call failed and it is not certain whether the mutex exists or not return FALSE; } CloseHandle (hMutex); return TRUE; } uint32 ReadDriverConfigurationFlags () { DWORD configMap; if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, &configMap)) configMap = 0; return configMap; } uint32 ReadEncryptionThreadPoolFreeCpuCountLimit () { DWORD count; if (!ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME, &count)) count = 0; return count; } BOOL LoadSysEncSettings (HWND hwndDlg) { BOOL status = TRUE; DWORD size = 0; char *sysEncCfgFileBuf = LoadFile (GetConfigPath (TC_APPD_FILENAME_SYSTEM_ENCRYPTION), &size); char *xml = sysEncCfgFileBuf; char paramName[100], paramVal[MAX_PATH]; // Defaults int newSystemEncryptionStatus = SYSENC_STATUS_NONE; WipeAlgorithmId newnWipeMode = TC_WIPE_NONE; if (!FileExists (GetConfigPath (TC_APPD_FILENAME_SYSTEM_ENCRYPTION))) { SystemEncryptionStatus = newSystemEncryptionStatus; nWipeMode = newnWipeMode; } if (xml == NULL) { return FALSE; } while (xml = XmlFindElement (xml, "config")) { XmlGetAttributeText (xml, "key", paramName, sizeof (paramName)); XmlGetNodeText (xml, paramVal, sizeof (paramVal)); if (strcmp (paramName, "SystemEncryptionStatus") == 0) { newSystemEncryptionStatus = atoi (paramVal); } else if (strcmp (paramName, "WipeMode") == 0) { newnWipeMode = (WipeAlgorithmId) atoi (paramVal); } xml++; } SystemEncryptionStatus = newSystemEncryptionStatus; nWipeMode = newnWipeMode; free (sysEncCfgFileBuf); return status; } // Returns the number of partitions where non-system in-place encryption is progress or had been in progress // but was interrupted. In addition, via the passed pointer, returns the last selected wipe algorithm ID. int LoadNonSysInPlaceEncSettings (WipeAlgorithmId *wipeAlgorithm) { char *fileBuf = NULL; char *fileBuf2 = NULL; DWORD size, size2; int count; *wipeAlgorithm = TC_WIPE_NONE; if (!FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC))) return 0; if ((fileBuf = LoadFile (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), &size)) == NULL) return 0; if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE))) { if ((fileBuf2 = LoadFile (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE), &size2)) != NULL) *wipeAlgorithm = (WipeAlgorithmId) atoi (fileBuf2); } count = atoi (fileBuf); if (fileBuf != NULL) TCfree (fileBuf); if (fileBuf2 != NULL) TCfree (fileBuf2); return (count); } void RemoveNonSysInPlaceEncNotifications (void) { if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC))) remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC)); if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE))) remove (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE)); if (!IsNonInstallMode () && SystemEncryptionStatus == SYSENC_STATUS_NONE) ManageStartupSeqWiz (TRUE, ""); } void SavePostInstallTasksSettings (int command) { FILE *f = NULL; if (IsNonInstallMode() && command != TC_POST_INSTALL_CFG_REMOVE_ALL) return; switch (command) { case TC_POST_INSTALL_CFG_REMOVE_ALL: remove (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL)); remove (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES)); break; case TC_POST_INSTALL_CFG_TUTORIAL: f = fopen (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL), "w"); break; case TC_POST_INSTALL_CFG_RELEASE_NOTES: f = fopen (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES), "w"); break; default: return; } if (f == NULL) return; if (fputs ("1", f) < 0) { // Error fclose (f); return; } TCFlushFile (f); fclose (f); } void DoPostInstallTasks (void) { BOOL bDone = FALSE; if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL))) { if (AskYesNo ("AFTER_INSTALL_TUTORIAL") == IDYES) Applink ("beginnerstutorial", TRUE, ""); bDone = TRUE; } if (FileExists (GetConfigPath (TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES))) { if (AskYesNo ("AFTER_UPGRADE_RELEASE_NOTES") == IDYES) Applink ("releasenotes", TRUE, ""); bDone = TRUE; } if (bDone) SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_REMOVE_ALL); } void InitOSVersionInfo () { OSVERSIONINFO os; os.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (GetVersionEx (&os) == FALSE) AbortProcess ("NO_OS_VER"); CurrentOSMajor = os.dwMajorVersion; CurrentOSMinor = os.dwMinorVersion; if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 5 && CurrentOSMinor == 0) nCurrentOS = WIN_2000; else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 5 && CurrentOSMinor == 1) nCurrentOS = WIN_XP; else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 5 && CurrentOSMinor == 2) { OSVERSIONINFOEX osEx; osEx.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); GetVersionEx ((LPOSVERSIONINFOA) &osEx); if (osEx.wProductType == VER_NT_SERVER || osEx.wProductType == VER_NT_DOMAIN_CONTROLLER) nCurrentOS = WIN_SERVER_2003; else nCurrentOS = WIN_XP64; } else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 0) { OSVERSIONINFOEX osEx; osEx.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); GetVersionEx ((LPOSVERSIONINFOA) &osEx); if (osEx.wProductType == VER_NT_SERVER || osEx.wProductType == VER_NT_DOMAIN_CONTROLLER) nCurrentOS = WIN_SERVER_2008; else nCurrentOS = WIN_VISTA; } else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 1) nCurrentOS = (IsServerOS() ? WIN_SERVER_2008_R2 : WIN_7); else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 4) nCurrentOS = WIN_NT4; else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && os.dwMajorVersion == 4 && os.dwMinorVersion == 0) nCurrentOS = WIN_95; else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && os.dwMajorVersion == 4 && os.dwMinorVersion == 10) nCurrentOS = WIN_98; else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && os.dwMajorVersion == 4 && os.dwMinorVersion == 90) nCurrentOS = WIN_ME; else if (os.dwPlatformId == VER_PLATFORM_WIN32s) nCurrentOS = WIN_31; else nCurrentOS = WIN_UNKNOWN; } /* InitApp - initialize the application, this function is called once in the applications WinMain function, but before the main dialog has been created */ void InitApp (HINSTANCE hInstance, char *lpszCommandLine) { WNDCLASS wc; char langId[6]; char dllPath[MAX_PATH]; /* Save the instance handle for later */ hInst = hInstance; InitOSVersionInfo(); SetErrorMode (SetErrorMode (0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); CoInitialize (NULL); #ifndef SETUP // Application ID typedef HRESULT (WINAPI *SetAppId_t) (PCWSTR appID); SetAppId_t setAppId = (SetAppId_t) GetProcAddress (GetModuleHandle ("shell32.dll"), "SetCurrentProcessExplicitAppUserModelID"); if (setAppId) setAppId (TC_APPLICATION_ID); #endif // Language langId[0] = 0; SetPreferredLangId (ConfigReadString ("Language", "", langId, sizeof (langId))); if (langId[0] == 0) DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_LANGUAGE), NULL, (DLGPROC) LanguageDlgProc, (LPARAM) 1); LoadLanguageFile (); #ifndef SETUP // UAC elevation moniker cannot be used in portable mode. // A new instance of the application must be created with elevated privileges. if (IsNonInstallMode () && !IsAdmin () && IsUacSupported ()) { char modPath[MAX_PATH], newCmdLine[4096]; WNDCLASSEX wcex; HWND hWnd; if (strstr (lpszCommandLine, "/q UAC ") == lpszCommandLine) { Error ("UAC_INIT_ERROR"); exit (1); } memset (&wcex, 0, sizeof (wcex)); wcex.cbSize = sizeof(WNDCLASSEX); wcex.lpfnWndProc = (WNDPROC) NonInstallUacWndProc; wcex.hInstance = hInstance; wcex.lpszClassName = "VeraCrypt"; RegisterClassEx (&wcex); // A small transparent window is necessary to bring the new instance to foreground hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_LAYERED, "VeraCrypt", "VeraCrypt", 0, GetSystemMetrics (SM_CXSCREEN)/2, GetSystemMetrics (SM_CYSCREEN)/2, 1, 1, NULL, NULL, hInstance, NULL); SetLayeredWindowAttributes (hWnd, 0, 0, LWA_ALPHA); ShowWindow (hWnd, SW_SHOWNORMAL); GetModuleFileName (NULL, modPath, sizeof (modPath)); StringCbCopyA (newCmdLine, sizeof(newCmdLine), "/q UAC "); StringCbCatA (newCmdLine, sizeof (newCmdLine), lpszCommandLine); if ((int)ShellExecute (hWnd, "runas", modPath, newCmdLine, NULL, SW_SHOWNORMAL) <= 32) exit (1); Sleep (2000); exit (0); } #endif SetUnhandledExceptionFilter (ExceptionHandler); _set_invalid_parameter_handler (InvalidParameterHandler); RemoteSession = GetSystemMetrics (SM_REMOTESESSION) != 0; // OS version check if (CurrentOSMajor < 5) { MessageBoxW (NULL, GetString ("UNSUPPORTED_OS"), lpszTitle, MB_ICONSTOP); exit (1); } else { OSVERSIONINFOEX osEx; // Service pack check & warnings about critical MS issues osEx.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); if (GetVersionEx ((LPOSVERSIONINFOA) &osEx) != 0) { CurrentOSServicePack = osEx.wServicePackMajor; switch (nCurrentOS) { case WIN_2000: if (osEx.wServicePackMajor < 3) Warning ("LARGE_IDE_WARNING_2K"); else { DWORD val = 0, size = sizeof(val); HKEY hkey; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Atapi\\Parameters", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { if (RegQueryValueEx (hkey, "EnableBigLba", 0, 0, (LPBYTE) &val, &size) != ERROR_SUCCESS || val != 1) { Warning ("LARGE_IDE_WARNING_2K_REGISTRY"); } RegCloseKey (hkey); } } break; case WIN_XP: if (osEx.wServicePackMajor < 1) { HKEY k; // PE environment does not report version of SP if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\minint", 0, KEY_READ, &k) != ERROR_SUCCESS) Warning ("LARGE_IDE_WARNING_XP"); else RegCloseKey (k); } break; } } } /* Get the attributes for the standard dialog class */ if ((GetClassInfo (hInst, WINDOWS_DIALOG_CLASS, &wc)) == 0) { handleWin32Error (NULL); AbortProcess ("INIT_REGISTER"); } #ifndef SETUP wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_TRUECRYPT_ICON)); #else #include "../setup/resource.h" wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_SETUP)); #endif wc.lpszClassName = TC_DLG_CLASS; wc.lpfnWndProc = &CustomDlgProc; wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.cbWndExtra = DLGWINDOWEXTRA; hDlgClass = RegisterClass (&wc); if (hDlgClass == 0) { handleWin32Error (NULL); AbortProcess ("INIT_REGISTER"); } wc.lpszClassName = TC_SPLASH_CLASS; wc.lpfnWndProc = &SplashDlgProc; wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.cbWndExtra = DLGWINDOWEXTRA; hSplashClass = RegisterClass (&wc); if (hSplashClass == 0) { handleWin32Error (NULL); AbortProcess ("INIT_REGISTER"); } if (GetSystemDirectory(dllPath, MAX_PATH)) StringCbCatA(dllPath, sizeof(dllPath), "\\Riched20.dll"); else StringCbCopyA(dllPath, sizeof(dllPath), "c:\\Windows\\System32\\Riched20.dll"); // Required for RichEdit text fields to work if (LoadLibrary(dllPath) == NULL) { // This error is fatal e.g. because legal notices could not be displayed handleWin32Error (NULL); AbortProcess ("INIT_RICHEDIT"); } // DPI and GUI aspect ratio DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_AUXILIARY_DLG), NULL, (DLGPROC) AuxiliaryDlgProc, (LPARAM) 1); InitHelpFileName (); #ifndef SETUP if (!EncryptionThreadPoolStart (ReadEncryptionThreadPoolFreeCpuCountLimit())) { handleWin32Error (NULL); exit (1); } #endif } void InitHelpFileName (void) { char *lpszTmp; GetModuleFileName (NULL, szHelpFile, sizeof (szHelpFile)); lpszTmp = strrchr (szHelpFile, '\\'); if (lpszTmp) { char szTemp[TC_MAX_PATH]; ++lpszTmp; *lpszTmp = 0; // add null terminating character to prepare for append operations // Primary file name if (strcmp (GetPreferredLangId(), "en") == 0 || strlen(GetPreferredLangId()) == 0) { StringCbCatA (szHelpFile, sizeof(szHelpFile), "VeraCrypt User Guide.pdf"); } else { StringCbPrintfA (szTemp, sizeof(szTemp), "VeraCrypt User Guide.%s.pdf", GetPreferredLangId()); StringCbCatA (szHelpFile, sizeof(szHelpFile), szTemp); } // Secondary file name (used when localized documentation is not found). GetModuleFileName (NULL, szHelpFile2, sizeof (szHelpFile2)); lpszTmp = strrchr (szHelpFile2, '\\'); if (lpszTmp) { ++lpszTmp; *lpszTmp = 0; StringCbCatA (szHelpFile2, sizeof(szHelpFile2), "VeraCrypt User Guide.pdf"); } } } BOOL OpenDevice (const char *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem) { DWORD dwResult; BOOL bResult; StringCbCopyA ((char *) &driver->wszFileName[0], sizeof(driver->wszFileName), lpszPath); ToUNICODE ((char *) &driver->wszFileName[0], sizeof(driver->wszFileName)); driver->bDetectTCBootLoader = FALSE; driver->DetectFilesystem = detectFilesystem; bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, driver, sizeof (OPEN_TEST_STRUCT), driver, sizeof (OPEN_TEST_STRUCT), &dwResult, NULL); if (bResult == FALSE) { dwResult = GetLastError (); if (dwResult == ERROR_SHARING_VIOLATION || dwResult == ERROR_NOT_READY) { driver->TCBootLoaderDetected = FALSE; driver->FilesystemDetected = FALSE; return TRUE; } else return FALSE; } return TRUE; } // Tells the driver that it's running in portable mode void NotifyDriverOfPortableMode (void) { if (hDriver != INVALID_HANDLE_VALUE) { DWORD dwResult; DeviceIoControl (hDriver, TC_IOCTL_SET_PORTABLE_MODE_STATUS, NULL, 0, NULL, 0, &dwResult, NULL); } } BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize) { DWORD fileSystemFlags; wchar_t root[] = { L'A' + (wchar_t) driveNo, L':', L'\\', 0 }; return GetVolumeInformationW (root, label, labelSize / 2, NULL, NULL, &fileSystemFlags, NULL, 0); } /* Stores the device path of the system partition in SysPartitionDevicePath and the device path of the system drive in SysDriveDevicePath. IMPORTANT: As this may take a very long time if called for the first time, it should be called only before performing a dangerous operation (such as header backup restore or formatting a supposedly non-system device) never at WM_INITDIALOG or any other GUI events -- instead call IsSystemDevicePath (path, hwndDlg, FALSE) for very fast preliminary GUI checks; also note that right after the "Select Device" dialog exits with an OK return code, you can use the global flags bSysPartitionSelected and bSysDriveSelected to see if the user selected the system partition/device. After this function completes successfully, the results are cached for the rest of the session and repeated executions complete very fast. Returns TRUE if successful (otherwise FALSE). */ BOOL GetSysDevicePaths (HWND hwndDlg) { if (!bCachedSysDevicePathsValid || strlen (SysPartitionDevicePath) <= 1 || strlen (SysDriveDevicePath) <= 1) { foreach (const HostDevice &device, GetAvailableHostDevices (false, true)) { if (device.ContainsSystem) strcpy_s (device.IsPartition ? SysPartitionDevicePath : SysDriveDevicePath, TC_MAX_PATH, device.Path.c_str()); } if (IsOSAtLeast (WIN_7)) { // Find extra boot partition foreach (const HostDevice &drive, GetAvailableHostDevices (false, false)) { if (drive.ContainsSystem) { foreach (const HostDevice &sysDrivePartition, drive.Partitions) { if (sysDrivePartition.Bootable) { if (sysDrivePartition.Size <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE) ExtraBootPartitionDevicePath = sysDrivePartition.Path; break; } } break; } } } bCachedSysDevicePathsValid = 1; } return (bCachedSysDevicePathsValid && strlen (SysPartitionDevicePath) > 1 && strlen (SysDriveDevicePath) > 1); } /* Determines whether the device path is the path of the system partition or of the system drive (or neither). If bReliableRequired is TRUE, very fast execution is guaranteed, but the results cannot be relied upon. If it's FALSE and the function is called for the first time, execution may take up to one minute but the results are reliable. IMPORTANT: As the execution may take a very long time if called for the first time with bReliableRequired set to TRUE, it should be called with bReliableRequired set to TRUE only before performing a dangerous operation (such as header backup restore or formatting a supposedly non-system device) never at WM_INITDIALOG or any other GUI events (use IsSystemDevicePath(path, hwndDlg, FALSE) for fast preliminary GUI checks; also note that right after the "Select Device" dialog exits with an OK return code, you can use the global flags bSysPartitionSelected and bSysDriveSelected to see if the user selected the system partition/device). After this function completes successfully, the results are cached for the rest of the session, bReliableRequired is ignored (TRUE implied), repeated executions complete very fast, and the results are always reliable. Return codes: 1 - it is the system partition path (e.g. \Device\Harddisk0\Partition1) 2 - it is the system drive path (e.g. \Device\Harddisk0\Partition0) 3 - it is the extra boot partition path 0 - it's not the system partition/drive path -1 - the result can't be determined, isn't reliable, or there was an error. */ int IsSystemDevicePath (const char *path, HWND hwndDlg, BOOL bReliableRequired) { if (!bCachedSysDevicePathsValid && bReliableRequired) { if (!GetSysDevicePaths (hwndDlg)) return -1; } if (strlen (SysPartitionDevicePath) <= 1 || strlen (SysDriveDevicePath) <= 1) return -1; if (!path) return -1; if (strncmp (path, SysPartitionDevicePath, max (strlen(path), strlen(SysPartitionDevicePath))) == 0) return 1; else if (strncmp (path, SysDriveDevicePath, max (strlen(path), strlen(SysDriveDevicePath))) == 0) return 2; else if (ExtraBootPartitionDevicePath == path) return 3; return 0; } wstring GetSysEncryptionPretestInfo2String (void) { // This huge string is divided into smaller portions to make it easier for translators to // re-translate it when a minor modification is made to it (the whole huge string will not be // reverted to English, so they will have to translate only a small portion of it). return (wstring (L"\n") + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_1") + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_2") + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_3") + GetString ("SYS_ENCRYPTION_PRETEST_INFO2_PORTION_4")); } wstring GetRescueDiskHelpString (void) { // This huge string is divided into smaller portions to make it easier for translators to // re-translate it when a minor modification is made to it (the whole huge string will not be // reverted to English, so they will have to translate only a small portion of it). return (wstring ( GetString ("RESCUE_DISK_HELP_PORTION_1")) + GetString ("RESCUE_DISK_HELP_PORTION_2") + GetString ("RESCUE_DISK_HELP_PORTION_3") + GetString ("RESCUE_DISK_HELP_PORTION_4") + GetString ("RESCUE_DISK_HELP_PORTION_5") + GetString ("RESCUE_DISK_HELP_PORTION_6") + GetString ("RESCUE_DISK_HELP_PORTION_7") + GetString ("RESCUE_DISK_HELP_PORTION_8") + GetString ("RESCUE_DISK_HELP_PORTION_9")); } wstring GetDecoyOsInstructionsString (void) { // This huge string is divided into smaller portions to make it easier for translators to // re-translate it when a minor modification is made to it (the whole huge string will not be // reverted to English, so they will have to translate only a small portion of it). return (wstring ( GetString ("DECOY_OS_INSTRUCTIONS_PORTION_1")) + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_2") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_3") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_4") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_5") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_6") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_7") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_8") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_9") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_10") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_11") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_12") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_13") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_14") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_15") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_16") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_17") + GetString ("DECOY_OS_INSTRUCTIONS_PORTION_18")); } BOOL TextInfoDialogBox (int nID) { return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TEXT_INFO_DIALOG_BOX_DLG), MainDlg, (DLGPROC) TextInfoDialogBoxDlgProc, (LPARAM) nID); } BOOL CALLBACK TextInfoDialogBoxDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); static int nID = 0; switch (msg) { case WM_INITDIALOG: { nID = (int) lParam; // Left margin for rich edit text field SendMessage (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), EM_SETMARGINS, (WPARAM) EC_LEFTMARGIN, (LPARAM) CompensateXDPI (4)); ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_HIDE); switch (nID) { case TC_TBXID_LEGAL_NOTICES: LocalizeDialog (hwndDlg, "LEGAL_NOTICES_DLG_TITLE"); break; case TC_TBXID_SYS_ENCRYPTION_PRETEST: LocalizeDialog (hwndDlg, NULL); ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW); break; case TC_TBXID_SYS_ENC_RESCUE_DISK: LocalizeDialog (hwndDlg, NULL); ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW); break; case TC_TBXID_DECOY_OS_INSTRUCTIONS: LocalizeDialog (hwndDlg, NULL); ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW); break; case TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS: LocalizeDialog (hwndDlg, NULL); ShowWindow(GetDlgItem(hwndDlg, IDC_PRINT), SW_SHOW); break; } SendMessage (hwndDlg, TC_APPMSG_LOAD_TEXT_BOX_CONTENT, 0, 0); } return 0; case WM_COMMAND: if (lw == IDOK || lw == IDCANCEL) { NormalCursor (); EndDialog (hwndDlg, 0); return 1; } if (lw == IDC_PRINT) { switch (nID) { case TC_TBXID_SYS_ENCRYPTION_PRETEST: PrintHardCopyTextUTF16 ((wchar_t *) GetSysEncryptionPretestInfo2String ().c_str(), "Pre-Boot Troubleshooting", GetSysEncryptionPretestInfo2String ().length () * 2); break; case TC_TBXID_SYS_ENC_RESCUE_DISK: PrintHardCopyTextUTF16 ((wchar_t *) GetRescueDiskHelpString ().c_str(), "VeraCrypt Rescue Disk Help", GetRescueDiskHelpString ().length () * 2); break; case TC_TBXID_DECOY_OS_INSTRUCTIONS: PrintHardCopyTextUTF16 ((wchar_t *) GetDecoyOsInstructionsString ().c_str(), "How to Create Decoy OS", GetDecoyOsInstructionsString ().length () * 2); break; case TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS: PrintHardCopyTextUTF16 (GetString ("EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS"), "How to Remove Extra Boot Partition", wcslen (GetString ("EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS")) * 2); break; } return 1; } return 0; case TC_APPMSG_LOAD_TEXT_BOX_CONTENT: { char *r = NULL; switch (nID) { case TC_TBXID_LEGAL_NOTICES: LocalizeDialog (hwndDlg, "LEGAL_NOTICES_DLG_TITLE"); r = GetLegalNotices (); if (r != NULL) { SetWindowText (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), r); free (r); } break; case TC_TBXID_SYS_ENCRYPTION_PRETEST: LocalizeDialog (hwndDlg, NULL); SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), (wchar_t *) GetSysEncryptionPretestInfo2String ().c_str()); break; case TC_TBXID_SYS_ENC_RESCUE_DISK: LocalizeDialog (hwndDlg, NULL); SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), (wchar_t *) GetRescueDiskHelpString ().c_str()); break; case TC_TBXID_DECOY_OS_INSTRUCTIONS: LocalizeDialog (hwndDlg, NULL); SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), (wchar_t *) GetDecoyOsInstructionsString ().c_str()); break; case TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS: LocalizeDialog (hwndDlg, NULL); SetWindowTextW (GetDlgItem (hwndDlg, IDC_INFO_BOX_TEXT), GetString ("EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS")); break; } } return 1; case WM_CLOSE: NormalCursor (); EndDialog (hwndDlg, 0); return 1; } return 0; } char * GetLegalNotices () { static char *resource; static DWORD size; char *buf = NULL; if (resource == NULL) resource = (char *) MapResource ("Text", IDR_LICENSE, &size); if (resource != NULL) { buf = (char *) malloc (size + 1); if (buf != NULL) { memcpy (buf, resource, size); buf[size] = 0; } } return buf; } BOOL CALLBACK RawDevicesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static char *lpszFileName; // This is actually a pointer to a GLOBAL array static vector devices; static map itemToDeviceMap; WORD lw = LOWORD (wParam); switch (msg) { case WM_INITDIALOG: { LVCOLUMNW LvCol; HWND hList = GetDlgItem (hwndDlg, IDC_DEVICELIST); LocalizeDialog (hwndDlg, "IDD_RAWDEVICES_DLG"); SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0, LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_TWOCLICKACTIVATE|LVS_EX_LABELTIP ); memset (&LvCol,0,sizeof(LvCol)); LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; LvCol.pszText = GetString ("DEVICE"); LvCol.cx = CompensateXDPI (186); LvCol.fmt = LVCFMT_LEFT; SendMessage (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&LvCol); LvCol.pszText = GetString ("DRIVE"); LvCol.cx = CompensateXDPI (38); LvCol.fmt = LVCFMT_LEFT; SendMessage (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&LvCol); LvCol.pszText = GetString ("SIZE"); LvCol.cx = CompensateXDPI (64); LvCol.fmt = LVCFMT_RIGHT; SendMessage (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol); LvCol.pszText = GetString ("LABEL"); LvCol.cx = CompensateXDPI (128); LvCol.fmt = LVCFMT_LEFT; SendMessage (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol); devices.clear(); itemToDeviceMap.clear(); WaitCursor(); devices = GetAvailableHostDevices (false, true, false); NormalCursor(); if (devices.empty()) { MessageBoxW (hwndDlg, GetString ("RAWDEVICES"), lpszTitle, ICON_HAND); EndDialog (hwndDlg, IDCANCEL); return 1; } int line = 1; LVITEM item; memset (&item, 0, sizeof (item)); item.mask = LVIF_TEXT; foreach (const HostDevice &device, devices) { item.iSubItem = 1; if (device.ContainsSystem) { if (device.IsPartition) strcpy_s (SysPartitionDevicePath, sizeof (SysPartitionDevicePath), device.Path.c_str()); else strcpy_s (SysDriveDevicePath, sizeof (SysDriveDevicePath), device.Path.c_str()); } // Path if (!device.IsPartition || device.DynamicVolume) { if (!device.Floppy && device.Size == 0) continue; if (line > 1) { ListItemAdd (hList, item.iItem, ""); item.iItem = line++; } if (device.Floppy || device.DynamicVolume) { ListItemAdd (hList, item.iItem, (char *) device.Path.c_str()); } else { wchar_t s[1024]; if (device.Removable) StringCbPrintfW (s, sizeof(s), L"%s %d", GetString ("REMOVABLE_DISK"), device.SystemNumber); else StringCbPrintfW (s, sizeof(s), L"%s %d", GetString ("HARDDISK"), device.SystemNumber); if (!device.Partitions.empty()) StringCbCatW (s, sizeof(s), L":"); ListItemAddW (hList, item.iItem, s); } } else { ListItemAdd (hList, item.iItem, (char *) device.Path.c_str()); } itemToDeviceMap[item.iItem] = device; // Size if (device.Size != 0) { wchar_t size[100] = { 0 }; GetSizeString (device.Size, size, sizeof(size)); ListSubItemSetW (hList, item.iItem, 2, size); } // Mount point if (!device.MountPoint.empty()) ListSubItemSet (hList, item.iItem, 1, (char *) device.MountPoint.c_str()); // Label if (!device.Name.empty()) ListSubItemSetW (hList, item.iItem, 3, (wchar_t *) device.Name.c_str()); #ifdef TCMOUNT else { wstring favoriteLabel = GetFavoriteVolumeLabel (device.Path); if (!favoriteLabel.empty()) ListSubItemSetW (hList, item.iItem, 3, (wchar_t *) favoriteLabel.c_str()); } #endif item.iItem = line++; } lpszFileName = (char *) lParam; #ifdef VOLFORMAT EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE); #endif return 1; } case WM_COMMAND: case WM_NOTIFY: // catch non-device line selected if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED && (((LPNMLISTVIEW) lParam)->uNewState & LVIS_FOCUSED )) { LVITEM LvItem; memset(&LvItem,0,sizeof(LvItem)); LvItem.mask = LVIF_TEXT | LVIF_PARAM; LvItem.iItem = ((LPNMLISTVIEW) lParam)->iItem; LvItem.pszText = lpszFileName; LvItem.cchTextMax = TC_MAX_PATH; SendMessage (GetDlgItem (hwndDlg, IDC_DEVICELIST), LVM_GETITEM, LvItem.iItem, (LPARAM) &LvItem); EnableWindow (GetDlgItem ((HWND) hwndDlg, IDOK), lpszFileName[0] != 0 && lpszFileName[0] != ' '); return 1; } if (msg == WM_COMMAND && lw == IDOK || msg == WM_NOTIFY && ((NMHDR *)lParam)->code == LVN_ITEMACTIVATE) { int selectedItem = ListView_GetSelectionMark (GetDlgItem (hwndDlg, IDC_DEVICELIST)); if (selectedItem == -1 || itemToDeviceMap.find (selectedItem) == itemToDeviceMap.end()) return 1; // non-device line selected const HostDevice selectedDevice = itemToDeviceMap[selectedItem]; strcpy_s (lpszFileName, TC_MAX_PATH, selectedDevice.Path.c_str()); #ifdef VOLFORMAT if (selectedDevice.ContainsSystem && selectedDevice.IsPartition) { if (WizardMode != WIZARD_MODE_SYS_DEVICE) { if (AskYesNo ("CONFIRM_SYSTEM_ENCRYPTION_MODE") == IDNO) { EndDialog (hwndDlg, IDCANCEL); return 1; } bSysPartitionSelected = TRUE; bSysDriveSelected = FALSE; lpszFileName[0] = 0; SwitchWizardToSysEncMode (); NormalCursor (); EndDialog (hwndDlg, IDOK); return 1; } else { // This should never be the case because the Select Device dialog is not available in this wizard mode bSysPartitionSelected = TRUE; bSysDriveSelected = FALSE; lpszFileName[0] = 0; SwitchWizardToSysEncMode (); NormalCursor (); EndDialog (hwndDlg, IDCANCEL); return 1; } } if (!(selectedDevice.ContainsSystem && !selectedDevice.IsPartition)) { if (bWarnDeviceFormatAdvanced && !bHiddenVolDirect && AskWarnNoYes("FORMAT_DEVICE_FOR_ADVANCED_ONLY") == IDNO) { if (AskNoYes("CONFIRM_CHANGE_WIZARD_MODE_TO_FILE_CONTAINER") == IDYES) { SwitchWizardToFileContainerMode (); } EndDialog (hwndDlg, IDCANCEL); return 1; } if (!bHiddenVolDirect) bWarnDeviceFormatAdvanced = FALSE; } #else // #ifdef VOLFORMAT bSysPartitionSelected = (selectedDevice.ContainsSystem && selectedDevice.IsPartition); bSysDriveSelected = FALSE; #endif // #ifdef VOLFORMAT if (!selectedDevice.IsPartition && !selectedDevice.Floppy) { // Whole device selected #ifdef VOLFORMAT if (selectedDevice.ContainsSystem && !selectedDevice.IsPartition) { if (WizardMode != WIZARD_MODE_SYS_DEVICE) { if (AskYesNo ("CONFIRM_SYSTEM_ENCRYPTION_MODE") == IDNO) { NormalCursor (); EndDialog (hwndDlg, IDCANCEL); return 1; } bSysDriveSelected = TRUE; bSysPartitionSelected = FALSE; lpszFileName[0] = 0; SwitchWizardToSysEncMode (); NormalCursor (); EndDialog (hwndDlg, IDOK); return 1; } else { // This should never be the case because the Select Device dialog is not available in this wizard mode bSysDriveSelected = TRUE; bSysPartitionSelected = FALSE; lpszFileName[0] = 0; SwitchWizardToSysEncMode (); NormalCursor (); EndDialog (hwndDlg, IDCANCEL); return 1; } } // Disallow format if the device contains partitions, but not if the partition is virtual or system if (!selectedDevice.IsVirtualPartition && !bHiddenVolDirect) { if (!selectedDevice.Partitions.empty()) { EnableWindow (GetDlgItem (hwndDlg, IDOK), FALSE); Error ("DEVICE_PARTITIONS_ERR_W_INPLACE_ENC_NOTE"); return 1; } if (AskWarnNoYes ("WHOLE_NONSYS_DEVICE_ENC_CONFIRM") == IDNO) return 1; } #else // #ifdef VOLFORMAT bSysDriveSelected = (selectedDevice.ContainsSystem && !selectedDevice.IsPartition); bSysPartitionSelected = FALSE; #endif // #ifdef VOLFORMAT } else bSysDriveSelected = FALSE; #ifdef VOLFORMAT bRemovableHostDevice = selectedDevice.Removable; #endif NormalCursor (); EndDialog (hwndDlg, IDOK); return 1; } if (lw == IDCANCEL) { NormalCursor (); EndDialog (hwndDlg, IDCANCEL); return 1; } return 0; } return 0; } BOOL DoDriverInstall (HWND hwndDlg) { #ifdef SETUP if (SystemEncryptionUpdate) return TRUE; #endif SC_HANDLE hManager, hService = NULL; BOOL bOK = FALSE, bRet; hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hManager == NULL) goto error; #ifdef SETUP StatusMessage (hwndDlg, "INSTALLING_DRIVER"); #endif hService = CreateService (hManager, "veracrypt", "veracrypt", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_SYSTEM_START, SERVICE_ERROR_NORMAL, "System32\\drivers\\veracrypt.sys", NULL, NULL, NULL, NULL, NULL); if (hService == NULL) goto error; else CloseServiceHandle (hService); hService = OpenService (hManager, "veracrypt", SERVICE_ALL_ACCESS); if (hService == NULL) goto error; #ifdef SETUP StatusMessage (hwndDlg, "STARTING_DRIVER"); #endif bRet = StartService (hService, 0, NULL); if (bRet == FALSE) goto error; bOK = TRUE; error: if (bOK == FALSE && GetLastError () != ERROR_SERVICE_ALREADY_RUNNING) { handleWin32Error (hwndDlg); MessageBoxW (hwndDlg, GetString ("DRIVER_INSTALL_FAILED"), lpszTitle, MB_ICONHAND); } else bOK = TRUE; if (hService != NULL) CloseServiceHandle (hService); if (hManager != NULL) CloseServiceHandle (hManager); return bOK; } // Install and start driver service and mark it for removal (non-install mode) static int DriverLoad () { HANDLE file; WIN32_FIND_DATA find; SC_HANDLE hManager, hService = NULL; char driverPath[TC_MAX_PATH*2]; BOOL res; char *tmp; DWORD startType; if (ReadLocalMachineRegistryDword ("SYSTEM\\CurrentControlSet\\Services\\veracrypt", "Start", &startType) && startType == SERVICE_BOOT_START) return ERR_PARAMETER_INCORRECT; GetModuleFileName (NULL, driverPath, sizeof (driverPath)); tmp = strrchr (driverPath, '\\'); if (!tmp) { driverPath[0] = '.'; driverPath[1] = 0; } else *tmp = 0; StringCbCatA (driverPath, sizeof(driverPath), !Is64BitOs () ? "\\veracrypt.sys" : "\\veracrypt-x64.sys"); file = FindFirstFile (driverPath, &find); if (file == INVALID_HANDLE_VALUE) { MessageBoxW (0, GetString ("DRIVER_NOT_FOUND"), lpszTitle, ICON_HAND); return ERR_DONT_REPORT; } FindClose (file); hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hManager == NULL) { if (GetLastError () == ERROR_ACCESS_DENIED) { MessageBoxW (0, GetString ("ADMIN_PRIVILEGES_DRIVER"), lpszTitle, ICON_HAND); return ERR_DONT_REPORT; } return ERR_OS_ERROR; } hService = OpenService (hManager, "veracrypt", SERVICE_ALL_ACCESS); if (hService != NULL) { // Remove stale service (driver is not loaded but service exists) DeleteService (hService); CloseServiceHandle (hService); Sleep (500); } hService = CreateService (hManager, "veracrypt", "veracrypt", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driverPath, NULL, NULL, NULL, NULL, NULL); if (hService == NULL) { CloseServiceHandle (hManager); return ERR_OS_ERROR; } res = StartService (hService, 0, NULL); DeleteService (hService); CloseServiceHandle (hManager); CloseServiceHandle (hService); return !res ? ERR_OS_ERROR : ERROR_SUCCESS; } BOOL DriverUnload () { MOUNT_LIST_STRUCT driver; int refCount; int volumesMounted; DWORD dwResult; BOOL bResult; SC_HANDLE hManager, hService = NULL; BOOL bRet; SERVICE_STATUS status; int x; BOOL driverUnloaded = FALSE; if (hDriver == INVALID_HANDLE_VALUE) return TRUE; try { if (BootEncryption (NULL).GetStatus().DeviceFilterActive) return FALSE; } catch (...) { } // Test for mounted volumes bResult = DeviceIoControl (hDriver, TC_IOCTL_IS_ANY_VOLUME_MOUNTED, NULL, 0, &volumesMounted, sizeof (volumesMounted), &dwResult, NULL); if (!bResult) { bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES, NULL, 0, &driver, sizeof (driver), &dwResult, NULL); if (bResult) volumesMounted = driver.ulMountedDrives; } if (bResult) { if (volumesMounted != 0) return FALSE; } else return TRUE; // Test for any applications attached to driver refCount = GetDriverRefCount (); if (refCount > 1) return FALSE; CloseHandle (hDriver); hDriver = INVALID_HANDLE_VALUE; // Stop driver service hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hManager == NULL) goto error; hService = OpenService (hManager, "veracrypt", SERVICE_ALL_ACCESS); if (hService == NULL) goto error; bRet = QueryServiceStatus (hService, &status); if (bRet != TRUE) goto error; if (status.dwCurrentState != SERVICE_STOPPED) { ControlService (hService, SERVICE_CONTROL_STOP, &status); for (x = 0; x < 10; x++) { bRet = QueryServiceStatus (hService, &status); if (bRet != TRUE) goto error; if (status.dwCurrentState == SERVICE_STOPPED) { driverUnloaded = TRUE; break; } Sleep (200); } } else driverUnloaded = TRUE; error: if (hService != NULL) CloseServiceHandle (hService); if (hManager != NULL) CloseServiceHandle (hManager); if (driverUnloaded) { hDriver = INVALID_HANDLE_VALUE; return TRUE; } return FALSE; } int DriverAttach (void) { /* Try to open a handle to the device driver. It will be closed later. */ #ifndef SETUP int nLoadRetryCount = 0; start: #endif hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDriver == INVALID_HANDLE_VALUE) { #ifndef SETUP LoadSysEncSettings (NULL); if (!CreateDriverSetupMutex ()) { // Another instance is already attempting to install, register or start the driver while (!CreateDriverSetupMutex ()) { Sleep (100); // Wait until the other instance finishes } // Try to open a handle to the driver again (keep the mutex in case the other instance failed) goto start; } else { // No other instance is currently attempting to install, register or start the driver if (SystemEncryptionStatus != SYSENC_STATUS_NONE) { // This is an inconsistent state. The config file indicates system encryption should be // active, but the driver is not running. This may happen e.g. when the pretest fails and // the user selects "Last Known Good Configuration" from the Windows boot menu. // To fix this, we're going to reinstall the driver, start it, and register it for boot. if (DoDriverInstall (NULL)) { Sleep (1000); hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); try { BootEncryption bootEnc (NULL); bootEnc.RegisterBootDriver (bootEnc.GetHiddenOSCreationPhase() != TC_HIDDEN_OS_CREATION_PHASE_NONE ? true : false); } catch (Exception &e) { e.Show (NULL); } } CloseDriverSetupMutex (); } else { // Attempt to load the driver (non-install/portable mode) load: BOOL res = DriverLoad (); CloseDriverSetupMutex (); if (res != ERROR_SUCCESS) return res; bPortableModeConfirmed = TRUE; if (hDriver != INVALID_HANDLE_VALUE) CloseHandle (hDriver); hDriver = CreateFile (WIN32_ROOT_PREFIX, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); } if (bPortableModeConfirmed) NotifyDriverOfPortableMode (); } #endif // #ifndef SETUP if (hDriver == INVALID_HANDLE_VALUE) return ERR_OS_ERROR; } CloseDriverSetupMutex (); if (hDriver != INVALID_HANDLE_VALUE) { DWORD dwResult; BOOL bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &DriverVersion, sizeof (DriverVersion), &dwResult, NULL); if (!bResult) bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_DRIVER_VERSION, NULL, 0, &DriverVersion, sizeof (DriverVersion), &dwResult, NULL); #ifndef SETUP // Don't check version during setup to allow removal of another version if (bResult == FALSE) { return ERR_OS_ERROR; } else if (DriverVersion != VERSION_NUM) { // Unload an incompatbile version of the driver loaded in non-install mode and load the required version if (IsNonInstallMode () && CreateDriverSetupMutex () && DriverUnload () && nLoadRetryCount++ < 3) goto load; CloseDriverSetupMutex (); CloseHandle (hDriver); hDriver = INVALID_HANDLE_VALUE; return ERR_DRIVER_VERSION; } #else if (!bResult) DriverVersion = 0; #endif } return 0; } void ResetCurrentDirectory () { char p[MAX_PATH]; if (!IsNonInstallMode () && SHGetFolderPath (NULL, CSIDL_PROFILE, NULL, 0, p) == ERROR_SUCCESS) { SetCurrentDirectory (p); } else { GetModPath (p, sizeof (p)); SetCurrentDirectory (p); } } BOOL BrowseFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter) { return BrowseFilesInDir (hwndDlg, stringId, NULL, lpszFileName, keepHistory, saveMode, browseFilter); } BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, char *initialDir, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter, const wchar_t *initialFileName, const wchar_t *defaultExtension) { OPENFILENAMEW ofn; wchar_t file[TC_MAX_PATH] = { 0 }; wchar_t wInitialDir[TC_MAX_PATH] = { 0 }; wchar_t filter[1024]; BOOL status = FALSE; CoInitialize (NULL); ZeroMemory (&ofn, sizeof (ofn)); *lpszFileName = 0; if (initialDir) { swprintf_s (wInitialDir, sizeof (wInitialDir) / 2, L"%hs", initialDir); ofn.lpstrInitialDir = wInitialDir; } if (initialFileName) wcscpy_s (file, array_capacity (file), initialFileName); ofn.lStructSize = sizeof (ofn); ofn.hwndOwner = hwndDlg; StringCbPrintfW (filter, sizeof(filter), L"%ls (*.*)%c*.*%c%ls (*.hc)%c*.hc%c%c", GetString ("ALL_FILES"), 0, 0, GetString ("TC_VOLUMES"), 0, 0, 0); ofn.lpstrFilter = browseFilter ? browseFilter : filter; ofn.nFilterIndex = 1; ofn.lpstrFile = file; ofn.nMaxFile = sizeof (file) / sizeof (file[0]); ofn.lpstrTitle = GetString (stringId); ofn.lpstrDefExt = defaultExtension; ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | (keepHistory ? 0 : OFN_DONTADDTORECENT) | (saveMode ? OFN_OVERWRITEPROMPT : 0); if (!keepHistory) CleanLastVisitedMRU (); SystemFileSelectorCallerThreadId = GetCurrentThreadId(); SystemFileSelectorCallPending = TRUE; if (!saveMode) { if (!GetOpenFileNameW (&ofn)) goto ret; } else { if (!GetSaveFileNameW (&ofn)) goto ret; } SystemFileSelectorCallPending = FALSE; WideCharToMultiByte (CP_ACP, 0, file, -1, lpszFileName, MAX_PATH, NULL, NULL); if (!keepHistory) CleanLastVisitedMRU (); status = TRUE; ret: SystemFileSelectorCallPending = FALSE; ResetCurrentDirectory(); CoUninitialize(); return status; } static char SelectMultipleFilesPath[131072]; static int SelectMultipleFilesOffset; BOOL SelectMultipleFiles (HWND hwndDlg, const char *stringId, char *lpszFileName, size_t cbFileName,BOOL keepHistory) { OPENFILENAMEW ofn; wchar_t file[0xffff * 2] = { 0 }; // The size must not exceed 0xffff*2 due to a bug in Windows 2000 and XP SP1 wchar_t filter[1024]; BOOL status = FALSE; CoInitialize (NULL); ZeroMemory (&ofn, sizeof (ofn)); *lpszFileName = 0; ofn.lStructSize = sizeof (ofn); ofn.hwndOwner = hwndDlg; StringCbPrintfW (filter, sizeof(filter), L"%ls (*.*)%c*.*%c%ls (*.hc)%c*.hc%c%c", GetString ("ALL_FILES"), 0, 0, GetString ("TC_VOLUMES"), 0, 0, 0); ofn.lpstrFilter = filter; ofn.nFilterIndex = 1; ofn.lpstrFile = file; ofn.nMaxFile = sizeof (file) / sizeof (file[0]); ofn.lpstrTitle = GetString (stringId); ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | (keepHistory ? 0 : OFN_DONTADDTORECENT); if (!keepHistory) CleanLastVisitedMRU (); SystemFileSelectorCallerThreadId = GetCurrentThreadId(); SystemFileSelectorCallPending = TRUE; if (!GetOpenFileNameW (&ofn)) goto ret; SystemFileSelectorCallPending = FALSE; if (file[ofn.nFileOffset - 1] != 0) { // Single file selected WideCharToMultiByte (CP_ACP, 0, file, -1, lpszFileName, MAX_PATH, NULL, NULL); SelectMultipleFilesOffset = 0; } else { // Multiple files selected int n; wchar_t *f = file; char *s = SelectMultipleFilesPath; while ((n = WideCharToMultiByte (CP_ACP, 0, f, -1, s, MAX_PATH, NULL, NULL)) > 1) { f += n; s += n; } SelectMultipleFilesOffset = ofn.nFileOffset; SelectMultipleFilesNext (lpszFileName, cbFileName); } if (!keepHistory) CleanLastVisitedMRU (); status = TRUE; ret: SystemFileSelectorCallPending = FALSE; ResetCurrentDirectory(); CoUninitialize(); return status; } BOOL SelectMultipleFilesNext (char *lpszFileName, size_t cbFileName) { if (SelectMultipleFilesOffset == 0) return FALSE; StringCbCopyA (lpszFileName, cbFileName,SelectMultipleFilesPath); lpszFileName[TC_MAX_PATH - 1] = 0; if (lpszFileName[strlen (lpszFileName) - 1] != '\\') StringCbCatA (lpszFileName, cbFileName,"\\"); StringCbCatA (lpszFileName, cbFileName,SelectMultipleFilesPath + SelectMultipleFilesOffset); SelectMultipleFilesOffset += strlen (SelectMultipleFilesPath + SelectMultipleFilesOffset) + 1; if (SelectMultipleFilesPath[SelectMultipleFilesOffset] == 0) SelectMultipleFilesOffset = 0; return TRUE; } static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData) { switch(uMsg) { case BFFM_INITIALIZED: { /* WParam is TRUE since we are passing a path. It would be FALSE if we were passing a pidl. */ SendMessage (hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)pData); break; } case BFFM_SELCHANGED: { char szDir[TC_MAX_PATH]; /* Set the status window to the currently selected path. */ if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szDir)) { SendMessage (hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir); } break; } default: break; } return 0; } BOOL BrowseDirectories (HWND hwndDlg, char *lpszTitle, char *dirName) { BROWSEINFOW bi; LPITEMIDLIST pidl; LPMALLOC pMalloc; BOOL bOK = FALSE; CoInitialize (NULL); if (SUCCEEDED (SHGetMalloc (&pMalloc))) { ZeroMemory (&bi, sizeof(bi)); bi.hwndOwner = hwndDlg; bi.pszDisplayName = 0; bi.lpszTitle = GetString (lpszTitle); bi.pidlRoot = 0; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)dirName; pidl = SHBrowseForFolderW (&bi); if (pidl != NULL) { if (SHGetPathFromIDList(pidl, dirName)) { bOK = TRUE; } pMalloc->Free (pidl); pMalloc->Release(); } } CoUninitialize(); return bOK; } std::wstring GetWrongPasswordErrorMessage (HWND hwndDlg) { WCHAR szTmp[8192]; StringCbPrintfW (szTmp, sizeof(szTmp), GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_WRONG" : "PASSWORD_WRONG")); if (CheckCapsLock (hwndDlg, TRUE)) StringCbCatW (szTmp, sizeof(szTmp), GetString ("PASSWORD_WRONG_CAPSLOCK_ON")); #ifdef TCMOUNT if (TCBootLoaderOnInactiveSysEncDrive ()) { StringCbPrintfW (szTmp, sizeof(szTmp), GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_OR_MODE_WRONG" : "PASSWORD_OR_MODE_WRONG")); if (CheckCapsLock (hwndDlg, TRUE)) StringCbCatW (szTmp, sizeof(szTmp), GetString ("PASSWORD_WRONG_CAPSLOCK_ON")); StringCbCatW (szTmp, sizeof(szTmp), GetString ("SYSENC_MOUNT_WITHOUT_PBA_NOTE")); } #endif wstring msg = szTmp; #ifdef TCMOUNT if (KeyFilesEnable && HiddenFilesPresentInKeyfilePath) { msg += GetString ("HIDDEN_FILES_PRESENT_IN_KEYFILE_PATH"); HiddenFilesPresentInKeyfilePath = FALSE; } #endif return msg; } void handleError (HWND hwndDlg, int code) { WCHAR szTmp[4096]; if (Silent) return; switch (code) { case ERR_OS_ERROR: handleWin32Error (hwndDlg); break; case ERR_OUTOFMEMORY: MessageBoxW (hwndDlg, GetString ("OUTOFMEMORY"), lpszTitle, ICON_HAND); break; case ERR_PASSWORD_WRONG: MessageBoxW (hwndDlg, GetWrongPasswordErrorMessage (hwndDlg).c_str(), lpszTitle, MB_ICONWARNING); break; case ERR_DRIVE_NOT_FOUND: MessageBoxW (hwndDlg, GetString ("NOT_FOUND"), lpszTitle, ICON_HAND); break; case ERR_FILES_OPEN: MessageBoxW (hwndDlg, GetString ("OPENFILES_DRIVER"), lpszTitle, ICON_HAND); break; case ERR_FILES_OPEN_LOCK: MessageBoxW (hwndDlg, GetString ("OPENFILES_LOCK"), lpszTitle, ICON_HAND); break; case ERR_VOL_SIZE_WRONG: MessageBoxW (hwndDlg, GetString ("VOL_SIZE_WRONG"), lpszTitle, ICON_HAND); break; case ERR_COMPRESSION_NOT_SUPPORTED: MessageBoxW (hwndDlg, GetString ("COMPRESSION_NOT_SUPPORTED"), lpszTitle, ICON_HAND); break; case ERR_PASSWORD_CHANGE_VOL_TYPE: MessageBoxW (hwndDlg, GetString ("WRONG_VOL_TYPE"), lpszTitle, ICON_HAND); break; case ERR_VOL_SEEKING: MessageBoxW (hwndDlg, GetString ("VOL_SEEKING"), lpszTitle, ICON_HAND); break; case ERR_CIPHER_INIT_FAILURE: MessageBoxW (hwndDlg, GetString ("ERR_CIPHER_INIT_FAILURE"), lpszTitle, ICON_HAND); break; case ERR_CIPHER_INIT_WEAK_KEY: MessageBoxW (hwndDlg, GetString ("ERR_CIPHER_INIT_WEAK_KEY"), lpszTitle, ICON_HAND); break; case ERR_VOL_ALREADY_MOUNTED: MessageBoxW (hwndDlg, GetString ("VOL_ALREADY_MOUNTED"), lpszTitle, ICON_HAND); break; case ERR_FILE_OPEN_FAILED: MessageBoxW (hwndDlg, GetString ("FILE_OPEN_FAILED"), lpszTitle, ICON_HAND); break; case ERR_VOL_MOUNT_FAILED: MessageBoxW (hwndDlg, GetString ("VOL_MOUNT_FAILED"), lpszTitle, ICON_HAND); break; case ERR_NO_FREE_DRIVES: MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND); break; case ERR_ACCESS_DENIED: MessageBoxW (hwndDlg, GetString ("ACCESS_DENIED"), lpszTitle, ICON_HAND); break; case ERR_DRIVER_VERSION: Error ("DRIVER_VERSION"); break; case ERR_NEW_VERSION_REQUIRED: MessageBoxW (hwndDlg, GetString ("NEW_VERSION_REQUIRED"), lpszTitle, ICON_HAND); break; case ERR_SELF_TESTS_FAILED: Error ("ERR_SELF_TESTS_FAILED"); break; case ERR_VOL_FORMAT_BAD: Error ("ERR_VOL_FORMAT_BAD"); break; case ERR_ENCRYPTION_NOT_COMPLETED: Error ("ERR_ENCRYPTION_NOT_COMPLETED"); break; case ERR_NONSYS_INPLACE_ENC_INCOMPLETE: Error ("ERR_NONSYS_INPLACE_ENC_INCOMPLETE"); break; case ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG: Error ("ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG"); break; case ERR_PARAMETER_INCORRECT: Error ("ERR_PARAMETER_INCORRECT"); break; case ERR_USER_ABORT: case ERR_DONT_REPORT: // A non-error break; default: StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("ERR_UNKNOWN"), code); MessageBoxW (hwndDlg, szTmp, lpszTitle, ICON_HAND); } } BOOL CheckFileStreamWriteErrors (FILE *file, const char *fileName) { if (ferror (file)) { wchar_t s[TC_MAX_PATH]; StringCbPrintfW (s, sizeof (s), GetString ("CANNOT_WRITE_FILE_X"), fileName); ErrorDirect (s); return FALSE; } return TRUE; } static BOOL CALLBACK LocalizeDialogEnum( HWND hwnd, LPARAM font) { // Localization of controls if (LocalizationActive) { int ctrlId = GetDlgCtrlID (hwnd); if (ctrlId != 0) { char name[10] = { 0 }; GetClassName (hwnd, name, sizeof (name)); if (_stricmp (name, "Button") == 0 || _stricmp (name, "Static") == 0) { wchar_t *str = (wchar_t *) GetDictionaryValueByInt (ctrlId); if (str != NULL) SetWindowTextW (hwnd, str); } } } // Font SendMessage (hwnd, WM_SETFONT, (WPARAM) font, 0); return TRUE; } void LocalizeDialog (HWND hwnd, char *stringId) { LastDialogId = stringId; SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) 'VERA'); SendMessage (hwnd, WM_SETFONT, (WPARAM) hUserFont, 0); if (stringId == NULL) SetWindowText (hwnd, "VeraCrypt"); else SetWindowTextW (hwnd, GetString (stringId)); if (hUserFont != 0) EnumChildWindows (hwnd, LocalizeDialogEnum, (LPARAM) hUserFont); } void OpenVolumeExplorerWindow (int driveNo) { char dosName[5]; SHFILEINFO fInfo; StringCbPrintfA (dosName, sizeof(dosName), "%c:\\", (char) driveNo + 'A'); // Force explorer to discover the drive SHGetFileInfo (dosName, 0, &fInfo, sizeof (fInfo), 0); ShellExecute (NULL, "open", dosName, NULL, NULL, SW_SHOWNORMAL); } static BOOL explorerCloseSent; static HWND explorerTopLevelWindow; static BOOL CALLBACK CloseVolumeExplorerWindowsChildEnum (HWND hwnd, LPARAM driveStr) { char s[MAX_PATH]; SendMessage (hwnd, WM_GETTEXT, sizeof (s), (LPARAM) s); if (strstr (s, (char *) driveStr) != NULL) { PostMessage (explorerTopLevelWindow, WM_CLOSE, 0, 0); explorerCloseSent = TRUE; return FALSE; } return TRUE; } static BOOL CALLBACK CloseVolumeExplorerWindowsEnum (HWND hwnd, LPARAM driveNo) { char driveStr[10]; char s[MAX_PATH]; StringCbPrintfA (driveStr, sizeof(driveStr), "%c:\\", driveNo + 'A'); GetClassName (hwnd, s, sizeof s); if (strcmp (s, "CabinetWClass") == 0) { GetWindowText (hwnd, s, sizeof s); if (strstr (s, driveStr) != NULL) { PostMessage (hwnd, WM_CLOSE, 0, 0); explorerCloseSent = TRUE; return TRUE; } explorerTopLevelWindow = hwnd; EnumChildWindows (hwnd, CloseVolumeExplorerWindowsChildEnum, (LPARAM) driveStr); } return TRUE; } BOOL CloseVolumeExplorerWindows (HWND hwnd, int driveNo) { if (driveNo >= 0) { explorerCloseSent = FALSE; EnumWindows (CloseVolumeExplorerWindowsEnum, (LPARAM) driveNo); } return explorerCloseSent; } string GetUserFriendlyVersionString (int version) { char szTmp [64]; StringCbPrintfA (szTmp, sizeof(szTmp), "%x", version); string versionString (szTmp); versionString.insert (version > 0xfff ? 2 : 1,"."); if (versionString[versionString.length()-1] == '0') versionString.erase (versionString.length()-1, 1); return (versionString); } void GetSizeString (unsigned __int64 size, wchar_t *str, size_t cbStr) { static wchar_t *b, *kb, *mb, *gb, *tb, *pb; static int serNo; if (b == NULL || serNo != LocalizationSerialNo) { serNo = LocalizationSerialNo; kb = GetString ("KB"); mb = GetString ("MB"); gb = GetString ("GB"); tb = GetString ("TB"); pb = GetString ("PB"); b = GetString ("BYTE"); } if (size > 1024I64*1024*1024*1024*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s", size/1024/1024/1024/1024/1024, pb); else if (size > 1024I64*1024*1024*1024*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(size/1024.0/1024/1024/1024/1024), pb); else if (size > 1024I64*1024*1024*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s",size/1024/1024/1024/1024, tb); else if (size > 1024I64*1024*1024*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(size/1024.0/1024/1024/1024), tb); else if (size > 1024I64*1024*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s",size/1024/1024/1024, gb); else if (size > 1024I64*1024*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(size/1024.0/1024/1024), gb); else if (size > 1024I64*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s", size/1024/1024, mb); else if (size > 1024I64*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(size/1024.0/1024), mb); else if (size >= 1024I64) StringCbPrintfW (str, cbStr, L"%I64d %s", size/1024, kb); else StringCbPrintfW (str, cbStr, L"%I64d %s", size, b); } #ifndef SETUP void GetSpeedString (unsigned __int64 speed, wchar_t *str, size_t cbStr) { static wchar_t *b, *kb, *mb, *gb, *tb, *pb; static int serNo; if (b == NULL || serNo != LocalizationSerialNo) { serNo = LocalizationSerialNo; kb = GetString ("KB_PER_SEC"); mb = GetString ("MB_PER_SEC"); gb = GetString ("GB_PER_SEC"); tb = GetString ("TB_PER_SEC"); pb = GetString ("PB_PER_SEC"); b = GetString ("B_PER_SEC"); } if (speed > 1024I64*1024*1024*1024*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s", speed/1024/1024/1024/1024/1024, pb); else if (speed > 1024I64*1024*1024*1024*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(speed/1024.0/1024/1024/1024/1024), pb); else if (speed > 1024I64*1024*1024*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s",speed/1024/1024/1024/1024, tb); else if (speed > 1024I64*1024*1024*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(speed/1024.0/1024/1024/1024), tb); else if (speed > 1024I64*1024*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s",speed/1024/1024/1024, gb); else if (speed > 1024I64*1024*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(speed/1024.0/1024/1024), gb); else if (speed > 1024I64*1024*99) StringCbPrintfW (str, cbStr, L"%I64d %s", speed/1024/1024, mb); else if (speed > 1024I64*1024) StringCbPrintfW (str, cbStr, L"%.1f %s",(double)(speed/1024.0/1024), mb); else if (speed > 1024I64) StringCbPrintfW (str, cbStr, L"%I64d %s", speed/1024, kb); else StringCbPrintfW (str, cbStr, L"%I64d %s", speed, b); } static void DisplayBenchmarkResults (HWND hwndDlg) { wchar_t item1[100]={0}; LVITEMW LvItem; HWND hList = GetDlgItem (hwndDlg, IDC_RESULTS); int ea, i; BOOL unsorted = TRUE; BENCHMARK_REC tmp_line; /* Sort the list */ switch (benchmarkSortMethod) { case BENCHMARK_SORT_BY_SPEED: while (unsorted) { unsorted = FALSE; for (i = 0; i < benchmarkTotalItems - 1; i++) { if (benchmarkTable[i].meanBytesPerSec < benchmarkTable[i+1].meanBytesPerSec) { unsorted = TRUE; memcpy (&tmp_line, &benchmarkTable[i], sizeof(BENCHMARK_REC)); memcpy (&benchmarkTable[i], &benchmarkTable[i+1], sizeof(BENCHMARK_REC)); memcpy (&benchmarkTable[i+1], &tmp_line, sizeof(BENCHMARK_REC)); } } } break; case BENCHMARK_SORT_BY_NAME: while (unsorted) { unsorted = FALSE; for (i = 0; i < benchmarkTotalItems - 1; i++) { if (benchmarkTable[i].id > benchmarkTable[i+1].id) { unsorted = TRUE; memcpy (&tmp_line, &benchmarkTable[i], sizeof(BENCHMARK_REC)); memcpy (&benchmarkTable[i], &benchmarkTable[i+1], sizeof(BENCHMARK_REC)); memcpy (&benchmarkTable[i+1], &tmp_line, sizeof(BENCHMARK_REC)); } } } break; } /* Render the results */ SendMessage (hList,LVM_DELETEALLITEMS,0,(LPARAM)&LvItem); for (i = 0; i < benchmarkTotalItems; i++) { ea = benchmarkTable[i].id; memset (&LvItem,0,sizeof(LvItem)); LvItem.mask = LVIF_TEXT; LvItem.iItem = i; LvItem.iSubItem = 0; LvItem.pszText = (LPWSTR) benchmarkTable[i].name; SendMessageW (hList, LVM_INSERTITEM, 0, (LPARAM)&LvItem); #if PKCS5_BENCHMARKS wcscpy (item1, L"-"); #else GetSpeedString ((unsigned __int64) (benchmarkLastBufferSize / ((float) benchmarkTable[i].encSpeed / benchmarkPerformanceFrequency.QuadPart)), item1, sizeof(item1)); #endif LvItem.iSubItem = 1; LvItem.pszText = item1; SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); #if PKCS5_BENCHMARKS wcscpy (item1, L"-"); #else GetSpeedString ((unsigned __int64) (benchmarkLastBufferSize / ((float) benchmarkTable[i].decSpeed / benchmarkPerformanceFrequency.QuadPart)), item1, sizeof(item1)); #endif LvItem.iSubItem = 2; LvItem.pszText = item1; SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); #if PKCS5_BENCHMARKS swprintf (item1, L"%d t", benchmarkTable[i].encSpeed); #else GetSpeedString (benchmarkTable[i].meanBytesPerSec, item1, sizeof(item1)); #endif LvItem.iSubItem = 3; LvItem.pszText = item1; SendMessageW (hList, LVM_SETITEMW, 0, (LPARAM)&LvItem); } } static BOOL PerformBenchmark(HWND hwndDlg) { LARGE_INTEGER performanceCountStart, performanceCountEnd; BYTE *lpTestBuffer; PCRYPTO_INFO ci = NULL; UINT64_STRUCT startDataUnitNo; startDataUnitNo.Value = 0; #if !(PKCS5_BENCHMARKS || HASH_FNC_BENCHMARKS) ci = crypto_open (); if (!ci) return FALSE; #endif if (QueryPerformanceFrequency (&benchmarkPerformanceFrequency) == 0) { MessageBoxW (hwndDlg, GetString ("ERR_PERF_COUNTER"), lpszTitle, ICON_HAND); return FALSE; } lpTestBuffer = (BYTE *) malloc(benchmarkBufferSize - (benchmarkBufferSize % 16)); if (lpTestBuffer == NULL) { MessageBoxW (hwndDlg, GetString ("ERR_MEM_ALLOC"), lpszTitle, ICON_HAND); return FALSE; } VirtualLock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16)); WaitCursor (); benchmarkTotalItems = 0; #if !(PKCS5_BENCHMARKS || HASH_FNC_BENCHMARKS) // CPU "warm up" (an attempt to prevent skewed results on systems where CPU frequency // gradually changes depending on CPU load). ci->ea = EAGetFirst(); if (!EAInit (ci->ea, ci->master_keydata, ci->ks)) { ci->mode = FIRST_MODE_OF_OPERATION_ID; if (EAInitMode (ci)) { int i; for (i = 0; i < 10; i++) { EncryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci); DecryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci); } } } #endif #if HASH_FNC_BENCHMARKS /* Measures the speed at which each of the hash algorithms processes the message to produce a single digest. The hash algorithm benchmarks are included here for development purposes only. Do not enable them when building a public release (the benchmark GUI strings wouldn't make sense). */ { BYTE *digest [MAX_DIGESTSIZE]; WHIRLPOOL_CTX wctx; RMD160_CTX rctx; sha512_ctx s2ctx; sha256_ctx s256ctx; int hid; for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; switch (hid) { case SHA512: sha512_begin (&s2ctx); sha512_hash (lpTestBuffer, benchmarkBufferSize, &s2ctx); sha512_end ((unsigned char *) digest, &s2ctx); break; case SHA256: sha256_begin (&s256ctx); sha256_hash (lpTestBuffer, benchmarkBufferSize, &s256ctx); sha256_end ((unsigned char *) digest, &s256ctx); break; case RIPEMD160: RMD160Init(&rctx); RMD160Update(&rctx, lpTestBuffer, benchmarkBufferSize); RMD160Final((unsigned char *) digest, &rctx); break; case WHIRLPOOL: WHIRLPOOL_init (&wctx); WHIRLPOOL_add (lpTestBuffer, benchmarkBufferSize * 8, &wctx); WHIRLPOOL_finalize (&wctx, (unsigned char *) digest); break; } if (QueryPerformanceCounter (&performanceCountEnd) == 0) goto counter_error; benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; benchmarkTable[benchmarkTotalItems].decSpeed = benchmarkTable[benchmarkTotalItems].encSpeed; benchmarkTable[benchmarkTotalItems].id = hid; benchmarkTable[benchmarkTotalItems].meanBytesPerSec = ((unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart)) + (unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].decSpeed / benchmarkPerformanceFrequency.QuadPart))) / 2; StringCbPrintfA (benchmarkTable[benchmarkTotalItems].name, sizeof(benchmarkTable[benchmarkTotalItems].name),"%s", HashGetName(hid)); benchmarkTotalItems++; } } #elif PKCS5_BENCHMARKS // #if HASH_FNC_BENCHMARKS /* Measures the time that it takes for the PKCS-5 routine to derive a header key using each of the implemented PRF algorithms. The PKCS-5 benchmarks are included here for development purposes only. Do not enable them when building a public release (the benchmark GUI strings wouldn't make sense). */ { int thid, i; char dk[MASTER_KEYDATA_SIZE]; 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"}; for (thid = FIRST_PRF_ID; thid <= LAST_PRF_ID; thid++) { if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; for (i = 1; i <= 5; i++) { switch (thid) { case SHA512: /* PKCS-5 test with HMAC-SHA-512 used as the PRF */ derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); break; case SHA256: /* PKCS-5 test with HMAC-SHA-256 used as the PRF */ derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); break; case RIPEMD160: /* PKCS-5 test with HMAC-RIPEMD-160 used as the PRF */ derive_key_ripemd160 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); break; case WHIRLPOOL: /* PKCS-5 test with HMAC-Whirlpool used as the PRF */ derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); break; } } if (QueryPerformanceCounter (&performanceCountEnd) == 0) goto counter_error; benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; benchmarkTable[benchmarkTotalItems].id = thid; StringCbPrintfA (benchmarkTable[benchmarkTotalItems].name, sizeof(benchmarkTable[benchmarkTable[benchmarkTotalItems].name),"%s", get_pkcs5_prf_name (thid)); benchmarkTotalItems++; } } #else // #elif PKCS5_BENCHMARKS /* Encryption algorithm benchmarks */ for (ci->ea = EAGetFirst(); ci->ea != 0; ci->ea = EAGetNext(ci->ea)) { if (!EAIsFormatEnabled (ci->ea)) continue; EAInit (ci->ea, ci->master_keydata, ci->ks); ci->mode = FIRST_MODE_OF_OPERATION_ID; EAInitMode (ci); if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; EncryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci); if (QueryPerformanceCounter (&performanceCountEnd) == 0) goto counter_error; benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; DecryptDataUnits (lpTestBuffer, &startDataUnitNo, (TC_LARGEST_COMPILER_UINT) benchmarkBufferSize / ENCRYPTION_DATA_UNIT_SIZE, ci); if (QueryPerformanceCounter (&performanceCountEnd) == 0) goto counter_error; benchmarkTable[benchmarkTotalItems].decSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; benchmarkTable[benchmarkTotalItems].id = ci->ea; benchmarkTable[benchmarkTotalItems].meanBytesPerSec = ((unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart)) + (unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].decSpeed / benchmarkPerformanceFrequency.QuadPart))) / 2; EAGetName (benchmarkTable[benchmarkTotalItems].name, ci->ea); benchmarkTotalItems++; } #endif // #elif PKCS5_BENCHMARKS (#else) if (ci) crypto_close (ci); VirtualUnlock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16)); free(lpTestBuffer); benchmarkLastBufferSize = benchmarkBufferSize; DisplayBenchmarkResults(hwndDlg); EnableWindow (GetDlgItem (hwndDlg, IDC_PERFORM_BENCHMARK), TRUE); EnableWindow (GetDlgItem (hwndDlg, IDCLOSE), TRUE); NormalCursor (); return TRUE; counter_error: if (ci) crypto_close (ci); VirtualUnlock (lpTestBuffer, benchmarkBufferSize - (benchmarkBufferSize % 16)); free(lpTestBuffer); NormalCursor (); EnableWindow (GetDlgItem (hwndDlg, IDC_PERFORM_BENCHMARK), TRUE); EnableWindow (GetDlgItem (hwndDlg, IDCLOSE), TRUE); MessageBoxW (hwndDlg, GetString ("ERR_PERF_COUNTER"), lpszTitle, ICON_HAND); return FALSE; } BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); LPARAM nIndex; HWND hCboxSortMethod = GetDlgItem (hwndDlg, IDC_BENCHMARK_SORT_METHOD); HWND hCboxBufferSize = GetDlgItem (hwndDlg, IDC_BENCHMARK_BUFFER_SIZE); switch (msg) { case WM_INITDIALOG: { LVCOLUMNW LvCol; wchar_t s[128]; HWND hList = GetDlgItem (hwndDlg, IDC_RESULTS); LocalizeDialog (hwndDlg, "IDD_BENCHMARK_DLG"); benchmarkBufferSize = BENCHMARK_DEFAULT_BUF_SIZE; benchmarkSortMethod = BENCHMARK_SORT_BY_SPEED; SendMessage (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0, LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_LABELTIP ); memset (&LvCol,0,sizeof(LvCol)); LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; LvCol.pszText = GetString ("ALGORITHM"); LvCol.cx = CompensateXDPI (114); LvCol.fmt = LVCFMT_LEFT; SendMessage (hList,LVM_INSERTCOLUMNW,0,(LPARAM)&LvCol); LvCol.pszText = GetString ("ENCRYPTION"); LvCol.cx = CompensateXDPI (80); LvCol.fmt = LVCFMT_RIGHT; SendMessageW (hList,LVM_INSERTCOLUMNW,1,(LPARAM)&LvCol); LvCol.pszText = GetString ("DECRYPTION"); LvCol.cx = CompensateXDPI (80); LvCol.fmt = LVCFMT_RIGHT; SendMessageW (hList,LVM_INSERTCOLUMNW,2,(LPARAM)&LvCol); LvCol.pszText = GetString ("MEAN"); LvCol.cx = CompensateXDPI (80); LvCol.fmt = LVCFMT_RIGHT; SendMessageW (hList,LVM_INSERTCOLUMNW,3,(LPARAM)&LvCol); /* Combo boxes */ // Sort method SendMessage (hCboxSortMethod, CB_RESETCONTENT, 0, 0); nIndex = SendMessageW (hCboxSortMethod, CB_ADDSTRING, 0, (LPARAM) GetString ("ALPHABETICAL_CATEGORIZED")); SendMessage (hCboxSortMethod, CB_SETITEMDATA, nIndex, (LPARAM) 0); nIndex = SendMessageW (hCboxSortMethod, CB_ADDSTRING, 0, (LPARAM) GetString ("MEAN_SPEED")); SendMessage (hCboxSortMethod, CB_SETITEMDATA, nIndex, (LPARAM) 0); SendMessage (hCboxSortMethod, CB_SETCURSEL, 1, 0); // Default sort method // Buffer size SendMessage (hCboxBufferSize, CB_RESETCONTENT, 0, 0); StringCbPrintfW (s, sizeof(s), L"100 %s", GetString ("KB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 100 * BYTES_PER_KB); StringCbPrintfW (s, sizeof(s), L"500 %s", GetString ("KB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 500 * BYTES_PER_KB); StringCbPrintfW (s, sizeof(s), L"1 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 1 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"5 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 5 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"10 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 10 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"50 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 50 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"100 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 100 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"200 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 200 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"500 %s", GetString ("MB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 500 * BYTES_PER_MB); StringCbPrintfW (s, sizeof(s), L"1 %s", GetString ("GB")); nIndex = SendMessageW (hCboxBufferSize, CB_ADDSTRING, 0, (LPARAM) s); SendMessage (hCboxBufferSize, CB_SETITEMDATA, nIndex, (LPARAM) 1 * BYTES_PER_GB); SendMessage (hCboxBufferSize, CB_SETCURSEL, 5, 0); // Default buffer size uint32 driverConfig = ReadDriverConfigurationFlags(); SetDlgItemTextW (hwndDlg, IDC_HW_AES, (wstring (L" ") + (GetString (is_aes_hw_cpu_supported() ? ((driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION) ? "UISTR_DISABLED" : "UISTR_YES") : "NOT_APPLICABLE_OR_NOT_AVAILABLE"))).c_str()); ToHyperlink (hwndDlg, IDC_HW_AES_LABEL_LINK); if (is_aes_hw_cpu_supported() && (driverConfig & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION)) { Warning ("DISABLED_HW_AES_AFFECTS_PERFORMANCE"); } SYSTEM_INFO sysInfo; GetSystemInfo (&sysInfo); size_t nbrThreads = GetEncryptionThreadCount(); wchar_t nbrThreadsStr [300]; if (sysInfo.dwNumberOfProcessors < 2) { StringCbCopyW (nbrThreadsStr, sizeof(nbrThreadsStr), GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE")); } else if (nbrThreads < 2) { StringCbCopyW (nbrThreadsStr, sizeof(nbrThreadsStr), GetString ("UISTR_DISABLED")); } else { StringCbPrintfW (nbrThreadsStr, sizeof(nbrThreadsStr), GetString ("NUMBER_OF_THREADS"), nbrThreads); } SetDlgItemTextW (hwndDlg, IDC_PARALLELIZATION, (wstring (L" ") + nbrThreadsStr).c_str()); ToHyperlink (hwndDlg, IDC_PARALLELIZATION_LABEL_LINK); if (nbrThreads < min (sysInfo.dwNumberOfProcessors, GetMaxEncryptionThreadCount()) && sysInfo.dwNumberOfProcessors > 1) { Warning ("LIMITED_THREAD_COUNT_AFFECTS_PERFORMANCE"); } return 1; } break; case WM_COMMAND: case WM_NOTIFY: switch (lw) { case IDC_BENCHMARK_SORT_METHOD: nIndex = SendMessage (hCboxSortMethod, CB_GETCURSEL, 0, 0); if (nIndex != benchmarkSortMethod) { benchmarkSortMethod = nIndex; DisplayBenchmarkResults (hwndDlg); } return 1; case IDC_PERFORM_BENCHMARK: nIndex = SendMessage (hCboxBufferSize, CB_GETCURSEL, 0, 0); benchmarkBufferSize = SendMessage (hCboxBufferSize, CB_GETITEMDATA, nIndex, 0); if (PerformBenchmark (hwndDlg) == FALSE) { EndDialog (hwndDlg, IDCLOSE); } return 1; case IDC_HW_AES_LABEL_LINK: Applink ("hwacceleration", TRUE, ""); return 1; case IDC_PARALLELIZATION_LABEL_LINK: Applink ("parallelization", TRUE, ""); return 1; case IDCLOSE: case IDCANCEL: EndDialog (hwndDlg, IDCLOSE); return 1; } return 0; break; case WM_CLOSE: EndDialog (hwndDlg, IDCLOSE); return 1; break; } return 0; } static BOOL CALLBACK RandomPoolEnrichementDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); WORD hw = HIWORD (wParam); static unsigned char randPool [RNG_POOL_SIZE]; static unsigned char lastRandPool [RNG_POOL_SIZE]; static char outputDispBuffer [RNG_POOL_SIZE * 3 + RANDPOOL_DISPLAY_ROWS + 2]; static BOOL bDisplayPoolContents = TRUE; static BOOL bRandPoolDispAscii = FALSE; int hash_algo = RandGetHashFunction(); int hid; switch (msg) { case WM_INITDIALOG: { HWND hComboBox = GetDlgItem (hwndDlg, IDC_PRF_ID); VirtualLock (randPool, sizeof(randPool)); VirtualLock (lastRandPool, sizeof(lastRandPool)); VirtualLock (outputDispBuffer, sizeof(outputDispBuffer)); LocalizeDialog (hwndDlg, "IDD_RANDOM_POOL_ENRICHMENT"); SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { if (!HashIsDeprecated (hid)) AddComboPair (hComboBox, HashGetName(hid), hid); } SelectAlgo (hComboBox, &hash_algo); SetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS, bDisplayPoolContents); SetTimer (hwndDlg, 0xfd, RANDPOOL_DISPLAY_REFRESH_INTERVAL, NULL); SendMessage (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE); return 1; } case WM_TIMER: { char tmp[4]; unsigned char tmpByte; int col, row; if (bDisplayPoolContents) { RandpeekBytes (randPool, sizeof (randPool)); if (memcmp (lastRandPool, randPool, sizeof(lastRandPool)) != 0) { outputDispBuffer[0] = 0; for (row = 0; row < RANDPOOL_DISPLAY_ROWS; row++) { for (col = 0; col < RANDPOOL_DISPLAY_COLUMNS; col++) { tmpByte = randPool[row * RANDPOOL_DISPLAY_COLUMNS + col]; StringCbPrintfA (tmp, sizeof(tmp), bRandPoolDispAscii ? ((tmpByte >= 32 && tmpByte < 255 && tmpByte != '&') ? " %c " : " . ") : "%02X ", tmpByte); StringCbCatA (outputDispBuffer, sizeof(outputDispBuffer), tmp); } StringCbCatA (outputDispBuffer, sizeof(outputDispBuffer), "\n"); } SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), outputDispBuffer); memcpy (lastRandPool, randPool, sizeof(lastRandPool)); } } return 1; } case WM_COMMAND: if (lw == IDC_CONTINUE) lw = IDOK; if (lw == IDOK || lw == IDCLOSE || lw == IDCANCEL) { goto exit; } if (lw == IDC_PRF_ID && hw == CBN_SELCHANGE) { hid = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETCURSEL, 0, 0); hash_algo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETITEMDATA, hid, 0); RandSetHashFunction (hash_algo); return 1; } if (lw == IDC_DISPLAY_POOL_CONTENTS) { if (!(bDisplayPoolContents = GetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS))) { char tmp[RNG_POOL_SIZE+1]; memset (tmp, ' ', sizeof(tmp)); tmp [RNG_POOL_SIZE] = 0; SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp); } return 1; } return 0; case WM_CLOSE: { char tmp[RNG_POOL_SIZE+1]; exit: KillTimer (hwndDlg, 0xfd); burn (randPool, sizeof(randPool)); burn (lastRandPool, sizeof(lastRandPool)); burn (outputDispBuffer, sizeof(outputDispBuffer)); // Attempt to wipe the pool contents in the GUI text area memset (tmp, ' ', RNG_POOL_SIZE); tmp [RNG_POOL_SIZE] = 0; SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp); if (msg == WM_COMMAND && lw == IDOK) EndDialog (hwndDlg, IDOK); else EndDialog (hwndDlg, IDCLOSE); return 1; } } return 0; } void UserEnrichRandomPool (HWND hwndDlg) { Randinit(); if (!IsRandomPoolEnrichedByUser()) { INT_PTR result = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_RANDOM_POOL_ENRICHMENT), hwndDlg ? hwndDlg : MainDlg, (DLGPROC) RandomPoolEnrichementDlgProc, (LPARAM) 0); SetRandomPoolEnrichedByUserStatus (result == IDOK); } } /* Except in response to the WM_INITDIALOG message, the dialog box procedure should return nonzero if it processes the message, and zero if it does not. - see DialogProc */ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); WORD hw = HIWORD (wParam); static unsigned char randPool [RNG_POOL_SIZE]; static unsigned char lastRandPool [RNG_POOL_SIZE]; static char outputDispBuffer [RNG_POOL_SIZE * 3 + RANDPOOL_DISPLAY_ROWS + 2]; static BOOL bDisplayPoolContents = TRUE; static BOOL bRandPoolDispAscii = FALSE; int hash_algo = RandGetHashFunction(); int hid; switch (msg) { case WM_INITDIALOG: { HWND hComboBox = GetDlgItem (hwndDlg, IDC_PRF_ID); VirtualLock (randPool, sizeof(randPool)); VirtualLock (lastRandPool, sizeof(lastRandPool)); VirtualLock (outputDispBuffer, sizeof(outputDispBuffer)); LocalizeDialog (hwndDlg, "IDD_KEYFILE_GENERATOR"); SendMessage (hComboBox, CB_RESETCONTENT, 0, 0); for (hid = FIRST_PRF_ID; hid <= LAST_PRF_ID; hid++) { if (!HashIsDeprecated (hid)) AddComboPair (hComboBox, HashGetName(hid), hid); } SelectAlgo (hComboBox, &hash_algo); SetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS, bDisplayPoolContents); #ifndef VOLFORMAT if (Randinit ()) { Error ("INIT_RAND"); EndDialog (hwndDlg, IDCLOSE); } #endif SetTimer (hwndDlg, 0xfd, RANDPOOL_DISPLAY_REFRESH_INTERVAL, NULL); SendMessage (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), WM_SETFONT, (WPARAM) hFixedDigitFont, (LPARAM) TRUE); // 9-digit limit for the number of keyfiles (more than enough!) SendMessage (GetDlgItem (hwndDlg, IDC_NUMBER_KEYFILES), EM_SETLIMITTEXT, (WPARAM) 9, 0); SetWindowText(GetDlgItem (hwndDlg, IDC_NUMBER_KEYFILES), "1"); // maximum keyfile size is 1048576, so limit the edit control to 7 characters SendMessage (GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), EM_SETLIMITTEXT, (WPARAM) 7, 0); SetWindowText(GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), "64"); // set the maximum length of the keyfile base name to (TC_MAX_PATH - 1) SendMessage (GetDlgItem (hwndDlg, IDC_KEYFILES_BASE_NAME), EM_SETLIMITTEXT, (WPARAM) (TC_MAX_PATH - 1), 0); return 1; } case WM_TIMER: { char tmp[4]; unsigned char tmpByte; int col, row; if (bDisplayPoolContents) { RandpeekBytes (randPool, sizeof (randPool)); if (memcmp (lastRandPool, randPool, sizeof(lastRandPool)) != 0) { outputDispBuffer[0] = 0; for (row = 0; row < RANDPOOL_DISPLAY_ROWS; row++) { for (col = 0; col < RANDPOOL_DISPLAY_COLUMNS; col++) { tmpByte = randPool[row * RANDPOOL_DISPLAY_COLUMNS + col]; StringCbPrintfA (tmp, sizeof(tmp), bRandPoolDispAscii ? ((tmpByte >= 32 && tmpByte < 255 && tmpByte != '&') ? " %c " : " . ") : "%02X ", tmpByte); StringCbCatA (outputDispBuffer, sizeof(outputDispBuffer), tmp); } StringCbCatA (outputDispBuffer, sizeof(outputDispBuffer), "\n"); } SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), outputDispBuffer); memcpy (lastRandPool, randPool, sizeof(lastRandPool)); } } return 1; } case WM_COMMAND: if (lw == IDCLOSE || lw == IDCANCEL) { goto exit; } if (lw == IDC_PRF_ID && hw == CBN_SELCHANGE) { hid = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETCURSEL, 0, 0); hash_algo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PRF_ID), CB_GETITEMDATA, hid, 0); RandSetHashFunction (hash_algo); return 1; } if (lw == IDC_DISPLAY_POOL_CONTENTS) { if (!(bDisplayPoolContents = GetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS))) { char tmp[RNG_POOL_SIZE+1]; memset (tmp, ' ', sizeof(tmp)); tmp [RNG_POOL_SIZE] = 0; SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp); } return 1; } if (lw == IDC_KEYFILES_RANDOM_SIZE) { EnableWindow(GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), !GetCheckBox (hwndDlg, IDC_KEYFILES_RANDOM_SIZE)); } if (lw == IDC_GENERATE_AND_SAVE_KEYFILE) { char szNumber[16] = {0}; char szFileBaseName[TC_MAX_PATH]; char szDirName[TC_MAX_PATH]; char szFileName [2*TC_MAX_PATH + 16]; unsigned char *keyfile = NULL; int fhKeyfile = -1, status; long keyfilesCount = 0, keyfilesSize = 0, i; char* fileExtensionPtr = 0; char szSuffix[32]; BOOL bRandomSize = GetCheckBox (hwndDlg, IDC_KEYFILES_RANDOM_SIZE); if (!GetWindowText(GetDlgItem (hwndDlg, IDC_NUMBER_KEYFILES), szNumber, sizeof(szNumber))) szNumber[0] = 0; keyfilesCount = strtoul(szNumber, NULL, 0); if (keyfilesCount <= 0 || keyfilesCount == LONG_MAX) { Warning("KEYFILE_INCORRECT_NUMBER"); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_NUMBER_KEYFILES), TRUE); return 1; } if (!bRandomSize) { if (!GetWindowText(GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), szNumber, sizeof(szNumber))) szNumber[0] = 0; keyfilesSize = strtoul(szNumber, NULL, 0); if (keyfilesSize < 64 || keyfilesSize > 1024*1024) { Warning("KEYFILE_INCORRECT_SIZE"); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), TRUE); return 1; } } if (!GetWindowText(GetDlgItem (hwndDlg, IDC_KEYFILES_BASE_NAME), szFileBaseName, TC_MAX_PATH)) szFileBaseName[0] = 0; // Trim trailing space if (TrimWhiteSpace(szFileBaseName) == 0) { Warning("KEYFILE_EMPTY_BASE_NAME"); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_KEYFILES_BASE_NAME), TRUE); return 1; } if (!IsValidFileName(szFileBaseName)) { Warning("KEYFILE_INVALID_BASE_NAME"); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_KEYFILES_BASE_NAME), TRUE); return 1; } fileExtensionPtr = strrchr(szFileBaseName, '.'); /* Select directory */ if (!BrowseDirectories (hwndDlg, "SELECT_KEYFILE_GENERATION_DIRECTORY", szDirName)) return 1; if (szDirName[strlen(szDirName) - 1] != '\\' && szDirName[strlen(szDirName) - 1] != '/') StringCbCat(szDirName, sizeof(szDirName), "\\"); WaitCursor(); keyfile = (unsigned char*) TCalloc( bRandomSize? KEYFILE_MAX_READ_LEN : keyfilesSize ); for (i= 0; i < keyfilesCount; i++) { StringCbCopy(szFileName, sizeof(szFileName), szDirName); if (i > 0) { StringCbPrintfA(szSuffix, sizeof(szSuffix), "_%d", i); // Append the counter to the name if (fileExtensionPtr) { StringCbCatN(szFileName, sizeof(szFileName), szFileBaseName, (size_t) (fileExtensionPtr - szFileBaseName)); StringCbCat(szFileName, sizeof(szFileName), szSuffix); StringCbCat(szFileName, sizeof(szFileName), fileExtensionPtr); } else { StringCbCat(szFileName, sizeof(szFileName), szFileBaseName); StringCbCat(szFileName, sizeof(szFileName), szSuffix); } } else StringCbCat(szFileName, sizeof(szFileName), szFileBaseName); // check if the file exists if ((fhKeyfile = _open(szFileName, _O_RDONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) != -1) { WCHAR s[4*TC_MAX_PATH] = {0}; WCHAR wszFileName[3*TC_MAX_PATH] = {0}; _close (fhKeyfile); MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wszFileName, sizeof(wszFileName) / sizeof(WCHAR)); StringCbPrintfW (s, sizeof(s), GetString ("KEYFILE_ALREADY_EXISTS"), wszFileName); status = AskWarnNoYesString (s); if (status == IDNO) { TCfree(keyfile); NormalCursor(); return 1; } } /* Conceive the file */ if ((fhKeyfile = _open(szFileName, _O_CREAT|_O_TRUNC|_O_WRONLY|_O_BINARY, _S_IREAD|_S_IWRITE)) == -1) { TCfree(keyfile); NormalCursor(); handleWin32Error (hwndDlg); return 1; } if (bRandomSize) { /* Generate a random size */ if (!RandgetBytes ((unsigned char*) &keyfilesSize, sizeof(keyfilesSize), FALSE)) { _close (fhKeyfile); DeleteFile (szFileName); TCfree(keyfile); NormalCursor(); return 1; } /* since keyfilesSize < 1024 * 1024, we mask with 0x000FFFFF */ keyfilesSize = (long) (((unsigned long) keyfilesSize) & 0x000FFFFF); keyfilesSize %= ((KEYFILE_MAX_READ_LEN - 64) + 1); keyfilesSize += 64; } /* Generate the keyfile */ if (!RandgetBytesFull (keyfile, keyfilesSize, TRUE, TRUE)) { _close (fhKeyfile); DeleteFile (szFileName); TCfree(keyfile); NormalCursor(); return 1; } /* Write the keyfile */ status = _write (fhKeyfile, keyfile, keyfilesSize); burn (keyfile, keyfilesSize); _close (fhKeyfile); if (status == -1) { TCfree(keyfile); NormalCursor(); handleWin32Error (hwndDlg); return 1; } } TCfree(keyfile); NormalCursor(); Info("KEYFILE_CREATED"); return 1; } return 0; case WM_CLOSE: { char tmp[RNG_POOL_SIZE+1]; exit: WaitCursor(); KillTimer (hwndDlg, 0xfd); #ifndef VOLFORMAT RandStop (FALSE); #endif /* Cleanup */ burn (randPool, sizeof(randPool)); burn (lastRandPool, sizeof(lastRandPool)); burn (outputDispBuffer, sizeof(outputDispBuffer)); // Attempt to wipe the pool contents in the GUI text area memset (tmp, ' ', RNG_POOL_SIZE); tmp [RNG_POOL_SIZE] = 0; SetWindowText (GetDlgItem (hwndDlg, IDC_POOL_CONTENTS), tmp); EndDialog (hwndDlg, IDCLOSE); NormalCursor (); return 1; } } return 0; } /* Except in response to the WM_INITDIALOG message, the dialog box procedure should return nonzero if it processes the message, and zero if it does not. - see DialogProc */ BOOL CALLBACK CipherTestDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int idTestCipher = -1; /* Currently selected cipher for the test vector facility (none = -1). */ static BOOL bXTSTestEnabled = FALSE; PCRYPTO_INFO ci; WORD lw = LOWORD (wParam); WORD hw = HIWORD (wParam); switch (uMsg) { case WM_INITDIALOG: { int ea; char buf[100]; LocalizeDialog (hwndDlg, "IDD_CIPHER_TEST_DLG"); SendMessage(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), WM_SETFONT, (WPARAM)hBoldFont, MAKELPARAM(TRUE,0)); SendMessage(GetDlgItem(hwndDlg, IDC_KEY), EM_LIMITTEXT, 128,0); SendMessage(GetDlgItem(hwndDlg, IDC_KEY), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0)); SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT), EM_LIMITTEXT,64,0); SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0)); SendMessage(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), EM_LIMITTEXT,64,0); SendMessage(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0)); SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), EM_LIMITTEXT, 128,0); SendMessage(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0)); SendMessage(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), EM_LIMITTEXT,32,0); SendMessage(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), WM_SETFONT, (WPARAM)hFixedDigitFont, MAKELPARAM(1,0)); SetCheckBox (hwndDlg, IDC_XTS_MODE_ENABLED, bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDC_SECONDARY_KEY), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDT_SECONDARY_KEY), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_BLOCK_NUMBER), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled); if (idTestCipher == -1) idTestCipher = (int) lParam; SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_RESETCONTENT, 0, 0); for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea)) { if (EAGetCipherCount (ea) == 1 && EAIsFormatEnabled (ea)) AddComboPair (GetDlgItem (hwndDlg, IDC_CIPHER), EAGetName (buf, ea), EAGetFirstCipher (ea)); } ResetCipherTest(hwndDlg, idTestCipher); SelectAlgo (GetDlgItem (hwndDlg, IDC_CIPHER), &idTestCipher); return 1; } case WM_COMMAND: if (hw == CBN_SELCHANGE && lw == IDC_CIPHER) { idTestCipher = (int) SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_CIPHER), CB_GETCURSEL, 0, 0), 0); ResetCipherTest(hwndDlg, idTestCipher); SendMessage (hwndDlg, WM_INITDIALOG, 0, 0); return 1; } if (hw == CBN_SELCHANGE && lw == IDC_KEY_SIZE) { // NOP return 1; } if (lw == IDC_RESET) { ResetCipherTest(hwndDlg, idTestCipher); return 1; } if (lw == IDC_AUTO) { WaitCursor (); if (!AutoTestAlgorithms()) { ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_SHOWNORMAL); SetWindowTextW(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), GetString ("TESTS_FAILED")); } else { ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_SHOWNORMAL); SetWindowTextW(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), GetString ("TESTS_PASSED")); ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_SHOWNORMAL); } NormalCursor (); return 1; } if (lw == IDC_XTS_MODE_ENABLED) { bXTSTestEnabled = GetCheckBox (hwndDlg, IDC_XTS_MODE_ENABLED); EnableWindow (GetDlgItem (hwndDlg, IDC_SECONDARY_KEY), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDT_SECONDARY_KEY), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_BLOCK_NUMBER), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDT_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled); EnableWindow (GetDlgItem (hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), bXTSTestEnabled); if (bXTSTestEnabled) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, 0,0); } if (lw == IDOK || lw == IDC_ENCRYPT || lw == IDC_DECRYPT) { char key[128+1], inputtext[128+1], secondaryKey[64+1], dataUnitNo[16+1], szTmp[128+1]; int ks, pt, n, tlen, blockNo = 0; BOOL bEncrypt; ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_HIDE); ks = (int) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_GETCURSEL, 0,0); ks = (int) SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_GETITEMDATA, ks,0); pt = (int) SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_GETITEMDATA, 0,0); bEncrypt = lw == IDC_ENCRYPT; memset(key,0,sizeof(key)); memset(szTmp,0,sizeof(szTmp)); n = GetWindowText(GetDlgItem(hwndDlg, IDC_KEY), szTmp, sizeof(szTmp)); if (n != ks * 2) { Warning ("TEST_KEY_SIZE"); return 1; } for (n = 0; n < ks; n ++) { char szTmp2[3], *ptr; long x; szTmp2[2] = 0; szTmp2[0] = szTmp[n * 2]; szTmp2[1] = szTmp[n * 2 + 1]; x = strtol(szTmp2, &ptr, 16); key[n] = (char) x; } memset(inputtext, 0, sizeof(inputtext)); memset(secondaryKey, 0, sizeof(secondaryKey)); memset(dataUnitNo, 0, sizeof(dataUnitNo)); memset(szTmp, 0, sizeof(szTmp)); if (bEncrypt) { n = GetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), szTmp, sizeof(szTmp)); } else { n = GetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), szTmp, sizeof(szTmp)); } if (n != pt * 2) { if (bEncrypt) { Warning ("TEST_PLAINTEXT_SIZE"); return 1; } else { Warning ("TEST_CIPHERTEXT_SIZE"); return 1; } } for (n = 0; n < pt; n ++) { char szTmp2[3], *ptr; long x; szTmp2[2] = 0; szTmp2[0] = szTmp[n * 2]; szTmp2[1] = szTmp[n * 2 + 1]; x = strtol(szTmp2, &ptr, 16); inputtext[n] = (char) x; } // XTS if (bXTSTestEnabled) { // Secondary key if (GetWindowText(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), szTmp, sizeof(szTmp)) != 64) { Warning ("TEST_INCORRECT_SECONDARY_KEY_SIZE"); return 1; } for (n = 0; n < 64; n ++) { char szTmp2[3], *ptr; long x; szTmp2[2] = 0; szTmp2[0] = szTmp[n * 2]; szTmp2[1] = szTmp[n * 2 + 1]; x = strtol(szTmp2, &ptr, 16); secondaryKey[n] = (char) x; } // Data unit number tlen = GetWindowText(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), szTmp, sizeof(szTmp)); if (tlen > 16 || tlen < 1) { Warning ("TEST_INCORRECT_TEST_DATA_UNIT_SIZE"); return 1; } LeftPadString (szTmp, tlen, 16, '0'); for (n = 0; n < 16; n ++) { char szTmp2[3], *ptr; long x; szTmp2[2] = 0; szTmp2[0] = szTmp[n * 2]; szTmp2[1] = szTmp[n * 2 + 1]; x = strtol(szTmp2, &ptr, 16); dataUnitNo[n] = (char) x; } // Block number blockNo = (int) SendMessage (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_GETCURSEL, 0, 0), 0); } // if (bXTSTestEnabled) /* Perform the actual tests */ if (ks != CB_ERR && pt != CB_ERR) { char tmp[128]; int tmpRetVal; /* Copy the plain/ciphertext */ memcpy(tmp,inputtext, pt); if (bXTSTestEnabled) { UINT64_STRUCT structDataUnitNo; /* XTS mode */ ci = crypto_open (); if (!ci) return 1; ci->mode = XTS; for (ci->ea = EAGetFirst (); ci->ea != 0 ; ci->ea = EAGetNext (ci->ea)) if (EAGetCipherCount (ci->ea) == 1 && EAGetFirstCipher (ci->ea) == idTestCipher) break; if ((tmpRetVal = EAInit (ci->ea, (unsigned char *) key, ci->ks)) != ERR_SUCCESS) { handleError (hwndDlg, tmpRetVal); return 1; } memcpy (&ci->k2, secondaryKey, sizeof (secondaryKey)); if (!EAInitMode (ci)) return 1; structDataUnitNo.Value = BE64(((unsigned __int64 *)dataUnitNo)[0]); if (bEncrypt) EncryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher); else DecryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher); crypto_close (ci); } else { CipherInit2(idTestCipher, key, ks_tmp, ks); if (bEncrypt) { EncipherBlock(idTestCipher, tmp, ks_tmp); } else { DecipherBlock(idTestCipher, tmp, ks_tmp); } } *szTmp = 0; for (n = 0; n < pt; n ++) { char szTmp2[3]; StringCbPrintfA(szTmp2, sizeof(szTmp2), "%02x", (int)((unsigned char)tmp[n])); StringCbCatA(szTmp, sizeof(szTmp), szTmp2); } if (bEncrypt) SetWindowText(GetDlgItem(hwndDlg,IDC_CIPHERTEXT), szTmp); else SetWindowText(GetDlgItem(hwndDlg,IDC_PLAINTEXT), szTmp); } return 1; } if (lw == IDCLOSE || lw == IDCANCEL) { idTestCipher = -1; EndDialog (hwndDlg, 0); return 1; } break; case WM_CLOSE: idTestCipher = -1; EndDialog (hwndDlg, 0); return 1; } return 0; } void ResetCipherTest(HWND hwndDlg, int idTestCipher) { int ndx; ShowWindow(GetDlgItem(hwndDlg, IDC_TESTS_MESSAGE), SW_HIDE); ShowWindow(GetDlgItem(hwndDlg, IDC_REDTICK), SW_HIDE); EnableWindow(GetDlgItem(hwndDlg,IDC_KEY_SIZE), FALSE); /* Setup the keysize and plaintext sizes for the selected cipher */ SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_RESETCONTENT, 0,0); SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_RESETCONTENT, 0,0); SendMessage (GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_RESETCONTENT, 0,0); ndx = SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_ADDSTRING, 0,(LPARAM) "64"); SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 8); SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETCURSEL, ndx,0); for (ndx = 0; ndx < BLOCKS_PER_XTS_DATA_UNIT; ndx++) { char tmpStr [16]; StringCbPrintfA (tmpStr, sizeof(tmpStr), "%d", ndx); ndx = SendMessage (GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_ADDSTRING, 0,(LPARAM) tmpStr); SendMessage(GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_SETITEMDATA, ndx,(LPARAM) ndx); } SendMessage(GetDlgItem(hwndDlg, IDC_TEST_BLOCK_NUMBER), CB_SETCURSEL, 0, 0); SetWindowText(GetDlgItem(hwndDlg, IDC_SECONDARY_KEY), "0000000000000000000000000000000000000000000000000000000000000000"); SetWindowText(GetDlgItem(hwndDlg, IDC_TEST_DATA_UNIT_NUMBER), "0"); SetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), "0000000000000000"); SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), "0000000000000000"); if (idTestCipher == AES || idTestCipher == SERPENT || idTestCipher == TWOFISH) { ndx = SendMessage (GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_ADDSTRING, 0,(LPARAM) "256"); SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 32); SendMessage(GetDlgItem(hwndDlg, IDC_KEY_SIZE), CB_SETCURSEL, ndx,0); SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_RESETCONTENT, 0,0); ndx = SendMessage (GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_ADDSTRING, 0,(LPARAM) "128"); SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETITEMDATA, ndx,(LPARAM) 16); SendMessage(GetDlgItem(hwndDlg, IDC_PLAINTEXT_SIZE), CB_SETCURSEL, ndx,0); SetWindowText(GetDlgItem(hwndDlg, IDC_KEY), "0000000000000000000000000000000000000000000000000000000000000000"); SetWindowText(GetDlgItem(hwndDlg, IDC_PLAINTEXT), "00000000000000000000000000000000"); SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), "00000000000000000000000000000000"); } } #endif // #ifndef SETUP BOOL CALLBACK MultiChoiceDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { int nChoiceIDs [MAX_MULTI_CHOICES+1] = { IDC_MULTI_CHOICE_MSG, IDC_CHOICE1, IDC_CHOICE2, IDC_CHOICE3, IDC_CHOICE4, IDC_CHOICE5, IDC_CHOICE6, IDC_CHOICE7, IDC_CHOICE8, IDC_CHOICE9, IDC_CHOICE10 }; int nBaseButtonWidth = 0; int nBaseButtonHeight = 0; int nActiveChoices = -1; int nStr = 0; int vertSubOffset, horizSubOffset, vertMsgHeightOffset; int vertOffset = 0; int nLongestButtonCaptionWidth = 6; int nLongestButtonCaptionCharLen = 1; int nTextGfxLineHeight = 0; int nMainTextLenInChars = 0; int newLineSeqCount = 0; RECT rec, wrec, wtrec, trec; BOOL bResolve; WORD lw = LOWORD (wParam); switch (uMsg) { case WM_INITDIALOG: { char **pStr = (char **) ((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->strings; char **pStrOrig = pStr; wchar_t **pwStr = (wchar_t **) ((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->strings; wchar_t **pwStrOrig = pwStr; LocalizeDialog (hwndDlg, NULL); SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); bResolve = (*pStr == NULL); // Style if (((MULTI_CHOICE_DLGPROC_PARAMS *) lParam)->bold) { SendMessage (GetDlgItem (hwndDlg, IDC_MULTI_CHOICE_MSG), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE); } // Process the strings pStr++; pwStr++; do { if (*pStr != 0) { SetWindowTextW (GetDlgItem(hwndDlg, nChoiceIDs[nStr]), bResolve ? GetString(*pStr) : *pwStr); if (nStr > 0) { nLongestButtonCaptionWidth = max ( GetTextGfxWidth (GetDlgItem(hwndDlg, IDC_CHOICE1), bResolve ? GetString(*pStr) : *pwStr, hUserFont), nLongestButtonCaptionWidth); nLongestButtonCaptionCharLen = max (nLongestButtonCaptionCharLen, (int) wcslen ((const wchar_t *) (bResolve ? GetString(*pStr) : *pwStr))); } nActiveChoices++; pStr++; pwStr++; } else { ShowWindow(GetDlgItem(hwndDlg, nChoiceIDs[nStr]), SW_HIDE); } nStr++; } while (nStr < MAX_MULTI_CHOICES+1); // Length of main message in characters (not bytes) nMainTextLenInChars = wcslen ((const wchar_t *) (bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1))); if (nMainTextLenInChars > 200 && nMainTextLenInChars / nLongestButtonCaptionCharLen >= 10) { // As the main text is longer than 200 characters, we will "pad" the widest button caption with // spaces (if it is not wide enough) so as to increase the width of the whole dialog window. // Otherwise, it would look too tall (dialog boxes look better when they are more wide than tall). nLongestButtonCaptionWidth = CompensateXDPI (max ( nLongestButtonCaptionWidth, min (350, nMainTextLenInChars))); } // Get the window coords GetWindowRect(hwndDlg, &wrec); // Get the base button size GetClientRect(GetDlgItem(hwndDlg, IDC_CHOICE1), &rec); nBaseButtonWidth = rec.right + 2; nBaseButtonHeight = rec.bottom + 2; // Increase in width based on the gfx length of the widest button caption horizSubOffset = min (CompensateXDPI (500), max (0, nLongestButtonCaptionWidth + CompensateXDPI (50) - nBaseButtonWidth)); // Vertical "title bar" offset GetClientRect(hwndDlg, &wtrec); vertOffset = wrec.bottom - wrec.top - wtrec.bottom - GetSystemMetrics(SM_CYFIXEDFRAME); // Height/width of the message text GetClientRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &trec); // Determine the number of newlines contained in the message text { int64 offset = -1; do { offset = FindString ((char *) (bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1)), (char *) L"\n", nMainTextLenInChars * 2, wcslen (L"\n") * 2, offset + 1); newLineSeqCount++; } while (offset != -1); } nTextGfxLineHeight = GetTextGfxHeight (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1), hUserFont); vertMsgHeightOffset = ((GetTextGfxWidth (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), bResolve ? GetString(*(pStrOrig+1)) : *(pwStrOrig+1), hUserFont) / (trec.right + horizSubOffset) + 1) * nTextGfxLineHeight) - trec.bottom; 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 // Reduction in height according to the number of shown buttons vertSubOffset = ((MAX_MULTI_CHOICES - nActiveChoices) * nBaseButtonHeight); if (horizSubOffset > 0 || vertMsgHeightOffset > 0 || vertOffset > 0) { // Resize/move each button if necessary for (nStr = 1; nStr < MAX_MULTI_CHOICES+1; nStr++) { GetWindowRect(GetDlgItem(hwndDlg, nChoiceIDs[nStr]), &rec); MoveWindow (GetDlgItem(hwndDlg, nChoiceIDs[nStr]), rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME), rec.top - wrec.top - vertOffset + vertMsgHeightOffset, nBaseButtonWidth + horizSubOffset, nBaseButtonHeight, TRUE); } // Resize/move the remaining GUI elements GetWindowRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &rec); GetClientRect(GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), &trec); MoveWindow (GetDlgItem(hwndDlg, IDC_MULTI_CHOICE_MSG), rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME), rec.top - wrec.top - vertOffset, trec.right + 2 + horizSubOffset, trec.bottom + 2 + vertMsgHeightOffset, TRUE); GetWindowRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), &rec); GetClientRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), &trec); MoveWindow (GetDlgItem(hwndDlg, IDC_MC_DLG_HR1), rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME), rec.top - wrec.top - vertOffset, trec.right + 2 + horizSubOffset, trec.bottom + 2, TRUE); GetWindowRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), &rec); GetClientRect(GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), &trec); MoveWindow (GetDlgItem(hwndDlg, IDC_MC_DLG_HR2), rec.left - wrec.left - GetSystemMetrics(SM_CXFIXEDFRAME), rec.top - wrec.top - vertOffset + vertMsgHeightOffset, trec.right + 2 + horizSubOffset, trec.bottom + 2, TRUE); } // Resize the window according to number of shown buttons and the longest button caption MoveWindow (hwndDlg, wrec.left - horizSubOffset / 2, wrec.top + vertSubOffset / 2 - vertMsgHeightOffset / 2, wrec.right - wrec.left + horizSubOffset, wrec.bottom - wrec.top - vertSubOffset + 1 + vertMsgHeightOffset, TRUE); return 1; } case WM_COMMAND: if (lw == IDCLOSE || lw == IDCANCEL) { EndDialog (hwndDlg, 0); return 1; } for (nStr = 1; nStr < MAX_MULTI_CHOICES+1; nStr++) { if (lw == nChoiceIDs[nStr]) { EndDialog (hwndDlg, nStr); return 1; } } break; case WM_CLOSE: EndDialog (hwndDlg, 0); return 1; } return 0; } BOOL CheckCapsLock (HWND hwnd, BOOL quiet) { if ((GetKeyState(VK_CAPITAL) & 1) != 0) { if (!quiet) { MessageBoxW (hwnd, GetString ("CAPSLOCK_ON"), lpszTitle, MB_ICONEXCLAMATION); } return TRUE; } return FALSE; } // Checks whether the file extension is not used for executable files or similarly problematic, which often // causes Windows and antivirus software to interfere with the container. BOOL CheckFileExtension (char *fileName) { int i = 0; char *ext = strrchr (fileName, '.'); static char *problemFileExt[] = { // These are protected by the Windows Resource Protection ".asa", ".asp", ".aspx", ".ax", ".bas", ".bat", ".bin", ".cer", ".chm", ".clb", ".cmd", ".cnt", ".cnv", ".com", ".cpl", ".cpx", ".crt", ".csh", ".dll", ".drv", ".dtd", ".exe", ".fxp", ".grp", ".h1s", ".hlp", ".hta", ".ime", ".inf", ".ins", ".isp", ".its", ".js", ".jse", ".ksh", ".lnk", ".mad", ".maf", ".mag", ".mam", ".man", ".maq", ".mar", ".mas", ".mat", ".mau", ".mav", ".maw", ".mda", ".mdb", ".mde", ".mdt", ".mdw", ".mdz", ".msc", ".msi", ".msp", ".mst", ".mui", ".nls", ".ocx", ".ops", ".pal", ".pcd", ".pif", ".prf", ".prg", ".pst", ".reg", ".scf", ".scr", ".sct", ".shb", ".shs", ".sys", ".tlb", ".tsp", ".url", ".vb", ".vbe", ".vbs", ".vsmacros", ".vss", ".vst", ".vsw", ".ws", ".wsc", ".wsf", ".wsh", ".xsd", ".xsl", // These additional file extensions are usually watched by antivirus programs ".386", ".acm", ".ade", ".adp", ".ani", ".app", ".asd", ".asf", ".asx", ".awx", ".ax", ".boo", ".bz2", ".cdf", ".class", ".dhtm", ".dhtml",".dlo", ".emf", ".eml", ".flt", ".fot", ".gz", ".hlp", ".htm", ".html", ".ini", ".j2k", ".jar", ".jff", ".jif", ".jmh", ".jng", ".jp2", ".jpe", ".jpeg", ".jpg", ".lsp", ".mod", ".nws", ".obj", ".olb", ".osd", ".ov1", ".ov2", ".ov3", ".ovl", ".ovl", ".ovr", ".pdr", ".pgm", ".php", ".pkg", ".pl", ".png", ".pot", ".pps", ".ppt", ".ps1", ".ps1xml", ".psc1", ".rar", ".rpl", ".rtf", ".sbf", ".script", ".sh", ".sha", ".shtm", ".shtml", ".spl", ".swf", ".tar", ".tgz", ".tmp", ".ttf", ".vcs", ".vlm", ".vxd", ".vxo", ".wiz", ".wll", ".wmd", ".wmf", ".wms", ".wmz", ".wpc", ".wsc", ".wsh", ".wwk", ".xhtm", ".xhtml", ".xl", ".xml", ".zip", ".7z", 0}; if (!ext) return FALSE; while (problemFileExt[i]) { if (!_stricmp (ext, problemFileExt[i++])) return TRUE; } return FALSE; } void IncreaseWrongPwdRetryCount (int count) { WrongPwdRetryCounter += count; } void ResetWrongPwdRetryCount (void) { WrongPwdRetryCounter = 0; } BOOL WrongPwdRetryCountOverLimit (void) { return (WrongPwdRetryCounter > TC_TRY_HEADER_BAK_AFTER_NBR_WRONG_PWD_TRIES); } int GetFirstAvailableDrive () { DWORD dwUsedDrives = GetLogicalDrives(); int i; for (i = 3; i < 26; i++) { if (!(dwUsedDrives & 1 << i)) return i; } return -1; } int GetLastAvailableDrive () { DWORD dwUsedDrives = GetLogicalDrives(); int i; for (i = 25; i > 2; i--) { if (!(dwUsedDrives & 1 << i)) return i; } return -1; } BOOL IsDriveAvailable (int driveNo) { return (GetLogicalDrives() & (1 << driveNo)) == 0; } BOOL IsDeviceMounted (char *deviceName) { BOOL bResult = FALSE; DWORD dwResult; HANDLE dev = INVALID_HANDLE_VALUE; if ((dev = CreateFile (deviceName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) { bResult = DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL); CloseHandle (dev); } return bResult; } int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced) { UNMOUNT_STRUCT unmount; DWORD dwResult; BOOL bResult; unmount.nDosDriveNo = nDosDriveNo; unmount.ignoreOpenFiles = forced; bResult = DeviceIoControl (hDriver, TC_IOCTL_DISMOUNT_VOLUME, &unmount, sizeof (unmount), &unmount, sizeof (unmount), &dwResult, NULL); if (bResult == FALSE) { handleWin32Error (hwndDlg); return 1; } #ifdef TCMOUNT if (unmount.nReturnCode == ERR_SUCCESS && unmount.HiddenVolumeProtectionTriggered && !VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo]) { wchar_t msg[4096]; VolumeNotificationsList.bHidVolDamagePrevReported [nDosDriveNo] = TRUE; StringCbPrintfW (msg, sizeof(msg), GetString ("DAMAGE_TO_HIDDEN_VOLUME_PREVENTED"), nDosDriveNo + 'A'); SetForegroundWindow (hwndDlg); MessageBoxW (hwndDlg, msg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); } #endif // #ifdef TCMOUNT return unmount.nReturnCode; } void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap) { DEV_BROADCAST_VOLUME dbv; DWORD_PTR dwResult; LONG eventId = 0; int i; if (DeviceChangeBroadcastDisabled) return; if (message == DBT_DEVICEARRIVAL) eventId = SHCNE_DRIVEADD; else if (message == DBT_DEVICEREMOVECOMPLETE) eventId = SHCNE_DRIVEREMOVED; else if (IsOSAtLeast (WIN_7) && message == DBT_DEVICEREMOVEPENDING) // Explorer on Windows 7 holds open handles of all drives when 'Computer' is expanded in navigation pane. SHCNE_DRIVEREMOVED must be used as DBT_DEVICEREMOVEPENDING is ignored. eventId = SHCNE_DRIVEREMOVED; if (driveMap == 0) driveMap = (1 << nDosDriveNo); if (eventId != 0) { for (i = 0; i < 26; i++) { if (driveMap & (1 << i)) { char root[] = { (char) i + 'A', ':', '\\', 0 }; SHChangeNotify (eventId, SHCNF_PATH, root, NULL); if (nCurrentOS == WIN_2000 && RemoteSession) { char target[32]; StringCbPrintfA (target, sizeof(target), "%ls%c", TC_MOUNT_PREFIX, i + 'A'); root[2] = 0; if (message == DBT_DEVICEARRIVAL) DefineDosDevice (DDD_RAW_TARGET_PATH, root, target); else if (message == DBT_DEVICEREMOVECOMPLETE) DefineDosDevice (DDD_RAW_TARGET_PATH| DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, root, target); } } } } dbv.dbcv_size = sizeof (dbv); dbv.dbcv_devicetype = DBT_DEVTYP_VOLUME; dbv.dbcv_reserved = 0; dbv.dbcv_unitmask = driveMap; dbv.dbcv_flags = 0; UINT timeOut = 1000; // SHChangeNotify() works on Vista, so the Explorer does not require WM_DEVICECHANGE if (CurrentOSMajor >= 6) timeOut = 100; IgnoreWmDeviceChange = TRUE; SendMessageTimeout (HWND_BROADCAST, WM_DEVICECHANGE, message, (LPARAM)(&dbv), SMTO_ABORTIFHUNG, timeOut, &dwResult); // Explorer prior Vista sometimes fails to register a new drive if (CurrentOSMajor < 6 && message == DBT_DEVICEARRIVAL) SendMessageTimeout (HWND_BROADCAST, WM_DEVICECHANGE, message, (LPARAM)(&dbv), SMTO_ABORTIFHUNG, 200, &dwResult); IgnoreWmDeviceChange = FALSE; } // Use only cached passwords if password = NULL // // Returns: // -1 = user aborted mount / error // 0 = mount failed // 1 = mount OK // 2 = mount OK in shared mode // // Note that some code calling this relies on the content of the mountOptions struct // to remain unmodified (don't remove the 'const' without proper revision). int MountVolume (HWND hwndDlg, int driveNo, char *volumePath, Password *password, BOOL cachePassword, BOOL sharedAccess, const MountOptions* const mountOptions, BOOL quiet, BOOL bReportWrongPassword) { MOUNT_STRUCT mount; DWORD dwResult; BOOL bResult, bDevice; char root[MAX_PATH]; int favoriteMountOnArrivalRetryCount = 0; #ifdef TCMOUNT if (mountOptions->PartitionInInactiveSysEncScope) { if (!CheckSysEncMountWithoutPBA (volumePath, quiet)) return -1; } #endif if (IsMountedVolume (volumePath)) { if (!quiet) Error ("VOL_ALREADY_MOUNTED"); return -1; } if (!IsDriveAvailable (driveNo)) { if (!quiet) Error ("DRIVE_LETTER_UNAVAILABLE"); return -1; } // If using cached passwords, check cache status first if (password == NULL && IsPasswordCacheEmpty ()) return 0; ZeroMemory (&mount, sizeof (mount)); mount.bExclusiveAccess = sharedAccess ? FALSE : TRUE; mount.SystemFavorite = MountVolumesAsSystemFavorite; mount.UseBackupHeader = mountOptions->UseBackupHeader; mount.RecoveryMode = mountOptions->RecoveryMode; retry: mount.nDosDriveNo = driveNo; mount.bCache = cachePassword; mount.bPartitionInInactiveSysEncScope = FALSE; if (password != NULL) mount.VolumePassword = *password; else mount.VolumePassword.Length = 0; if (!mountOptions->ReadOnly && mountOptions->ProtectHiddenVolume) { mount.ProtectedHidVolPassword = mountOptions->ProtectedHidVolPassword; mount.bProtectHiddenVolume = TRUE; } else mount.bProtectHiddenVolume = FALSE; mount.bMountReadOnly = mountOptions->ReadOnly; mount.bMountRemovable = mountOptions->Removable; mount.bPreserveTimestamp = mountOptions->PreserveTimestamp; mount.bMountManager = TRUE; // Windows 2000 mount manager causes problems with remounted volumes if (CurrentOSMajor == 5 && CurrentOSMinor == 0) mount.bMountManager = FALSE; string path = volumePath; if (path.find ("\\\\?\\") == 0) { // Remove \\?\ prefix path = path.substr (4); strcpy_s (volumePath, TC_MAX_PATH, path.c_str()); } if (path.find ("Volume{") == 0 && path.rfind ("}\\") == path.size() - 2) { string resolvedPath = VolumeGuidPathToDevicePath (path); if (!resolvedPath.empty()) strcpy_s (volumePath, TC_MAX_PATH, resolvedPath.c_str()); } CreateFullVolumePath ((char *) mount.wszVolume, sizeof(mount.wszVolume), volumePath, &bDevice); if (!bDevice) { // UNC path if (path.find ("\\\\") == 0) { strcpy_s ((char *)mount.wszVolume, array_capacity (mount.wszVolume), ("UNC" + path.substr (1)).c_str()); } if (GetVolumePathName (volumePath, root, sizeof (root) - 1)) { DWORD bps, flags, d; if (GetDiskFreeSpace (root, &d, &bps, &d, &d)) mount.BytesPerSector = bps; // Read-only host filesystem if (!mount.bMountReadOnly && GetVolumeInformation (root, NULL, 0, NULL, &d, &flags, NULL, 0)) mount.bMountReadOnly = (flags & FILE_READ_ONLY_VOLUME) != 0; } } ToUNICODE ((char *) mount.wszVolume, sizeof(mount.wszVolume)); if (mountOptions->PartitionInInactiveSysEncScope) { if (mount.wszVolume == NULL || swscanf_s ((const wchar_t *) mount.wszVolume, WIDE("\\Device\\Harddisk%d\\Partition"), &mount.nPartitionInInactiveSysEncScopeDriveNo, sizeof(mount.nPartitionInInactiveSysEncScopeDriveNo)) != 1) { return -1; } mount.bPartitionInInactiveSysEncScope = TRUE; } bResult = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, &mount, sizeof (mount), &mount, sizeof (mount), &dwResult, NULL); burn (&mount.VolumePassword, sizeof (mount.VolumePassword)); burn (&mount.ProtectedHidVolPassword, sizeof (mount.ProtectedHidVolPassword)); if (bResult == FALSE) { // Volume already open by another process if (GetLastError () == ERROR_SHARING_VIOLATION) { if (FavoriteMountOnArrivalInProgress && ++favoriteMountOnArrivalRetryCount < 10) { Sleep (500); goto retry; } if (mount.bExclusiveAccess == FALSE) { if (!quiet) Error ("FILE_IN_USE_FAILED"); return -1; } else { if (quiet) { mount.bExclusiveAccess = FALSE; goto retry; } // Ask user if (IDYES == AskWarnNoYes ("FILE_IN_USE")) { mount.bExclusiveAccess = FALSE; goto retry; } } return -1; } if (!quiet && (!MultipleMountOperationInProgress || GetLastError() != ERROR_NOT_READY)) handleWin32Error (hwndDlg); return -1; } if (mount.nReturnCode != 0) { if (mount.nReturnCode == ERR_PASSWORD_WRONG) { // Do not report wrong password, if not instructed to if (bReportWrongPassword) { IncreaseWrongPwdRetryCount (1); // We increase the count here only if bReportWrongPassword is TRUE, because "Auto-Mount All Devices" and other callers do it separately if (WrongPwdRetryCountOverLimit () && !mount.UseBackupHeader) { // Retry using embedded header backup (if any) mount.UseBackupHeader = TRUE; goto retry; } if (bDevice && mount.bProtectHiddenVolume) { int driveNo; if (sscanf (volumePath, "\\Device\\Harddisk%d\\Partition", &driveNo) == 1) { OPEN_TEST_STRUCT openTestStruct; memset (&openTestStruct, 0, sizeof (openTestStruct)); openTestStruct.bDetectTCBootLoader = TRUE; StringCchPrintfW ((wchar_t *) openTestStruct.wszFileName, array_capacity (openTestStruct.wszFileName), L"\\Device\\Harddisk%d\\Partition0", driveNo); DWORD dwResult; if (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, &openTestStruct, sizeof (OPEN_TEST_STRUCT), &openTestStruct, sizeof (OPEN_TEST_STRUCT), &dwResult, NULL) && openTestStruct.TCBootLoaderDetected) WarningDirect ((GetWrongPasswordErrorMessage (hwndDlg) + L"\n\n" + GetString ("HIDDEN_VOL_PROT_PASSWORD_US_KEYB_LAYOUT")).c_str()); else handleError (hwndDlg, mount.nReturnCode); } } else handleError (hwndDlg, mount.nReturnCode); } return 0; } if (!quiet) handleError (hwndDlg, mount.nReturnCode); return 0; } // Mount successful if (mount.UseBackupHeader != mountOptions->UseBackupHeader && mount.UseBackupHeader) { if (bReportWrongPassword && !Silent) Warning ("HEADER_DAMAGED_AUTO_USED_HEADER_BAK"); } LastMountedVolumeDirty = mount.FilesystemDirty; if (mount.FilesystemDirty) { wchar_t msg[1024]; wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 }; StringCbPrintfW (msg, sizeof(msg), GetString ("MOUNTED_VOLUME_DIRTY"), mountPoint); if (AskWarnYesNoStringTopmost (msg) == IDYES) CheckFilesystem (driveNo, TRUE); } if (mount.VolumeMountedReadOnlyAfterAccessDenied && !Silent && !bDevice && !FileHasReadOnlyAttribute (volumePath) && !IsFileOnReadOnlyFilesystem (volumePath)) { wchar_t msg[1024]; wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 }; StringCbPrintfW (msg, sizeof(msg), GetString ("MOUNTED_CONTAINER_FORCED_READ_ONLY"), mountPoint); WarningDirect (msg); } if (mount.VolumeMountedReadOnlyAfterAccessDenied && !Silent && bDevice) { wchar_t msg[1024]; wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 }; StringCbPrintfW (msg, sizeof(msg), GetString ("MOUNTED_DEVICE_FORCED_READ_ONLY"), mountPoint); WarningDirect (msg); } if (mount.VolumeMountedReadOnlyAfterDeviceWriteProtected && !Silent && strstr (volumePath, "\\Device\\Harddisk") == volumePath) { wchar_t msg[1024]; wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 }; StringCbPrintfW (msg, sizeof(msg), GetString ("MOUNTED_DEVICE_FORCED_READ_ONLY_WRITE_PROTECTION"), mountPoint); WarningDirect (msg); if (CurrentOSMajor >= 6 && strstr (volumePath, "\\Device\\HarddiskVolume") != volumePath && AskNoYes ("ASK_REMOVE_DEVICE_WRITE_PROTECTION") == IDYES) { RemoveDeviceWriteProtection (hwndDlg, volumePath); } } ResetWrongPwdRetryCount (); BroadcastDeviceChange (DBT_DEVICEARRIVAL, driveNo, 0); if (mount.bExclusiveAccess == FALSE) return 2; return 1; } BOOL UnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forceUnmount) { int result; BOOL forced = forceUnmount; int dismountMaxRetries = UNMOUNT_MAX_AUTO_RETRIES; retry: BroadcastDeviceChange (DBT_DEVICEREMOVEPENDING, nDosDriveNo, 0); do { result = DriverUnmountVolume (hwndDlg, nDosDriveNo, forced); if (result == ERR_FILES_OPEN) Sleep (UNMOUNT_AUTO_RETRY_DELAY); else break; } while (--dismountMaxRetries > 0); if (result != 0) { if (result == ERR_FILES_OPEN && !Silent) { if (IDYES == AskWarnYesNoTopmost ("UNMOUNT_LOCK_FAILED")) { forced = TRUE; goto retry; } if (IsOSAtLeast (WIN_7)) { // Undo SHCNE_DRIVEREMOVED char root[] = { (char) nDosDriveNo + 'A', ':', '\\', 0 }; SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL); } return FALSE; } Error ("UNMOUNT_FAILED"); return FALSE; } BroadcastDeviceChange (DBT_DEVICEREMOVECOMPLETE, nDosDriveNo, 0); return TRUE; } BOOL IsPasswordCacheEmpty (void) { DWORD dw; return !DeviceIoControl (hDriver, TC_IOCTL_GET_PASSWORD_CACHE_STATUS, 0, 0, 0, 0, &dw, 0); } BOOL IsMountedVolume (const char *volname) { MOUNT_LIST_STRUCT mlist; DWORD dwResult; int i; char volume[TC_MAX_PATH*2+16]; StringCbCopyA (volume, sizeof(volume), volname); if (strstr (volname, "\\Device\\") != volname) StringCbPrintfA(volume, sizeof(volume), "\\??\\%s", volname); string resolvedPath = VolumeGuidPathToDevicePath (volname); if (!resolvedPath.empty()) StringCbCopyA (volume, sizeof (volume), resolvedPath.c_str()); ToUNICODE (volume, sizeof(volume)); memset (&mlist, 0, sizeof (mlist)); DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist, sizeof (mlist), &mlist, sizeof (mlist), &dwResult, NULL); for (i=0 ; i<26; i++) if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume)) return TRUE; return FALSE; } int GetMountedVolumeDriveNo (char *volname) { MOUNT_LIST_STRUCT mlist; DWORD dwResult; int i; char volume[TC_MAX_PATH*2+16]; if (volname == NULL) return -1; StringCbCopyA (volume, sizeof(volume), volname); if (strstr (volname, "\\Device\\") != volname) StringCbPrintfA (volume, sizeof(volume), "\\??\\%s", volname); string resolvedPath = VolumeGuidPathToDevicePath (volname); if (!resolvedPath.empty()) StringCbCopyA (volume, sizeof (volume), resolvedPath.c_str()); ToUNICODE (volume, sizeof(volume)); memset (&mlist, 0, sizeof (mlist)); DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist, sizeof (mlist), &mlist, sizeof (mlist), &dwResult, NULL); for (i=0 ; i<26; i++) if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume)) return i; return -1; } BOOL IsAdmin (void) { return IsUserAnAdmin (); } BOOL IsBuiltInAdmin () { HANDLE procToken; DWORD size; if (!IsAdmin() || !OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &procToken)) return FALSE; finally_do_arg (HANDLE, procToken, { CloseHandle (finally_arg); }); if (GetTokenInformation (procToken, TokenUser, NULL, 0, &size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE; TOKEN_USER *tokenUser = (TOKEN_USER *) malloc (size); if (!tokenUser) return FALSE; finally_do_arg (void *, tokenUser, { free (finally_arg); }); if (!GetTokenInformation (procToken, TokenUser, tokenUser, size, &size)) return FALSE; return IsWellKnownSid (tokenUser->User.Sid, WinAccountAdministratorSid); } BOOL IsUacSupported () { HKEY hkey; DWORD value = 1, size = sizeof (DWORD); if (!IsOSAtLeast (WIN_VISTA)) return FALSE; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { if (RegQueryValueEx (hkey, "EnableLUA", 0, 0, (LPBYTE) &value, &size) != ERROR_SUCCESS) value = 1; RegCloseKey (hkey); } return value != 0; } BOOL ResolveSymbolicLink (const wchar_t *symLinkName, PWSTR targetName, size_t cbTargetName) { BOOL bResult; DWORD dwResult; RESOLVE_SYMLINK_STRUCT resolve; memset (&resolve, 0, sizeof(resolve)); StringCbCopyW (resolve.symLinkName, sizeof(resolve.symLinkName), symLinkName); bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_RESOLVED_SYMLINK, &resolve, sizeof (resolve), &resolve, sizeof (resolve), &dwResult, NULL); StringCbCopyW (targetName, cbTargetName, resolve.targetName); return bResult; } BOOL GetPartitionInfo (const char *deviceName, PPARTITION_INFORMATION rpartInfo) { BOOL bResult; DWORD dwResult; DISK_PARTITION_INFO_STRUCT dpi; memset (&dpi, 0, sizeof(dpi)); StringCbPrintfW ((PWSTR) &dpi.deviceName, sizeof(dpi.deviceName), L"%hs", deviceName); bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_PARTITION_INFO, &dpi, sizeof (dpi), &dpi, sizeof (dpi), &dwResult, NULL); memcpy (rpartInfo, &dpi.partInfo, sizeof (PARTITION_INFORMATION)); return bResult; } BOOL GetDeviceInfo (const char *deviceName, DISK_PARTITION_INFO_STRUCT *info) { DWORD dwResult; memset (info, 0, sizeof(*info)); StringCbPrintfW ((PWSTR) &info->deviceName, sizeof(info->deviceName), L"%hs", deviceName); return DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_PARTITION_INFO, info, sizeof (*info), info, sizeof (*info), &dwResult, NULL); } BOOL GetDriveGeometry (const char *deviceName, PDISK_GEOMETRY diskGeometry) { BOOL bResult; DWORD dwResult; DISK_GEOMETRY_STRUCT dg; memset (&dg, 0, sizeof(dg)); StringCbPrintfW ((PWSTR) &dg.deviceName, sizeof(dg.deviceName), L"%hs", deviceName); bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVE_GEOMETRY, &dg, sizeof (dg), &dg, sizeof (dg), &dwResult, NULL); memcpy (diskGeometry, &dg.diskGeometry, sizeof (DISK_GEOMETRY)); return bResult; } // Returns drive letter number assigned to device (-1 if none) int GetDiskDeviceDriveLetter (PWSTR deviceName) { int i; WCHAR link[MAX_PATH]; WCHAR target[MAX_PATH]; WCHAR device[MAX_PATH]; if (!ResolveSymbolicLink (deviceName, device, sizeof(device))) StringCchCopyW (device, MAX_PATH, deviceName); for (i = 0; i < 26; i++) { WCHAR drive[] = { (WCHAR) i + 'A', ':', 0 }; StringCchCopyW (link, MAX_PATH, L"\\DosDevices\\"); StringCchCatW (link, MAX_PATH, drive); ResolveSymbolicLink (link, target, sizeof(target)); if (wcscmp (device, target) == 0) return i; } return -1; } // WARNING: This function does NOT provide 100% reliable results -- do NOT use it for critical/dangerous operations! // Return values: 0 - filesystem does not appear empty, 1 - filesystem appears empty, -1 - an error occurred int FileSystemAppearsEmpty (const char *devicePath) { float percentFreeSpace = 0.0; __int64 occupiedBytes = 0; if (GetStatsFreeSpaceOnPartition (devicePath, &percentFreeSpace, &occupiedBytes, TRUE) != -1) { 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. || percentFreeSpace < 88) // A 24-MB NTFS filesystem has 11.5% of space in use even if there are no files stored on it. { return 0; } else return 1; } else return -1; } // Returns the free space on the specified partition (volume) in bytes. If the 'occupiedBytes' pointer // is not NULL, size of occupied space (in bytes) is written to the pointed location. In addition, if the // 'percent' pointer is not NULL, % of free space is stored in the pointed location. If there's an error, // returns -1. __int64 GetStatsFreeSpaceOnPartition (const char *devicePath, float *percentFree, __int64 *occupiedBytes, BOOL silent) { WCHAR devPath [MAX_PATH]; int driveLetterNo = -1; char szRootPath[4] = {0, ':', '\\', 0}; ULARGE_INTEGER freeSpaceSize; ULARGE_INTEGER totalNumberOfBytes; ULARGE_INTEGER totalNumberOfFreeBytes; StringCbCopyA ((char *) devPath, sizeof(devPath), devicePath); ToUNICODE ((char *) devPath, sizeof(devPath)); driveLetterNo = GetDiskDeviceDriveLetter (devPath); szRootPath[0] = (char) driveLetterNo + 'A'; if (!GetDiskFreeSpaceEx (szRootPath, &freeSpaceSize, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { if (!silent) { handleWin32Error (MainDlg); Error ("CANNOT_CALC_SPACE"); } return -1; } if (percentFree != NULL || occupiedBytes != NULL) { // Determine occupied space and % of free space PARTITION_INFORMATION partitionInfo; if (!GetPartitionInfo (devicePath, &partitionInfo)) { if (!silent) { handleWin32Error (MainDlg); Error ("CANT_GET_VOLSIZE"); } return -1; } if (occupiedBytes != NULL) *occupiedBytes = partitionInfo.PartitionLength.QuadPart - freeSpaceSize.QuadPart; if (percentFree != NULL) *percentFree = (float) ((double) freeSpaceSize.QuadPart / (double) partitionInfo.PartitionLength.QuadPart * 100.0); } return freeSpaceSize.QuadPart; } // Returns -1 if there's an error. __int64 GetDeviceSize (const char *devicePath) { PARTITION_INFORMATION partitionInfo; if (!GetPartitionInfo (devicePath, &partitionInfo)) return -1; return partitionInfo.PartitionLength.QuadPart; } HANDLE DismountDrive (char *devName, char *devicePath) { DWORD dwResult; HANDLE hVolume; BOOL bResult = FALSE; int attempt = UNMOUNT_MAX_AUTO_RETRIES; int driveLetterNo = -1; WCHAR devPath [MAX_PATH]; StringCbCopyA ((char *) devPath, sizeof(devPath), devicePath); ToUNICODE ((char *) devPath, sizeof(devPath)); driveLetterNo = GetDiskDeviceDriveLetter (devPath); hVolume = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hVolume == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE; // Try to lock the volume first so that dismount is not forced. // If we fail, we will dismount anyway even if it needs to be forced. CloseVolumeExplorerWindows (MainDlg, driveLetterNo); while (!(bResult = DeviceIoControl (hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL)) && attempt > 0) { Sleep (UNMOUNT_AUTO_RETRY_DELAY); attempt--; } // Try to dismount the volume attempt = UNMOUNT_MAX_AUTO_RETRIES; while (!(bResult = DeviceIoControl (hVolume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwResult, NULL)) && attempt > 0) { Sleep (UNMOUNT_AUTO_RETRY_DELAY); attempt--; } if (!bResult) CloseHandle (hVolume); return (bResult ? hVolume : INVALID_HANDLE_VALUE); } // Returns -1 if the specified string is not found in the buffer. Otherwise, returns the // offset of the first occurrence of the string. The string and the buffer may contain zeroes, // which do NOT terminate them. int64 FindString (const char *buf, const char *str, int64 bufLen, size_t strLen, int64 startOffset) { if (buf == NULL || str == NULL || strLen > bufLen || bufLen < 1 || strLen < 1 || startOffset > bufLen - strLen) { return -1; } for (int64 i = startOffset; i <= bufLen - strLen; i++) { if (memcmp (buf + i, str, strLen) == 0) return i; } return -1; } // Returns TRUE if the file or directory exists (both may be enclosed in quotation marks). BOOL FileExists (const char *filePathPtr) { char filePath [TC_MAX_PATH * 2 + 1]; // Strip quotation marks (if any) if (filePathPtr [0] == '"') { StringCbCopyA (filePath, sizeof(filePath), filePathPtr + 1); } else { StringCbCopyA (filePath, sizeof(filePath), filePathPtr); } // Strip quotation marks (if any) if (filePath [strlen (filePath) - 1] == '"') filePath [strlen (filePath) - 1] = 0; return (_access (filePath, 0) != -1); } // Searches the file from its end for the LAST occurrence of the string str. // The string may contain zeroes, which do NOT terminate the string. // If the string is found, its offset from the start of the file is returned. // If the string isn't found or if any error occurs, -1 is returned. __int64 FindStringInFile (const char *filePath, const char* str, int strLen) { int bufSize = 64 * BYTES_PER_KB; char *buffer = (char *) err_malloc (bufSize); HANDLE src = NULL; DWORD bytesRead; BOOL readRetVal; __int64 filePos = GetFileSize64 (filePath); int bufPos = 0; LARGE_INTEGER seekOffset, seekOffsetNew; BOOL bExit = FALSE; int filePosStep; __int64 retVal = -1; if (filePos <= 0 || buffer == NULL || strLen > bufSize || strLen < 1) { if (buffer) free (buffer); return -1; } src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (src == INVALID_HANDLE_VALUE) { free (buffer); return -1; } filePosStep = bufSize - strLen + 1; do { filePos -= filePosStep; if (filePos < 0) { filePos = 0; bExit = TRUE; } seekOffset.QuadPart = filePos; if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0) goto fsif_end; if ((readRetVal = ReadFile (src, buffer, bufSize, &bytesRead, NULL)) == 0 || bytesRead == 0) goto fsif_end; bufPos = bytesRead - strLen; while (bufPos > 0) { if (memcmp (buffer + bufPos, str, strLen) == 0) { // String found retVal = filePos + bufPos; goto fsif_end; } bufPos--; } } while (!bExit); fsif_end: CloseHandle (src); free (buffer); return retVal; } // System CopyFile() copies source file attributes (like FILE_ATTRIBUTE_ENCRYPTED) // so we need to use our own copy function BOOL TCCopyFile (char *sourceFileName, char *destinationFile) { __int8 *buffer; HANDLE src, dst; FILETIME fileTime; DWORD bytesRead, bytesWritten; BOOL res; src = CreateFile (sourceFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (src == INVALID_HANDLE_VALUE) return FALSE; dst = CreateFile (destinationFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (dst == INVALID_HANDLE_VALUE) { CloseHandle (src); return FALSE; } buffer = (char *) malloc (64 * 1024); if (!buffer) { CloseHandle (src); CloseHandle (dst); return FALSE; } while (res = ReadFile (src, buffer, 64 * 1024, &bytesRead, NULL)) { if (bytesRead == 0) { res = 1; break; } if (!WriteFile (dst, buffer, bytesRead, &bytesWritten, NULL) || bytesRead != bytesWritten) { res = 0; break; } } GetFileTime (src, NULL, NULL, &fileTime); SetFileTime (dst, NULL, NULL, &fileTime); CloseHandle (src); CloseHandle (dst); free (buffer); return res != 0; } // If bAppend is TRUE, the buffer is appended to an existing file. If bAppend is FALSE, any existing file // is replaced. If an error occurs, the incomplete file is deleted (provided that bAppend is FALSE). BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend) { HANDLE dst; DWORD bytesWritten; BOOL res = TRUE; dst = CreateFile (destinationFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL); if (dst == INVALID_HANDLE_VALUE) { handleWin32Error (MainDlg); return FALSE; } if (bAppend) SetFilePointer (dst, 0, NULL, FILE_END); if (!WriteFile (dst, inputBuffer, inputLength, &bytesWritten, NULL) || inputLength != bytesWritten) { res = FALSE; } if (!res) { // If CREATE_ALWAYS is used, ERROR_ALREADY_EXISTS is returned after successful overwrite // of an existing file (it's not an error) if (! (GetLastError() == ERROR_ALREADY_EXISTS && !bAppend) ) handleWin32Error (MainDlg); } CloseHandle (dst); if (!res && !bAppend) remove (destinationFile); return res; } // Proper flush for Windows systems. Returns TRUE if successful. BOOL TCFlushFile (FILE *f) { HANDLE hf = (HANDLE) _get_osfhandle (_fileno (f)); fflush (f); if (hf == INVALID_HANDLE_VALUE) return FALSE; return FlushFileBuffers (hf) != 0; } // Prints a UTF-16 text (note that this involves a real printer, not a screen). // textByteLen - length of the text in bytes // title - printed as part of the page header and used as the filename for a temporary file BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, int textByteLen) { char cl [MAX_PATH*3] = {"/p \""}; char path [MAX_PATH * 2] = { 0 }; char filename [MAX_PATH + 1] = { 0 }; StringCbCopyA (filename, sizeof(filename), title); //strcat (filename, ".txt"); GetTempPath (sizeof (path), path); if (!FileExists (path)) { StringCbCopyA (path, sizeof(path), GetConfigPath (filename)); if (strlen(path) < 2) return FALSE; } else { StringCbCatA (path, sizeof(path), filename); } // Write the Unicode signature if (!SaveBufferToFile ("\xFF\xFE", path, 2, FALSE)) { remove (path); return FALSE; } // Write the actual text if (!SaveBufferToFile ((char *) text, path, textByteLen, TRUE)) { remove (path); return FALSE; } StringCbCatA (cl, sizeof(cl), path); StringCbCatA (cl, sizeof(cl), "\""); // Get the absolute path for notepad if (GetWindowsDirectory(filename, MAX_PATH)) { if (filename[strlen (filename) - 1] != '\\') StringCbCatA (filename, sizeof(filename), "\\"); StringCbCatA(filename, sizeof(filename), PRINT_TOOL); } else StringCbCopyA(filename, sizeof(filename), "C:\\Windows\\" PRINT_TOOL); WaitCursor (); ShellExecute (NULL, "open", filename, cl, NULL, SW_HIDE); Sleep (6000); NormalCursor(); remove (path); return TRUE; } BOOL IsNonInstallMode () { HKEY hkey; DWORD dw; if (bPortableModeConfirmed) return TRUE; if (hDriver != INVALID_HANDLE_VALUE) { // The driver is running if (DeviceIoControl (hDriver, TC_IOCTL_GET_PORTABLE_MODE_STATUS, NULL, 0, NULL, 0, &dw, 0)) { bPortableModeConfirmed = TRUE; return TRUE; } else { // This is also returned if we fail to determine the status (it does not mean that portable mode is disproved). return FALSE; } } else { // The tests in this block are necessary because this function is in some cases called before DriverAttach(). HANDLE hDriverTmp = CreateFile (WIN32_ROOT_PREFIX, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDriverTmp == INVALID_HANDLE_VALUE) { // The driver was not found in the system path char path[MAX_PATH * 2] = { 0 }; // We can't use GetConfigPath() here because it would call us back (indirect recursion) if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path))) { StringCbCatA (path, MAX_PATH * 2, "\\VeraCrypt\\"); StringCbCatA (path, MAX_PATH * 2, TC_APPD_FILENAME_SYSTEM_ENCRYPTION); if (FileExists (path)) { // To maintain consistency and safety, if the system encryption config file exits, we cannot // allow portable mode. (This happens e.g. when the pretest fails and the user selects // "Last Known Good Configuration" from the Windows boot menu.) // However, if UAC elevation is needed, we have to confirm portable mode first (after we are elevated, we won't). if (!IsAdmin () && IsUacSupported ()) return TRUE; return FALSE; } } // As the driver was not found in the system path, we can predict that we will run in portable mode return TRUE; } else CloseHandle (hDriverTmp); } // The following test may be unreliable in some cases (e.g. after the user selects restore "Last Known Good // Configuration" from the Windows boot menu). if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { RegCloseKey (hkey); return FALSE; } else return TRUE; } LRESULT SetCheckBox (HWND hwndDlg, int dlgItem, BOOL state) { return SendDlgItemMessage (hwndDlg, dlgItem, BM_SETCHECK, state ? BST_CHECKED : BST_UNCHECKED, 0); } BOOL GetCheckBox (HWND hwndDlg, int dlgItem) { return IsButtonChecked (GetDlgItem (hwndDlg, dlgItem)); } // Scroll the listview vertically so that the item with index of topMostVisibleItem is the topmost visible item. void SetListScrollHPos (HWND hList, int topMostVisibleItem) { int testedPos = 0; do { SendMessage (hList, LVM_SCROLL, 0, testedPos); } while (ListView_GetTopIndex (hList) < topMostVisibleItem && ++testedPos < 10000); } // Adds or removes TrueCrypt.exe to/from the system startup sequence (with appropriate command line arguments) void ManageStartupSeq (void) { if (!IsNonInstallMode ()) { char regk [64]; GetStartupRegKeyName (regk, sizeof(regk)); if (bStartOnLogon || bMountDevicesOnLogon || bMountFavoritesOnLogon) { char exe[MAX_PATH * 2] = { '"' }; GetModuleFileName (NULL, exe + 1, sizeof (exe) - 1); #ifdef VOLFORMAT { char *tmp = NULL; if (tmp = strrchr (exe, '\\')) { *tmp = 0; StringCbCatA (exe, MAX_PATH * 2, "\\VeraCrypt.exe"); } } #endif StringCbCatA (exe, MAX_PATH * 2, "\" /q preferences /a logon"); if (bMountDevicesOnLogon) StringCbCatA (exe, MAX_PATH * 2, " /a devices"); if (bMountFavoritesOnLogon) StringCbCatA (exe, MAX_PATH * 2, " /a favorites"); WriteRegistryString (regk, "VeraCrypt", exe); } else DeleteRegistryValue (regk, "VeraCrypt"); } } // Adds or removes the VeraCrypt Volume Creation Wizard to/from the system startup sequence void ManageStartupSeqWiz (BOOL bRemove, const char *arg) { char regk [64]; GetStartupRegKeyName (regk, sizeof(regk)); if (!bRemove) { size_t exeSize = (MAX_PATH * 2) + 3 + 20 + strlen (arg); // enough room for all concatenation operations char* exe = (char*) calloc(1, exeSize); exe[0] = '"'; GetModuleFileName (NULL, exe + 1, (DWORD) (exeSize - 1)); #ifndef VOLFORMAT { char *tmp = NULL; if (tmp = strrchr (exe, '\\')) { *tmp = 0; StringCbCatA (exe, exeSize, "\\VeraCrypt Format.exe"); } } #endif if (strlen (arg) > 0) { StringCbCatA (exe, exeSize, "\" "); StringCbCatA (exe, exeSize, arg); } WriteRegistryString (regk, "VeraCrypt Format", exe); free(exe); } else DeleteRegistryValue (regk, "VeraCrypt Format"); } // Delete the last used Windows file selector path for TrueCrypt from the registry void CleanLastVisitedMRU (void) { WCHAR exeFilename[MAX_PATH]; WCHAR *strToMatch; WCHAR strTmp[4096]; char regPath[128]; char key[64]; int id, len; GetModuleFileNameW (NULL, exeFilename, sizeof (exeFilename) / sizeof(exeFilename[0])); strToMatch = wcsrchr (exeFilename, '\\') + 1; StringCbPrintfA (regPath, sizeof(regPath), "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisited%sMRU", IsOSAtLeast (WIN_VISTA) ? "Pidl" : ""); for (id = (IsOSAtLeast (WIN_VISTA) ? 0 : 'a'); id <= (IsOSAtLeast (WIN_VISTA) ? 1000 : 'z'); id++) { *strTmp = 0; StringCbPrintfA (key, sizeof(key), (IsOSAtLeast (WIN_VISTA) ? "%d" : "%c"), id); if ((len = ReadRegistryBytes (regPath, key, (char *) strTmp, sizeof (strTmp))) > 0) { if (_wcsicmp (strTmp, strToMatch) == 0) { char buf[65536], bufout[sizeof (buf)]; // Overwrite the entry with zeroes while keeping its original size memset (strTmp, 0, len); if (!WriteRegistryBytes (regPath, key, (char *) strTmp, len)) MessageBoxW (NULL, GetString ("CLEAN_WINMRU_FAILED"), lpszTitle, ICON_HAND); DeleteRegistryValue (regPath, key); // Remove ID from MRUList if (IsOSAtLeast (WIN_VISTA)) { int *p = (int *)buf; int *pout = (int *)bufout; int l; l = len = ReadRegistryBytes ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", "MRUListEx", buf, sizeof (buf)); while (l > 0) { l -= sizeof (int); if (*p == id) { p++; len -= sizeof (int); continue; } *pout++ = *p++; } WriteRegistryBytes ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", "MRUListEx", bufout, len); } else { char *p = buf; char *pout = bufout; ReadRegistryString ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", "MRUList", "", buf, sizeof (buf)); while (*p) { if (*p == id) { p++; continue; } *pout++ = *p++; } *pout++ = 0; WriteRegistryString ("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", "MRUList", bufout); } break; } } } } #ifndef SETUP void ClearHistory (HWND hwndDlgItem) { ArrowWaitCursor (); ClearCombo (hwndDlgItem); DumpCombo (hwndDlgItem, TRUE); CleanLastVisitedMRU (); NormalCursor (); } #endif // #ifndef SETUP LRESULT ListItemAdd (HWND list, int index, char *string) { LVITEM li; memset (&li, 0, sizeof(li)); li.mask = LVIF_TEXT; li.pszText = string; li.iItem = index; li.iSubItem = 0; return ListView_InsertItem (list, &li); } LRESULT ListItemAddW (HWND list, int index, wchar_t *string) { LVITEMW li; memset (&li, 0, sizeof(li)); li.mask = LVIF_TEXT; li.pszText = string; li.iItem = index; li.iSubItem = 0; return SendMessageW (list, LVM_INSERTITEMW, 0, (LPARAM)(&li)); } LRESULT ListSubItemSet (HWND list, int index, int subIndex, char *string) { LVITEM li; memset (&li, 0, sizeof(li)); li.mask = LVIF_TEXT; li.pszText = string; li.iItem = index; li.iSubItem = subIndex; return ListView_SetItem (list, &li); } LRESULT ListSubItemSetW (HWND list, int index, int subIndex, wchar_t *string) { LVITEMW li; memset (&li, 0, sizeof(li)); li.mask = LVIF_TEXT; li.pszText = string; li.iItem = index; li.iSubItem = subIndex; return SendMessageW (list, LVM_SETITEMW, 0, (LPARAM)(&li)); } BOOL GetMountList (MOUNT_LIST_STRUCT *list) { DWORD dwResult; memset (list, 0, sizeof (*list)); return DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, list, sizeof (*list), list, sizeof (*list), &dwResult, NULL); } int GetDriverRefCount () { DWORD dwResult; BOOL bResult; int refCount; bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DEVICE_REFCOUNT, &refCount, sizeof (refCount), &refCount, sizeof (refCount), &dwResult, NULL); if (bResult) return refCount; else return -1; } // Loads a 32-bit integer from the file at the specified file offset. The saved value is assumed to have been // processed by mputLong(). The result is stored in *result. Returns TRUE if successful (otherwise FALSE). BOOL LoadInt32 (char *filePath, unsigned __int32 *result, __int64 fileOffset) { size_t bufSize = sizeof(__int32); unsigned char *buffer = (unsigned char *) malloc (bufSize); unsigned char *bufferPtr = buffer; HANDLE src = NULL; DWORD bytesRead; LARGE_INTEGER seekOffset, seekOffsetNew; BOOL retVal = FALSE; if (buffer == NULL) return -1; src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (src == INVALID_HANDLE_VALUE) { free (buffer); return FALSE; } seekOffset.QuadPart = fileOffset; if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0) goto fsif_end; if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0 || bytesRead != bufSize) goto fsif_end; retVal = TRUE; *result = mgetLong(bufferPtr); fsif_end: CloseHandle (src); free (buffer); return retVal; } // Loads a 16-bit integer from the file at the specified file offset. The saved value is assumed to have been // processed by mputWord(). The result is stored in *result. Returns TRUE if successful (otherwise FALSE). BOOL LoadInt16 (char *filePath, int *result, __int64 fileOffset) { size_t bufSize = sizeof(__int16); unsigned char *buffer = (unsigned char *) malloc (bufSize); unsigned char *bufferPtr = buffer; HANDLE src = NULL; DWORD bytesRead; LARGE_INTEGER seekOffset, seekOffsetNew; BOOL retVal = FALSE; if (buffer == NULL) return -1; src = CreateFile (filePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (src == INVALID_HANDLE_VALUE) { free (buffer); return FALSE; } seekOffset.QuadPart = fileOffset; if (SetFilePointerEx (src, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0) goto fsif_end; if (ReadFile (src, buffer, bufSize, &bytesRead, NULL) == 0 || bytesRead != bufSize) goto fsif_end; retVal = TRUE; *result = mgetWord(bufferPtr); fsif_end: CloseHandle (src); free (buffer); return retVal; } // Returns NULL if there's any error. Although the buffer can contain binary data, it is always null-terminated. char *LoadFile (const char *fileName, DWORD *size) { char *buf; DWORD fileSize = INVALID_FILE_SIZE; HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) return NULL; if ((fileSize = GetFileSize (h, NULL)) == INVALID_FILE_SIZE) { CloseHandle (h); return NULL; } *size = fileSize; buf = (char *) calloc (*size + 1, 1); if (buf == NULL) { CloseHandle (h); return NULL; } if (!ReadFile (h, buf, *size, size, NULL)) { free (buf); buf = NULL; } CloseHandle (h); return buf; } // Returns NULL if there's any error. char *LoadFileBlock (char *fileName, __int64 fileOffset, size_t count) { char *buf; DWORD bytesRead = 0; LARGE_INTEGER seekOffset, seekOffsetNew; HANDLE h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (h == INVALID_HANDLE_VALUE) return NULL; seekOffset.QuadPart = fileOffset; if (SetFilePointerEx (h, seekOffset, &seekOffsetNew, FILE_BEGIN) == 0) { CloseHandle (h); return NULL; } buf = (char *) calloc (count, 1); if (buf == NULL) { CloseHandle (h); return NULL; } ReadFile (h, buf, count, &bytesRead, NULL); CloseHandle (h); if (bytesRead != count) { free (buf); return NULL; } return buf; } // Returns -1 if there is an error, or the size of the file. __int64 GetFileSize64 (const char *path) { HANDLE h = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); LARGE_INTEGER size; __int64 retSize = -1; if (h) { if (GetFileSizeEx (h, &size)) { retSize = size.QuadPart; } CloseHandle (h); } return retSize; } char *GetModPath (char *path, int maxSize) { GetModuleFileName (NULL, path, maxSize); char* ptr = strrchr (path, '\\'); if (ptr) ptr[1] = 0; return path; } char *GetConfigPath (char *fileName) { static char path[MAX_PATH * 2] = { 0 }; if (IsNonInstallMode ()) { GetModPath (path, sizeof (path)); StringCbCatA (path, (MAX_PATH * 2), fileName); return path; } if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) { StringCbCatA (path, (MAX_PATH * 2), "\\VeraCrypt\\"); CreateDirectory (path, NULL); StringCbCatA (path, (MAX_PATH * 2), fileName); } else path[0] = 0; return path; } char *GetProgramConfigPath (char *fileName) { static char path[MAX_PATH * 2] = { 0 }; if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) { StringCbCatA (path, (MAX_PATH * 2), "\\VeraCrypt\\"); CreateDirectory (path, NULL); StringCbCatA (path, (MAX_PATH * 2), fileName); } else path[0] = 0; return path; } std::string GetServiceConfigPath (const char *fileName) { char sysPath[TC_MAX_PATH]; if (Is64BitOs()) { typedef UINT (WINAPI *GetSystemWow64Directory_t) (LPTSTR lpBuffer, UINT uSize); GetSystemWow64Directory_t getSystemWow64Directory = (GetSystemWow64Directory_t) GetProcAddress (GetModuleHandle ("kernel32"), "GetSystemWow64DirectoryA"); getSystemWow64Directory (sysPath, sizeof (sysPath)); } else GetSystemDirectory (sysPath, sizeof (sysPath)); return string (sysPath) + "\\" + fileName; } // Returns 0 if an error occurs or the drive letter (as an upper-case char) of the system partition (e.g. 'C'); char GetSystemDriveLetter (void) { char systemDir [MAX_PATH]; if (GetSystemDirectory (systemDir, sizeof (systemDir))) return (char) (toupper (systemDir [0])); else return 0; } void TaskBarIconDisplayBalloonTooltip (HWND hwnd, wchar_t *headline, wchar_t *text, BOOL warning) { if (nCurrentOS == WIN_2000) { MessageBoxW (MainDlg, text, headline, warning ? MB_ICONWARNING : MB_ICONINFORMATION); return; } NOTIFYICONDATAW tnid; ZeroMemory (&tnid, sizeof (tnid)); tnid.cbSize = sizeof (tnid); tnid.hWnd = hwnd; tnid.uID = IDI_TRUECRYPT_ICON; //tnid.uVersion = (IsOSAtLeast (WIN_VISTA) ? NOTIFYICON_VERSION_4 : NOTIFYICON_VERSION); //Shell_NotifyIconW (NIM_SETVERSION, &tnid); tnid.uFlags = NIF_INFO; tnid.dwInfoFlags = (warning ? NIIF_WARNING : NIIF_INFO); tnid.uTimeout = (IsOSAtLeast (WIN_VISTA) ? 1000 : 5000); // in ms StringCbCopyW (tnid.szInfoTitle, sizeof(tnid.szInfoTitle), headline); StringCbCopyW (tnid.szInfo, sizeof(tnid.szInfo),text); // Display the balloon tooltip quickly twice in a row to avoid the slow and unwanted "fade-in" phase Shell_NotifyIconW (NIM_MODIFY, &tnid); Shell_NotifyIconW (NIM_MODIFY, &tnid); } // Either of the pointers may be NULL void InfoBalloon (char *headingStringId, char *textStringId) { if (Silent) return; TaskBarIconDisplayBalloonTooltip (MainDlg, headingStringId == NULL ? L"VeraCrypt" : GetString (headingStringId), textStringId == NULL ? L" " : GetString (textStringId), FALSE); } // Either of the pointers may be NULL void InfoBalloonDirect (wchar_t *headingString, wchar_t *textString) { if (Silent) return; TaskBarIconDisplayBalloonTooltip (MainDlg, headingString == NULL ? L"VeraCrypt" : headingString, textString == NULL ? L" " : textString, FALSE); } // Either of the pointers may be NULL void WarningBalloon (char *headingStringId, char *textStringId) { if (Silent) return; TaskBarIconDisplayBalloonTooltip (MainDlg, headingStringId == NULL ? L"VeraCrypt" : GetString (headingStringId), textStringId == NULL ? L" " : GetString (textStringId), TRUE); } // Either of the pointers may be NULL void WarningBalloonDirect (wchar_t *headingString, wchar_t *textString) { if (Silent) return; TaskBarIconDisplayBalloonTooltip (MainDlg, headingString == NULL ? L"VeraCrypt" : headingString, textString == NULL ? L" " : textString, TRUE); } int Info (char *stringId) { if (Silent) return 0; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONINFORMATION); } int InfoTopMost (char *stringId) { if (Silent) return 0; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST); } int InfoDirect (const wchar_t *msg) { if (Silent) return 0; return MessageBoxW (MainDlg, msg, lpszTitle, MB_ICONINFORMATION); } int Warning (char *stringId) { if (Silent) return 0; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING); } int WarningTopMost (char *stringId) { if (Silent) return 0; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); } int WarningDirect (const wchar_t *warnMsg) { if (Silent) return 0; return MessageBoxW (MainDlg, warnMsg, lpszTitle, MB_ICONWARNING); } int Error (char *stringId) { if (Silent) return 0; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR); } int ErrorTopMost (char *stringId) { if (Silent) return 0; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); } int ErrorDirect (const wchar_t *errMsg) { if (Silent) return 0; return MessageBoxW (MainDlg, errMsg, lpszTitle, MB_ICONERROR); } int AskYesNo (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1); } int AskYesNoString (const wchar_t *str) { if (Silent) return IDNO; return MessageBoxW (MainDlg, str, lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1); } int AskYesNoTopmost (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1 | MB_SETFOREGROUND | MB_TOPMOST); } int AskNoYes (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2); } int AskOkCancel (char *stringId) { if (Silent) return IDCANCEL; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONQUESTION | MB_OKCANCEL | MB_DEFBUTTON1); } int AskWarnYesNo (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1); } int AskWarnYesNoString (const wchar_t *string) { if (Silent) return IDNO; return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1); } int AskWarnYesNoTopmost (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1 | MB_SETFOREGROUND | MB_TOPMOST); } int AskWarnYesNoStringTopmost (const wchar_t *string) { if (Silent) return IDNO; return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1 | MB_SETFOREGROUND | MB_TOPMOST); } int AskWarnNoYes (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2); } int AskWarnNoYesString (const wchar_t *string) { if (Silent) return IDNO; return MessageBoxW (MainDlg, string, lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2); } int AskWarnNoYesTopmost (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 | MB_SETFOREGROUND | MB_TOPMOST); } int AskWarnOkCancel (char *stringId) { if (Silent) return IDCANCEL; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON1); } int AskWarnCancelOk (char *stringId) { if (Silent) return IDCANCEL; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2); } int AskErrYesNo (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_YESNO | MB_DEFBUTTON1); } int AskErrNoYes (char *stringId) { if (Silent) return IDNO; return MessageBoxW (MainDlg, GetString (stringId), lpszTitle, MB_ICONERROR | MB_YESNO | MB_DEFBUTTON2); } // The function accepts two input formats: // Input format 1: {0, "MESSAGE_STRING_ID", "BUTTON_1_STRING_ID", ... "LAST_BUTTON_STRING_ID", 0}; // Input format 2: {L"", L"Message text", L"Button caption 1", ... L"Last button caption", 0}; // The second format is to be used if any of the strings contains format specification (e.g. %s, %d) or // in any other cases where a string needs to be resolved before calling this function. // If the returned value is 0, the user closed the dialog window without making a choice. // If the user made a choice, the returned value is the ordinal number of the choice (1..MAX_MULTI_CHOICES) int AskMultiChoice (void *strings[], BOOL bBold) { MULTI_CHOICE_DLGPROC_PARAMS params; params.strings = &strings[0]; params.bold = bBold; return DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_MULTI_CHOICE_DLG), MainDlg, (DLGPROC) MultiChoiceDialogProc, (LPARAM) ¶ms); } BOOL ConfigWriteBegin () { DWORD size; if (ConfigFileHandle != NULL) return FALSE; if (ConfigBuffer == NULL) ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size); ConfigFileHandle = fopen (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), "w"); if (ConfigFileHandle == NULL) { free (ConfigBuffer); ConfigBuffer = NULL; return FALSE; } XmlWriteHeader (ConfigFileHandle); fputs ("\n\t", ConfigFileHandle); return TRUE; } BOOL ConfigWriteEnd () { char *xml = ConfigBuffer; char key[128], value[2048]; if (ConfigFileHandle == NULL) return FALSE; // Write unmodified values while (xml && (xml = XmlFindElement (xml, "config"))) { XmlGetAttributeText (xml, "key", key, sizeof (key)); XmlGetNodeText (xml, value, sizeof (value)); fprintf (ConfigFileHandle, "\n\t\t%s", key, value); xml++; } fputs ("\n\t", ConfigFileHandle); XmlWriteFooter (ConfigFileHandle); TCFlushFile (ConfigFileHandle); CheckFileStreamWriteErrors (ConfigFileHandle, TC_APPD_FILENAME_CONFIGURATION); fclose (ConfigFileHandle); ConfigFileHandle = NULL; if (ConfigBuffer != NULL) { DWORD size; free (ConfigBuffer); ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size); } return TRUE; } BOOL ConfigWriteString (char *configKey, char *configValue) { char *c; if (ConfigFileHandle == NULL) return FALSE; // Mark previous config value as updated if (ConfigBuffer != NULL) { c = XmlFindElementByAttributeValue (ConfigBuffer, "config", "key", configKey); if (c != NULL) c[1] = '!'; } return 0 != fprintf ( ConfigFileHandle, "\n\t\t%s", configKey, configValue); } BOOL ConfigWriteInt (char *configKey, int configValue) { char val[32]; StringCbPrintfA (val, sizeof(val), "%d", configValue); return ConfigWriteString (configKey, val); } static BOOL ConfigRead (char *configKey, char *configValue, int maxValueSize) { DWORD size; char *xml; if (ConfigBuffer == NULL) ConfigBuffer = LoadFile (GetConfigPath (TC_APPD_FILENAME_CONFIGURATION), &size); xml = ConfigBuffer; if (xml != NULL) { xml = XmlFindElementByAttributeValue (xml, "config", "key", configKey); if (xml != NULL) { XmlGetNodeText (xml, configValue, maxValueSize); return TRUE; } } return FALSE; } int ConfigReadInt (char *configKey, int defaultValue) { char s[32]; if (ConfigRead (configKey, s, sizeof (s))) return atoi (s); else return defaultValue; } char *ConfigReadString (char *configKey, char *defaultValue, char *str, int maxLen) { if (ConfigRead (configKey, str, maxLen)) return str; else return defaultValue; } void OpenPageHelp (HWND hwndDlg, int nPage) { int r = (int)ShellExecute (NULL, "open", szHelpFile, NULL, NULL, SW_SHOWNORMAL); if (r == ERROR_FILE_NOT_FOUND) { // Try the secondary help file r = (int)ShellExecute (NULL, "open", szHelpFile2, NULL, NULL, SW_SHOWNORMAL); if (r == ERROR_FILE_NOT_FOUND) { OpenOnlineHelp (); return; } } if (r == SE_ERR_NOASSOC) { if (AskYesNo ("HELP_READER_ERROR") == IDYES) OpenOnlineHelp (); } } void OpenOnlineHelp () { Applink ("help", TRUE, ""); } #ifndef SETUP void RestoreDefaultKeyFilesParam (void) { KeyFileRemoveAll (&FirstKeyFile); if (defaultKeyFilesParam.FirstKeyFile != NULL) { FirstKeyFile = KeyFileCloneAll (defaultKeyFilesParam.FirstKeyFile); KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles; } else KeyFilesEnable = FALSE; } BOOL LoadDefaultKeyFilesParam (void) { BOOL status = TRUE; DWORD size; char *defaultKeyfilesFile = LoadFile (GetConfigPath (TC_APPD_FILENAME_DEFAULT_KEYFILES), &size); char *xml = defaultKeyfilesFile; KeyFile *kf; if (xml == NULL) return FALSE; KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); while (xml = XmlFindElement (xml, "keyfile")) { kf = (KeyFile *) malloc (sizeof (KeyFile)); if (kf) { if (XmlGetNodeText (xml, kf->FileName, sizeof (kf->FileName)) != NULL) defaultKeyFilesParam.FirstKeyFile = KeyFileAdd (defaultKeyFilesParam.FirstKeyFile, kf); else free (kf); } else { KeyFileRemoveAll (&defaultKeyFilesParam.FirstKeyFile); status = FALSE; break; } xml++; } free (defaultKeyfilesFile); if (status) KeyFilesEnable = defaultKeyFilesParam.EnableKeyFiles; return status; } #endif /* #ifndef SETUP */ void Debug (char *format, ...) { char buf[1024]; va_list val; va_start(val, format); StringCbVPrintfA (buf, sizeof (buf), format, val); va_end(val); OutputDebugString (buf); } void DebugMsgBox (char *format, ...) { char buf[1024]; va_list val; va_start(val, format); StringCbVPrintfA (buf, sizeof (buf), format, val); va_end(val); MessageBox (MainDlg, buf, "VeraCrypt debug", 0); } BOOL IsOSAtLeast (OSVersionEnum reqMinOS) { return IsOSVersionAtLeast (reqMinOS, 0); } // Returns TRUE if the operating system is at least reqMinOS and service pack at least reqMinServicePack. // Example 1: IsOSVersionAtLeast (WIN_VISTA, 1) called under Windows 2008, returns TRUE. // Example 2: IsOSVersionAtLeast (WIN_XP, 3) called under Windows XP SP1, returns FALSE. // Example 3: IsOSVersionAtLeast (WIN_XP, 3) called under Windows Vista SP1, returns TRUE. BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack) { /* When updating this function, update IsOSAtLeast() in Ntdriver.c too. */ if (CurrentOSMajor <= 0) TC_THROW_FATAL_EXCEPTION; int major = 0, minor = 0; switch (reqMinOS) { case WIN_2000: major = 5; minor = 0; break; case WIN_XP: major = 5; minor = 1; break; case WIN_SERVER_2003: major = 5; minor = 2; break; case WIN_VISTA: major = 6; minor = 0; break; case WIN_7: major = 6; minor = 1; break; default: TC_THROW_FATAL_EXCEPTION; break; } return ((CurrentOSMajor << 16 | CurrentOSMinor << 8 | CurrentOSServicePack) >= (major << 16 | minor << 8 | reqMinServicePack)); } BOOL Is64BitOs () { static BOOL isWow64 = FALSE; static BOOL valid = FALSE; typedef BOOL (__stdcall *LPFN_ISWOW64PROCESS ) (HANDLE hProcess,PBOOL Wow64Process); LPFN_ISWOW64PROCESS fnIsWow64Process; if (valid) return isWow64; fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle("kernel32"), "IsWow64Process"); if (fnIsWow64Process != NULL) if (!fnIsWow64Process (GetCurrentProcess(), &isWow64)) isWow64 = FALSE; valid = TRUE; return isWow64; } BOOL IsServerOS () { OSVERSIONINFOEXA osVer; osVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXA); GetVersionExA ((LPOSVERSIONINFOA) &osVer); return (osVer.wProductType == VER_NT_SERVER || osVer.wProductType == VER_NT_DOMAIN_CONTROLLER); } // Returns TRUE, if the currently running operating system is installed in a hidden volume. If it's not, or if // there's an error, returns FALSE. BOOL IsHiddenOSRunning (void) { static BOOL statusCached = FALSE; static BOOL hiddenOSRunning; if (!statusCached) { try { hiddenOSRunning = BootEncryption (MainDlg).IsHiddenSystemRunning(); } catch (...) { hiddenOSRunning = FALSE; } statusCached = TRUE; } return hiddenOSRunning; } BOOL EnableWow64FsRedirection (BOOL enable) { typedef BOOLEAN (__stdcall *Wow64EnableWow64FsRedirection_t) (BOOL enable); Wow64EnableWow64FsRedirection_t wow64EnableWow64FsRedirection = (Wow64EnableWow64FsRedirection_t) GetProcAddress (GetModuleHandle ("kernel32"), "Wow64EnableWow64FsRedirection"); if (!wow64EnableWow64FsRedirection) return FALSE; return wow64EnableWow64FsRedirection (enable); } BOOL RestartComputer (void) { TOKEN_PRIVILEGES tokenPrivil; HANDLE hTkn; if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hTkn)) { return false; } LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, &tokenPrivil.Privileges[0].Luid); tokenPrivil.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tokenPrivil.PrivilegeCount = 1; AdjustTokenPrivileges (hTkn, false, &tokenPrivil, 0, (PTOKEN_PRIVILEGES) NULL, 0); if (GetLastError() != ERROR_SUCCESS) { CloseHandle(hTkn); return false; } if (!ExitWindowsEx (EWX_REBOOT, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED)) { CloseHandle(hTkn); return false; } CloseHandle(hTkn); return true; } std::string GetWindowsEdition () { string osname = "win"; OSVERSIONINFOEXA osVer; osVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXA); GetVersionExA ((LPOSVERSIONINFOA) &osVer); BOOL home = (osVer.wSuiteMask & VER_SUITE_PERSONAL); BOOL server = (osVer.wProductType == VER_NT_SERVER || osVer.wProductType == VER_NT_DOMAIN_CONTROLLER); HKEY hkey; char productName[300] = {0}; DWORD productNameSize = sizeof (productName); if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) { if (RegQueryValueEx (hkey, "ProductName", 0, 0, (LPBYTE) &productName, &productNameSize) != ERROR_SUCCESS || productNameSize < 1) productName[0] = 0; RegCloseKey (hkey); } switch (nCurrentOS) { case WIN_2000: osname += "2000"; break; case WIN_XP: case WIN_XP64: osname += "xp"; osname += home ? "-home" : "-pro"; break; case WIN_SERVER_2003: osname += "2003"; break; case WIN_VISTA: osname += "vista"; break; case WIN_SERVER_2008: osname += "2008"; break; case WIN_7: osname += "7"; break; case WIN_SERVER_2008_R2: osname += "2008r2"; break; default: stringstream s; s << CurrentOSMajor << "." << CurrentOSMinor; osname += s.str(); break; } if (server) osname += "-server"; if (IsOSAtLeast (WIN_VISTA)) { if (home) osname += "-home"; else if (strstr (productName, "Standard") != 0) osname += "-standard"; else if (strstr (productName, "Professional") != 0) osname += "-pro"; else if (strstr (productName, "Business") != 0) osname += "-business"; else if (strstr (productName, "Enterprise") != 0) osname += "-enterprise"; else if (strstr (productName, "Datacenter") != 0) osname += "-datacenter"; else if (strstr (productName, "Ultimate") != 0) osname += "-ultimate"; } if (GetSystemMetrics (SM_STARTER)) osname += "-starter"; else if (strstr (productName, "Basic") != 0) osname += "-basic"; if (Is64BitOs()) osname += "-x64"; if (CurrentOSServicePack > 0) { stringstream s; s << "-sp" << CurrentOSServicePack; osname += s.str(); } return osname; } void Applink (char *dest, BOOL bSendOS, char *extraOutput) { char url [MAX_URL_LENGTH]; ArrowWaitCursor (); // sprintf_s (url, sizeof (url), TC_APPLINK "%s%s&dest=%s", bSendOS ? ("&os=" + GetWindowsEdition()).c_str() : "", extraOutput, dest); if (strcmp(dest, "donate") == 0) { StringCbCopyA (url, sizeof (url),"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5BCXVMTTNJDCY"); } else if (strcmp(dest, "main") == 0) { StringCbCopyA (url, sizeof (url),TC_HOMEPAGE); } else if (strcmp(dest,"localizations") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Language%20Packs"); } else if (strcmp(dest, "beginnerstutorial") == 0 || strcmp(dest,"tutorial") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Beginner%27s%20Tutorial"); } else if (strcmp(dest, "releasenotes") == 0 || strcmp(dest, "history") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Release%20Notes"); } else if (strcmp(dest, "hwacceleration") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Hardware%20Acceleration"); } else if (strcmp(dest, "parallelization") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Parallelization"); } else if (strcmp(dest, "help") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/documentation"); } else if (strcmp(dest, "keyfiles") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Keyfiles"); } else if (strcmp(dest, "introcontainer") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Creating%20New%20Volumes"); } else if (strcmp(dest, "introsysenc") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=System%20Encryption"); } else if (strcmp(dest, "hiddensysenc") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=VeraCrypt%20Hidden%20Operating%20System"); } else if (strcmp(dest, "sysencprogressinfo") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=System%20Encryption"); } else if (strcmp(dest, "hiddenvolume") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Hidden%20Volume"); } else if (strcmp(dest, "aes") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=AES"); } else if (strcmp(dest, "serpent") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Serpent"); } else if (strcmp(dest, "twofish") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Twofish"); } else if (strcmp(dest, "cascades") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Cascades"); } else if (strcmp(dest, "hashalgorithms") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Hash%20Algorithms"); } else if (strcmp(dest, "isoburning") == 0) { StringCbCopyA (url, sizeof (url),"https://cdburnerxp.se/en/home"); } else if (strcmp(dest, "sysfavorites") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=System%20Favorite%20Volumes"); } else if (strcmp(dest, "favorites") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Favorite%20Volumes"); } else if (strcmp(dest, "hiddenvolprotection") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Protection%20of%20Hidden%20Volumes"); } else if (strcmp(dest, "faq") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=FAQ"); } else if (strcmp(dest, "downloads") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Downloads"); } else if (strcmp(dest, "news") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=News"); } else if (strcmp(dest, "contact") == 0) { StringCbCopyA (url, sizeof (url),"https://veracrypt.codeplex.com/wikipage?title=Contact"); } else { StringCbCopyA (url, sizeof (url),TC_APPLINK); } ShellExecute (NULL, "open", url, NULL, NULL, SW_SHOWNORMAL); Sleep (200); NormalCursor (); } char *RelativePath2Absolute (char *szFileName) { if (szFileName[0] != '\\' && strchr (szFileName, ':') == 0 && strstr (szFileName, "Volume{") != szFileName) { char path[MAX_PATH*2]; GetCurrentDirectory (MAX_PATH, path); if (path[strlen (path) - 1] != '\\') StringCbCatA (path, (MAX_PATH * 2), "\\"); StringCbCatA (path, (MAX_PATH * 2), szFileName); StringCbCopyA (szFileName, MAX_PATH + 1, path); // szFileName size is always at least (MAX_PATH + 1) } return szFileName; } void HandleDriveNotReadyError () { HKEY hkey = 0; DWORD value = 0, size = sizeof (DWORD); if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\MountMgr", 0, KEY_READ, &hkey) != ERROR_SUCCESS) return; if (RegQueryValueEx (hkey, "NoAutoMount", 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS && value != 0) { Warning ("SYS_AUTOMOUNT_DISABLED"); } else if (nCurrentOS == WIN_VISTA && CurrentOSServicePack < 1) Warning ("SYS_ASSIGN_DRIVE_LETTER"); else Warning ("DEVICE_NOT_READY_ERROR"); RegCloseKey (hkey); } BOOL CALLBACK CloseTCWindowsEnum (HWND hwnd, LPARAM lParam) { LONG_PTR userDataVal = GetWindowLongPtr (hwnd, GWLP_USERDATA); if ((userDataVal == (LONG_PTR) 'VERA') || (userDataVal == (LONG_PTR) 'TRUE')) // Prior to 1.0e, 'TRUE' was used for VeraCrypt dialogs { char name[1024] = { 0 }; GetWindowText (hwnd, name, sizeof (name) - 1); if (hwnd != MainDlg && strstr (name, "VeraCrypt")) { PostMessage (hwnd, TC_APPMSG_CLOSE_BKG_TASK, 0, 0); PostMessage (hwnd, WM_CLOSE, 0, 0); if (lParam != 0) *((BOOL *)lParam) = TRUE; } } return TRUE; } BOOL CALLBACK FindTCWindowEnum (HWND hwnd, LPARAM lParam) { if (*(HWND *)lParam == hwnd) return TRUE; LONG_PTR userDataVal = GetWindowLongPtr (hwnd, GWLP_USERDATA); if ((userDataVal == (LONG_PTR) 'VERA') || (userDataVal == (LONG_PTR) 'TRUE')) // Prior to 1.0e, 'TRUE' was used for VeraCrypt dialogs { char name[32] = { 0 }; GetWindowText (hwnd, name, sizeof (name) - 1); if (hwnd != MainDlg && strcmp (name, "VeraCrypt") == 0) { if (lParam != 0) *((HWND *)lParam) = hwnd; } } return TRUE; } BYTE *MapResource (char *resourceType, int resourceId, PDWORD size) { HGLOBAL hResL; HRSRC hRes; hRes = FindResource (NULL, MAKEINTRESOURCE(resourceId), resourceType); hResL = LoadResource (NULL, hRes); if (size != NULL) *size = SizeofResource (NULL, hRes); return (BYTE *) LockResource (hResL); } void InconsistencyResolved (char *techInfo) { wchar_t finalMsg[8024]; StringCbPrintfW (finalMsg, sizeof(finalMsg), GetString ("INCONSISTENCY_RESOLVED"), techInfo); MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); } void ReportUnexpectedState (char *techInfo) { wchar_t finalMsg[8024]; StringCbPrintfW (finalMsg, sizeof(finalMsg), GetString ("UNEXPECTED_STATE"), techInfo); MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); } #ifndef SETUP int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader) { int status = ERR_PARAMETER_INCORRECT; int volumeType; char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; char szDosDevice[TC_MAX_PATH]; char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; LARGE_INTEGER headerOffset; DWORD dwResult; DISK_GEOMETRY deviceGeometry; context->VolumeIsOpen = FALSE; context->CryptoInfo = NULL; context->HostFileHandle = INVALID_HANDLE_VALUE; context->TimestampsValid = FALSE; CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), volumePath, &context->IsDevice); if (context->IsDevice) { status = FakeDosNameForDevice (szDiskFile, szDosDevice, sizeof(szDosDevice), szCFDevice, sizeof(szCFDevice), FALSE); if (status != 0) return status; preserveTimestamps = FALSE; if (!GetDriveGeometry (volumePath, &deviceGeometry)) { status = ERR_OS_ERROR; goto error; } } else StringCbCopyA (szCFDevice, sizeof(szCFDevice), szDiskFile); if (preserveTimestamps) write = TRUE; context->HostFileHandle = CreateFile (szCFDevice, GENERIC_READ | (write ? GENERIC_WRITE : 0), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (context->HostFileHandle == INVALID_HANDLE_VALUE) { status = ERR_OS_ERROR; goto error; } if (context->IsDevice) { // Try to gain "raw" access to the partition in case there is a live filesystem on it (otherwise, // the NTFS driver guards hidden sectors and prevents e.g. header backup restore after the user // accidentally quick-formats a dismounted partition-hosted TrueCrypt volume as NTFS, etc.) DeviceIoControl (context->HostFileHandle, FSCTL_ALLOW_EXTENDED_DASD_IO, NULL, 0, NULL, 0, &dwResult, NULL); } context->VolumeIsOpen = TRUE; // Remember the container modification/creation date and time if (!context->IsDevice && preserveTimestamps) { if (GetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime) == 0) context->TimestampsValid = FALSE; else context->TimestampsValid = TRUE; } // Determine host size if (context->IsDevice) { PARTITION_INFORMATION diskInfo; if (GetPartitionInfo (volumePath, &diskInfo)) { context->HostSize = diskInfo.PartitionLength.QuadPart; } else { DISK_GEOMETRY driveInfo; if (!DeviceIoControl (context->HostFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL)) { status = ERR_OS_ERROR; goto error; } context->HostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector * driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder; } if (context->HostSize == 0) { status = ERR_VOL_SIZE_WRONG; goto error; } } else { LARGE_INTEGER fileSize; if (!GetFileSizeEx (context->HostFileHandle, &fileSize)) { status = ERR_OS_ERROR; goto error; } context->HostSize = fileSize.QuadPart; } for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++) { // Seek the volume header switch (volumeType) { case TC_VOLUME_TYPE_NORMAL: headerOffset.QuadPart = useBackupHeader ? context->HostSize - TC_VOLUME_HEADER_GROUP_SIZE : TC_VOLUME_HEADER_OFFSET; break; case TC_VOLUME_TYPE_HIDDEN: if (TC_HIDDEN_VOLUME_HEADER_OFFSET + TC_VOLUME_HEADER_SIZE > context->HostSize) continue; headerOffset.QuadPart = useBackupHeader ? context->HostSize - TC_VOLUME_HEADER_SIZE : TC_HIDDEN_VOLUME_HEADER_OFFSET; break; case TC_VOLUME_TYPE_HIDDEN_LEGACY: if (useBackupHeader) { status = ERR_PASSWORD_WRONG; goto error; } if (context->IsDevice && deviceGeometry.BytesPerSector != TC_SECTOR_SIZE_LEGACY) continue; headerOffset.QuadPart = context->HostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY; break; } if (!SetFilePointerEx ((HANDLE) context->HostFileHandle, headerOffset, NULL, FILE_BEGIN)) { status = ERR_OS_ERROR; goto error; } // Read volume header DWORD bytesRead; if (!ReadEffectiveVolumeHeader (context->IsDevice, context->HostFileHandle, (byte *) buffer, &bytesRead)) { status = ERR_OS_ERROR; goto error; } if (bytesRead != sizeof (buffer) && context->IsDevice) { // If FSCTL_ALLOW_EXTENDED_DASD_IO failed and there is a live filesystem on the partition, then the // filesystem driver may report EOF when we are reading hidden sectors (when the filesystem is // shorter than the partition). This can happen for example after the user quick-formats a dismounted // partition-hosted TrueCrypt volume and then tries to read the embedded backup header. memset (buffer, 0, sizeof (buffer)); } // Decrypt volume header status = ReadVolumeHeader (FALSE, buffer, password, &context->CryptoInfo, NULL); if (status == ERR_PASSWORD_WRONG) continue; // Try next volume type break; } if (status == ERR_SUCCESS) return status; error: DWORD sysError = GetLastError (); CloseVolume (context); SetLastError (sysError); return status; } void CloseVolume (OpenVolumeContext *context) { if (!context->VolumeIsOpen) return; if (context->HostFileHandle != INVALID_HANDLE_VALUE) { if (context->TimestampsValid) SetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime); CloseHandle (context->HostFileHandle); context->HostFileHandle = INVALID_HANDLE_VALUE; } if (context->CryptoInfo) { crypto_close (context->CryptoInfo); context->CryptoInfo = NULL; } context->VolumeIsOpen = FALSE; } int ReEncryptVolumeHeader (char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, BOOL wipeMode) { CRYPTO_INFO *newCryptoInfo = NULL; RandSetHashFunction (cryptoInfo->pkcs5); if (Randinit() != ERR_SUCCESS) return ERR_PARAMETER_INCORRECT; UserEnrichRandomPool (NULL); int status = CreateVolumeHeaderInMemory (bBoot, buffer, cryptoInfo->ea, cryptoInfo->mode, password, cryptoInfo->pkcs5, (char *) cryptoInfo->master_keydata, &newCryptoInfo, cryptoInfo->VolumeSize.Value, cryptoInfo->hiddenVolume ? cryptoInfo->hiddenVolumeSize : 0, cryptoInfo->EncryptedAreaStart.Value, cryptoInfo->EncryptedAreaLength.Value, cryptoInfo->RequiredProgramVersion, cryptoInfo->HeaderFlags, cryptoInfo->SectorSize, wipeMode); if (newCryptoInfo != NULL) crypto_close (newCryptoInfo); return status; } #endif // !SETUP BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly) { // GlobalMemoryStatusEx() cannot be used to determine if a paging file is active char data[65536]; DWORD size = sizeof (data); if (IsPagingFileWildcardActive()) return TRUE; if (ReadLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", data, &size) && size > 12 && !checkNonWindowsPartitionsOnly) return TRUE; if (!IsAdmin()) AbortProcess ("UAC_INIT_ERROR"); for (char drive = 'C'; drive <= 'Z'; ++drive) { // Query geometry of the drive first to prevent "no medium" pop-ups string drivePath = "\\\\.\\X:"; drivePath[4] = drive; if (checkNonWindowsPartitionsOnly) { char sysDir[MAX_PATH]; if (GetSystemDirectory (sysDir, sizeof (sysDir)) != 0 && toupper (sysDir[0]) == drive) continue; } HANDLE handle = CreateFile (drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (handle == INVALID_HANDLE_VALUE) continue; DISK_GEOMETRY driveInfo; DWORD dwResult; if (!DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &driveInfo, sizeof (driveInfo), &dwResult, NULL)) { CloseHandle (handle); continue; } CloseHandle (handle); // Test if a paging file exists and is locked by another process string path = "X:\\pagefile.sys"; path[0] = drive; handle = CreateFile (path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (handle != INVALID_HANDLE_VALUE) CloseHandle (handle); else if (GetLastError() == ERROR_SHARING_VIOLATION) return TRUE; } return FALSE; } BOOL IsPagingFileWildcardActive () { char pagingFiles[65536]; DWORD size = sizeof (pagingFiles); char *mmKey = "System\\CurrentControlSet\\Control\\Session Manager\\Memory Management"; if (!ReadLocalMachineRegistryString (mmKey, "PagingFiles", pagingFiles, &size)) { size = sizeof (pagingFiles); if (!ReadLocalMachineRegistryMultiString (mmKey, "PagingFiles", pagingFiles, &size)) size = 0; } return size > 0 && strstr (pagingFiles, "?:\\") == pagingFiles; } BOOL DisablePagingFile () { char empty[] = { 0, 0 }; return WriteLocalMachineRegistryMultiString ("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", "PagingFiles", empty, sizeof (empty)); } std::wstring SingleStringToWide (const std::string &singleString) { if (singleString.empty()) return std::wstring(); WCHAR wbuf[65536]; int wideLen = MultiByteToWideChar (CP_ACP, 0, singleString.c_str(), -1, wbuf, array_capacity (wbuf) - 1); throw_sys_if (wideLen == 0); wbuf[wideLen] = 0; return wbuf; } std::wstring Utf8StringToWide (const std::string &utf8String) { if (utf8String.empty()) return std::wstring(); WCHAR wbuf[65536]; int wideLen = MultiByteToWideChar (CP_UTF8, 0, utf8String.c_str(), -1, wbuf, array_capacity (wbuf) - 1); throw_sys_if (wideLen == 0); wbuf[wideLen] = 0; return wbuf; } std::string WideToUtf8String (const std::wstring &wideString) { if (wideString.empty()) return std::string(); char buf[65536]; int len = WideCharToMultiByte (CP_UTF8, 0, wideString.c_str(), -1, buf, array_capacity (buf) - 1, NULL, NULL); throw_sys_if (len == 0); buf[len] = 0; return buf; } std::string WideToSingleString (const std::wstring &wideString) { if (wideString.empty()) return std::string(); char buf[65536]; int len = WideCharToMultiByte (CP_ACP, 0, wideString.c_str(), -1, buf, array_capacity (buf) - 1, NULL, NULL); throw_sys_if (len == 0); buf[len] = 0; return buf; } std::string StringToUpperCase (const std::string &str) { string upperCase (str); _strupr ((char *) upperCase.c_str()); return upperCase; } #ifndef SETUP BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { WORD lw = LOWORD (wParam); static string *password; switch (msg) { case WM_INITDIALOG: { password = (string *) lParam; LocalizeDialog (hwndDlg, "IDD_TOKEN_PASSWORD"); wchar_t s[1024]; StringCbPrintfW (s, sizeof(s), GetString ("ENTER_TOKEN_PASSWORD"), Utf8StringToWide (password->c_str()).c_str()); SetWindowTextW (GetDlgItem (hwndDlg, IDT_TOKEN_PASSWORD_INFO), s); SendMessage (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), EM_LIMITTEXT, SecurityToken::MaxPasswordLength, 0); SetForegroundWindow (hwndDlg); SetFocus (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD)); } return 0; case WM_COMMAND: if (lw == IDCANCEL || lw == IDOK) { if (lw == IDOK) { wchar_t passwordWide[SecurityToken::MaxPasswordLength + 1]; if (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), passwordWide, SecurityToken::MaxPasswordLength + 1) == 0) { handleWin32Error (hwndDlg); break; } char passwordUtf8[SecurityToken::MaxPasswordLength + 1]; int len = WideCharToMultiByte (CP_UTF8, 0, passwordWide, -1, passwordUtf8, array_capacity (passwordUtf8) - 1, nullptr, nullptr); passwordUtf8[len] = 0; *password = passwordUtf8; burn (passwordWide, sizeof (passwordWide)); burn (passwordUtf8, sizeof (passwordUtf8)); } // Attempt to wipe password stored in the input field buffer char tmp[SecurityToken::MaxPasswordLength+1]; memset (tmp, 'X', SecurityToken::MaxPasswordLength); tmp[SecurityToken::MaxPasswordLength] = 0; SetWindowText (GetDlgItem (hwndDlg, IDC_TOKEN_PASSWORD), tmp); EndDialog (hwndDlg, lw); } return 1; } return 0; } struct NewSecurityTokenKeyfileDlgProcParams { CK_SLOT_ID SlotId; string Name; }; static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static NewSecurityTokenKeyfileDlgProcParams *newParams; WORD lw = LOWORD (wParam); switch (msg) { case WM_INITDIALOG: { LocalizeDialog (hwndDlg, "IDD_NEW_TOKEN_KEYFILE"); newParams = (NewSecurityTokenKeyfileDlgProcParams *) lParam; WaitCursor(); finally_do ({ NormalCursor(); }); list tokens; try { tokens = SecurityToken::GetAvailableTokens(); } catch (Exception &e) { e.Show (hwndDlg); } if (tokens.empty()) { Error ("NO_TOKENS_FOUND"); EndDialog (hwndDlg, IDCANCEL); return 1; } foreach (const SecurityTokenInfo &token, tokens) { wstringstream tokenLabel; tokenLabel << L"[" << token.SlotId << L"] " << token.Label; AddComboPairW (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token.SlotId); } ComboBox_SetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), 0); SetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), Utf8StringToWide (newParams->Name).c_str()); return 1; } case WM_COMMAND: switch (lw) { case IDOK: { int selectedToken = ComboBox_GetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN)); if (selectedToken == CB_ERR) { EndDialog (hwndDlg, IDCANCEL); return 1; } newParams->SlotId = ComboBox_GetItemData (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), selectedToken); wchar_t name[1024]; if (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), name, array_capacity (name)) != 0) { try { newParams->Name = WideToUtf8String (name); } catch (...) { } } EndDialog (hwndDlg, IDOK); return 1; } case IDCANCEL: EndDialog (hwndDlg, IDCANCEL); return 1; } if (HIWORD (wParam) == EN_CHANGE) { wchar_t name[2]; EnableWindow (GetDlgItem (hwndDlg, IDOK), (GetWindowTextW (GetDlgItem (hwndDlg, IDC_TOKEN_KEYFILE_NAME), name, array_capacity (name)) != 0)); return 1; } } return 0; } static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector &keyfiles) { HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST); LVITEMW lvItem; int line = 0; ListView_DeleteAllItems (tokenListControl); foreach (const SecurityTokenKeyfile &keyfile, keyfiles) { memset (&lvItem, 0, sizeof(lvItem)); lvItem.mask = LVIF_TEXT; lvItem.iItem = line++; stringstream s; s << keyfile.SlotId; ListItemAdd (tokenListControl, lvItem.iItem, (char *) s.str().c_str()); ListSubItemSetW (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile.Token.Label.c_str()); ListSubItemSetW (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile.Id.c_str()); } BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1); EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected); EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected); } static list SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector &keyfiles) { HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST); list selectedKeyfiles; int itemId = -1; while ((itemId = ListView_GetNextItem (tokenListControl, itemId, LVIS_SELECTED)) != -1) { selectedKeyfiles.push_back (keyfiles[itemId]); } return selectedKeyfiles; } BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static list *selectedTokenKeyfiles; static vector keyfiles; WORD lw = LOWORD (wParam); switch (msg) { case WM_INITDIALOG: { selectedTokenKeyfiles = (list *) lParam; LVCOLUMNW LvCol; HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST); LocalizeDialog (hwndDlg, selectedTokenKeyfiles ? "SELECT_TOKEN_KEYFILES" : "IDD_TOKEN_KEYFILES"); SendMessage (tokenListControl,LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_TWOCLICKACTIVATE|LVS_EX_LABELTIP ); memset (&LvCol, 0, sizeof(LvCol)); LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT; LvCol.pszText = GetString ("TOKEN_SLOT_ID"); LvCol.cx = CompensateXDPI (40); LvCol.fmt = LVCFMT_CENTER; SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 1, (LPARAM)&LvCol); LvCol.pszText = GetString ("TOKEN_NAME"); LvCol.cx = CompensateXDPI (128); LvCol.fmt = LVCFMT_LEFT; SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 2, (LPARAM)&LvCol); LvCol.pszText = GetString ("TOKEN_DATA_OBJECT_LABEL"); LvCol.cx = CompensateXDPI (195); LvCol.fmt = LVCFMT_LEFT; SendMessage (tokenListControl, LVM_INSERTCOLUMNW, 3, (LPARAM)&LvCol); keyfiles.clear(); try { WaitCursor(); finally_do ({ NormalCursor(); }); keyfiles = SecurityToken::GetAvailableKeyfiles(); } catch (UserAbort&) { EndDialog (hwndDlg, IDCANCEL); return 1; } catch (Exception &e) { e.Show (hwndDlg); if (keyfiles.empty()) { EndDialog (hwndDlg, IDCANCEL); return 1; } } SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles); return 1; } case WM_COMMAND: case WM_NOTIFY: if (msg == WM_COMMAND && lw == IDOK || msg == WM_NOTIFY && ((NMHDR *)lParam)->code == LVN_ITEMACTIVATE) { if (selectedTokenKeyfiles) { foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) { selectedTokenKeyfiles->push_back (SecurityTokenKeyfilePath (keyfile)); } } EndDialog (hwndDlg, IDOK); return 1; } if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) { BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1); EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected); EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected); return 1; } switch (lw) { case IDCANCEL: EndDialog (hwndDlg, IDCANCEL); return 1; case IDC_IMPORT_KEYFILE: { char keyfilePath[TC_MAX_PATH]; if (BrowseFiles (hwndDlg, "SELECT_KEYFILE", keyfilePath, bHistory, FALSE, NULL)) { DWORD keyfileSize; byte *keyfileData = (byte *) LoadFile (keyfilePath, &keyfileSize); if (!keyfileData) { handleWin32Error (hwndDlg); return 1; } if (keyfileSize != 0) { NewSecurityTokenKeyfileDlgProcParams newParams; newParams.Name = WideToUtf8String (SingleStringToWide (keyfilePath)); size_t lastBackSlash = newParams.Name.find_last_of ('\\'); if (lastBackSlash != string::npos) newParams.Name = newParams.Name.substr (lastBackSlash + 1); if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_NEW_TOKEN_KEYFILE), hwndDlg, (DLGPROC) NewSecurityTokenKeyfileDlgProc, (LPARAM) &newParams) == IDOK) { vector keyfileDataVector (keyfileSize); memcpy (&keyfileDataVector.front(), keyfileData, keyfileSize); try { WaitCursor(); finally_do ({ NormalCursor(); }); SecurityToken::CreateKeyfile (newParams.SlotId, keyfileDataVector, newParams.Name); keyfiles = SecurityToken::GetAvailableKeyfiles(); SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles); } catch (Exception &e) { e.Show (hwndDlg); } burn (&keyfileDataVector.front(), keyfileSize); } } else { SetLastError (ERROR_HANDLE_EOF); handleWin32Error (hwndDlg); } burn (keyfileData, keyfileSize); TCfree (keyfileData); } return 1; } case IDC_EXPORT: { try { foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) { char keyfilePath[TC_MAX_PATH]; if (!BrowseFiles (hwndDlg, "OPEN_TITLE", keyfilePath, bHistory, TRUE, NULL)) break; { WaitCursor(); finally_do ({ NormalCursor(); }); vector keyfileData; SecurityToken::GetKeyfileData (keyfile, keyfileData); if (keyfileData.empty()) { SetLastError (ERROR_HANDLE_EOF); handleWin32Error (hwndDlg); return 1; } finally_do_arg (vector *, &keyfileData, { burn (&finally_arg->front(), finally_arg->size()); }); if (!SaveBufferToFile ((char *) &keyfileData.front(), keyfilePath, keyfileData.size(), FALSE)) throw SystemException (); } Info ("KEYFILE_EXPORTED"); } } catch (Exception &e) { e.Show (hwndDlg); } return 1; } case IDC_DELETE: { if (AskNoYes ("CONFIRM_SEL_FILES_DELETE") == IDNO) return 1; try { WaitCursor(); finally_do ({ NormalCursor(); }); foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles)) { SecurityToken::DeleteKeyfile (keyfile); } keyfiles = SecurityToken::GetAvailableKeyfiles(); SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles); } catch (Exception &e) { e.Show (hwndDlg); } return 1; } } return 0; } return 0; } BOOL InitSecurityTokenLibrary () { if (SecurityTokenLibraryPath[0] == 0) { Error ("NO_PKCS11_MODULE_SPECIFIED"); return FALSE; } struct PinRequestHandler : public GetPinFunctor { virtual void operator() (string &str) { if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_PASSWORD), MainDlg, (DLGPROC) SecurityTokenPasswordDlgProc, (LPARAM) &str) == IDCANCEL) throw UserAbort (SRC_POS); if (hCursor != NULL) SetCursor (hCursor); } }; struct WarningHandler : public SendExceptionFunctor { virtual void operator() (const Exception &e) { e.Show (NULL); } }; try { SecurityToken::InitLibrary (SecurityTokenLibraryPath, auto_ptr (new PinRequestHandler), auto_ptr (new WarningHandler)); } catch (Exception &e) { e.Show (NULL); Error ("PKCS11_MODULE_INIT_FAILED"); return FALSE; } return TRUE; } #endif // !SETUP std::vector GetAvailableHostDevices (bool noDeviceProperties, bool singleList, bool noFloppy, bool detectUnencryptedFilesystems) { vector devices; size_t dev0; for (int devNumber = 0; devNumber < MAX_HOST_DRIVE_NUMBER; devNumber++) { for (int partNumber = 0; partNumber < MAX_HOST_PARTITION_NUMBER; partNumber++) { stringstream strm; strm << "\\Device\\Harddisk" << devNumber << "\\Partition" << partNumber; string devPathStr (strm.str()); const char *devPath = devPathStr.c_str(); OPEN_TEST_STRUCT openTest; if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems && partNumber != 0)) { if (partNumber == 0) break; continue; } HostDevice device; device.SystemNumber = devNumber; device.Path = devPath; PARTITION_INFORMATION partInfo; if (GetPartitionInfo (devPath, &partInfo)) { device.Bootable = partInfo.BootIndicator ? true : false; device.Size = partInfo.PartitionLength.QuadPart; } device.HasUnencryptedFilesystem = (detectUnencryptedFilesystems && openTest.FilesystemDetected) ? true : false; if (!noDeviceProperties) { DISK_GEOMETRY geometry; wstringstream ws; ws << devPathStr.c_str(); int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str()); if (driveNumber >= 0) { device.MountPoint += (char) (driveNumber + 'A'); device.MountPoint += ":"; wchar_t name[64]; if (GetDriveLabel (driveNumber, name, sizeof (name))) device.Name = name; if (GetSystemDriveLetter() == 'A' + driveNumber) device.ContainsSystem = true; } if (partNumber == 0 && GetDriveGeometry (devPath, &geometry)) device.Removable = (geometry.MediaType == RemovableMedia); } if (partNumber == 0) { devices.push_back (device); dev0 = devices.size() - 1; } else { // System creates a virtual partition1 for some storage devices without // partition table. We try to detect this case by comparing sizes of // partition0 and partition1. If they match, no partition of the device // is displayed to the user to avoid confusion. Drive letter assigned by // system to partition1 is assigned partition0 if (partNumber == 1 && devices[dev0].Size == device.Size) { devices[dev0].IsVirtualPartition = true; devices[dev0].MountPoint = device.MountPoint; devices[dev0].Name = device.Name; devices[dev0].Path = device.Path; devices[dev0].HasUnencryptedFilesystem = device.HasUnencryptedFilesystem; break; } device.IsPartition = true; device.SystemNumber = partNumber; device.Removable = devices[dev0].Removable; if (device.ContainsSystem) devices[dev0].ContainsSystem = true; if (singleList) devices.push_back (device); devices[dev0].Partitions.push_back (device); } } } // Vista does not create partition links for dynamic volumes so it is necessary to scan \\Device\\HarddiskVolumeX devices if (CurrentOSMajor >= 6) { for (int devNumber = 0; devNumber < 256; devNumber++) { stringstream strm; strm << "\\Device\\HarddiskVolume" << devNumber; string devPathStr (strm.str()); const char *devPath = devPathStr.c_str(); OPEN_TEST_STRUCT openTest; if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems)) continue; DISK_PARTITION_INFO_STRUCT info; if (GetDeviceInfo (devPath, &info) && info.IsDynamic) { HostDevice device; device.DynamicVolume = true; device.IsPartition = true; device.SystemNumber = devNumber; device.Path = devPath; device.Size = info.partInfo.PartitionLength.QuadPart; device.HasUnencryptedFilesystem = (detectUnencryptedFilesystems && openTest.FilesystemDetected) ? true : false; if (!noDeviceProperties) { wstringstream ws; ws << devPathStr.c_str(); int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) ws.str().c_str()); if (driveNumber >= 0) { device.MountPoint += (char) (driveNumber + 'A'); device.MountPoint += ":"; wchar_t name[64]; if (GetDriveLabel (driveNumber, name, sizeof (name))) device.Name = name; if (GetSystemDriveLetter() == 'A' + driveNumber) device.ContainsSystem = true; } } devices.push_back (device); } } } return devices; } BOOL FileHasReadOnlyAttribute (const char *path) { DWORD attributes = GetFileAttributes (path); return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_READONLY) != 0; } BOOL IsFileOnReadOnlyFilesystem (const char *path) { char root[MAX_PATH]; if (!GetVolumePathName (path, root, sizeof (root))) return FALSE; DWORD flags, d; if (!GetVolumeInformation (root, NULL, 0, NULL, &d, &flags, NULL, 0)) return FALSE; return (flags & FILE_READ_ONLY_VOLUME) ? TRUE : FALSE; } void CheckFilesystem (int driveNo, BOOL fixErrors) { wchar_t msg[1024], param[1024], cmdPath[MAX_PATH]; char driveRoot[] = { 'A' + (char) driveNo, ':', 0 }; if (fixErrors && AskWarnYesNo ("FILESYS_REPAIR_CONFIRM_BACKUP") == IDNO) return; StringCbPrintfW (msg, sizeof(msg), GetString (fixErrors ? "REPAIRING_FS" : "CHECKING_FS"), driveRoot); StringCbPrintfW (param, sizeof(param), fixErrors ? L"/C echo %s & chkdsk %hs /F /X & pause" : L"/C echo %s & chkdsk %hs & pause", msg, driveRoot); if (GetSystemDirectoryW(cmdPath, MAX_PATH)) { StringCbCatW(cmdPath, sizeof(cmdPath), L"\\cmd.exe"); } else StringCbCopyW(cmdPath, sizeof(cmdPath), L"C:\\Windows\\System32\\cmd.exe"); ShellExecuteW (NULL, (!IsAdmin() && IsUacSupported()) ? L"runas" : L"open", cmdPath, param, NULL, SW_SHOW); } BOOL BufferContainsString (const byte *buffer, size_t bufferSize, const char *str) { size_t strLen = strlen (str); if (bufferSize < strLen) return FALSE; bufferSize -= strLen; for (size_t i = 0; i < bufferSize; ++i) { if (memcmp (buffer + i, str, strLen) == 0) return TRUE; } return FALSE; } #ifndef SETUP int AskNonSysInPlaceEncryptionResume () { if (AskWarnYesNo ("NONSYS_INPLACE_ENC_RESUME_PROMPT") == IDYES) return IDYES; char *multiChoiceStr[] = { 0, "ASK_NONSYS_INPLACE_ENC_NOTIFICATION_REMOVAL", "DO_NOT_PROMPT_ME", "KEEP_PROMPTING_ME", 0 }; switch (AskMultiChoice ((void **) multiChoiceStr, FALSE)) { case 1: RemoveNonSysInPlaceEncNotifications(); Warning ("NONSYS_INPLACE_ENC_NOTIFICATION_REMOVAL_NOTE"); break; default: // NOP break; } return IDNO; } #endif // !SETUP BOOL RemoveDeviceWriteProtection (HWND hwndDlg, char *devicePath) { int driveNumber; int partitionNumber; char temp[MAX_PATH*2]; char cmdBatch[MAX_PATH*2]; char diskpartScript[MAX_PATH*2]; if (sscanf (devicePath, "\\Device\\Harddisk%d\\Partition%d", &driveNumber, &partitionNumber) != 2) return FALSE; if (GetTempPath (sizeof (temp), temp) == 0) return FALSE; StringCbPrintfA (cmdBatch, sizeof (cmdBatch), "%s\\VeraCrypt_Write_Protection_Removal.cmd", temp); StringCbPrintfA (diskpartScript, sizeof (diskpartScript), "%s\\VeraCrypt_Write_Protection_Removal.diskpart", temp); FILE *f = fopen (cmdBatch, "w"); if (!f) { handleWin32Error (hwndDlg); return FALSE; } fprintf (f, "@diskpart /s \"%s\"\n@pause\n@del \"%s\" \"%s\"", diskpartScript, diskpartScript, cmdBatch); CheckFileStreamWriteErrors (f, cmdBatch); fclose (f); f = fopen (diskpartScript, "w"); if (!f) { handleWin32Error (hwndDlg); DeleteFile (cmdBatch); return FALSE; } fprintf (f, "select disk %d\nattributes disk clear readonly\n", driveNumber); if (partitionNumber != 0) fprintf (f, "select partition %d\nattributes volume clear readonly\n", partitionNumber); fprintf (f, "exit\n"); CheckFileStreamWriteErrors (f, diskpartScript); fclose (f); ShellExecute (NULL, (!IsAdmin() && IsUacSupported()) ? "runas" : "open", cmdBatch, NULL, NULL, SW_SHOW); return TRUE; } static LRESULT CALLBACK EnableElevatedCursorChangeWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { return DefWindowProc (hWnd, message, wParam, lParam); } void EnableElevatedCursorChange (HWND parent) { // Create a transparent window to work around a UAC issue preventing change of the cursor if (UacElevated) { const char *className = "VeraCryptEnableElevatedCursorChange"; WNDCLASSEX winClass; HWND hWnd; memset (&winClass, 0, sizeof (winClass)); winClass.cbSize = sizeof (WNDCLASSEX); winClass.lpfnWndProc = (WNDPROC) EnableElevatedCursorChangeWndProc; winClass.hInstance = hInst; winClass.lpszClassName = className; RegisterClassEx (&winClass); hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_LAYERED, className, "VeraCrypt UAC", 0, 0, 0, GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN), parent, NULL, hInst, NULL); if (hWnd) { SetLayeredWindowAttributes (hWnd, 0, 1, LWA_ALPHA); ShowWindow (hWnd, SW_SHOWNORMAL); DestroyWindow (hWnd); } UnregisterClass (className, hInst); } } BOOL DisableFileCompression (HANDLE file) { USHORT format; DWORD bytesOut; if (!DeviceIoControl (file, FSCTL_GET_COMPRESSION, NULL, 0, &format, sizeof (format), &bytesOut, NULL)) return FALSE; if (format == COMPRESSION_FORMAT_NONE) return TRUE; format = COMPRESSION_FORMAT_NONE; return DeviceIoControl (file, FSCTL_SET_COMPRESSION, &format, sizeof (format), NULL, 0, &bytesOut, NULL); } BOOL VolumePathExists (const char *volumePath) { OPEN_TEST_STRUCT openTest; char upperCasePath[TC_MAX_PATH + 1]; UpperCaseCopy (upperCasePath, sizeof(upperCasePath), volumePath); if (strstr (upperCasePath, "\\DEVICE\\") == upperCasePath) return OpenDevice (volumePath, &openTest, FALSE); string path = volumePath; if (path.find ("\\\\?\\Volume{") == 0 && path.rfind ("}\\") == path.size() - 2) { char devicePath[TC_MAX_PATH]; if (QueryDosDevice (path.substr (4, path.size() - 5).c_str(), devicePath, TC_MAX_PATH) != 0) return TRUE; } return _access (volumePath, 0) == 0; } BOOL IsWindowsIsoBurnerAvailable () { char path[MAX_PATH*2] = { 0 }; if (!IsOSAtLeast (WIN_7)) { return FALSE; } if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_SYSTEM, NULL, 0, path))) { StringCbCatA (path, MAX_PATH*2, "\\" ISO_BURNER_TOOL); return (FileExists (path)); } return FALSE; } BOOL LaunchWindowsIsoBurner (HWND hwnd, const char *isoPath) { char path[MAX_PATH*2] = { 0 }; int r; if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_SYSTEM, NULL, 0, path))) StringCbCatA (path, MAX_PATH*2, "\\" ISO_BURNER_TOOL); else StringCbCopyA (path, MAX_PATH*2, "C:\\Windows\\System32\\" ISO_BURNER_TOOL); r = (int) ShellExecute (hwnd, "open", path, (string ("\"") + isoPath + "\"").c_str(), NULL, SW_SHOWNORMAL); if (r <= 32) { SetLastError (r); handleWin32Error (hwnd); return FALSE; } return TRUE; } std::string VolumeGuidPathToDevicePath (std::string volumeGuidPath) { if (volumeGuidPath.find ("\\\\?\\") == 0) volumeGuidPath = volumeGuidPath.substr (4); if (volumeGuidPath.find ("Volume{") != 0 || volumeGuidPath.rfind ("}\\") != volumeGuidPath.size() - 2) return string(); char volDevPath[TC_MAX_PATH]; if (QueryDosDevice (volumeGuidPath.substr (0, volumeGuidPath.size() - 1).c_str(), volDevPath, TC_MAX_PATH) == 0) return string(); string partitionPath = HarddiskVolumePathToPartitionPath (volDevPath); return partitionPath.empty() ? volDevPath : partitionPath; } std::string HarddiskVolumePathToPartitionPath (const std::string &harddiskVolumePath) { wstring volPath = SingleStringToWide (harddiskVolumePath); for (int driveNumber = 0; driveNumber < MAX_HOST_DRIVE_NUMBER; driveNumber++) { for (int partNumber = 0; partNumber < MAX_HOST_PARTITION_NUMBER; partNumber++) { wchar_t partitionPath[TC_MAX_PATH]; swprintf_s (partitionPath, ARRAYSIZE (partitionPath), L"\\Device\\Harddisk%d\\Partition%d", driveNumber, partNumber); wchar_t resolvedPath[TC_MAX_PATH]; if (ResolveSymbolicLink (partitionPath, resolvedPath, sizeof(resolvedPath))) { if (volPath == resolvedPath) return WideToSingleString (partitionPath); } else if (partNumber == 0) break; } } return string(); } BOOL IsApplicationInstalled (const char *appName) { const char *uninstallRegName = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; BOOL installed = FALSE; HKEY unistallKey; LONG res = RegOpenKeyEx (HKEY_LOCAL_MACHINE, uninstallRegName, 0, KEY_READ | KEY_WOW64_64KEY, &unistallKey); if (res != ERROR_SUCCESS) { SetLastError (res); return FALSE; } char regName[1024]; DWORD regNameSize = sizeof (regName); DWORD index = 0; while (RegEnumKeyEx (unistallKey, index++, regName, ®NameSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { if (strstr (regName, "{") == regName) { regNameSize = sizeof (regName); if (!ReadLocalMachineRegistryStringNonReflected ((string (uninstallRegName) + "\\" + regName).c_str(), "DisplayName", regName, ®NameSize)) regName[0] = 0; } if (_stricmp (regName, appName) == 0) { installed = TRUE; break; } regNameSize = sizeof (regName); } RegCloseKey (unistallKey); return installed; } std::string FindLatestFileOrDirectory (const std::string &directory, const char *namePattern, bool findDirectory, bool findFile) { string name; ULARGE_INTEGER latestTime; latestTime.QuadPart = 0; WIN32_FIND_DATA findData; HANDLE find = FindFirstFile ((directory + "\\" + namePattern).c_str(), &findData); if (find != INVALID_HANDLE_VALUE) { do { if (strcmp (findData.cFileName, ".") == 0 || strcmp (findData.cFileName, "..") == 0) continue; ULARGE_INTEGER writeTime; writeTime.LowPart = findData.ftLastWriteTime.dwLowDateTime; writeTime.HighPart = findData.ftLastWriteTime.dwHighDateTime; if ((!findFile && !(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) || (!findDirectory && (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))) continue; if (latestTime.QuadPart < writeTime.QuadPart) { latestTime = writeTime; name = findData.cFileName; } } while (FindNextFile (find, &findData)); FindClose (find); } if (name.empty()) return name; return string (directory) + "\\" + name; } src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Changing%20Passwords%20and%20Keyfiles.html">Changing Passwords and Keyfiles</a>
diff --git a/doc/html/Choosing Passwords and Keyfiles.html b/doc/html/Choosing Passwords and Keyfiles.html
index 89bf5deb..3797009a 100644
--- a/doc/html/Choosing Passwords and Keyfiles.html
+++ b/doc/html/Choosing Passwords and Keyfiles.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Security%20Requirements%20and%20Precautions.html">Security Requirements and Precautions</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Choosing%20Passwords%20and%20Keyfiles.html">Choosing Passwords and Keyfiles</a>
diff --git a/doc/html/Command Line Usage.html b/doc/html/Command Line Usage.html
index d9318b10..c463b04c 100644
--- a/doc/html/Command Line Usage.html
+++ b/doc/html/Command Line Usage.html
@@ -1,72 +1,72 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Command%20Line%20Usage.html">Command Line Usage</a>
</p></div>
<div class="wikidoc">
<div>
<h1>Command Line Usage</h1>
<p>Note that this section applies to the Windows version of VeraCrypt. For information on command line usage applying to the
<strong>Linux and Mac OS X versions</strong>, please run: veracrypt &ndash;h</p>
-<table border="1" cellspacing="0" cellpadding="0">
+<table border="1" cellspacing="0" cellpadding="1">
<tbody>
<tr>
<td><em>/help</em> or <em>/?</em></td>
<td>Display command line help.</td>
</tr>
<tr>
<td><em>/truecrypt or /tc</em></td>
<td>Activate TrueCrypt compatibility mode which enables mounting volumes created with TrueCrypt 6.x and 7.x series.</td>
</tr>
<tr>
<td><em>/hash</em></td>
-<td>It must be followed by a parameter indicating the PRF hash algorithm to use when mounting the volume. Possible values for /hash parameter are: sha256, sha-256, sha512, sha-512, whirlpool, ripemd160 and ripemd-160. When /hash is omitted, VeraCrypt will try
+<td>It must be followed by a parameter indicating the PRF hash algorithm to use when mounting the volume. Possible values for /hash parameter are: sha256, sha-256, sha512, sha-512, whirlpool, blake2s and blake2s-256. When /hash is omitted, VeraCrypt will try
all possible PRF algorithms thus lengthening the mount operation time.</td>
</tr>
<tr>
<td id="volume"><em>/volume</em> or <em>/v</em></td>
<td>
<p>It must be followed by a parameter indicating the file and path name of a VeraCrypt volume to mount (do not use when dismounting) or the Volume ID of the disk/partition to mount.<br>
The syntax of the volume ID is <strong>ID:XXXXXX...XX</strong> where the XX part is a 64 hexadecimal characters string that represent the 32-Bytes ID of the desired volume to mount.<br>
<br>
To mount a partition/device-hosted volume, use, for example, /v \Device\Harddisk1\Partition3 (to determine the path to a partition/device, run VeraCrypt and click
<em>Select Device</em>). You can also mount a partition or dynamic volume using its volume name (for example, /v \\?\Volume{5cceb196-48bf-46ab-ad00-70965512253a}\). To determine the volume name use e.g. mountvol.exe. Also note that device paths are case-sensitive.<br>
<br>
You can also specify the Volume ID of the partition/device-hosted volume to mount, for example: /v ID:53B9A8D59CC84264004DA8728FC8F3E2EE6C130145ABD3835695C29FD601EDCA. The Volume ID value can be retrieved using the volume properties dialog.</p>
</td>
</tr>
<tr>
<td><em>/letter</em> or <em>/l</em></td>
<td>It must be followed by a parameter indicating the driver letter to mount the volume as. When /l is omitted and when /a is used, the first free drive letter is used.</td>
</tr>
<tr>
<td><em>/explore</em> or <em>/e</em></td>
@@ -90,56 +90,57 @@ You can also specify the Volume ID of the partition/device-hosted volume to moun
<td>Forces dismount (if the volume to be dismounted contains files being used by the system or an application) and forces mounting in shared mode (i.e., without exclusive access).</td>
</tr>
<tr>
<td><em>/keyfile</em> or <em>/k</em></td>
<td>It must be followed by a parameter specifying a keyfile or a keyfile search path. For multiple keyfiles, specify e.g.: /k c:\keyfile1.dat /k d:\KeyfileFolder /k c:\kf2 To specify a keyfile stored on a security token or smart card, use the following syntax:
token://slot/SLOT_NUMBER/file/FILE_NAME</td>
</tr>
<tr id="tryemptypass">
<td><em>/tryemptypass&nbsp;&nbsp; </em></td>
<td>ONLY when default keyfile configured or when a keyfile is specified in the command line.<br>
If it is followed by <strong>y</strong> or <strong>yes</strong> or if no parameter is specified: try to mount using an empty password and the keyfile before displaying password prompt.<br>
if it is followed by <strong>n </strong>or<strong> no</strong>: don't try to mount using an empty password and the keyfile, and display password prompt right away.</td>
</tr>
<tr>
<td><em>/nowaitdlg</em></td>
<td>If it is followed by <strong>y</strong> or <strong>yes</strong> or if no parameter is specified: don&rsquo;t display the waiting dialog while performing operations like mounting volumes.<br>
If it is followed by <strong>n</strong> or <strong>no</strong>: force the display waiting dialog is displayed while performing operations.</td>
</tr>
<tr>
<td><em>/secureDesktop</em></td>
-<td>If it is followed by <strong>y</strong> or <strong>yes</strong> or if no parameter is specified: display password dialog in a dedicated secure desktop to protect against certain types of attacks.<br>
-If it is followed by <strong>n</strong> or <strong>no</strong>: the password dialog is displayed in the normal desktop.</td>
+<td>If it is followed by <strong>y</strong> or <strong>yes</strong> or if no parameter is specified: display password dialog and token PIN dialog in a dedicated secure desktop to protect against certain types of attacks.<br>
+If it is followed by <strong>n</strong> or <strong>no</strong>: the password dialog and token PIN dialog are displayed in the normal desktop.</td>
</tr>
<tr>
<td><em>/tokenlib</em></td>
<td>It must be followed by a parameter indicating the PKCS #11 library to use for security tokens and smart cards. (e.g.: /tokenlib c:\pkcs11lib.dll)</td>
</tr>
<tr>
<td><em>/tokenpin</em></td>
<td>It must be followed by a parameter indicating the PIN to use in order to authenticate to the security token or smart card (e.g.: /tokenpin 0000). Warning: This method of entering a smart card PIN may be insecure, for example, when an unencrypted command
prompt history log is being saved to unencrypted disk.</td>
</tr>
<tr>
<td><em>/cache</em> or <em>/c</em></td>
<td>If it is followed by <strong>y</strong> or <strong>yes</strong> or if no parameter is specified: enable password cache;
<br>
+If it is followed by <strong>p </strong>or<strong> pim</strong>: enable both password and PIM cache (e.g., /c p).<br>
If it is followed by <strong>n </strong>or<strong> no</strong>: disable password cache (e.g., /c n).<br>
If it is followed by <strong>f </strong>or<strong> favorites</strong>: temporary cache password when mounting multiple favorites&nbsp; (e.g., /c f).<br>
Note that turning the password cache off will not clear it (use /w to clear the password cache).</td>
</tr>
<tr>
<td><em>/history</em> or <em>/h</em></td>
<td>If it is followed by <strong>y</strong> or no parameter: enables saving history of mounted volumes; if it is followed by
<strong>n</strong>: disables saving history of mounted volumes (e.g., /h n).</td>
</tr>
<tr>
<td><em>/wipecache</em> or <em>/w</em></td>
<td>Wipes any passwords cached in the driver memory.</td>
</tr>
<tr>
<td><em>/password</em> or <em>/p</em></td>
<td>It must be followed by a parameter indicating the volume password. If the password contains spaces, it must be enclosed in quotation marks (e.g., /p &rdquo;My Password&rdquo;). Use /p &rdquo;&rdquo; to specify an empty password.
<em>Warning: This method of entering a volume password may be insecure, for example, when an unencrypted command prompt history log is being saved to unencrypted disk.</em></td>
</tr>
<tr>
<td><em>/pim</em></td>
@@ -153,111 +154,172 @@ Note that turning the password cache off will not clear it (use /w to clear the
<tr>
<td><em>/silent</em> or <em>/s</em></td>
<td>If /q is specified, suppresses interaction with the user (prompts, error messages, warnings, etc.). If /q is not specified, this option has no effect.</td>
</tr>
<tr>
<td><em>/mountoption</em> or <em>/m</em></td>
<td>
<p>It must be followed by a parameter which can have one of the values indicated below.</p>
<p><strong>ro</strong> or<strong> readonly</strong>: Mount volume as read-only.</p>
<p><strong>rm</strong> or <strong>removable</strong>: Mount volume as removable medium (see section
<a href="Removable%20Medium%20Volume.html">
<em>Volume Mounted as Removable Medium</em></a>).</p>
<p><strong>ts</strong> or <strong>timestamp</strong>: Do not preserve container modification timestamp.</p>
<p><strong>sm</strong> or <strong>system</strong>: Without pre-boot authentication, mount a partition that is within the key scope of system encryption (for example, a partition located on the encrypted system drive of another operating system that is not running).
Useful e.g. for backup or repair operations. Note: If you supply a password as a parameter of /p, make sure that the password has been typed using the standard US keyboard layout (in contrast, the GUI ensures this automatically). This is required due to the
fact that the password needs to be typed in the pre-boot environment (before Windows starts) where non-US Windows keyboard layouts are not available.</p>
<p><strong>bk</strong> or <strong>headerbak</strong>: Mount volume using embedded backup header. Note: All volumes created by VeraCrypt contain an embedded backup header (located at the end of the volume).</p>
<p><strong>recovery</strong>: Do not verify any checksums stored in the volume header. This option should be used only when the volume header is damaged and the volume cannot be mounted even with the mount option headerbak. Example: /m ro</p>
<p><strong>label=LabelValue</strong>: Use the given string value <strong>LabelValue</strong> as a label of the mounted volume in Windows Explorer. The maximum length for
<strong>LabelValue&nbsp;</strong> is 32 characters for NTFS volumes and 11 characters for FAT volumes. For example,
-<em>/m label=MyDrive</em> will set the label of the drive in Explorer to <em>MyDrive</em>.<br>
-<br>
-Please note that this switch may be present several times in the command line in order to specify multiple mount options (e.g.: /m rm /m ts)</p>
+<em>/m label=MyDrive</em> will set the label of the drive in Explorer to <em>MyDrive</em>.</p>
+<p><strong>noattach</strong>: Only create virtual device without actually attaching the mounted volume to the selected drive letter.</p>
+<p>Please note that this switch may be present several times in the command line in order to specify multiple mount options (e.g.: /m rm /m ts)</p>
</td>
</tr>
+<tr>
+<td><em>/DisableDeviceUpdate</em>&nbsp;</td>
+<td>Disables periodic internel check on devices connected to the system that is used for handling favorites identified with VolumeID and replace it with on-demande checks.</td>
+</tr>
+<tr>
+<td><em>/protectMemory</em>&nbsp;</td>
+<td>Activates a mechanism that protects VeraCrypt process memory from being accessed by other non-admin processes.</td>
+</tr>
+<tr>
+<td><em>/signalExit</em>&nbsp;</td>
+<td>It must be followed by a parameter specifying the name of the signal to send to unblock a waiting <a href="https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/waitfor" target="_blank">WAITFOR.EXE</a> command when VeraCrypt exists.<br>
+The name of signal must be the same as the one specified to WAITFOR.EXE command (e.g."veracrypt.exe /q /v test.hc /l Z /signal SigName" followed by "waitfor.exe SigName"<br>
+This switch is ignored if /q is not specified</td>
+</tr>
</tbody>
</table>
<h4>VeraCrypt Format.exe (VeraCrypt Volume Creation Wizard):</h4>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>/create</td>
<td>Create a container based volume in command line mode. It must be followed by the file name of the container to be created.</td>
</tr>
<tr>
<td>/size</td>
<td>
<p>(Only with /create)<br>
It must be followed by a parameter indicating the size of the container file that will be created. This parameter is a number indicating the size in Bytes. It can have a suffixe 'K', 'M', 'G' or 'T' to indicate that the value is in Kilobytes, Megabytes, Gigabytes
or Terabytes respectively. For example:</p>
<ul>
<li>/size 5000000: the container size will be 5000000 bytes </li><li>/size 25K: the container size will be 25 KiloBytes. </li><li>/size 100M: the container size will be 100 MegaBytes. </li><li>/size 2G: the container size will be 2 GigaBytes. </li><li>/size 1T: the container size will be 1 TeraBytes. </li></ul>
</td>
</tr>
<tr>
<td>&nbsp;/password</td>
<td>&nbsp;(Only with /create)<br>
It must be followed by a parameter indicating the password of the container that will be created.</td>
</tr>
<tr>
+<td>&nbsp;/keyfile or /k</td>
+<td>&nbsp;(Only with /create)<br>
+It must be followed by a parameter specifying a keyfile or a keyfile search path. For multiple keyfiles, specify e.g.: /k c:\keyfile1.dat /k d:\KeyfileFolder /k c:\kf2 To specify a keyfile stored on a security token or smart card, use the following syntax:
+ token://slot/SLOT_NUMBER/file/FILE_NAME</td>
+</tr>
+<tr>
+<td><em>/tokenlib</em></td>
+<td>&nbsp;(Only with /create)<br>
+It must be followed by a parameter indicating the PKCS #11 library to use for security tokens and smart cards. (e.g.: /tokenlib c:\pkcs11lib.dll)</td>
+</tr>
+<tr>
+<td><em>/tokenpin</em></td>
+<td>&nbsp;(Only with /create)<br>
+It must be followed by a parameter indicating the PIN to use in order to authenticate to the security token or smart card (e.g.: /tokenpin 0000). Warning: This method of entering a smart card PIN may be insecure, for example, when an unencrypted command
+ prompt history log is being saved to unencrypted disk.</td>
+</tr>
+<tr>
<td>&nbsp;<em>/hash</em></td>
<td>(Only with /create)<br>
It must be followed by a parameter indicating the PRF hash algorithm to use when creating the volume. It has the same syntax as VeraCrypt.exe.</td>
</tr>
<tr>
<td>/encryption</td>
<td>(Only with /create)<br>
It must be followed by a parameter indicating the encryption algorithm to use. The default is AES if this switch is not specified. The parameter can have the following values (case insensitive):
<ul>
-<li>AES </li><li>Serpent </li><li>Twofish </li><li>AES(Twofish) </li><li>AES(Twofish(Serpent)) </li><li>Serpent(AES) </li><li>Serpent(Twofish(AES)) </li><li>Twofish(Serpent) </li></ul>
+<li>AES </li><li>Serpent </li><li>Twofish </li><li>Camellia </li><li>Kuznyechik </li><li>AES(Twofish) </li><li>AES(Twofish(Serpent)) </li><li>Serpent(AES) </li><li>Serpent(Twofish(AES)) </li><li>Twofish(Serpent) </li>
+<li>Camellia(Kuznyechik) </li>
+<li>Kuznyechik(Twofish) </li>
+<li>Camellia(Serpent) </li>
+<li>Kuznyechik(AES) </li>
+<li>Kuznyechik(Serpent(Camellia)) </li>
+</ul>
</td>
</tr>
<tr>
<td>/filesystem</td>
<td>(Only with /create)<br>
It must be followed by a parameter indicating the file system to use for the volume. The parameter can have the following values:
<ul>
<li>None: don't use any filesystem </li><li>FAT: format using FAT/FAT32 </li><li>NTFS: format using NTFS. Please note that in this case a UAC prompt will be displayed unless the process is run with full administrative privileges.
-</li></ul>
+</li>
+<li>ExFAT: format using ExFAT. This switch is available starting from Windows Vista SP1 </li>
+<li>ReFS: format using ReFS. This switch is available starting from Windows 10 </li>
+</ul>
</td>
</tr>
<tr>
<td>/dynamic</td>
<td>(Only with /create)<br>
It has no parameters and it indicates that the volume will be created as a dynamic volume.</td>
</tr>
<tr>
<td>/force</td>
<td>(Only with /create)<br>
It has no parameters and it indicates that overwrite will be forced without requiring user confirmation.</td>
</tr>
<tr>
<td>/silent</td>
<td>(Only with /create)<br>
It has no parameters and it indicates that no message box or dialog will be displayed to the user. If there is any error, the operation will fail silently.</td>
</tr>
<tr>
<td><em>/noisocheck</em> or <em>/n</em></td>
<td>Do not verify that VeraCrypt Rescue Disks are correctly burned. <strong>WARNING</strong>: Never attempt to use this option to facilitate the reuse of a previously created VeraCrypt Rescue Disk. Note that every time you encrypt a system partition/drive,
you must create a new VeraCrypt Rescue Disk even if you use the same password. A previously created VeraCrypt Rescue Disk cannot be reused as it was created for a different master key.</td>
</tr>
+<tr>
+<td>/nosizecheck</td>
+<td>Don't check that the given size of the file container is smaller than the available disk free. This applies to both UI and command line.</td>
+</tr>
+<tr>
+<td>/quick</td>
+<td>Perform quick formatting of volumes instead of full formatting. This applies to both UI and command line.</td>
+</tr>
+<tr>
+<td>/FastCreateFile</td>
+<td>Enables a faster, albeit potentially insecure, method for creating file containers. This option carries security risks as it can embed existing disk content into the file container, possibly exposing sensitive data if an attacker gains access to it. Note that this switch affects all file container creation methods, whether initiated from the command line, using the /create switch, or through the UI wizard.</td>
+</tr>
+<tr>
+<td><em>/protectMemory</em>&nbsp;</td>
+<td>Activates a mechanism that protects VeraCrypt Format process memory from being accessed by other non-admin processes.</td>
+</tr>
+<tr>
+<td><em>/secureDesktop</em></td>
+<td>If it is followed by <strong>y</strong> or <strong>yes</strong> or if no parameter is specified: display password dialog and token PIN dialog in a dedicated secure desktop to protect against certain types of attacks.<br>
+If it is followed by <strong>n</strong> or <strong>no</strong>: the password dialog and token PIN dialog are displayed in the normal desktop.</td>
+</tr>
</tbody>
</table>
<h4>Syntax</h4>
-<p>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |ripemd160|ripemd-160}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [drive letter]] [/e] [/f] [/h [y|n]] [/k keyfile or search path] [tryemptypass [y|n]] [/l drive letter] [/m {bk|rm|recovery|ro|sm|ts}]
+<p>VeraCrypt.exe [/tc] [/hash {sha256|sha-256|sha512|sha-512|whirlpool |blake2s|blake2s-256}][/a [devices|favorites]] [/b] [/c [y|n|f]] [/d [drive letter]] [/e] [/f] [/h [y|n]] [/k keyfile or search path] [tryemptypass [y|n]] [/l drive letter] [/m {bk|rm|recovery|ro|sm|ts|noattach}]
[/p password] [/pim pimvalue] [/q [background|preferences]] [/s] [/tokenlib path] [/v volume] [/w]</p>
-<p>&quot;VeraCrypt Format.exe&quot; [/n] [/create] [/size number[{K|M|G|T}]] [/p password]&nbsp; [/encryption {AES | Serpent | Twofish | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent)}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|ripemd160|ripemd-160}]
- [/filesystem {None|FAT|NTFS}] [/dynamic] [/force] [/silent]</p>
+<p>&quot;VeraCrypt Format.exe&quot; [/n] [/create] [/size number[{K|M|G|T}]] [/p password]&nbsp; [/encryption {AES | Serpent | Twofish | Camellia | Kuznyechik | AES(Twofish) | AES(Twofish(Serpent)) | Serpent(AES) | Serpent(Twofish(AES)) | Twofish(Serpent) | Camellia(Kuznyechik) | Kuznyechik(Twofish) | Camellia(Serpent) | Kuznyechik(AES) | Kuznyechik(Serpent(Camellia))}] [/hash {sha256|sha-256|sha512|sha-512|whirlpool|blake2s|blake2s-256}]
+ [/filesystem {None|FAT|NTFS|ExFAT|ReFS}] [/dynamic] [/force] [/silent] [/noisocheck] [FastCreateFile] [/quick]</p>
<p>Note that the order in which options are specified does not matter.</p>
<h4>Examples</h4>
<p>Mount the volume <em>d:\myvolume</em> as the first free drive letter, using the password prompt (the main program window will not be displayed):</p>
<p>veracrypt /q /v d:\myvolume</p>
<p>Dismount a volume mounted as the drive letter <em>X</em> (the main program window will not be displayed):</p>
<p>veracrypt /q /d x</p>
<p>Mount a volume called <em>myvolume.tc</em> using the password <em>MyPassword</em>, as the drive letter
<em>X</em>. VeraCrypt will open an explorer window and beep; mounting will be automatic:</p>
<p>veracrypt /v myvolume.tc /l x /a /p MyPassword /e /b</p>
<p>Create a 10 MB file container using the password <em>test</em> and formatted using FAT:</p>
<p><code>&quot;C:\Program Files\VeraCrypt\VeraCrypt Format.exe&quot; /create c:\Data\test.hc /password test /hash sha512 /encryption serpent /filesystem FAT /size 10M /force</code></p>
</div>
</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/CompilingGuidelineLinux.html b/doc/html/CompilingGuidelineLinux.html
new file mode 100644
index 00000000..7b0d1df3
--- /dev/null
+++ b/doc/html/CompilingGuidelineLinux.html
@@ -0,0 +1,314 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<style>
+.textbox {
+ vertical-align: top;
+ height: auto !important;
+ font-family: Helvetica,sans-serif;
+ font-size: 20px;
+ font-weight: bold;
+ margin: 10px;
+ padding: 10px;
+ background-color: white;
+ width: auto;
+ border-radius: 10px;
+}
+
+.texttohide {
+ font-family: Helvetica,sans-serif;
+ font-size: 14px;
+ font-weight: normal;
+}
+
+
+</style>
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
+<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
+<meta name="keywords" content="encryption, security"/>
+<link href="styles.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<div>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+</div>
+
+<div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
+ </ul>
+</div>
+
+<div>
+<p>
+<a href="Documentation.html">Documentation</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="Technical%20Details.html">Technical Details</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="CompilingGuidelines.html">Building VeraCrypt From Source</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="CompilingGuidelineLinux.html">Linux Build Guide</a>
+</p></div>
+
+<div class="wikidoc">
+This guide describes how to set up a Linux System to build VeraCrypt from source and how to perform compilation. <br>
+The procedure for a Ubuntu 22.04 LTS system is described here as an example, the procedure for other Linux systems is analogous.
+</div>
+
+<div class="wikidoc">
+<br>
+<br>
+The following components are required for compiling VeraCrypt:
+<ol>
+ <li>GNU Make</li>
+ <li>GNU C/C++ Compiler</li>
+ <li>YASM 1.3.0</li>
+ <li>pkg-config</li>
+ <li>wxWidgets 3.x shared library and header files installed by the system or wxWidgets 3.x library source code </li>
+ <li>FUSE library and header files</li>
+ <li>PCSC-lite library and header files</li>
+</ol>
+</div>
+
+<div class="wikidoc">
+<p>Below are the procedure steps. Clicking on any of the link takes directly to the related step:
+<ul>
+<li><strong><a href="#InstallationOfGNUMake">Installation of GNU Make</a></li></strong>
+<li><strong><a href="#InstallationOfGNUCompiler">Installation of GNU C/C++ Compiler</a></li></strong>
+<li><strong><a href="#InstallationOfYASM">Installation of YASM</a></li></strong>
+<li><strong><a href="#InstallationOfPKGConfig">Installation of pkg-config</a></li></strong>
+<li><strong><a href="#InstallationOfwxWidgets">Installation of wxWidgets 3.2</a></li></strong>
+<li><strong><a href="#InstallationOfFuse">Installation of libfuse</a></li></strong>
+<li><strong><a href="#InstallationOfPCSCLite">Installation of libpcsclite</a></li></strong>
+<li><strong><a href="#DownloadVeraCrypt">Download VeraCrypt</a></li></strong>
+<li><strong><a href="#CompileVeraCrypt">Compile VeraCrypt</a></li></strong>
+</ul>
+</p>
+<p>They can also be performed by running the below list of commands in a terminal or by copying them to a script:<br>
+<code>
+sudo apt update <br>
+sudo apt install -y build-essential yasm pkg-config libwxgtk3.0-gtk3-dev <br>
+sudo apt install -y libfuse-dev git libpcsclite-dev <br>
+git clone https://github.com/veracrypt/VeraCrypt.git <br>
+cd ~/VeraCrypt/src <br>
+make
+</code>
+</p>
+</div>
+
+<div class="wikidoc">
+ <div class="textbox" id="InstallationOfGNUMake">
+ <a href="#InstallationOfGNUMake">Installation of GNU Make</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install build-essential
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfGNUCompiler">
+ <a href="#InstallationOfGNUCompiler">Installation of GNU C/C++ Compiler</a>
+ <div class="texttohide">
+ <p> If the build-essential were already installed in the step before, this step can be skipped.
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install build-essential
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfYASM">
+ <a href="#InstallationOfYASM">Installation of YASM</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install yasm
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfPKGConfig">
+ <a href="#InstallationOfPKGConfig">Installation of pkg-config</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install pkg-config
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfwxWidgets">
+ <a href="#InstallationOfwxWidgets">Installation of wxWidgets 3.2</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install libwxgtk3.0-gtk3-dev <br>
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfFuse">
+ <a href="#InstallationOfFuse">Installation of libfuse</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install libfuse-dev
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+<div class="textbox" id="InstallationOfPCSCLite">
+ <a href="#InstallationOfPCSCLite">Installation of libpcsclite</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install libpcsclite-dev
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+</div>
+
+ <div class="textbox" id="DownloadVeraCrypt">
+ <a href="#DownloadVeraCrypt">Download VeraCrypt</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ sudo apt update <br>
+ sudo apt install git <br>
+ git clone https://github.com/veracrypt/VeraCrypt.git
+ </code>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="CompileVeraCrypt">
+ <a href="#CompileVeraCrypt">Compile VeraCrypt</a>
+ <div class="texttohide">
+ <p> Remarks: <br>
+ <ul>
+ <li>
+ By default, a universal executable supporting both graphical and text user interface (through the switch --text) is built. <br>
+ On Linux, a console-only executable, which requires no GUI library, can be built using the 'NOGUI' parameter. <br>
+ For that, you need to dowload wxWidgets sources, extract them to a location of your choice and then run the following commands: <br>
+ <code>
+ make NOGUI=1 WXSTATIC=1 WX_ROOT=/path/to/wxWidgetsSources wxbuild <br>
+ make NOGUI=1 WXSTATIC=1 WX_ROOT=/path/to/wxWidgetsSources
+ </code>
+ </li>
+ <li>
+ If you are not using the system wxWidgets library, you will have to download and use wxWidgets sources like the remark above but this time the following commands should be run to build GUI version of VeraCrypt (NOGUI is not specified): <br>
+ <code>
+ make WXSTATIC=1 WX_ROOT=/path/to/wxWidgetsSources wxbuild <br>
+ make WXSTATIC=1 WX_ROOT=/path/to/wxWidgetsSources
+ </code>
+ </li>
+ </ul>
+ Steps:
+ <ol>
+ <li>
+ Open a terminal
+ </li>
+ <li>
+ Execute the following commands: <br>
+ <code>
+ cd ~/VeraCrypt/src <br>
+ make
+ </code>
+ </li>
+ <li>
+ If successful, the VeraCrypt executable should be located in the directory 'Main'.
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+</div>
+</body></html>
diff --git a/doc/html/CompilingGuidelineWin.html b/doc/html/CompilingGuidelineWin.html
new file mode 100644
index 00000000..ec08af4f
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin.html
@@ -0,0 +1,1225 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<style>
+.textbox {
+ vertical-align: top;
+ height: auto !important;
+ font-family: Helvetica,sans-serif;
+ font-size: 20px;
+ font-weight: bold;
+ margin: 10px;
+ padding: 10px;
+ background-color: white;
+ width: auto;
+ border-radius: 10px;
+}
+
+.texttohide {
+ font-family: Helvetica,sans-serif;
+ font-size: 14px;
+ font-weight: normal;
+}
+
+
+</style>
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
+<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
+<meta name="keywords" content="encryption, security"/>
+<link href="styles.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<div>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+</div>
+
+<div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
+ </ul>
+</div>
+
+<div>
+<p>
+<a href="Documentation.html">Documentation</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="Technical%20Details.html">Technical Details</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="CompilingGuidelines.html">Building VeraCrypt From Source</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="CompilingGuidelineWin.html">Windows Build Guide</a>
+</p></div>
+
+<div class="wikidoc">
+This guide describes how to set up a Windows system that can compile the VeraCrypt. Further it is described how VeraCrypt is going to be compiled. <br>
+The procedure for a Windows 10 system is described here as an example, but the procedure for other Windows systems is analogous.
+</div>
+
+<div class="wikidoc">
+The following components are required for compiling VeraCrypt:
+
+<ol>
+ <li>Microsoft Visual Studio 2010</li>
+ <li>Microsoft Visual Studio 2010 Service Pack 1</li>
+ <li>NASM</li>
+ <li>YASM</li>
+ <li>Visual C++ 1.52</li>
+ <li>Windows SDK 7.1</li>
+ <li>Windows Driver Kit 7.1</li>
+ <li>Windows 8.1 SDK</li>
+ <li>gzip</li>
+ <li>upx</li>
+ <li>7zip</li>
+ <li>Wix3</li>
+ <li>Microsoft Visual Studio 2019</li>
+ <li>Windows 10 SDK</li>
+ <li>Windows Driver Kit 1903</li>
+ <li>Visual Studio build tools</li>
+
+</ol>
+
+</div>
+
+<div class="wikidoc">
+Below are the procedure steps. Clicking on any of the link takes directly to the related step:
+<ul>
+<li><strong><a href="#InstallationOfMicrosoftVisualStudio2010">Installation of Microsoft Visual Studio 2010</a></li></strong>
+<li><strong><a href="#InstallationOfMicrosoftVisualStudio2010ServicePack1">Installation of Microsoft Visual Studio 2010 Service Pack 1</a></li></strong>
+<li><strong><a href="#InstallationOfNASM">Installation of NASM</a></li></strong>
+<li><strong><a href="#InstallationOfYASM">Installation of YASM</a></li></strong>
+<li><strong><a href="#InstallationOfVisualCPP">Installation of Microsoft Visual C++ 1.52</a></li></strong>
+<li><strong><a href="#InstallationOfWindowsSDK71PP">Installation of the Windows SDK 7.1</a></li></strong>
+<li><strong><a href="#InstallationOfWDK71PP">Installation of the Windows Driver Kit 7.1</a></li></strong>
+<li><strong><a href="#InstallationOfSDK81PP">Installation of the Windows 8.1 SDK</a></li></strong>
+<li><strong><a href="#InstallationOfGzip">Installation of gzip</a></li></strong>
+<li><strong><a href="#InstallationOfUpx">Installation of upx</a></li></strong>
+<li><strong><a href="#InstallationOf7zip">Installation of 7zip</a></li></strong>
+<li><strong><a href="#InstallationOfWix3">Installation of Wix3</a></li></strong>
+<li><strong><a href="#InstallationOfVS2019">Installation of Microsoft Visual Studio 2019</a></li></strong>
+<li><strong><a href="#InstallationOfWDK10">Installation of the Windows Driver Kit 2004</a></li></strong>
+<li><strong><a href="#InstallationOfVisualBuildTools">Installation of the Visual Studio build tools</a></li></strong>
+<li><strong><a href="#DownloadVeraCrypt">Download VeraCrypt Source Files</a></li></strong>
+<li><strong><a href="#CompileWin32X64">Compile the Win32/x64 Versions of VeraCrypt</a></li></strong>
+<li><strong><a href="#CompileARM64">Compile the ARM64 Version of VeraCrypt</a></li></strong>
+<li><strong><a href="#BuildVeraCryptExecutables">Build the VeraCrypt Executables</a></li></strong>
+<li><strong><a href="#ImportCertificates">Import the Certificates</a></li></strong>
+<li><strong><a href="#KnownIssues">Known Issues</a></li></strong>
+</ul>
+</div>
+
+<div class="wikidoc">
+ <div class="textbox" id="InstallationOfMicrosoftVisualStudio2010">
+ <a href="#InstallationOfMicrosoftVisualStudio2010">Installation of Microsoft Visual Studio 2010</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Visit the following Microsoft website and log in with a free Microsoft account: <br>
+ <a href="https://my.visualstudio.com/Downloads?q=Visual%20Studio%202010%20Professional&pgroup=" target="_blank">https://my.visualstudio.com/Downloads?q=Visual%20Studio%202010%20Professional&pgroup=</a>
+ </li>
+ <li>
+ Please download a (trial) version of “Visual Studio Professional 2010” <br>
+ <img src="CompilingGuidelineWin/DownloadVS2010.jpg" width="80%">
+ </li>
+ <li>
+ Mount the downloaded ISO file by doubleclicking it
+ </li>
+ <li>
+ Run the file "autorun.exe" as administrator
+ </li>
+ <li>
+ Install Microsoft Visual Studio 2010 with the default settings
+ </li>
+ </ol>
+ The installation of the Microsoft SQL Server 2008 Express Service Pack 1 (x64) may fail, but it is not required for compiling VeraCrypt.
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfMicrosoftVisualStudio2010ServicePack1">
+ <a href="#InstallationOfMicrosoftVisualStudio2010ServicePack1">Installation of Microsoft Visual Studio 2010 Service Pack 1</a>
+ <div class="texttohide">
+ <p>
+ Note: The content the official installer from Microsoft tries to download is no longer available. Therefore, it is necessary to use an offline installer.
+ <ol>
+ <li>
+ Visit the website of the internet archive and download the iso image of the Microsoft Visual Studio 2010 Service Pack 1:<br>
+ <a href="https://archive.org/details/vs-2010-sp-1dvd-1" target="_blank">https://archive.org/details/vs-2010-sp-1dvd-1</a>
+ </li>
+ <li>
+ Mount the downloaded ISO file by doubleclicking it
+ </li>
+ <li>
+ Run the file "Setup.exe" as administrator
+ </li>
+ <li>
+ Install Microsoft Visual Studio 2010 Service Pack 1 with the default settings
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfNASM">
+ <a href="#InstallationOfNASM">Installation of NASM</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Download “nasm-2.08-installer.exe” at: <br>
+ <a href="https://www.nasm.us/pub/nasm/releasebuilds/2.08/win32/" target="_blank">https://www.nasm.us/pub/nasm/releasebuilds/2.08/win32/</a>
+ </li>
+ <li>
+ Run the file as administrator
+ </li>
+ <li>
+ Install NASM with the default settings
+ </li>
+ <li>
+ Add NASM to the path Variable. This will make the command globally available on the command line. <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Open a file explorer
+ </li>
+ <li>
+ Within the left file tree, please make a right click on "This PC" and select "Properties" <br>
+ <img src="CompilingGuidelineWin/SelectThisPC.jpg" width="40%">
+ </li>
+ <li>
+ Within the right menu, please click on "Advanced system settings" <br>
+ <img src="CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg" width="50%">
+ </li>
+ <li>
+ Please click on "Environment Variables" <br>
+ <img src="CompilingGuidelineWin/SelectEnvironmentVariables.jpg" width="17%">
+ </li>
+ <li>
+ Within the area of the system variables, please select the "Path" variable and click on "Edit..." <br>
+ <img src="CompilingGuidelineWin/SelectPathVariable.jpg" width="25%">
+ </li>
+ <li>
+ Click on "New" and add the following value: <br>
+ <p style="font-family: 'Courier New', monospace;">C:\Program Files (x86)\nasm</p>
+ </li>
+ <li>
+ Close the windows by clicking on "OK"
+ </li>
+ </ol>
+ </li>
+ <li>
+ To check if the configuration is working correctly, please open a command prompt and watch the output of the following command: <br>
+ <p style="font-family: 'Courier New', monospace;">nasm</p> <br>
+ <img src="CompilingGuidelineWin/NasmCommandLine.jpg" width="50%">
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfYASM">
+ <a href="#InstallationOfYASM">Installation of YASM</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please create the following folder: <br>
+ C:\Program Files\YASM
+ </li>
+ <li>
+ Please download the file "Win64 VS2010 .zip" at: <br>
+ <a href="https://yasm.tortall.net/Download.html" target="_blank">https://yasm.tortall.net/Download.html</a>
+ </li>
+ <li>
+ Your browser might inform you that the file might be a security risk due to the low download rate or the unencrypted connection. Nevertheless, the official website is the most reliable source for this file, so we recommend to allow the download
+ </li>
+ <li>
+ Unzip the zip file and copy the files to “C:\Program Files\YASM”
+ </li>
+ <li>
+ Please download the file "Win64 .exe" at: <br>
+ <a href="https://yasm.tortall.net/Download.html" target="_blank">https://yasm.tortall.net/Download.html</a>
+ </li>
+ <li>
+ Your browser might inform you that the file might be a security risk due to the low download rate or the unencrypted connection. Nevertheless, the official website is the most reliable source for this file, so we recommend to allow the download
+ </li>
+ <li>
+ Rename the file to “yasm.exe” and copy it to “C:\Program Files\YASM”
+ </li>
+ <li>
+ Add YASM to the path Variable and create a new system variable for YASM. This will make the command globally available on the command line. <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Open a file explorer
+ </li>
+ <li>
+ Within the left file tree, please make a right click on "This PC" and select "Properties" <br>
+ <img src="CompilingGuidelineWin/SelectThisPC.jpg" width="40%">
+ </li>
+ <li>
+ Within the right menu, please click on "Advanced system settings" <br>
+ <img src="CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg" width="50%">
+ </li>
+ <li>
+ Please click on "Environment Variables" <br>
+ <img src="CompilingGuidelineWin/SelectEnvironmentVariables.jpg" width="17%">
+ </li>
+ <li>
+ Within the area of the system variables, please select the "Path" variable and click on "Edit..." <br>
+ <img src="CompilingGuidelineWin/SelectPathVariable.jpg" width="25%">
+ </li>
+ <li>
+ Click on "New" and add the following value: <br>
+ <p style="font-family: 'Courier New', monospace;">C:\Program Files\YASM</p>
+ </li>
+ <li>
+ Close the top window by clicking on "OK"
+ </li>
+ <li>
+ Within the area of the system variables, please click on "New..." <br>
+ <img src="CompilingGuidelineWin/AddNewSystemVar.jpg" width="25%">
+ </li>
+ <li>
+ Fill out the form with the following values: <br>
+ <p style="font-family: 'Courier New', monospace;">Variable name: YASMPATH<br> Variable value: C:\Program Files\YASM</p>
+ </li>
+ <li>
+ Close the windows by clicking on "OK"
+ </li>
+ </ol>
+ </li>
+ <li>
+ To check if the configuration is working correctly, please open a command prompt and watch the output of the following command: <br>
+ <p style="font-family: 'Courier New', monospace;">yasm</p> <br>
+ and <br>
+ <p style="font-family: 'Courier New', monospace;">vsyasm</p> <br>
+ <img src="CompilingGuidelineWin/YasmCommandLine.jpg" width="50%">
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfVisualCPP">
+ <a href="#InstallationOfVisualCPP">Installation of Microsoft Visual C++ 1.52</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Visual C++ 1.52 is available via the paid Microsoft MSDN subscription. If you do not have a subscription, you download the ISO image via the internet archive: <br>
+ <a href="https://archive.org/details/ms-vc152" target="_blank">https://archive.org/details/ms-vc152</a>
+ </li>
+ <li>
+ Create the folder “C:\MSVC15”
+ </li>
+ <li>
+ Mount the ISO file and copy the content of the folder “MSVC” to “C:\MSVC15”
+ </li>
+ <li>
+ Create a system variable for Microsoft Visual C++ 1.52 <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Open a file explorer
+ </li>
+ <li>
+ Within the left file tree, please make a right click on "This PC" and select "Properties" <br>
+ <img src="CompilingGuidelineWin/SelectThisPC.jpg" width="40%">
+ </li>
+ <li>
+ Within the right menu, please click on "Advanced system settings" <br>
+ <img src="CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg" width="50%">
+ </li>
+ <li>
+ Please click on "Environment Variables" <br>
+ <img src="CompilingGuidelineWin/SelectEnvironmentVariables.jpg" width="17%">
+ </li>
+ <li>
+ Within the area of the system variables, please click on "New..." <br>
+ <img src="CompilingGuidelineWin/AddNewSystemVar.jpg" width="25%">
+ </li>
+ <li>
+ Fill out the form with the following values: <br>
+ <p style="font-family: 'Courier New', monospace;">Variable name: MSVC16_ROOT<br> Variable value: C:\MSVC15</p>
+ </li>
+ <li>
+ Close the windows by clicking on "OK"
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfWindowsSDK71PP">
+ <a href="#InstallationOfWindowsSDK71PP">Installation of the Windows SDK 7.1</a>
+ <div class="texttohide">
+ <p>
+ The installer requires .Net Framework 4 (Not a newer one like .Net Framework 4.8!). Since a newer version is already preinstalled with Windows 10, the installer has to be tricked:
+ <ol>
+ <li>
+ Click on the start button and search for: "regedit.msc". Start the first finding.
+ </li>
+ <li>
+ Navigate to "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\"
+ </li>
+ <li>
+ Change the permissions for the "Client" folder, so you can edit the keys: <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Right click on the subfolder "Client" and select "Permissions..."
+ </li>
+ <li>
+ Click on "Advanced" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-1.jpg" width="17%">
+ </li>
+ <li>
+ Change the owner to your user and click on "Add" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-2.jpg" width="35%">
+ </li>
+ <li>
+ Set the principal to your user, select "Full Control" and click on "OK" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-3.jpg" width="35%">
+ </li>
+ <li>
+ Within the folder "Client" note down the value of the entry "Version"
+ </li>
+ <li>
+ Doubleclick on the entry "Version" and change the value to "4.0.30319" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-4.jpg" width="30%">
+ </li>
+ </ol>
+ </li>
+ <li>
+ Change the permissions for the "Full" folder, so you can edit the keys: <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Right click on the subfolder "Full" and select "Permissions..."
+ </li>
+ <li>
+ Click on "Advanced" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-1.jpg" width="17%">
+ </li>
+ <li>
+ Change the owner to your user and click on "Add" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-2.jpg" width="35%">
+ </li>
+ <li>
+ Set the principal to your user, select "Full Control" and click on "OK" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-3.jpg" width="35%">
+ </li>
+ <li>
+ Within the folder "Full" note down the value of the entry "Version"
+ </li>
+ <li>
+ Doubleclick on the entry "Version" and change the value to "4.0.30319" <br>
+ <img src="CompilingGuidelineWin/RegeditPermissions-4.jpg" width="30%">
+ </li>
+ </ol>
+ </li>
+ <li>
+ Download the Windows SDK 7.1 at: <br>
+ <a href="https://www.microsoft.com/en-us/download/details.aspx?id=8279" target="_blank">https://www.microsoft.com/en-us/download/details.aspx?id=8279</a>
+ </li>
+ <li>
+ Run the downloaded file as administrator and install the application with default settings
+ </li>
+ <li>
+ After the installation, revert the changes done in the registry editor. <br>
+ <b>Note:</b> The owner "TrustedInstaller" can be restored by searching for: "NT Service\TrustedInstaller"
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfWDK71PP">
+ <a href="#InstallationOfWDK71PP">Installation of the Windows Driver Kit 7.1</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please download the ISO of the Windows Diver Kit 7.1 at: <br>
+ <a href="https://www.microsoft.com/en-us/download/details.aspx?id=11800" target="_blank">https://www.microsoft.com/en-us/download/details.aspx?id=11800</a>
+ </li>
+ <li>
+ Mount the downloaded ISO file by doubleclicking it
+ </li>
+ <li>
+ Run the file "KitSetup.exe" as administrator. Within the installation select all features to be installed. <br>
+ <b>Note: </b>It might be that during the installed you are requested to install the .NET Framework 3.5. In this case click on "Download and install this feature".
+ </li>
+ <li>
+ Install the Driver Kit to the default location
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfSDK81PP">
+ <a href="#InstallationOfSDK81PP">Installation of the Windows 8.1 SDK</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please download the ISO of the Windows 8.1 SDK at: <br>
+ <a href="https://developer.microsoft.com/de-de/windows/downloads/sdk-archive/" target="_blank">https://developer.microsoft.com/de-de/windows/downloads/sdk-archive/</a>
+ </li>
+ <li>
+ Run the downloaded file as administrator and install the Windows 8.1 SDK with default settings
+ </li>
+ <li>
+ Create a system variable for the Windows 8.1 SDK <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Open a file explorer
+ </li>
+ <li>
+ Within the left file tree, please make a right click on "This PC" and select "Properties" <br>
+ <img src="CompilingGuidelineWin/SelectThisPC.jpg" width="40%">
+ </li>
+ <li>
+ Within the right menu, please click on "Advanced system settings" <br>
+ <img src="CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg" width="50%">
+ </li>
+ <li>
+ Please click on "Environment Variables" <br>
+ <img src="CompilingGuidelineWin/SelectEnvironmentVariables.jpg" width="17%">
+ </li>
+ <li>
+ Within the area of the system variables, please click on "New..." <br>
+ <img src="CompilingGuidelineWin/AddNewSystemVar.jpg" width="25%">
+ </li>
+ <li>
+ Fill out the form with the following values: <br>
+ <p style="font-family: 'Courier New', monospace;">Variable name: WSDK81<br> Variable value: C:\Program Files (x86)\Windows Kits\8.1\</p>
+ </li>
+ <li>
+ Close the windows by clicking on "OK"
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfGzip">
+ <a href="#InstallationOfGzip">Installation of gzip</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please create the following folder: <br>
+ C:\Program Files (x86)\gzip
+ </li>
+ <li>
+ Please download gzip version at: <br>
+ <a href="https://sourceforge.net/projects/gnuwin32/files/gzip/1.3.12-1/gzip-1.3.12-1-bin.zip/download?use-mirror=netix&download=" target="_blank">https://sourceforge.net/projects/gnuwin32/files/gzip/1.3.12-1/gzip-1.3.12-1-bin.zip/download?use-mirror=netix&download=</a>
+ </li>
+ <li>
+ Copy the content of the downloaded zip to “C:\Program Files (x86)\gzip”
+ </li>
+ <li>
+ Add gzip to the path Variable. This will make the command globally available on the command line. <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Open a file explorer
+ </li>
+ <li>
+ Within the left file tree, please make a right click on "This PC" and select "Properties" <br>
+ <img src="CompilingGuidelineWin/SelectThisPC.jpg" width="40%">
+ </li>
+ <li>
+ Within the right menu, please click on "Advanced system settings" <br>
+ <img src="CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg" width="50%">
+ </li>
+ <li>
+ Please click on "Environment Variables" <br>
+ <img src="CompilingGuidelineWin/SelectEnvironmentVariables.jpg" width="17%">
+ </li>
+ <li>
+ Within the area of the system variables, please select the "Path" variable and click on "Edit..." <br>
+ <img src="CompilingGuidelineWin/SelectPathVariable.jpg" width="25%">
+ </li>
+ <li>
+ Click on "New" and add the following value: <br>
+ <p style="font-family: 'Courier New', monospace;">C:\Program Files (x86)\gzip\bin</p>
+ </li>
+ <li>
+ Close the windows by clicking on "OK"
+ </li>
+ </ol>
+ </li>
+ <li>
+ To check if the configuration is working correctly, please open a command prompt and watch the output of the following command: <br>
+ <p style="font-family: 'Courier New', monospace;">gzip</p> <br>
+ <img src="CompilingGuidelineWin/gzipCommandLine.jpg" width="50%">
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfUpx">
+ <a href="#InstallationOfUpx">Installation of upx</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please create the following folder: <br>
+ C:\Program Files (x86)\upx
+ </li>
+ <li>
+ Please download the latest upx-X-XX-win64.zip version at: <br>
+ <a href="https://github.com/upx/upx/releases/tag/v3.96" target="_blank">https://github.com/upx/upx/releases/tag/v3.96</a>
+ </li>
+ <li>
+ Copy the content of the downloaded zip to “C:\Program Files (x86)\upx”
+ </li>
+ <li>
+ Add gzip to the path Variable. This will make the command globally available on the command line. <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Open a file explorer
+ </li>
+ <li>
+ Within the left file tree, please make a right click on "This PC" and select "Properties" <br>
+ <img src="CompilingGuidelineWin/SelectThisPC.jpg" width="40%">
+ </li>
+ <li>
+ Within the right menu, please click on "Advanced system settings" <br>
+ <img src="CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg" width="50%">
+ </li>
+ <li>
+ Please click on "Environment Variables" <br>
+ <img src="CompilingGuidelineWin/SelectEnvironmentVariables.jpg" width="17%">
+ </li>
+ <li>
+ Within the area of the system variables, please select the "Path" variable and click on "Edit..." <br>
+ <img src="CompilingGuidelineWin/SelectPathVariable.jpg" width="25%">
+ </li>
+ <li>
+ Click on "New" and add the following value: <br>
+ <p style="font-family: 'Courier New', monospace;">C:\Program Files (x86)\upx</p>
+ </li>
+ <li>
+ Close the windows by clicking on "OK"
+ </li>
+ </ol>
+ </li>
+ <li>
+ To check if the configuration is working correctly, please open a command prompt and watch the output of the following command: <br>
+ <p style="font-family: 'Courier New', monospace;">upx</p> <br>
+ <img src="CompilingGuidelineWin/upxCommandLine.jpg" width="50%">
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOf7zip">
+ <a href="#InstallationOf7zip">Installation of 7zip</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please download the latest version of 7zip at: <br>
+ <a href="https://www.7-zip.de/" target="_blank">https://www.7-zip.de/</a>
+ </li>
+ <li>
+ Run the downloaded file as administrator and install 7zip with default settings
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfWix3">
+ <a href="#InstallationOfWix3">Installation of Wix3</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please download wix311.exe at: <br>
+ <a href="https://github.com/wixtoolset/wix3/releases" target="_blank">https://github.com/wixtoolset/wix3/releases</a>
+ </li>
+ <li>
+ Run the downloaded file as administrator and install WiX Toolset with default settings
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfVS2019">
+ <a href="#InstallationOfVS2019">Installation of Microsoft Visual Studio 2019</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Visit the following Microsoft website and log in with a free Microsoft account: <br>
+ <a href="https://my.visualstudio.com/Downloads?q=visual%20studio%202019%20Professional" target="_blank">https://my.visualstudio.com/Downloads?q=visual%20studio%202019%20Professional</a>
+ </li>
+ <li>
+ Please download the latest (trial) version of “Visual Studio Professional 2019” <br>
+ <img src="CompilingGuidelineWin/DownloadVS2019.jpg" width="80%">
+ </li>
+ <li>
+ Run the downloaded file as administrator and go through the wizard. <br>
+ Select the following Workloads for installation: <br>
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Desktop development with C++
+ </li>
+ <li>
+ .NET desktop development
+ </li>
+ </ol>
+ Select the following individual components for installation:
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ .NET
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ .NET 6.0 Runtime
+ </li>
+ <li>
+ .NET Core 3.1 Runtime (LTS)
+ </li>
+ <li>
+ .NET Framework 4 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.5 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.5.1 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.5.2 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.6 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.6.1 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.7.2 targeting pack
+ </li>
+ <li>
+ .NET Framework 4.8 SDK
+ </li>
+ <li>
+ .NET Framework 4.8 targeting pack
+ </li>
+ <li>
+ .NET SDK
+ </li>
+ <li>
+ ML.NET Model Builder (Preview)
+ </li>
+ </ol>
+ </li>
+ <li>
+ Cloud, database, and server
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ CLR data types for SQL Server
+ </li>
+ <li>
+ Connectivity and publishing tools
+ </li>
+ </ol>
+ </li>
+ <li>
+ Code tools
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ NuGet package manager
+ </li>
+ <li>
+ Text Template Transformation
+ </li>
+ </ol>
+ </li>
+ <li>
+ Compilers, build tools, and runtimes
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ .NET Compiler Platform SDK
+ </li>
+ <li>
+ C# and Visual Basic Roslyn compilers
+ </li>
+ <li>
+ C++ 2019 Redistributable Update
+ </li>
+ <li>
+ C++ CMake tools for Windows
+ </li>
+ <li>
+ C++/CLI support for v142 build tools (Latest)
+ </li>
+ <li>
+ MSBuild
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ ARM64 build tools (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ ARM64 Spectre-mitigated libs (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ x64/x86 build tools (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ x64/x86 Spectre-mitigated libs (Latest)
+ </li>
+ </ol>
+ </li>
+ <li>
+ Debugging and testing
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ .NET profiling tools
+ </li>
+ <li>
+ C++ AddressSanatizer
+ </li>
+ <li>
+ C++ profiling tools
+ </li>
+ <li>
+ Just-In-Time debugger
+ </li>
+ <li>
+ Test Adapter for Boost.Test
+ </li>
+ <li>
+ Test Adapter for Google Test
+ </li>
+ </ol>
+ </li>
+ <li>
+ Development activities
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ C# and Visual Basic
+ </li>
+ <li>
+ C++ core features
+ </li>
+ <li>
+ F# language support
+ </li>
+ <li>
+ IntelliCode
+ </li>
+ <li>
+ JavaScript and TypeScript language support
+ </li>
+ <li>
+ Live Share
+ </li>
+ </ol>
+ </li>
+ <li>
+ Emulators
+ <ol style="list-style-type: upper-roman;">
+ NONE
+ </ol>
+ </li>
+ <li>
+ Games and Graphics
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ Graphics debugger and GPU profiler for DirectX
+ </li>
+ </ol>
+ </li>
+ <li>
+ SDKs, libraries, and frameworks
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ C++ ATL for latest v142 build tools (ARM64)
+ </li>
+ <li>
+ C++ ATL for latest v142 build tools (x86 & x64)
+ </li>
+ <li>
+ C++ ATL for latest v142 build tools with Spectre Mitigations (ARM64)
+ </li>
+ <li>
+ C++ ATL for latest v142 build tools with Spectre Mitigations (x86 & x64)
+ </li>
+ <li>
+ C++ MFC for latest v142 build tools (ARM64)
+ </li>
+ <li>
+ C++ MFC for latest v142 build tools (x86 & x64)
+ </li>
+ <li>
+ C++ MFC for latest v142 build tools with Spectre Mitigations (ARM64)
+ </li>
+ <li>
+ C++ MFC for latest v142 build tools with Spectre Mitigations (x86 & x64)
+ </li>
+ <li>
+ Entity Framework 6 tools
+ </li>
+ <li>
+ TypeScript 4.3 SDK
+ </li>
+ <li>
+ Windows 10 SDK (10.0.19041.0)
+ </li>
+ <li>
+ Windows Universal C Runtime
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfWDK10">
+ <a href="#InstallationOfWDK10">Installation of the Windows Driver Kit version 2004</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please download the Windows Driver Kit (WDK) version 2004 at: <br>
+ <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads" target="_blank">https://docs.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads</a>
+ </li>
+ <li>
+ Run the downloaded file as administrator and install the WDK with default settings
+ </li>
+ <li>
+ At the end of the installation you will be asked if you want to "install Windows Driver Kit Visual Studio extension". <br>
+ Please make sure, that this option is selected before closing the dialog.
+ </li>
+ <li>
+ A different setup will start automatically and will detect Visual Studio Professional 2019 as possible target for the extension. <br>
+ Please select it and proceed with the installation.
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="InstallationOfVisualBuildTools">
+ <a href="#InstallationOfVisualBuildTools">Installation of the Visual Studio build tools</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Visit the following Microsoft website and log in with a free Microsoft account: <br>
+ <a href="https://my.visualstudio.com/Downloads?q=visual%20studio%202019%20build%20tools" target="_blank">https://my.visualstudio.com/Downloads?q=visual%20studio%202019%20build%20tools</a>
+ </li>
+ <li>
+ Please download the latest version of “Build Tools for Visual Studio 2019” <br>
+ <img src="CompilingGuidelineWin/DownloadVSBuildTools.jpg" width="80%">
+ </li>
+ <li>
+ Run the downloaded file as administrator and go through the wizard. Select the following individual components for installation:
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ .NET
+ <ol style="list-style-type: upper-roman;">
+ NONE
+ </ol>
+ </li>
+ <li>
+ Cloud, database, and server
+ <ol style="list-style-type: upper-roman;">
+ NONE
+ </ol>
+ </li>
+ <li>
+ Code tools
+ <ol style="list-style-type: upper-roman;">
+ NONE
+ </ol>
+ </li>
+ <li>
+ Compilers, build tools, and runtimes
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ C++/CLI support for v142 build tools (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ ARM64 build tools (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ ARM64 Spectre-mitigated libs (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ x64/x86 build tools (Latest)
+ </li>
+ <li>
+ MSVC v142 - VS 2019 C++ x64/x86 Spectre-mitigated libs (Latest)
+ </li>
+ </ol>
+ </li>
+ <li>
+ Debugging and testing
+ <ol style="list-style-type: upper-roman;">
+ NONE
+ </ol>
+ </li>
+ <li>
+ Development activities
+ <ol style="list-style-type: upper-roman;">
+ NONE
+ </ol>
+ </li>
+ <li>
+ SDKs, libraries, and frameworks
+ <ol style="list-style-type: upper-roman;">
+ <li>
+ C++ ATL for latest v142 build tools (ARM64)
+ </li>
+ <li>
+ C++ ATL for latest v142 build tools (x86 & x64)
+ </li>
+ <li>
+ C++ ATL for latest v142 build tools with Spectre Mitigations (ARM64)
+ </li>
+ <li>
+ C++ ATL for latest v142 build tools with Spectre Mitigations (x86 & x64)
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="DownloadVeraCrypt">
+ <a href="#DownloadVeraCrypt">Download VeraCrypt Source Files</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Visit the VeraCrypt Github repository at: <br>
+ <a href="https://github.com/veracrypt/VeraCrypt" target="_blank">https://github.com/veracrypt/VeraCrypt</a>
+ </li>
+ <li>
+ Please click on the green button with the label "Code" and download the code. <br>
+ You can download the repository as zip file, but you may consider to use the git protocol in order to track changes.
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="CompileWin32X64">
+ <a href="#CompileWin32X64">Compile the Win32/x64 Versions of VeraCrypt</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please open the file "src/VeraCrypt.sln" in Visual Studio <b>2010</b>
+ </li>
+ <li>
+ Please select "All|Win32" as active configuration <br>
+ <img src="CompilingGuidelineWin/VS2010Win32Config.jpg" width="80%">
+ </li>
+ <li>
+ Please click on "Build -> Build Solution" <br>
+ <img src="CompilingGuidelineWin/VS2010BuildSolution.jpg" width="40%">
+ </li>
+ <li>
+ The compiling process should end with warnings, but without errors. Some projects should be skipped.
+ </li>
+ <li>
+ Please select "All|x64" as active configuration <br>
+ <img src="CompilingGuidelineWin/VS2010X64Config.jpg" width="80%">
+ </li>
+ <li>
+ Please click on "Build -> Build Solution" <br>
+ <img src="CompilingGuidelineWin/VS2010BuildSolution.jpg" width="40%">
+ </li>
+ <li>
+ The compiling process should end with warnings, but without errors. Some projects should be skipped. <br>
+ Please close Visual Studio 2010 after the compiling process finished
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="CompileARM64">
+ <a href="#CompileARM64">Compile the ARM64 Version of VeraCrypt</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please open the file "src/VeraCrypt_vs2019.sln" in Visual Studio <b>2019</b>
+ </li>
+ <li>
+ Please select "All|ARM64" as active configuration <br>
+ <img src="CompilingGuidelineWin/VS2019ARM64Config.jpg" width="80%">
+ </li>
+ <li>
+ Please click on "Build -> Build Solution" <br>
+ <img src="CompilingGuidelineWin/VS2019BuildSolution.jpg" width="40%">
+ </li>
+ <li>
+ The compiling process should end with warnings, but without errors. One project should be skipped. <br>
+ Please close Visual Studio 2019 after the compiling process finished
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="BuildVeraCryptExecutables">
+ <a href="#BuildVeraCryptExecutables">Build the VeraCrypt Executables</a>
+ <div class="texttohide">
+ <p>
+ <ol>
+ <li>
+ Please open a command line as administrator
+ </li>
+ <li>
+ Go into the folder "src/Signing/"
+ </li>
+ <li>
+ Run the script "sign_test.bat"
+ </li>
+ <li>
+ You will find the generated exectuables within the folder "src/Release/Setup Files"
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="ImportCertificates">
+ <a href="#ImportCertificates">Import the Certificates</a>
+ <div class="texttohide">
+ <p> With the sign_test.bat script you just signed the VeraCrypt executables. This is necessary, since Windows only accepts drivers, which are trusted by a signed Certificate Authority. <br>
+ Since you did not use the official VeraCrypt signing certificate to sign your code, but a public development version, you have to import and therefore trust the certificates used.
+ <ol>
+ <li>
+ Open the folder "src/Signing"
+ </li>
+ <li>
+ Import the following certificates to your Local Machine Certificate storage, by double clicking them:
+ <ul>
+ <li>GlobalSign_R3Cross.cer</li>
+ <li>GlobalSign_SHA256_EV_CodeSigning_CA.cer</li>
+ <li>TestCertificates/idrix_codeSign.pfx</li>
+ <li>TestCertificates/idrix_Sha256CodeSign.pfx</li>
+ <li>TestCertificates/idrix_SHA256TestRootCA.crt</li>
+ <li>TestCertificates/idrix_TestRootCA.crt</li>
+ </ul>
+ Note: If prompted, the password for .pfx certificates is <b>idrix</b>.
+ </li>
+ </ol>
+ </p>
+ </div>
+ </div>
+
+ <div class="textbox" id="KnownIssues">
+ <a href="#KnownIssues">Known Issues</a>
+ <div class="texttohide">
+ <p>
+ <ul>
+ <li>
+ <b>This distribution package is damaged</b> <br>
+ <img src="CompilingGuidelineWin/DistributionPackageDamaged.jpg" width="20%"> <br>
+ On Windows 10 or higher you might get the error message above. In order to avoid this, you will need to:<br>
+ <ul>
+ <li>Double-check the installation of the root certificate that issued the test code signing certificate in the "Local Machine Trusted Root Certification Authorities" store.</li>
+ <li>Compute SHA512 fingerprint of the test code signing certificate and update the gpbSha512CodeSignCertFingerprint array in the file "src/Common/Dlgcode.c" accordingly.</li>
+ </ul>
+ Please see <a href="https://sourceforge.net/p/veracrypt/discussion/technical/thread/83d5a2d6e8/#db12" target="_blank">https://sourceforge.net/p/veracrypt/discussion/technical/thread/83d5a2d6e8/#db12</a> for further details.<br>
+ <br>
+ Another approach is to disable the signature verification in the VeraCrypt code. This should be done only for testing purposes and not for production use:
+ <ol>
+ <li>
+ Open the file "src/Common/Dlgcode.c"
+ </li>
+ <li>
+ Look for the function "VerifyModuleSignature"
+ </li>
+ <li>
+ Replace the following lines: <br>
+ Find:<br>
+ <p style="font-family: 'Courier New', monospace;">
+ if (!IsOSAtLeast (WIN_10)) <br>
+ return TRUE;
+ </p> <br>
+ Replace:<br>
+ <p style="font-family: 'Courier New', monospace;">
+ return TRUE;
+ </p>
+ </li>
+ <li>
+ Compile the VeraCrypt code again
+ </li>
+ </ol>
+ </li>
+ <li>
+ <b>Driver Installation Failure during VeraCrypt Setup from Custom Builds</b> <br>
+ <img src="CompilingGuidelineWin/CertVerifyFails.jpg" width="20%"> <br>
+ Windows validates the signature for every driver which is going to be installed.<br>
+ For security reasons, Windows allows only drivers signed by Microsoft to load.<br>
+ So, when using a custom build:<br>
+ <ul>
+ <li>If you have not modified the VeraCrypt driver source code, you can use the Microsoft-signed drivers included in the VeraCrypt source code (under "src\Release\Setup Files").</li>
+ <li>If you have made modifications, <strong>you will need to boot Windows into "Test Mode"</strong>. This mode allows Windows to load drivers that aren't signed by Microsoft. However, even in "Test Mode", there are certain requirements for signatures, and failures can still occur due to reasons discussed below.</li>
+ </ul>
+ Potential Causes for Installation Failure under "Test Mode":
+ <ol>
+ <li>
+ <b>The certificate used for signing is not trusted by Windows</b><br>
+ You can verify if you are affected by checking the properties of the executable:
+ <ol>
+ <li>
+ Make a right click on the VeraCrypt Setup executable: "src/Release/Setup Files/VeraCrypt Setup 1.XX.exe"
+ </li>
+ <li>
+ Click on properties
+ </li>
+ <li>
+ Go to the top menu "Digital Signatures". Her you will find two signatures in the Signature list
+ </li>
+ Check both by double clicking on it. If the headline says "The certificate in the signature cannot be verified", the corresponding signing certificate was not imported correctly.<br>
+ Click on "View Certificate" and then on "Install Certificate..." to import the certificate to Local Machine certificate storage. For the Root certificates, you may need to choose "Place all certificates in the following store", and select the "Trusted Root Certification Authorities" store.<br>
+ <img src="CompilingGuidelineWin/CertificateCannotBeVerified.jpg" width="40%"> <br>
+ <li>
+ </ol>
+ </li>
+ <li>
+ <b>The driver was modified after the signing process.</b> <br>
+ In this case, please use the script "src/Signing/sign_test.bat" to sign your code again with the test certificates
+ </li>
+ </ol>
+ </li>
+ </ul>
+ </p>
+ </div>
+ </div>
+
+</div>
+</body></html>
diff --git a/doc/html/CompilingGuidelineWin/AddNewSystemVar.jpg b/doc/html/CompilingGuidelineWin/AddNewSystemVar.jpg
new file mode 100644
index 00000000..8e4bded1
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/AddNewSystemVar.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/CertVerifyFails.jpg b/doc/html/CompilingGuidelineWin/CertVerifyFails.jpg
new file mode 100644
index 00000000..c7166ffa
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/CertVerifyFails.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/CertificateCannotBeVerified.jpg b/doc/html/CompilingGuidelineWin/CertificateCannotBeVerified.jpg
new file mode 100644
index 00000000..f5dc2f21
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/CertificateCannotBeVerified.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/DistributionPackageDamaged.jpg b/doc/html/CompilingGuidelineWin/DistributionPackageDamaged.jpg
new file mode 100644
index 00000000..e04f07c7
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/DistributionPackageDamaged.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/DownloadVS2010.jpg b/doc/html/CompilingGuidelineWin/DownloadVS2010.jpg
new file mode 100644
index 00000000..1e4ba165
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/DownloadVS2010.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/DownloadVS2019.jpg b/doc/html/CompilingGuidelineWin/DownloadVS2019.jpg
new file mode 100644
index 00000000..98428292
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/DownloadVS2019.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/DownloadVSBuildTools.jpg b/doc/html/CompilingGuidelineWin/DownloadVSBuildTools.jpg
new file mode 100644
index 00000000..37217733
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/DownloadVSBuildTools.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/NasmCommandLine.jpg b/doc/html/CompilingGuidelineWin/NasmCommandLine.jpg
new file mode 100644
index 00000000..d3a2f2f3
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/NasmCommandLine.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/RegeditPermissions-1.jpg b/doc/html/CompilingGuidelineWin/RegeditPermissions-1.jpg
new file mode 100644
index 00000000..46fcabbc
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/RegeditPermissions-1.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/RegeditPermissions-2.jpg b/doc/html/CompilingGuidelineWin/RegeditPermissions-2.jpg
new file mode 100644
index 00000000..5e3432cc
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/RegeditPermissions-2.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/RegeditPermissions-3.jpg b/doc/html/CompilingGuidelineWin/RegeditPermissions-3.jpg
new file mode 100644
index 00000000..7aa66aa0
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/RegeditPermissions-3.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/RegeditPermissions-4.jpg b/doc/html/CompilingGuidelineWin/RegeditPermissions-4.jpg
new file mode 100644
index 00000000..aa9f1c7b
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/RegeditPermissions-4.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg b/doc/html/CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg
new file mode 100644
index 00000000..753840d5
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/SelectAdvancedSystemSettings.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/SelectEnvironmentVariables.jpg b/doc/html/CompilingGuidelineWin/SelectEnvironmentVariables.jpg
new file mode 100644
index 00000000..709589ba
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/SelectEnvironmentVariables.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/SelectPathVariable.jpg b/doc/html/CompilingGuidelineWin/SelectPathVariable.jpg
new file mode 100644
index 00000000..ef5aa44d
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/SelectPathVariable.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/SelectThisPC.jpg b/doc/html/CompilingGuidelineWin/SelectThisPC.jpg
new file mode 100644
index 00000000..439182d7
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/SelectThisPC.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/VS2010BuildSolution.jpg b/doc/html/CompilingGuidelineWin/VS2010BuildSolution.jpg
new file mode 100644
index 00000000..7870cb51
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/VS2010BuildSolution.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/VS2010Win32Config.jpg b/doc/html/CompilingGuidelineWin/VS2010Win32Config.jpg
new file mode 100644
index 00000000..f0be29b0
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/VS2010Win32Config.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/VS2010X64Config.jpg b/doc/html/CompilingGuidelineWin/VS2010X64Config.jpg
new file mode 100644
index 00000000..b8d989a2
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/VS2010X64Config.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/VS2019ARM64Config.jpg b/doc/html/CompilingGuidelineWin/VS2019ARM64Config.jpg
new file mode 100644
index 00000000..825079da
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/VS2019ARM64Config.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/VS2019BuildSolution.jpg b/doc/html/CompilingGuidelineWin/VS2019BuildSolution.jpg
new file mode 100644
index 00000000..015ab357
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/VS2019BuildSolution.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/YasmCommandLine.jpg b/doc/html/CompilingGuidelineWin/YasmCommandLine.jpg
new file mode 100644
index 00000000..9b414160
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/YasmCommandLine.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/gzipCommandLine.jpg b/doc/html/CompilingGuidelineWin/gzipCommandLine.jpg
new file mode 100644
index 00000000..958f3f6a
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/gzipCommandLine.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelineWin/upxCommandLine.jpg b/doc/html/CompilingGuidelineWin/upxCommandLine.jpg
new file mode 100644
index 00000000..cb0af820
--- /dev/null
+++ b/doc/html/CompilingGuidelineWin/upxCommandLine.jpg
Binary files differ
diff --git a/doc/html/CompilingGuidelines.html b/doc/html/CompilingGuidelines.html
new file mode 100644
index 00000000..22d30d34
--- /dev/null
+++ b/doc/html/CompilingGuidelines.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
+<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
+<meta name="keywords" content="encryption, security"/>
+<link href="styles.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<div>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+</div>
+
+<div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
+ </ul>
+</div>
+
+<div>
+<p>
+<a href="Documentation.html">Documentation</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="Technical%20Details.html">Technical Details</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="CompilingGuidelines.html">Building VeraCrypt From Source</a>
+</p></div>
+
+<div class="wikidoc">
+<h1>Building VeraCrypt From Source</h1>
+<p>In order to build VeraCrypt from the source code, you can follow these step-by-step guidelines:
+<ul style="text-align:left; margin-top:18px; margin-bottom:19px; padding-top:0px; padding-bottom:0px">
+<li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
+<a href="CompilingGuidelineWin.html" style="text-align:left; color:#0080c0; text-decoration:none.html">Windows Build Guide</a>
+</li><li style="text-align:left; margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px">
+<a href="CompilingGuidelineLinux.html" style="text-align:left; color:#0080c0; text-decoration:none.html">Linux Build Guide</a>
+</li></ul>
+</p>
+</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Contact.html b/doc/html/Contact.html
index 5e114af9..36d8755a 100644
--- a/doc/html/Contact.html
+++ b/doc/html/Contact.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Contact.html">Contact</a>
</p></div>
diff --git a/doc/html/Contributed Resources.html b/doc/html/Contributed Resources.html
index 97045cac..fda44f9c 100644
--- a/doc/html/Contributed Resources.html
+++ b/doc/html/Contributed Resources.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a class="active" href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div class="wikidoc">
<p>Here you'll find useful resources contributed by VeraCrypt users.</p>
<h3>Third party binaries:</h3>
<ul>
<li>Linux Ubuntu <strong>PPA</strong> provided by user&nbsp;<a href="https://unit193.net/" target="_blank">&quot;Unit 193&quot;</a> (build done by Launchpad):
<ul>
<li><a href="https://launchpad.net/~unit193/&#43;archive/ubuntu/encryption" target="_blank">https://launchpad.net/~unit193/&#43;archive/ubuntu/encryption</a>
diff --git a/doc/html/Conversion_Guide_VeraCrypt_1.26_and_Later.html b/doc/html/Conversion_Guide_VeraCrypt_1.26_and_Later.html
new file mode 100644
index 00000000..493d371c
--- /dev/null
+++ b/doc/html/Conversion_Guide_VeraCrypt_1.26_and_Later.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>VeraCrypt - Conversion Guide for Versions 1.26 and Later</title>
+<meta name="description" content="Guide on how to handle deprecated features and conversion of TrueCrypt volumes in VeraCrypt versions 1.26 and later."/>
+<meta name="keywords" content="VeraCrypt, TrueCrypt, Conversion, Encryption, Security"/>
+<link href="styles.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<div>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+</div>
+
+<div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
+ </ul>
+</div>
+
+<div>
+<p>
+<a href="Documentation.html">Documentation</a>
+<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
+<a href="Conversion_Guide_VeraCrypt_1.26_and_Later.html">Conversion Guide for Versions 1.26 and Later</a>
+</p></div>
+
+<div class="wikidoc">
+<h1>Conversion Guide for VeraCrypt 1.26 and Later</h1>
+
+<h2>1. Introduction</h2>
+<p>Version 1.26 and newer of VeraCrypt have introduced significant changes by removing support for certain features. If you encounter issues while mounting volumes, this guide will help you understand and resolve them.</p>
+
+<h2>2. Deprecated Features in VeraCrypt 1.26 and Later</h2>
+<p>The following features have been deprecated:</p>
+<ul>
+<li>TrueCrypt Mode</li>
+<li>HMAC-RIPEMD-160 Hash Algorithm</li>
+<li>GOST89 Encryption Algorithm</li>
+</ul>
+<p>If you experience mounting errors with volumes created in VeraCrypt 1.25.9 or older, use VeraCrypt 1.25.9 to check if these deprecated features are in use. Highlight the volume and click on "Volume Properties" in the GUI to check.</p>
+
+<h2>3. Remediation Procedures Based on Version</h2>
+
+<h3>3.1 Scenario 1: Using VeraCrypt 1.25.9 or Older</h3>
+<p>If you are using or can upgrade to VeraCrypt 1.25.9, follow these steps:</p>
+<ul>
+<li>Convert TrueCrypt Volumes to VeraCrypt Volumes</li>
+<li>Change from Deprecated HMAC-RIPEMD-160 Hash Algorithm</li>
+<li>Recreate VeraCrypt Volume if Using GOST89 Encryption Algorithm</li>
+</ul>
+<p>Download the 1.25.9 version <a href="https://veracrypt.fr/en/Downloads_1.25.9.html">here</a>.</p>
+
+<h3>3.2 Scenario 2: Upgraded to VeraCrypt 1.26 or Newer</h3>
+<p>If you have already upgraded to VeraCrypt 1.26 or newer, follow these steps:</p>
+<ul>
+<li>Convert TrueCrypt Volumes to VeraCrypt Volumes</li>
+<li>Change from Deprecated HMAC-RIPEMD-160 Hash Algorithm</li>
+</ul>
+<p>If you are on Linux or Mac, temporarily downgrade to VeraCrypt 1.25.9. Windows users can use the VCPassChanger tool <a href="https://launchpad.net/veracrypt/trunk/1.25.9/+download/VCPassChanger_%28TrueCrypt_Convertion%29.zip">that can be downloaded from here</a>.</p>
+<ul>
+<li>Recreate VeraCrypt Volume if Using GOST89 Encryption Algorithm</li>
+</ul>
+All OSes temporarily downgrade to 1.25.9 version.
+<h2>4. Conversion and Remediation Procedures</h2>
+
+<h3>4.1 Converting TrueCrypt Volumes to VeraCrypt</h3>
+<p>TrueCrypt file containers and partitions created with TrueCrypt versions 6.x or 7.x can be converted to VeraCrypt using VeraCrypt 1.25.9 or the VCPassChanger tool on Windows. For more details, refer to the <a href="Converting%20TrueCrypt%20volumes%20and%20partitions.html">documentation</a>.</p>
+<p>After conversion, the file extension will remain as <code>.tc</code>. Manually change it to <code>.hc</code> if you want VeraCrypt 1.26 or newer to automatically recognize it.</p>
+
+<h3>4.2 Changing Deprecated HMAC-RIPEMD-160 Hash Algorithm</h3>
+<p>Use the "Set Header Key Derivation Algorithm" feature to change the HMAC-RIPEMD-160 hash algorithm to one supported in VeraCrypt 1.26. Refer to the <a href="Hash%20Algorithms.html">documentation</a> for more details.</p>
+
+<h3>4.3 Recreating VeraCrypt Volume if Using GOST89 Encryption Algorithm</h3>
+<p>If your volume uses the GOST89 encryption algorithm, you will need to copy your data elsewhere and recreate the volume using a supported encryption algorithm. More details are available in the <a href="Encryption%20Algorithms.html">encryption algorithm documentation</a>.</p>
+
+<h2>5. Important Notes</h2>
+<p><strong>Note to users who created volumes with VeraCrypt 1.17 or earlier:</strong></p>
+<blockquote>
+<p>To avoid revealing whether your volumes contain a hidden volume or not, or if you rely on plausible deniability, you must recreate both the outer and hidden volumes, including system encryption and hidden OS. Discard existing volumes created prior to VeraCrypt 1.18a.</p>
+</blockquote>
+
+<p>For more information, visit:</p>
+<ul>
+<li><a href="TrueCrypt%20Support.html">TrueCrypt Support</a></li>
+<li><a href="Converting%20TrueCrypt%20volumes%20and%20partitions.html">Converting TrueCrypt Volumes and Partitions</a></li>
+</ul>
+
+</div>
+
+<div class="ClearBoth"></div>
+</body>
+</html>
diff --git a/doc/html/Converting TrueCrypt volumes and partitions.html b/doc/html/Converting TrueCrypt volumes and partitions.html
index 324c8c53..b5485266 100644
--- a/doc/html/Converting TrueCrypt volumes and partitions.html
+++ b/doc/html/Converting TrueCrypt volumes and partitions.html
@@ -1,43 +1,47 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Converting%20TrueCrypt%20volumes%20and%20partitions.html">Converting TrueCrypt volumes and partitions</a>
</p></div>
<div class="wikidoc">
<h1>Converting TrueCrypt volumes and partitions</h1>
-<p>Starting from version 1.0f, TrueCrypt volumes and <strong>non-system</strong> partitions can be converted to VeraCrypt format using any of the following actions:</p>
+<p><strong>⚠️ Warning:</strong> <span style="color: red;">After conversion, ensure that the "TrueCrypt Mode" checkbox is not selected during the mount of the converted volume. Since it is no longer a TrueCrypt volume, mounting it with this option will lead to a mount failure.</span></p>
+<p><strong>⚠️ Important Notice:</strong> As of version 1.26, VeraCrypt has removed support for "TrueCrypt Mode." Consequently, the conversion of TrueCrypt volumes and partitions using this method is no longer possible. Please refer to <a href="Conversion_Guide_VeraCrypt_1.26_and_Later.html">this documentation page</a> for guidance on how to proceed with TrueCrypt volumes in VeraCrypt versions 1.26 and later.</p>
+<p>From version 1.0f up to and including version 1.25.9, TrueCrypt volumes and <strong>non-system</strong> partitions created with TrueCrypt versions 6.x and 7.x, starting with version 6.0 released on July 4th 2008, can be converted to VeraCrypt format using any of the following actions:</p>
<ul>
<li>Change Volume Password </li><li>Set Header Key Derivation Algorithm </li><li>Add/Remove key files </li><li>Remove all key files </li></ul>
-<p>&ldquo;TrueCrypt Mode&rdquo; must be checked in the dialog as show below:</p>
-<p>&nbsp;<img src="Converting TrueCrypt volumes and partitions_truecrypt_convertion.jpg" alt="" width="511" height="436"></p>
+<p>If the TrueCrypt volume contains a hidden volume, it should also be converted using the same approach, by specifying the hidden volume password and/or keyfiles.</p>
+<p>🚨 After conversion of a file container, the file extension will remain as .tc. Manually change it to .hc if you want VeraCrypt 1.26 or newer to automatically recognize it.</p>
+<p>&ldquo;TrueCrypt Mode&rdquo; must be checked in the dialog as shown below:</p>
+<p>&nbsp;<img src="Converting TrueCrypt volumes and partitions_truecrypt_convertion.jpg" alt=""></p>
<p><strong>Note: </strong>Converting system partitions encrypted with TrueCrypt is not supported.</p>
</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Converting TrueCrypt volumes and partitions_truecrypt_convertion.jpg b/doc/html/Converting TrueCrypt volumes and partitions_truecrypt_convertion.jpg
index 12119bfd..8a2d4d58 100644
--- a/doc/html/Converting TrueCrypt volumes and partitions_truecrypt_convertion.jpg
+++ b/doc/html/Converting TrueCrypt volumes and partitions_truecrypt_convertion.jpg
Binary files differ
diff --git a/doc/html/Creating New Volumes.html b/doc/html/Creating New Volumes.html
index 9dc7ef69..7fe6144e 100644
--- a/doc/html/Creating New Volumes.html
+++ b/doc/html/Creating New Volumes.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="VeraCrypt%20Volume.html">VeraCrypt Volume</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Creating%20New%20Volumes.html">Creating New Volumes</a>
@@ -42,41 +42,41 @@
from the system (for more information, please see the section <a href="Random%20Number%20Generator.html">
<em>Random Number Generator</em></a>). The Wizard provides help and information necessary to successfully create a new VeraCrypt volume. However, several items deserve further explanation:</p>
<h3>Hash Algorithm</h3>
<p>Allows you to select which hash algorithm VeraCrypt will use. The selected hash algorithm is used by the random number generator (as a pseudorandom mixing function), which generates the master key, secondary key (XTS mode), and salt (for more information,
please see the section <a href="Random%20Number%20Generator.html">
<em>Random Number Generator</em></a>). It is also used in deriving the new volume header key and secondary header key (see the section
<a href="Header%20Key%20Derivation.html">
<em>Header Key Derivation, Salt, and Iteration Count</em></a>).<br>
<br>
For information about the implemented hash algorithms, see the chapter <a href="Hash%20Algorithms.html">
<em>Hash Algorithms.</em></a><br>
<br>
Note that the output of a hash function is <em>never </em>used directly as an encryption key. For more information, please refer to the chapter
<a href="Technical%20Details.html"><em>Technical Details</em></a>.</p>
<h3>Encryption Algorithm</h3>
<p>This allows you to select the encryption algorithm with which your new volume will be encrypted. Note that the encryption algorithm cannot be changed after the volume is created. For more information, please see the chapter
<a href="Encryption%20Algorithms.html"><em>Encryption Algorithms</em></a>.</p>
<h3 id="QuickFormat">Quick Format</h3>
<p>If unchecked, each sector of the new volume will be formatted. This means that the new volume will be
<em>entirely </em>filled with random data. Quick format is much faster but may be less secure because until the whole volume has been filled with files, it may be possible to tell how much data it contains (if the space was not filled with random data beforehand).
- If you are not sure whether to enable or disable Quick Format, we recommend that you leave this option unchecked. Note that Quick Format can only be enabled when encrypting partitions/devices.</p>
+ If you are not sure whether to enable or disable Quick Format, we recommend that you leave this option unchecked. Note that Quick Format can only be enabled when encrypting partitions/devices, except on Windows where it is also available when creating file containers.</p>
<p>Important: When encrypting a partition/device within which you intend to create a hidden volume afterwards, leave this option unchecked.</p>
<h3 id="dynamic">Dynamic</h3>
<p>Dynamic VeraCrypt container is a pre-allocated NTFS sparse file whose physical size (actual disk space used) grows as new data is added to it. Note that the physical size of the container (actual disk space that the container uses) will not decrease when
files are deleted on the VeraCrypt volume. The physical size of the container can only
<em>increase </em>up to the maximum value that is specified by the user during the volume creation process. After the maximum specified size is reached, the physical size of the container will remain constant.<br>
<br>
Note that sparse files can only be created in the NTFS file system. If you are creating a container in the FAT file system, the option
<em>Dynamic </em>will be disabled (&ldquo;grayed out&rdquo;).<br>
<br>
Note that the size of a dynamic (sparse-file-hosted) VeraCrypt volume reported by Windows and by VeraCrypt will always be equal to its maximum size (which you specify when creating the volume). To find out current physical size of the container (actual disk
space it uses), right-click the container file (in a Windows Explorer window, not in VeraCrypt), then select
<em>Properties </em>and see the Size on disk value.</p>
<p>WARNING: Performance of dynamic (sparse-file-hosted) VeraCrypt volumes is significantly worse than performance of regular volumes. Dynamic (sparse-file-hosted) VeraCrypt volumes are also less secure, because it is possible to tell which volume sectors are
unused. Furthermore, if data is written to a dynamic volume when there is not enough free space in its host file system, the encrypted file system may get corrupted.</p>
<h3>Cluster Size</h3>
<p>Cluster is an allocation unit. For example, one cluster is allocated on a FAT file system for a one- byte file. When the file grows beyond the cluster boundary, another cluster is allocated. Theoretically, this means that the bigger the cluster size, the
more disk space is wasted; however, the better the performance. If you do not know which value to use, use the default.</p>
<h3>VeraCrypt Volumes on CDs and DVDs</h3>
<p>If you want a VeraCrypt volume to be stored on a CD or a DVD, first create a file-hosted VeraCrypt container on a hard drive and then burn it onto a CD/DVD using any CD/DVD burning software (or, under Windows XP or later, using the CD burning tool provided
with the operating system). Remember that if you need to mount a VeraCrypt volume that is stored on a read-only medium (such as a CD/DVD) under Windows 2000, you must format the VeraCrypt volume as FAT. The reason is that Windows 2000 cannot mount NTFS file
diff --git a/doc/html/Data Leaks.html b/doc/html/Data Leaks.html
index ee37fd69..e12e07a3 100644
--- a/doc/html/Data Leaks.html
+++ b/doc/html/Data Leaks.html
@@ -1,61 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Security%20Requirements%20and%20Precautions.html">Security Requirements and Precautions</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Data%20Leaks.html">Data Leaks</a>
</p></div>
<div class="wikidoc">
<h2>Data Leaks</h2>
<p>When a VeraCrypt volume is mounted, the operating system and third-party applications may write to unencrypted volumes (typically, to the unencrypted system volume) unencrypted information about the data stored in the VeraCrypt volume (e.g. filenames and
- locations of recently accessed files, databases created by file indexing tools, etc.), or the data itself in an unencrypted form (temporary files, etc.), or unencrypted information about the filesystem residing in the VeraCrypt volume. Note that Windows automatically
- records large amounts of potentially sensitive data, such as the names and locations of files you open, applications you run, etc.</p>
+ locations of recently accessed files, databases created by file indexing tools, etc.), or the data itself in an unencrypted form (temporary files, etc.), or unencrypted information about the filesystem residing in the VeraCrypt volume.</p>
+<p>Note that Windows automatically records large amounts of potentially sensitive data, such as the names and locations of files you open, applications you run, etc. For example, Windows uses a set of Registry keys known as “shellbags” to store the name, size, view, icon, and position of a folder when using Explorer.
+Each time you open a folder, this information is updated including the time and date of access. Windows Shellbags may be found in a few locations, depending on operating system version and user profile.
+On a Windows XP system, shellbags may be found under <strong>"HKEY_USERS\{USERID}\Software\Microsoft\Windows\Shell\"</strong> and <strong>"HKEY_USERS\{USERID}\Software\Microsoft\Windows\ShellNoRoam\"</strong>.
+On a Windows 7 system, shellbags may be found under <strong>"HEKY_USERS\{USERID}\Local Settings\Software\Microsoft\Windows\Shell\"</strong>. More information available at <a href="https://www.sans.org/reading-room/whitepapers/forensics/windows-shellbag-forensics-in-depth-34545" target="_blank">https://www.sans.org/reading-room/whitepapers/forensics/windows-shellbag-forensics-in-depth-34545</a>.
<p>Also, starting from Windows 8, every time a VeraCrypt volume that is formatted using NTFS is mounted, an Event 98 is written for the system Events Log and it will contain the device name (\\device\VeraCryptVolumeXX) of the volume. This event log &quot;feature&quot;
was introduced in Windows 8 as part of newly introduced NTFS health checks as explained
<a href="https://blogs.msdn.microsoft.com/b8/2012/05/09/redesigning-chkdsk-and-the-new-ntfs-health-model/" target="_blank">
here</a>. To avoid this leak, the VeraCrypt volume must be mounted <a href="Removable%20Medium%20Volume.html">
as a removable medium</a>. Big thanks to Liran Elharar for discovering this leak and its workaround.<br>
<br>
In order to prevent data leaks, you must follow these steps (alternative steps may exist):</p>
<ul>
<li>If you do <em>not</em> need plausible deniability:
<ul>
<li>Encrypt the system partition/drive (for information on how to do so, see the chapter
<a href="System%20Encryption.html"><em>System Encryption</em></a>) and ensure that only encrypted or read-only filesystems are mounted during each session in which you work with sensitive data.<br>
<br>
or, </li><li>If you cannot do the above, download or create a &quot;live CD&quot; version of your operating system (i.e. a &quot;live&quot; system entirely stored on and booted from a CD/DVD) that ensures that any data written to the system volume is written to a RAM disk. When you need
to work with sensitive data, boot such a live CD/DVD and ensure that only encrypted and/or read-only filesystems are mounted during the session.
</li></ul>
</li><li>If you need plausible deniability:
<ul>
<li>Create a hidden operating system. VeraCrypt will provide automatic data leak protection. For more information, see the section
<a href="Hidden%20Operating%20System.html">
diff --git a/doc/html/Default Mount Parameters.html b/doc/html/Default Mount Parameters.html
index 899c4280..a55a0f0a 100644
--- a/doc/html/Default Mount Parameters.html
+++ b/doc/html/Default Mount Parameters.html
@@ -1,51 +1,51 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Default%20Mount%20Parameters.html">Default Mount Parameters</a>
</p></div>
<div class="wikidoc">
<h2>Default Mount Parameters</h2>
<p>Starting from version 1.0f-2, it is possible to specify the PRF algorithm and the TrueCrypt mode that will be selected by default in the password dialog.</p>
<p>As show below, select the entry &quot;Default Mount Parameters&quot; under the menu &quot;Settings&quot;:</p>
-<p><img src="Home_VeraCrypt_menu_Default_Mount_Parameters.png" alt="Menu Default Mount Parameters" width="241" height="254"></p>
+<p><img src="Home_VeraCrypt_menu_Default_Mount_Parameters.png" alt="Menu Default Mount Parameters"></p>
<p>&nbsp;</p>
<p>The following dialog will be displayed:</p>
-<p><img src="Home_VeraCrypt_Default_Mount_Parameters.png" alt="Default Mount Parameters Dialog" width="267" height="144"></p>
+<p><img src="Home_VeraCrypt_Default_Mount_Parameters.png" alt="Default Mount Parameters Dialog"></p>
<p>Make your modifications and then click OK.</p>
<p>The chosen values are then written to VeraCrypt main configuration file (Configuration.xml) making them persistent.</p>
<p>All subsequent password request dialogs will use the default values chosen previously. For example, if in the Default Mount Parameters dialog you check TrueCrypt Mode and you select SHA-512 as a PRF, then subsequent password dialogs will look like:<br>
-<img src="Default Mount Parameters_VeraCrypt_password_using_default_parameters.png" alt="Mount Password Dialog using default values" width="499" height="205"></p>
+<img src="Default Mount Parameters_VeraCrypt_password_using_default_parameters.png" alt="Mount Password Dialog using default values"></p>
<p>&nbsp;</p>
<p><strong>Note:</strong> The default mount parameters can be overridden by the&nbsp;<a href="Command%20Line%20Usage.html">Command Line</a> switches
<strong>/tc</strong> and <strong>/hash</strong> which always take precedence.</p>
<p>&nbsp;</p>
</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Default Mount Parameters_VeraCrypt_password_using_default_parameters.png b/doc/html/Default Mount Parameters_VeraCrypt_password_using_default_parameters.png
index 0c349d0b..b8a9dda6 100644
--- a/doc/html/Default Mount Parameters_VeraCrypt_password_using_default_parameters.png
+++ b/doc/html/Default Mount Parameters_VeraCrypt_password_using_default_parameters.png
Binary files differ
diff --git a/doc/html/Defragmenting.html b/doc/html/Defragmenting.html
index c7c16534..8ef7a572 100644
--- a/doc/html/Defragmenting.html
+++ b/doc/html/Defragmenting.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Security%20Requirements%20and%20Precautions.html">Security Requirements and Precautions</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Defragmenting.html">Defragmenting</a>
diff --git a/doc/html/Digital Signatures.html b/doc/html/Digital Signatures.html
index 17717b48..1d108cbd 100644
--- a/doc/html/Digital Signatures.html
+++ b/doc/html/Digital Signatures.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Miscellaneous.html">Miscellaneous</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Digital%20Signatures.html">Digital Signatures</a>
@@ -60,40 +60,47 @@ Therefore, you should always verify the integrity and authenticity of each VeraC
<p>PGP signatures have the following advantages, in comparison to X.509 signatures:</p>
<ul>
<li>They do not depend on any certificate authority (which might be e.g. infiltrated or controlled by an adversary, or be untrustworthy for other reasons).
</li></ul>
<h3>How to Verify X.509 Signatures</h3>
<p>Please note that X.509 signatures are currently available only for the VeraCrypt self-extracting installation packages for Windows. An X.509 digital signature is embedded in each of those files along with the digital certificate of the VeraCrypt Foundation
issued by a public certification authority. To verify the integrity and authenticity of a self-extracting installation package for Windows, follow these steps:</p>
<ol>
<li>Download the VeraCrypt self-extracting installation package. </li><li>In the Windows Explorer, click the downloaded file (&lsquo;<em>VeraCrypt Setup.exe</em>&rsquo;) with the right mouse button and select &lsquo;<em>Properties</em>&rsquo; from the context menu.
</li><li>In the <em>Properties</em> dialog window, select the &lsquo;<em>Digital Signatures</em>&rsquo; tab.
</li><li>On the &lsquo;<em>Digital Signatures</em>&rsquo; tab, in the &lsquo;<em>Signature list</em>&rsquo;, double click the line saying &quot;<em>IDRIX</em>&quot; or
<em>&quot;IDRIX SARL&quot;</em>. </li><li>The &lsquo;<em>Digital Signature Details</em>&rsquo; dialog window should appear now. If you see the following sentence at the top of the dialog window, then the integrity and authenticity of the package have been successfully verified:<br>
<br>
&quot;<em>This digital signature is OK.</em>&quot;<br>
<br>
If you do not see the above sentence, the file is very likely corrupted. Note: On some obsolete versions of Windows, some of the necessary certificates are missing, which causes the signature verification to fail.
</li></ol>
<h3 id="VerifyPGPSignature">How to Verify PGP Signatures</h3>
<p>To verify a PGP signature, follow these steps:</p>
<ol>
-<li>Install any public-key encryption software that supports PGP signatures. For Windows, you can download
-<a href="http://www.gpg4win.org/" target="_blank">Gpg4win</a>. For more information, you can visit
-<a href="https://www.gnupg.org/">https://www.gnupg.org/</a>. </li><li>Create a private key (for information on how to do so, please see the documentation for the public-key encryption software).
-</li><li>Download our PGP public key from <strong>IDRIX</strong> website (<a href="https://www.idrix.fr/VeraCrypt/VeraCrypt_PGP_public_key.asc" target="_blank">https://www.idrix.fr/VeraCrypt/VeraCrypt_PGP_public_key.asc</a>) or from a trusted public key repository
- (ID=0x54DDD393), and import the downloaded key to your keyring (for information on how to do so, please see the documentation for the public-key encryption software). Please check that its fingerprint is
-<strong>993B7D7E8E413809828F0F29EB559C7C54DDD393</strong>. </li><li>Sign the imported key with your private key to mark it as trusted (for information on how to do so, please see the documentation for the public-key encryption software).<br>
+<li>Install any public-key encryption software that supports PGP signatures. For Windows, you can download <a href="http://www.gpg4win.org/" target="_blank">Gpg4win</a>. For more information, you can visit <a href="https://www.gnupg.org/">https://www.gnupg.org/</a>. </li>
+<li>Create a private key (for information on how to do so, please see the documentation for the public-key encryption software).</li>
+<li>Download our PGP public key from <strong>IDRIX</strong> website (<a href="https://www.idrix.fr/VeraCrypt/VeraCrypt_PGP_public_key.asc" target="_blank">https://www.idrix.fr/VeraCrypt/VeraCrypt_PGP_public_key.asc</a>) or from a trusted public key repository
+ (ID=0x680D16DE), and import the downloaded key to your keyring (for information on how to do so, please see the documentation for the public-key encryption software). Please check that its fingerprint is
+<strong>5069A233D55A0EEB174A5FC3821ACD02680D16DE</strong>.
+<ul>
+<li>For VeraCrypt version 1.22 and below, the verification must use the PGP public key available at <a href="https://www.idrix.fr/VeraCrypt/VeraCrypt_PGP_public_key_2014.asc" target="_blank">https://www.idrix.fr/VeraCrypt/VeraCrypt_PGP_public_key_2014.asc</a> or from a trusted public key repository
+ (ID=0x54DDD393), whose fingerprint is <strong>993B7D7E8E413809828F0F29EB559C7C54DDD393</strong>.
+</li>
+</ul>
+</li>
+<li>Sign the imported key with your private key to mark it as trusted (for information on how to do so, please see the documentation for the public-key encryption software).<br>
<br>
Note: If you skip this step and attempt to verify any of our PGP signatures, you will receive an error message stating that the signing key is invalid.
-</li><li>Download the digital signature by downloading the <em>PGP Signature</em> of the file you want to verify (on the
-<a href="Downloads.html">Downloads page</a>).
-</li><li>Verify the downloaded signature (for information on how to do so, please see the documentation for the public-key encryption software).
-</li></ol>
+</li>
+<li>Download the digital signature by downloading the <em>PGP Signature</em> of the file you want to verify (on the <a href="https://www.veracrypt.fr/en/Downloads.html">Downloads page</a>).
+</li>
+<li>Verify the downloaded signature (for information on how to do so, please see the documentation for the public-key encryption software).</li>
+</ol>
<p>Under Linux, these steps can be achieved using the following commands:</p>
<ul>
-<li>Check that the fingerprint of the public key is <strong>993B7D7E8E413809828F0F29EB559C7C54DDD393</strong>:
-<strong>gpg --with-fingerprint VeraCrypt_PGP_public_key.asc</strong> </li><li>If the fingerprint is the expected one, import the public key: <strong>gpg --import VeraCrypt_PGP_public_key.asc</strong>
-</li><li>Verify the signature of the Linux setup archive (here for version 1.0e): <strong>
-gpg --verify veracrypt-1.0e-setup.tar.bz2.sig veracrypt-1.0e-setup.tar.bz2</strong>
+<li>Check that the fingerprint of the public key is <strong>5069A233D55A0EEB174A5FC3821ACD02680D16DE</strong>:<strong>gpg --import --import-options show-only VeraCrypt_PGP_public_key.asc</strong> (for older gpg versions, type instead:
+<strong>gpg --with-fingerprint VeraCrypt_PGP_public_key.asc</strong>)</li><li>If the fingerprint is the expected one, import the public key: <strong>gpg --import VeraCrypt_PGP_public_key.asc</strong>
+</li><li>Verify the signature of the Linux setup archive (here for version 1.23): <strong>
+gpg --verify veracrypt-1.23-setup.tar.bz2.sig veracrypt-1.23-setup.tar.bz2</strong>
</li></ul>
</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Disclaimers.html b/doc/html/Disclaimers.html
index e5085d08..b3a38ddc 100644
--- a/doc/html/Disclaimers.html
+++ b/doc/html/Disclaimers.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Disclaimers.html">Disclaimers</a>
</p></div>
diff --git a/doc/html/Documentation.html b/doc/html/Documentation.html
index 4ea96b44..9f6f6587 100644
--- a/doc/html/Documentation.html
+++ b/doc/html/Documentation.html
@@ -1,147 +1,158 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div class="wikidoc">
<h1>Table of Contents</h1>
<p><em style="text-align:left">This documentation is not guaranteed to be error-free and is provided &quot;as is&quot; without warranty of any kind. For more information, see
<a href="Disclaimers.html">Disclaimers</a>.</em></p>
<ul>
<li><a title="Preface" href="Preface.html"><strong>Preface</strong></a>
</li><li><strong><a href="Introduction.html">Introduction</a></strong>
</li><li><strong><a href="Beginner%27s%20Tutorial.html">Beginner's Tutorial</a></strong>
-</li><li><strong><strong><a href="VeraCrypt%20Volume.html">VeraCrypt Volume</a></strong></strong>
+</li><li><strong><a href="VeraCrypt%20Volume.html">VeraCrypt Volume</a></strong>
<ul>
<li><a href="Creating%20New%20Volumes.html">Creating a New VeraCrypt Volume</a>
</li><li><a href="Favorite%20Volumes.html">Favorite Volumes</a>
</li><li><a href="System%20Favorite%20Volumes.html">System Favorite Volumes</a>
</li></ul>
</li><li><strong><a href="System%20Encryption.html">System Encryption</a></strong>
<ul>
<li><a href="Hidden%20Operating%20System.html">Hidden Operating System</a>
</li><li><a href="Supported%20Systems%20for%20System%20Encryption.html">Operating Systems Supported for System Encryption</a>
</li><li><a href="VeraCrypt%20Rescue%20Disk.html">VeraCrypt Rescue Disk</a>
</li></ul>
</li><li><strong><a href="Plausible%20Deniability.html">Plausible Deniability</a></strong><br>
<ul>
<li><a href="Hidden%20Volume.html">Hidden Volume</a>
<ul>
<li><a href="Protection%20of%20Hidden%20Volumes.html">Protection of Hidden Volumes Against Damage</a>
</li><li><a href="Security%20Requirements%20for%20Hidden%20Volumes.html">Security Requirements and Precautions Pertaining to Hidden Volumes</a>
</li></ul>
</li><li><a href="VeraCrypt%20Hidden%20Operating%20System.html">Hidden Operating System</a>
</li></ul>
</li><li><strong><a href="Main%20Program%20Window.html">Main Program Window</a></strong>
<ul>
<li><a href="Program%20Menu.html">Program Menu</a>
</li><li><a href="Mounting%20VeraCrypt%20Volumes.html">Mounting Volumes</a>
</li></ul>
+</li><li><strong><a href="Normal%20Dismount%20vs%20Force%20Dismount.html">Normal Dismount vs Force Dismount</a></strong>
+</li><li><strong><a href="Avoid%20Third-Party%20File%20Extensions.html">Avoid Third-Party File Extensions</a></strong>
</li><li><strong><a href="Parallelization.html">Parallelization</a></strong>
</li><li><strong><a href="Pipelining.html">Pipelining</a></strong>
</li><li><strong><a href="Hardware%20Acceleration.html">Hardware acceleration</a></strong>
</li><li><strong><a href="Hot%20Keys.html">Hot keys</a></strong>
</li><li><strong><a href="Keyfiles%20in%20VeraCrypt.html">Keyfiles</a></strong>
</li><li><strong><a href="Security%20Tokens%20%26%20Smart%20Cards.html">Security Tokens &amp; Smart Cards</a></strong>
+</li><li><strong><a href="EMV%20Smart%20Cards.html">EMV Smart Cards</a></strong>
</li><li><strong><a href="Portable%20Mode.html">Portable Mode</a></strong>
</li><li><strong><a href="TrueCrypt%20Support.html">TrueCrypt Support</a></strong>
</li><li><strong><a href="Converting%20TrueCrypt%20volumes%20and%20partitions.html">Converting TrueCrypt Volumes &amp; Partitions</a></strong>
+</li><li><strong><a href="Conversion_Guide_VeraCrypt_1.26_and_Later.html">Conversion Guide for Versions 1.26 and Later</a></strong>
</li><li><strong><a href="Default%20Mount%20Parameters.html">Default Mount Parameters</a></strong>
</li><li><strong><a href="Language%20Packs.html">Language Packs</a></strong>
</li><li><strong><a href="Encryption%20Algorithms.html">Encryption Algorithms</a></strong>
<ul>
<li><a href="AES.html">AES</a> </li><li><a href="Camellia.html">Camellia</a>
</li><li><a href="Kuznyechik.html">Kuznyechik</a>
</li><li><a href="Serpent.html">Serpent</a> </li><li><a href="Twofish.html">Twofish</a> </li><li><a href="Cascades.html">Cascades of ciphers</a>
</li></ul>
</li><li><strong><a href="Hash%20Algorithms.html">Hash Algorithms</a></strong>
<ul>
-<li><a href="RIPEMD-160.html">RIPEMD-160</a>
+<li><a href="BLAKE2s-256.html">BLAKE2s-256</a>
</li><li><a href="SHA-256.html">SHA-256</a> </li><li><a href="SHA-512.html">SHA-512</a> </li><li><a href="Whirlpool.html">Whirlpool</a>
</li><li><a href="Streebog.html">Streebog</a></li></ul>
</li><li><strong><a href="Supported%20Operating%20Systems.html">Supported Operating Systems</a></strong>
</li><li><strong><a href="Command%20Line%20Usage.html">Command Line Usage</a></strong>
</li><li><strong><a href="Security%20Model.html">Security Model</a></strong>
</li><li><strong><a href="Security%20Requirements%20and%20Precautions.html">Security Requirements And Precautions<br>
</a></strong>
<ul>
<li><a href="Data%20Leaks.html">Data Leaks</a>
<ul>
<li><a href="Paging%20File.html">Paging File</a>
</li><li><a href="Memory%20Dump%20Files.html">Memory Dump Files</a>
</li><li><a href="Hibernation%20File.html">Hibernation File</a>
</li></ul>
</li><li><a href="Unencrypted%20Data%20in%20RAM.html">Unencrypted Data in RAM</a>
+</li><li><a href="VeraCrypt%20RAM%20Encryption.html">VeraCrypt RAM Encryption</a>
+</li><li><a href="VeraCrypt%20Memory%20Protection.html">VeraCrypt Memory Protection</a>
</li><li><a href="Physical%20Security.html">Physical Security</a>
</li><li><a href="Malware.html">Malware</a> </li><li><a href="Multi-User%20Environment.html">Multi-User Environment</a>
</li><li><a href="Authenticity%20and%20Integrity.html">Authenticity and Integrity</a>
</li><li><a href="Choosing%20Passwords%20and%20Keyfiles.html">Choosing Passwords and Keyfiles</a>
</li><li><a href="Changing%20Passwords%20and%20Keyfiles.html">Changing Passwords and Keyfiles</a>
</li><li><a href="Trim%20Operation.html">Trim Operation</a>
</li><li><a href="Wear-Leveling.html">Wear-Leveling</a>
</li><li><a href="Reallocated%20Sectors.html">Reallocated Sectors</a>
</li><li><a href="Defragmenting.html">Defragmenting</a>
</li><li><a href="Journaling%20File%20Systems.html">Journaling File Systems</a>
</li><li><a href="Volume%20Clones.html">Volume Clones</a>
</li><li><a href="Additional%20Security%20Requirements%20and%20Precautions.html">Additional Security Requirements and Precautions</a>
</li></ul>
</li><li><strong><a href="How%20to%20Back%20Up%20Securely.html">How To Back Up Securely</a></strong>
</li><li><strong><a href="Miscellaneous.html">Miscellaneous</a></strong>
<ul>
<li><a href="Using%20VeraCrypt%20Without%20Administrator%20Privileges.html">Using VeraCrypt Without Administrator Privileges</a>
</li><li><a href="Sharing%20over%20Network.html">Sharing Over Network</a>
</li><li><a href="VeraCrypt%20Background%20Task.html">VeraCrypt Background Task</a>
</li><li><a href="Removable%20Medium%20Volume.html">Volume Mounted as Removable Medium</a>
</li><li><a href="VeraCrypt%20System%20Files.html">VeraCrypt System Files &amp; Application Data</a>
</li><li><a href="Removing%20Encryption.html">How To Remove Encryption</a>
</li><li><a href="Uninstalling%20VeraCrypt.html">Uninstalling VeraCrypt</a>
</li><li><a href="Digital%20Signatures.html">Digital Signatures</a>
</li></ul>
</li><li><strong><a href="Troubleshooting.html">Troubleshooting</a></strong>
</li><li><strong><a href="Incompatibilities.html">Incompatibilities</a></strong>
</li><li><strong><a href="Issues%20and%20Limitations.html">Known Issues and Limitations</a></strong>
</li><li><strong><a href="FAQ.html">Frequently Asked Questions</a></strong>
-</li><li><strong><strong><a href="Technical%20Details.html">Technical Details</a></strong></strong>
+</li><li><strong><a href="Technical%20Details.html">Technical Details</a></strong>
<ul>
<li><a href="Notation.html">Notation</a>
</li><li><a href="Encryption%20Scheme.html">Encryption Scheme</a>
</li><li><a href="Modes%20of%20Operation.html">Modes of Operation</a>
</li><li><a href="Header%20Key%20Derivation.html">Header Key Derivation, Salt, and Iteration Count</a>
</li><li><a href="Random%20Number%20Generator.html">Random Number Generator</a>
</li><li><a href="Keyfiles.html">Keyfiles</a>
</li><li><a title="PIM" href="Personal%20Iterations%20Multiplier%20(PIM).html">PIM</a>
</li><li><a href="VeraCrypt%20Volume%20Format%20Specification.html">VeraCrypt Volume Format Specification</a>
</li><li><a href="Standard%20Compliance.html">Compliance with Standards and Specifications</a>
</li><li><a href="Source%20Code.html">Source Code</a>
+</li><li><a href="CompilingGuidelines.html">Building VeraCrypt From Source</a>
+<ul>
+<li><a href="CompilingGuidelineWin.html">Windows Build Guide</a>
+</li><li><a href="CompilingGuidelineLinux.html">Linux Build Guide</a>
+</li></ul>
</li></ul>
</li><li><strong><a href="Contact.html">Contact</a></strong>
</li><li><strong><a href="Legal%20Information.html">Legal Information</a></strong>
</li><li><strong><a href="Release%20Notes.html">Version History</a></strong>
</li><li><strong><a href="Acknowledgements.html">Acknowledgements</a></strong>
</li><li><strong><a href="References.html">References</a></strong>
</li></ul>
</div>
</body></html>
diff --git a/doc/html/Donation.html b/doc/html/Donation.html
index daa5759a..3abcf14d 100644
--- a/doc/html/Donation.html
+++ b/doc/html/Donation.html
@@ -1,104 +1,122 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a href="Documentation.html">Documentation</a></li>
<li><a class="active" href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div class="wikidoc">
<h1>Donation to VeraCrypt</h1>
-<p>You can support VeraCrypt development through donations using PayPal, Bitcoins, bank transfers. It is also possible to donate using Flattr and Tibit.</p>
-<table border="1" width="645" style="height:427px">
-<tbody>
-<tr>
-<th>
-<h4>PayPal</h4>
-</th>
-<th>
-<h4>Bitcoins</h4>
-</th>
-<th>
-<h4 style="text-align:center">Others</h4>
-</th>
-</tr>
-<tr>
-<td>
-<table border="1">
+<p>You can support VeraCrypt development through donations using PayPal, bank transfers and cryptocurrencies (<a href="#Bitcoin">Bitcoin</a>, <a href="#BitcoinCash">Bitcoin Cash</a>, <a href="#Ethereum">Ethereum</a>, <a href="#Litecoin">Litecoin</a> and <a href="#Monero">Monero</a>). It is also possible to donate using Liberapay and Flattr.</p>
+
+<hr>
+<h3><img src="paypal_30x30.png" style="vertical-align: middle; margin-right: 5px">PayPal</h3>
+<table>
<tbody>
<tr>
-<td><strong>Euro</strong></td>
-<td>
-<h3><a title="Donate to VeraCrypt in Euros" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=H25GJLUDHBMB6" target="_blank"><img src="Donation_donate_Euros.gif" alt="" width="92" height="26"></a></h3>
-</td>
-</tr>
-<tr>
-<td><strong>US Dollar</strong></td>
-<td>
-<h3><a title="VeraCrypt Donation in USD" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=B8PU86SHE2ZVA" target="_blank"><img src="Donation_donate_Dollars.gif" alt="" width="92" height="26"></a></h3>
-</td>
-</tr>
-<tr>
-<td><strong>Pound Sterling</strong></td>
-<td>
-<h3><a title="VeraCrypt Donation in GBP" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MFAZACXK9NXT8" target="_blank"><img src="Donation_donate_GBP.gif" alt="" width="92" height="26"></a></h3>
-</td>
-</tr>
-<tr>
-<td><strong>Canadian Dollar</strong></td>
-<td>
-<h3><a title="VeraCrypt Donation in Canadian Dollar" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QAN6T5E5F7F5J" target="_blank"><img src="Donation_donate_Dollars.gif" alt="" width="92" height="26"></a></h3>
-</td>
+<td align="center"><a title="Donate to VeraCrypt in Euros" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=H25GJLUDHBMB6" target="_blank"><img src="Donation_donate_Euros.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in USD" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=B8PU86SHE2ZVA" target="_blank"><img src="Donation_donate_Dollars.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in GBP" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MFAZACXK9NXT8" target="_blank"><img src="Donation_donate_GBP.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in Canadian Dollar" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QAN6T5E5F7F5J" target="_blank"><img src="Donation_donate_Dollars.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in Swiss Francs" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=98RJHVLY5NJ5U" target="_blank"><img src="Donation_donate_CHF.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in Japanese Yen" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=M9DXZ83WD7S8Y" target="_blank"><img src="Donation_donate_YEN.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in Australian Dollar" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=S9L769QS6WAU6" target="_blank"><img src="Donation_donate_Dollars.gif" alt="" width="92" height="26"></a></td>
+<td align="center"><a title="VeraCrypt Donation in Polish złoty" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2WDGT7KUJ5GH8" target="_blank"><img src="Donation_donate_PLN.gif" alt="" width="92" height="26"></a></td>
</tr>
<tr>
-<td><strong>Swiss Franc</strong></td>
-<td>
-<h3><a title="VeraCrypt Donation in Swiss Francs" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=98RJHVLY5NJ5U" target="_blank"><img src="Donation_donate_CHF.gif" alt="" width="92" height="26"></a></h3>
-</td>
-</tr>
-<tr>
-<td><strong>Japanese Yen</strong></td>
-<td>
-<h3><a title="VeraCrypt Donation in Japanese Yen" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=M9DXZ83WD7S8Y" target="_blank"><img src="Donation_donate_YEN.gif" alt="" width="92" height="26"></a></h3>
-</td>
+<td align="center">Euro</td>
+<td align="center">US Dollar</td>
+<td align="center">Pound Sterling</td>
+<td align="center">Canadian Dollar</td>
+<td align="center">Swiss Franc</td>
+<td align="center">Japanese Yen</td>
+<td align="center">Australian Dollar</td>
+<td align="center">Polish złoty</td>
</tr>
</tbody>
</table>
-</td>
-<td style="text-align:center; vertical-align:middle">
-<p><img src="Donation_VeraCrypt_Bitcoin.png" alt="VeraCrypt Bitcoin Address" width="250" height="250"></p>
-<p><strong>1NRoPQsm8by5iWyMMmHQy3P5takur3kYgG</strong></p>
-</td>
-<td style="text-align:left; vertical-align:top">
-<p><strong>Tibit:<br>
-<a title="Donate a tib to VeraCrypt" href="https://tib.me/1NRoPQsm8by5iWyMMmHQy3P5takur3kYgG/VeraCrypt/?TIB=https://veracrypt.codeplex.com" target="_blank"><img src="Home_tibitDonateButton.png" alt="Donate using Tibit" width="120" height="40"></a></strong></p>
+
+<p>For other currencies, click on the button below and then select your currency using the drop-down list under the amount.</p>
+<a title="VeraCrypt Donation in any currency" href="https://www.paypal.me/idrix" target="_blank"><img src="Donation_donate.gif" alt="" width="92" height="26"></a>
+
+
+<hr>
+<h3><a href="Donation_Bank.html"><img src="bank_30x30.png" style="margin-right: 5px"></a>Bank Transfer</h3>
+<p>You can use <a href="Donation_Bank.html">IDRIX bank details available here</a> to send your donations using bank transfers.
+
+<hr>
+<h3>Donation Platforms:</h3>
+<ul>
+<li><strong>Liberapay: <a href="https://liberapay.com/VeraCrypt/donate" target="_blank"><img alt="Donate using Liberapay" src="liberapay_donate.svg" style="vertical-align: middle; margin-bottom: 5px"></a></strong></li>
+</ul>
+
+<hr>
+<h3 id="Bitcoin"><img src="BC_Logo_30x30.png" style="vertical-align: middle; margin-right: 5px">Bitcoin</h3>
+<ul>
+<li><strong>Legacy:</strong>
+<p><img src="Donation_VeraCrypt_Bitcoin_small.png" alt="VeraCrypt Bitcoin Address" width="200" height="200"></p>
+<p><strong>14atYG4FNGwd3F89h1wDAfeRDwYodgRLcf</strong></p>
+</li>
+<li><strong>SegWit:</strong>
+<p><img src="Donation_VC_BTC_Sigwit.png" alt="VeraCrypt BTC SegWit Address" width="200" height="200"></p>
+<p><strong>bc1q28x9udhvjp8jzwmmpsv7ehzw8za60c7g62xauh</strong></p>
+</li>
+</ul>
+
+<hr>
+<h3 id="BitcoinCash"><img src="BCH_Logo_30x30.png" style="vertical-align: middle; margin-right: 5px">Bitcoin Cash</h3>
+<p><img src="Donation_VeraCrypt_BitcoinCash.png" alt="VeraCrypt Bitcoin Cash Address" width="200" height="200"></p>
+<p><strong>bitcoincash:qp5vrqwln247f7l9p98ucj4cqye0cjcyusc94jlpy9</strong></p>
+
+<hr>
+<h3 id="Ethereum"><img src="Ethereum_Logo_19x30.png" style="vertical-align: middle; margin-right: 5px">Ethereum</h3>
+<p><img src="Donation_VeraCrypt_Ethereum.png" alt="VeraCrypt Ethereum Address" width="200" height="200"></p>
+<p><strong>0x0a7a86a3eB5f533d969500831e8CC681454a8bD2</strong></p>
+
+<hr>
+<h3 id="Litecoin"><img src="LTC_Logo_30x30.png" style="vertical-align: middle; margin-right: 5px">Litecoin</h3>
+<p><img src="Donation_VeraCrypt_Litecoin.png" alt="VeraCrypt Litecoin Address" width="200" height="200"></p>
+<p><strong>LZkkfkMs4qHmWaP9DAvS1Ep1fAxaf8A2T7</strong></p>
+
+<hr>
+<h3 id="Monero"><img src="Monero_Logo_30x30.png" style="vertical-align: middle; margin-right: 5px">Monero</h3>
+<p><img src="Donation_VeraCrypt_Monero.png" alt="VeraCrypt Monero Address" width="200" height="200"></p>
+<p><strong>464GGAau9CE5XiER4PSZ6SMbK4wxPCgdm2r36uqnL8NoS6zDjxUYXnyQymbUsK1QipDMY2fsSgDyZ3tMaLfpWvSr2EE8wMw</strong></p>
+
+
+<hr>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
<p>&nbsp;</p>
-<p><strong>Flattr:</strong><br>
-<a title="Donate using Flattr" href="https://flattr.com/submit/auto?user_id=idrix&url=https://veracrypt.codeplex.com&title=VeraCrypt" target="_blank"><img title="Flattr VeraCrypt" src="flattr-badge-large.png" alt="Flattr VeraCrypt" width="93" height="20" border="0"></a></p>
-</td>
-</tr>
-</tbody>
-</table>
-<p><img src="bank_30x30.png" style="margin-right: 5px"><strong>Donate using bank transfer:</strong>&nbsp;<a href="Contact.html" target="_blank.html">contact us</a> for bank account details (based in France).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Donation_Bank.html b/doc/html/Donation_Bank.html
new file mode 100644
index 00000000..b7f1f391
--- /dev/null
+++ b/doc/html/Donation_Bank.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
+<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
+<meta name="keywords" content="encryption, security"/>
+<link href="styles.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<div>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+</div>
+
+<div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a href="Documentation.html">Documentation</a></li>
+ <li><a class="active" href="Donation.html">Donate</a></li>
+ <li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
+ </ul>
+</div>
+
+<div class="wikidoc">
+<h1>Donation to VeraCrypt using bank transfer</h1>
+<p>You can support VeraCrypt development through donations using bank transfers to one of IDRIX bank accounts below, depending on the currency used.<br>
+The supported currencies are <a href="#Euro">Euro<img src="flag-eu-small.png" style="vertical-align: top; margin-left: 5px"></a>, <a href="#USD">US Dollar<img src="flag-us-small.png" style="vertical-align: top; margin-left: 5px"></a>, <a href="#GBP">British Pound<img src="flag-gb-small.png" style="vertical-align: top; margin-left: 5px"></a>, <a href="#AUD">Australian Dollar<img src="flag-au-small.png" style="vertical-align: top; margin-left: 5px"></a> and <a href="#NZD">New Zealand Dollar<img src="flag-nz-small.png" style="vertical-align: top; margin-left: 5px"></a>.<br>
+Please <a href="Contact.html" target="_blank.html">contact us</a> if you need an official invoice for your donation.</p>
+<hr>
+<h3 id="Euro"><img src="flag-eu.png" style="vertical-align: middle; margin-right: 5px">Euro SEPA Bank Details</h3>
+<p>Accepted payment types are SEPA bank transferts or SWIFT in Euro only.</p>
+Account Holder: IDRIX SARL<br>
+IBAN: BE16 9670 3707 4574<br>
+Bank code (SWIFT / BIC): TRWIBEB1XXX<br>
+Address: TransferWise Europe SA, Avenue Marnix 13-17, Brussels 1000, Belgium<br>
+Reference: Open Source Donation<br>
+<hr>
+
+<h3 id="USD"><img src="flag-us.png" style="vertical-align: middle; margin-right: 5px">US Dollar Bank Details</h3>
+<p>From within the US, accepted payment types are ACH and Wire.</p>
+Account Holder: IDRIX SARL<br>
+Account number: 8310085792<br>
+ACH and Wire routing number: 026073150<br>
+Account Type: Checking<br>
+Address: Wise, 30 W. 26th Street, Sixth Floor, New York NY 10010, United States<br>
+Reference: Open Source Donation<br>
+
+<p>From outside the US, accepted payment in SWIFT.</p>
+Account Holder: IDRIX SARL<br>
+Account number: 8310085792<br>
+Routing number: 026073150<br>
+Bank code (SWIFT/BIC): CMFGUS33<br>
+Address: Wise, 30 W. 26th Street, Sixth Floor, New York NY 10010, United States<br>
+Reference: Open Source Donation<br>
+<hr>
+
+<h3 id="GBP"><img src="flag-gb.png" style="vertical-align: middle; margin-right: 5px">British Pound Bank Details</h3>
+<p>Accepted payment types are Faster Payments (FPS), BACS and CHAPS from withing the UK only.</p>
+
+Account Holder: IDRIX SARL<br>
+Account number: 56385007<br>
+UK Sort Code: 23-14-70<br>
+IBAN (to receive GBP from UK only): GB18 TRWI 2314 7056 3850 07<br>
+Address: Wise, 56 Shoreditch High Street, London, E1 6JJ, United Kingdom<br>
+Reference: Open Source Donation<br>
+<hr>
+
+<h3 id="AUD"><img src="flag-au.png" style="vertical-align: middle; margin-right: 5px">Australian Dollar Bank Details</h3>
+<p>Accepted payment types to this account are local AUD bank transfers only.</p>
+Account Holder: IDRIX SARL<br>
+Account number: 711714051<br>
+BSB Code: 802-985<br>
+Address: Wise, 36-38 Gipps Street, Collingwood VIC 3066, Autralia.<br>
+Reference: Open Source Donation<br>
+<hr>
+
+<h3 id="NZD"><img src="flag-nz.png" style="vertical-align: middle; margin-right: 5px">New Zealand Dollar Bank Details</h3>
+<p>Accepted payment types to this account are local NZD bank transfers only.</p>
+Account Holder: IDRIX SARL<br>
+Account number: 02-1291-0218919-000<br>
+Address: Wise, 56 Shoreditch High Street, London, E1 6JJ, United Kingdom<br>
+Reference: Open Source Donation<br>
+<hr>
+
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Donation_VC_BTC_Sigwit.png b/doc/html/Donation_VC_BTC_Sigwit.png
new file mode 100644
index 00000000..d754760e
--- /dev/null
+++ b/doc/html/Donation_VC_BTC_Sigwit.png
Binary files differ
diff --git a/doc/html/Donation_VeraCrypt_Bitcoin.png b/doc/html/Donation_VeraCrypt_Bitcoin.png
deleted file mode 100644
index 4817d925..00000000
--- a/doc/html/Donation_VeraCrypt_Bitcoin.png
+++ /dev/null
Binary files differ
diff --git a/doc/html/Donation_VeraCrypt_BitcoinCash.png b/doc/html/Donation_VeraCrypt_BitcoinCash.png
new file mode 100644
index 00000000..c7e22e54
--- /dev/null
+++ b/doc/html/Donation_VeraCrypt_BitcoinCash.png
Binary files differ
diff --git a/doc/html/Donation_VeraCrypt_Bitcoin_small.png b/doc/html/Donation_VeraCrypt_Bitcoin_small.png
new file mode 100644
index 00000000..72ceae5c
--- /dev/null
+++ b/doc/html/Donation_VeraCrypt_Bitcoin_small.png
Binary files differ
diff --git a/doc/html/Donation_VeraCrypt_Ethereum.png b/doc/html/Donation_VeraCrypt_Ethereum.png
new file mode 100644
index 00000000..fa511247
--- /dev/null
+++ b/doc/html/Donation_VeraCrypt_Ethereum.png
Binary files differ
diff --git a/doc/html/Donation_VeraCrypt_Litecoin.png b/doc/html/Donation_VeraCrypt_Litecoin.png
new file mode 100644
index 00000000..6f5d858a
--- /dev/null
+++ b/doc/html/Donation_VeraCrypt_Litecoin.png
Binary files differ
diff --git a/doc/html/Donation_VeraCrypt_Monero.png b/doc/html/Donation_VeraCrypt_Monero.png
new file mode 100644
index 00000000..4085a721
--- /dev/null
+++ b/doc/html/Donation_VeraCrypt_Monero.png
Binary files differ
diff --git a/doc/html/Donation_donate.gif b/doc/html/Donation_donate.gif
new file mode 100644
index 00000000..43cef691
--- /dev/null
+++ b/doc/html/Donation_donate.gif
Binary files differ
diff --git a/doc/html/Donation_donate_PLN.gif b/doc/html/Donation_donate_PLN.gif
new file mode 100644
index 00000000..16ab23e9
--- /dev/null
+++ b/doc/html/Donation_donate_PLN.gif
Binary files differ
diff --git a/doc/html/EMV Smart Cards.html b/doc/html/EMV Smart Cards.html
new file mode 100644
index 00000000..d9c8716a
--- /dev/null
+++ b/doc/html/EMV Smart Cards.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <title>
+ VeraCrypt - Free Open source disk encryption with strong security for the
+ Paranoid
+ </title>
+ <meta
+ name="description"
+ content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."
+ />
+ <meta name="keywords" content="encryption, security" />
+ <link href="styles.css" rel="stylesheet" type="text/css" />
+ </head>
+ <body>
+ <div>
+ <a href="Documentation.html"
+ ><img src="VeraCrypt128x128.png" alt="VeraCrypt"
+ /></a>
+ </div>
+
+ <div id="menu">
+ <ul>
+ <li><a href="Home.html">Home</a></li>
+ <li><a href="/code/">Source Code</a></li>
+ <li><a href="Downloads.html">Downloads</a></li>
+ <li><a class="active" href="Documentation.html">Documentation</a></li>
+ <li><a href="Donation.html">Donate</a></li>
+ <li>
+ <a
+ href="https://sourceforge.net/p/veracrypt/discussion/"
+ target="_blank"
+ >Forums</a
+ >
+ </li>
+ </ul>
+ </div>
+
+ <div>
+ <p>
+ <a href="Documentation.html">Documentation</a>
+ <img src="arrow_right.gif" alt=">>" style="margin-top: 5px" />
+ <a href="EMV%20Smart%20Cards.html">EMV Smart Cards</a>
+ </p>
+ </div>
+
+ <div class="wikidoc">
+ <h1>EMV Smart Cards</h1>
+ <div
+ style="
+ text-align: left;
+ margin-top: 19px;
+ margin-bottom: 19px;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ "
+ >
+ <p>
+ Windows and Linux versions of VeraCrypt offer to use EMV compliant
+ smart cards as a feature. Indeed, the use of PKCS#11 compliant smart
+ cards is dedicated to users with more or less cybersecurity skills.
+ However, in some situations, having such a card strongly reduces the
+ plausible deniability of the user.
+ </p>
+ <p>
+ To overcome this problem, the idea is to allow the use of a type of
+ smart card owned by anyone: EMV compliant smart cards. According to
+ the standard of the same name, these cards spread all over the world
+ are used to carry out banking operations. Using internal data of the
+ user's EMV card as keyfiles will strengthen the security of his volume
+ while keeping his denial plausible.
+ </p>
+ <p>
+ For more technical information, please see the section
+ <em style="text-align: left">EMV Smart Cards</em> in the chapter
+ <a
+ href="Keyfiles%20in%20VeraCrypt.html"
+ style="text-align: left; color: #0080c0; text-decoration: none.html"
+ >
+ <em style="text-align: left">Keyfiles</em></a
+ >.
+ </p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/doc/html/Encryption Algorithms.html b/doc/html/Encryption Algorithms.html
index 0619fd65..2866e332 100644
--- a/doc/html/Encryption Algorithms.html
+++ b/doc/html/Encryption Algorithms.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Encryption%20Algorithms.html">Encryption Algorithms</a>
</p></div>
@@ -137,40 +137,100 @@ XTS</td>
256; 256</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
128</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
XTS</td>
</tr>
<tr style="text-align:left">
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">AES-Twofish-Serpent</a></td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
&nbsp;</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
256; 256; 256</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
128</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
XTS</td>
</tr>
<tr style="text-align:left">
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Camellia-Kuznyechik</a></td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+&nbsp;</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+256; 256</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+128</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+XTS</td>
+</tr>
+<tr style="text-align:left">
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Camellia-Serpent</a></td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+&nbsp;</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+256; 256</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+128</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+XTS</td>
+</tr>
+<tr style="text-align:left">
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Kuznyechik-AES</a></td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+&nbsp;</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+256; 256</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+128</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+XTS</td>
+</tr>
+<tr style="text-align:left">
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Kuznyechik-Serpent-Camellia</a></td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+&nbsp;</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+256; 256; 256</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+128</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+XTS</td>
+</tr>
+<tr style="text-align:left">
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Kuznyechik-Twofish</a></td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+&nbsp;</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+256; 256</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+128</td>
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
+XTS</td>
+</tr>
+<tr style="text-align:left">
+<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Serpent-AES</a></td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
&nbsp;</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
256; 256</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
128</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
XTS</td>
</tr>
<tr style="text-align:left">
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
<a href="Cascades.html" style="color:#0080c0; text-decoration:none.html">Serpent-Twofish-AES</a></td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
&nbsp;</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
256; 256; 256</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
128</td>
<td style="color:#000000; font-size:11px; line-height:13px; font-family:Verdana,Arial,Helvetica,sans-serif; text-align:center; vertical-align:middle; border-width:0px 1px 0px 0px; border-style:none solid solid none; padding:5px; border-color:white #000000 #ffffff white">
diff --git a/doc/html/Encryption Scheme.html b/doc/html/Encryption Scheme.html
index b77a0aaf..88c586a2 100644
--- a/doc/html/Encryption Scheme.html
+++ b/doc/html/Encryption Scheme.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>
<meta name="keywords" content="encryption, security"/>
<link href="styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div>
-<a href="https://www.veracrypt.fr/en/Home.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
+<a href="Documentation.html"><img src="VeraCrypt128x128.png" alt="VeraCrypt"/></a>
</div>
<div id="menu">
<ul>
<li><a href="Home.html">Home</a></li>
<li><a href="/code/">Source Code</a></li>
<li><a href="Downloads.html">Downloads</a></li>
<li><a class="active" href="Documentation.html">Documentation</a></li>
<li><a href="Donation.html">Donate</a></li>
<li><a href="https://sourceforge.net/p/veracrypt/discussion/" target="_blank">Forums</a></li>
</ul>
</div>
<div>
<p>
<a href="Documentation.html">Documentation</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Technical%20Details.html">Technical Details</a>
<img src="arrow_right.gif" alt=">>" style="margin-top: 5px">
<a href="Encryption%20Scheme.html">Encryption Scheme</a>
@@ -37,53 +37,53 @@
<div class="wikidoc">
<h1>Encryption Scheme</h1>
<p>When mounting a VeraCrypt volume (assume there are no cached passwords/keyfiles) or when performing pre-boot authentication, the following steps are performed:</p>
<ol>
<li>The first 512 bytes of the volume (i.e., the standard volume header) are read into RAM, out of which the first 64 bytes are the salt (see
<a href="VeraCrypt%20Volume%20Format%20Specification.html">
<em>VeraCrypt Volume Format Specification</em></a>). For system encryption (see the chapter
<a href="System%20Encryption.html"><em>System Encryption</em></a>), the last 512 bytes of the first logical drive track are read into RAM (the VeraCrypt Boot Loader is stored in the first track of the system drive and/or
on the VeraCrypt Rescue Disk). </li><li>Bytes 65536&ndash;66047 of the volume are read into RAM (see the section <a href="VeraCrypt%20Volume%20Format%20Specification.html">
<em>VeraCrypt Volume Format Specification</em></a>). For system encryption, bytes 65536&ndash;66047 of the first partition located behind the active partition* are read (see the section
<a href="Hidden%20Operating%20System.html">
Hidden Operating System</a>). If there is a hidden volume within this volume (or within the partition behind the boot partition), we have read its header at this point; otherwise, we have just read random data (whether or not there is a hidden volume within
it has to be determined by attempting to decrypt this data; for more information see the section
<a href="Hidden%20Volume.html"><em>Hidden Volume</em></a>).
</li><li>Now VeraCrypt attempts to decrypt the standard volume header read in (1). All data used and generated in the course of the process of decryption are kept in RAM (VeraCrypt never saves them to disk). The following parameters are unknown&dagger; and have
to be determined through the process of trial and error (i.e., by testing all possible combinations of the following):
<ol type="a">
<li>PRF used by the header key derivation function (as specified in PKCS #5 v2.0; see the section
<a href="Header%20Key%20Derivation.html">
<em>Header Key Derivation, Salt, and Iteration Count</em></a>), which can be one of the following:
-<p>HMAC-SHA-512, HMAC-SHA-256, HMAC-RIPEMD-160, HMAC-Whirlpool. If a PRF is explicitly specified by the user, it will be used directly without trying the other possibilities.</p>
+<p>HMAC-SHA-512, HMAC-SHA-256, HMAC-BLAKE2S-256, HMAC-Whirlpool. If a PRF is explicitly specified by the user, it will be used directly without trying the other possibilities.</p>
<p>A password entered by the user (to which one or more keyfiles may have been applied &ndash; see the section
<a href="Keyfiles%20in%20VeraCrypt.html">
<em>Keyfiles</em></a>), a PIM value (if specified) and the salt read in (1) are passed to the header key derivation function, which produces a sequence of values (see the section
<a href="Header%20Key%20Derivation.html">
<em>Header Key Derivation, Salt, and Iteration Count</em></a>) from which the header encryption key and secondary header key (XTS mode) are formed. (These keys are used to decrypt the volume header.)</p>
</li><li>Encryption algorithm: AES-256, Serpent, Twofish, AES-Serpent, AES-Twofish- Serpent, etc.
</li><li>Mode of operation: only XTS is supported </li><li>Key size(s) </li></ol>
</li><li>Decryption is considered successful if the first 4 bytes of the decrypted data contain the ASCII string &ldquo;VERA&rdquo;, and if the CRC-32 checksum of the last 256 bytes of the decrypted data (volume header) matches the value located at byte #8 of the
decrypted data (this value is unknown to an adversary because it is encrypted &ndash; see the section
<a href="VeraCrypt%20Volume%20Format%20Specification.html">
<em>VeraCrypt Volume Format Specification</em></a>). If these conditions are not met, the process continues from (3) again, but this time, instead of the data read in (1), the data read in (2) are used (i.e., possible hidden volume header). If the conditions
are not met again, mounting is terminated (wrong password, corrupted volume, or not a VeraCrypt volume).
</li><li>Now we know (or assume with very high probability) that we have the correct password, the correct encryption algorithm, mode, key size, and the correct header key derivation algorithm. If we successfully decrypted the data read in (2), we also know that
we are mounting a hidden volume and its size is retrieved from data read in (2) decrypted in (3).
</li><li>The encryption routine is reinitialized with the primary master key** and the secondary master key (XTS mode &ndash; see the section
<a href="Modes%20of%20Operation.html"><em>Modes of Operation</em></a>), which are retrieved from the decrypted volume header (see the section
<a href="VeraCrypt%20Volume%20Format%20Specification.html">
<em>VeraCrypt Volume Format Specification</em></a>). These keys can be used to decrypt any sector of the volume, except the volume header area (or the key data area, for system encryption), which has been encrypted using the header keys. The volume is mounted.
</li></ol>
<p>See also section <a href="Modes%20of%20Operation.html">
<em>Modes of Operation</em></a> and section <a href="Header%20Key%20Derivation.html">
<em>Header Key Derivation, Salt, and Iteration Count</em></a> and also the chapter
<a href="Security%20Model.html"><em>Security Model</em></a>.</p>
<p>* If the size of the active partition is less than 256 MB, then the data is read from the
<em>second</em> partition behind the active one (Windows 7 and later, by default, do not boot from the partition on which they are installed).</p>
<p>&dagger; These parameters are kept secret <em>not</em> in order to increase the complexity of an attack, but primarily to make VeraCrypt volumes unidentifiable (indistinguishable from random data), which would be difficult to achieve if these parameters
- were stored unencrypted within the volume header. Also note that if a non-cascaded encryption algorithm is used for system encryption, the algorithm
+ were stored unencrypted within the volume header. Also note that in the case of legacy MBR boot mode, if a non-cascaded encryption algorithm is used for system encryption, the algorithm
<em>is</em> known (it can be determined by analyzing the contents of the unencrypted VeraCrypt Boot Loader stored in the first logical drive track or on the VeraCrypt Rescue Disk).</p>
<p>** The master keys were generated during the volume creation and cannot be changed later. Volume password change is accomplished by re-encrypting the volume header using a new header key (derived from a new password).</p>
<p>&nbsp;</p>
<p><a href="Modes%20of%20Operation.html" style="text-align:left; color:#0080c0; text-decoration:none; font-weight:bold.html">Next Section &gt;&gt;</a></p>
</div><div class="ClearBoth"></div></body></html>
diff --git a/doc/html/Ethereum_Logo_19x30.png b/doc/html/Ethereum_Logo_19x30.png
new file mode 100644
index 00000000..0df3a66a
--- /dev/null
+++ b/doc/html/Ethereum_Logo_19x30.png
Binary files differ
diff --git a/doc/html/FAQ.html b/doc/html/FAQ.html
index 8bb3df05..e310f3e8 100644
--- a/doc/html/FAQ.html
+++ b/doc/html/FAQ.html
@@ -1,34 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>VeraCrypt - Free Open source disk encryption with strong security for the Paranoid</title>
<meta name="description" content="VeraCrypt is free open-source disk encryption software for Windows, Mac OS X and Linux. In case an attacker forces you to reveal the password, VeraCrypt provides plausible deniability. In contrast to file encryption, data encryption performed by VeraCrypt is real-time (on-the-fly), automatic, transparent, needs very little memory, and does not involve temporary unencrypted files."/>