VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Dlgcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/Dlgcode.c')
-rw-r--r--src/Common/Dlgcode.c4193
1 files changed, 2318 insertions, 1875 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 6462e319..78aa3844 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -18,6 +18,7 @@
#include <dbt.h>
#include <Setupapi.h>
#include <aclapi.h>
+#include <Netlistmgr.h>
#include <fcntl.h>
#include <io.h>
#include <math.h>
@@ -32,6 +33,9 @@
#include <process.h>
#include <Tlhelp32.h>
#endif
+#if _WIN32_WINNT >= 0x0602
+#include "processthreadsapi.h"
+#endif
#include "Resource.h"
@@ -82,7 +86,15 @@
#include <WinTrust.h>
#include <strsafe.h>
-#pragma comment( lib, "setupapi.lib" )
+#define _WIN32_DCOM
+#include <comdef.h>
+#include <Wbemidl.h>
+
+#pragma comment(lib, "wbemuuid.lib")
+#pragma comment(lib, "Shlwapi.lib")
+#pragma comment(lib, "setupapi.lib" )
+#pragma comment(lib, "Wintrust.lib" )
+#pragma comment(lib, "Comctl32.lib" )
#ifndef TTI_INFO_LARGE
#define TTI_INFO_LARGE 4
@@ -166,6 +178,12 @@ BOOL bHistory = FALSE;
#ifndef SETUP
BOOL bLanguageSetInSetup = FALSE;
+#else
+extern BOOL bMakePackage;
+#endif
+
+#ifdef TCMOUNT
+extern BOOL ServiceMode;
#endif
// Status of detection of hidden sectors (whole-system-drive encryption).
@@ -196,11 +214,14 @@ BOOL LastMountedVolumeDirty;
BOOL MountVolumesAsSystemFavorite = FALSE;
BOOL FavoriteMountOnArrivalInProgress = FALSE;
BOOL MultipleMountOperationInProgress = FALSE;
+BOOL EMVSupportEnabled = FALSE;
volatile BOOL NeedPeriodicDeviceListUpdate = FALSE;
BOOL DisablePeriodicDeviceListUpdate = FALSE;
BOOL EnableMemoryProtection = FALSE;
+BOOL MemoryProtectionActivated = FALSE;
+
BOOL WaitDialogDisplaying = FALSE;
/* Handle to the device driver */
@@ -273,147 +294,29 @@ DWORD SystemFileSelectorCallerThreadId;
#define RANDPOOL_DISPLAY_ROWS 16
#define RANDPOOL_DISPLAY_COLUMNS 20
-HMODULE hRichEditDll = NULL;
-HMODULE hComctl32Dll = NULL;
-HMODULE hSetupDll = NULL;
-HMODULE hShlwapiDll = NULL;
-HMODULE hProfApiDll = NULL;
-HMODULE hUsp10Dll = NULL;
-HMODULE hCryptSpDll = NULL;
-HMODULE hUXThemeDll = NULL;
-HMODULE hUserenvDll = NULL;
-HMODULE hRsaenhDll = NULL;
-HMODULE himm32dll = NULL;
-HMODULE hMSCTFdll = NULL;
-HMODULE hfltlibdll = NULL;
-HMODULE hframedyndll = NULL;
-HMODULE hpsapidll = NULL;
-HMODULE hsecur32dll = NULL;
-HMODULE hnetapi32dll = NULL;
-HMODULE hauthzdll = NULL;
-HMODULE hxmllitedll = NULL;
-HMODULE hmprdll = NULL;
-HMODULE hsppdll = NULL;
-HMODULE vssapidll = NULL;
-HMODULE hvsstracedll = NULL;
-HMODULE hcfgmgr32dll = NULL;
-HMODULE hdevobjdll = NULL;
-HMODULE hpowrprofdll = NULL;
-HMODULE hsspiclidll = NULL;
-HMODULE hcryptbasedll = NULL;
-HMODULE hdwmapidll = NULL;
-HMODULE hmsasn1dll = NULL;
-HMODULE hcrypt32dll = NULL;
-HMODULE hbcryptdll = NULL;
-HMODULE hbcryptprimitivesdll = NULL;
-HMODULE hMsls31 = NULL;
-HMODULE hntmartadll = NULL;
-HMODULE hwinscarddll = NULL;
-HMODULE hmsvcrtdll = NULL;
-HMODULE hWinTrustLib = NULL;
-HMODULE hAdvapi32Dll = NULL;
-
-#define FREE_DLL(h) if (h) { FreeLibrary (h); h = NULL;}
-
-#ifndef BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE
-#define BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE 0x00000001
-#endif
-
-#ifndef BASE_SEARCH_PATH_PERMANENT
-#define BASE_SEARCH_PATH_PERMANENT 0x00008000
-#endif
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
-
-typedef BOOL (WINAPI *SetDllDirectoryPtr)(LPCWSTR lpPathName);
-typedef BOOL (WINAPI *SetSearchPathModePtr)(DWORD Flags);
typedef BOOL (WINAPI *SetDefaultDllDirectoriesPtr)(DWORD DirectoryFlags);
-
-typedef void (WINAPI *InitCommonControlsPtr)(void);
-typedef HIMAGELIST (WINAPI *ImageList_CreatePtr)(int cx, int cy, UINT flags, int cInitial, int cGrow);
-typedef int (WINAPI *ImageList_AddPtr)(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask);
-
-typedef VOID (WINAPI *SetupCloseInfFilePtr)(HINF InfHandle);
-typedef HKEY (WINAPI *SetupDiOpenClassRegKeyPtr)(CONST GUID *ClassGuid,REGSAM samDesired);
-typedef BOOL (WINAPI *SetupInstallFromInfSectionWPtr)(HWND,HINF,PCWSTR,UINT,HKEY,PCWSTR,UINT,PSP_FILE_CALLBACK_W,PVOID,HDEVINFO,PSP_DEVINFO_DATA);
-typedef HINF (WINAPI *SetupOpenInfFileWPtr)(PCWSTR FileName,PCWSTR InfClass,DWORD InfStyle,PUINT ErrorLine);
-
-typedef LSTATUS (STDAPICALLTYPE *SHDeleteKeyWPtr)(HKEY hkey, LPCWSTR pszSubKey);
-
-typedef HRESULT (STDAPICALLTYPE *SHStrDupWPtr)(LPCWSTR psz, LPWSTR *ppwsz);
-
-typedef HRESULT (STDAPICALLTYPE *UrlUnescapeWPtr)(
- PWSTR pszUrl,
- PWSTR pszUnescaped,
- DWORD *pcchUnescaped,
- DWORD dwFlags
-);
-
-// ChangeWindowMessageFilter
-typedef BOOL (WINAPI *ChangeWindowMessageFilterPtr) (UINT, DWORD);
-
-typedef BOOL (WINAPI *CreateProcessWithTokenWFn)(
- __in HANDLE hToken,
- __in DWORD dwLogonFlags,
- __in_opt LPCWSTR lpApplicationName,
- __inout_opt LPWSTR lpCommandLine,
- __in DWORD dwCreationFlags,
- __in_opt LPVOID lpEnvironment,
- __in_opt LPCWSTR lpCurrentDirectory,
- __in LPSTARTUPINFOW lpStartupInfo,
- __out LPPROCESS_INFORMATION lpProcessInformation
- );
-
-SetDllDirectoryPtr SetDllDirectoryFn = NULL;
-SetSearchPathModePtr SetSearchPathModeFn = NULL;
-SetDefaultDllDirectoriesPtr SetDefaultDllDirectoriesFn = NULL;
-
-ImageList_CreatePtr ImageList_CreateFn = NULL;
-ImageList_AddPtr ImageList_AddFn = NULL;
-
-SetupCloseInfFilePtr SetupCloseInfFileFn = NULL;
-SetupDiOpenClassRegKeyPtr SetupDiOpenClassRegKeyFn = NULL;
-SetupInstallFromInfSectionWPtr SetupInstallFromInfSectionWFn = NULL;
-SetupOpenInfFileWPtr SetupOpenInfFileWFn = NULL;
-SHDeleteKeyWPtr SHDeleteKeyWFn = NULL;
-SHStrDupWPtr SHStrDupWFn = NULL;
-UrlUnescapeWPtr UrlUnescapeWFn = NULL;
-ChangeWindowMessageFilterPtr ChangeWindowMessageFilterFn = NULL;
-CreateProcessWithTokenWFn CreateProcessWithTokenWPtr = NULL;
-
-typedef LONG (WINAPI *WINVERIFYTRUST)(HWND hwnd, GUID *pgActionID, LPVOID pWVTData);
-typedef CRYPT_PROVIDER_DATA* (WINAPI *WTHELPERPROVDATAFROMSTATEDATA)(HANDLE hStateData);
-typedef CRYPT_PROVIDER_SGNR* (WINAPI *WTHELPERGETPROVSIGNERFROMCHAIN)(CRYPT_PROVIDER_DATA *pProvData,
- DWORD idxSigner,
- BOOL fCounterSigner,
- DWORD idxCounterSigner);
-typedef CRYPT_PROVIDER_CERT* (WINAPI *WTHELPERGETPROVCERTFROMCHAIN)(CRYPT_PROVIDER_SGNR *pSgnr,
- DWORD idxCert);
-
-static WINVERIFYTRUST WinVerifyTrustFn = NULL;
-static WTHELPERPROVDATAFROMSTATEDATA WTHelperProvDataFromStateDataFn = NULL;
-static WTHELPERGETPROVSIGNERFROMCHAIN WTHelperGetProvSignerFromChainFn = NULL;
-static WTHELPERGETPROVCERTFROMCHAIN WTHelperGetProvCertFromChainFn = NULL;
-
-static unsigned char gpbSha256CodeSignCertFingerprint[64] = {
- 0xF2, 0x09, 0xD3, 0xC5, 0xF5, 0x36, 0x73, 0x4A, 0x64, 0x33, 0xEA, 0x00,
- 0x6C, 0x4D, 0x44, 0xE9, 0xAF, 0x3D, 0x50, 0xE5, 0x6B, 0xBB, 0xCD, 0xED,
- 0xD1, 0x37, 0x75, 0x49, 0xF5, 0xC1, 0xDE, 0xFB, 0xAD, 0xA0, 0xA6, 0x9A,
- 0xC9, 0xA1, 0xD7, 0x2E, 0xB1, 0xCC, 0xFE, 0x68, 0xA0, 0x2C, 0x00, 0xCA,
- 0x26, 0x52, 0xD3, 0x27, 0xDF, 0x4C, 0xEF, 0x94, 0x3D, 0x0D, 0xD1, 0xAA,
- 0xB1, 0x3B, 0xA6, 0xBF
+static unsigned char gpbSha512CodeSignCertFingerprint[64] = {
+ 0x9C, 0xA0, 0x21, 0xD3, 0x7C, 0x90, 0x61, 0x88, 0xEF, 0x5F, 0x99, 0x3D,
+ 0x54, 0x9F, 0xB8, 0xCE, 0x72, 0x32, 0x4F, 0x57, 0x4F, 0x19, 0xD2, 0xA4,
+ 0xDC, 0x84, 0xFF, 0xE2, 0x84, 0x2B, 0xD4, 0x30, 0xAB, 0xA7, 0xE4, 0x63,
+ 0x18, 0xD1, 0xD8, 0x32, 0x0E, 0xA4, 0x81, 0x3C, 0x19, 0xBF, 0x13, 0x11,
+ 0xA4, 0x37, 0xD6, 0xDB, 0x26, 0xBA, 0xDC, 0x8F, 0x86, 0x96, 0x55, 0x96,
+ 0xDB, 0x6F, 0xC0, 0x62
};
-
-typedef HRESULT (WINAPI *SHGETKNOWNFOLDERPATH) (
- _In_ REFKNOWNFOLDERID rfid,
- _In_ DWORD dwFlags,
- _In_opt_ HANDLE hToken,
- _Out_ PWSTR *ppszPath
-);
+static unsigned char gpbSha512MSCodeSignCertFingerprint[64] = {
+ 0xEB, 0x76, 0x2E, 0xD3, 0x5B, 0x4A, 0xB1, 0x0E, 0xF5, 0x3B, 0x99, 0x4E,
+ 0xC1, 0xF7, 0x48, 0x88, 0xF6, 0xA0, 0xE9, 0xAC, 0x32, 0x69, 0xCF, 0x20,
+ 0xE1, 0x60, 0xC4, 0x0C, 0xEF, 0x01, 0x1F, 0xCB, 0x41, 0x95, 0x72, 0xB9,
+ 0xED, 0x63, 0x0C, 0x6B, 0xB9, 0xE9, 0xA2, 0x72, 0xA6, 0x78, 0x96, 0x4C,
+ 0x69, 0x9F, 0x90, 0x3F, 0xB1, 0x3C, 0x64, 0xF2, 0xAB, 0xCF, 0x14, 0x1D,
+ 0xEC, 0x7C, 0xB0, 0xC7
+};
/* Windows dialog class */
#define WINDOWS_DIALOG_CLASS L"#32770"
@@ -487,6 +390,825 @@ typedef struct
} MULTI_CHOICE_DLGPROC_PARAMS;
+
+
+
+// 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 (const wchar_t *filePath, unsigned __int32 *result, __int64 fileOffset)
+{
+ DWORD 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 (const wchar_t *filePath, int *result, __int64 fileOffset)
+{
+ DWORD 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 wchar_t *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);
+ *size = 0;
+ if (h == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ if ((fileSize = GetFileSize (h, NULL)) == INVALID_FILE_SIZE)
+ {
+ CloseHandle (h);
+ return NULL;
+ }
+
+ buf = (char *) calloc (fileSize + 1, 1);
+
+ if (buf == NULL)
+ {
+ CloseHandle (h);
+ return NULL;
+ }
+
+ if (!ReadFile (h, buf, fileSize, size, NULL))
+ {
+ free (buf);
+ buf = NULL;
+ }
+ else
+ {
+ buf[*size] = 0; //make coverity happy eventhough buf is guaranteed to be null terminated because of fileSize+1 in calloc call
+ }
+
+ CloseHandle (h);
+ return buf;
+}
+
+
+// Returns NULL if there's any error.
+char *LoadFileBlock (const wchar_t *fileName, __int64 fileOffset, DWORD count)
+{
+ char *buf;
+ DWORD bytesRead = 0;
+ LARGE_INTEGER seekOffset, seekOffsetNew;
+ BOOL bStatus;
+
+ 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;
+ }
+
+ bStatus = ReadFile (h, buf, count, &bytesRead, NULL);
+
+ CloseHandle (h);
+
+ if (!bStatus || (bytesRead != count))
+ {
+ free (buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+
+// Returns -1 if there is an error, or the size of the file.
+__int64 GetFileSize64 (const wchar_t *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;
+}
+
+// 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 wchar_t *destinationFile, DWORD inputLength, BOOL bAppend, BOOL bRenameIfFailed)
+{
+ HANDLE dst;
+ DWORD bytesWritten;
+ BOOL res = TRUE;
+ DWORD dwLastError = 0;
+
+ dst = CreateFile (destinationFile,
+ GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
+
+ dwLastError = GetLastError();
+ if (!bAppend && bRenameIfFailed && (dst == INVALID_HANDLE_VALUE) && (GetLastError () == ERROR_SHARING_VIOLATION))
+ {
+ wchar_t renamedPath[TC_MAX_PATH + 1];
+ StringCbCopyW (renamedPath, sizeof(renamedPath), destinationFile);
+ StringCbCatW (renamedPath, sizeof(renamedPath), VC_FILENAME_RENAMED_SUFFIX);
+
+ /* rename the locked file in order to be able to create a new one */
+ if (MoveFileEx (destinationFile, renamedPath, MOVEFILE_REPLACE_EXISTING))
+ {
+ dst = CreateFile (destinationFile,
+ GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
+ dwLastError = GetLastError();
+ if (dst == INVALID_HANDLE_VALUE)
+ {
+ /* restore the original file name */
+ MoveFileEx (renamedPath, destinationFile, MOVEFILE_REPLACE_EXISTING);
+ }
+ else
+ {
+ /* delete the renamed file when the machine reboots */
+ MoveFileEx (renamedPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
+ }
+ }
+ }
+
+ if (dst == INVALID_HANDLE_VALUE)
+ {
+ SetLastError (dwLastError);
+ handleWin32Error (MainDlg, SRC_POS);
+ 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, SRC_POS);
+ }
+
+ CloseHandle (dst);
+
+ if (!res && !bAppend)
+ _wremove (destinationFile);
+
+ return res;
+}
+
+
+// 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, int64 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, (size_t) strLen) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+// Returns TRUE if the file or directory exists (both may be enclosed in quotation marks).
+BOOL FileExists (const wchar_t *filePathPtr)
+{
+ wchar_t filePath [TC_MAX_PATH * 2 + 1];
+
+ // Strip quotation marks (if any)
+ if (filePathPtr [0] == L'"')
+ {
+ StringCbCopyW (filePath, sizeof(filePath), filePathPtr + 1);
+ }
+ else
+ {
+ StringCbCopyW (filePath, sizeof(filePath), filePathPtr);
+ }
+
+ // Strip quotation marks (if any)
+ if (filePath [wcslen (filePath) - 1] == L'"')
+ filePath [wcslen (filePath) - 1] = 0;
+
+ return (_waccess (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 wchar_t *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 TCCopyFileBase (HANDLE src, HANDLE dst)
+{
+ __int8 *buffer;
+ FILETIME fileTime;
+ DWORD bytesRead, bytesWritten;
+ BOOL res;
+
+ 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;
+ }
+ }
+
+ if (GetFileTime (src, NULL, NULL, &fileTime))
+ SetFileTime (dst, NULL, NULL, &fileTime);
+
+ CloseHandle (src);
+ CloseHandle (dst);
+
+ free (buffer);
+ return res != 0;
+}
+
+BOOL TCCopyFile (wchar_t *sourceFileName, wchar_t *destinationFile)
+{
+ HANDLE src, dst;
+
+ src = CreateFileW (sourceFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
+
+ if (src == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ dst = CreateFileW (destinationFile,
+ GENERIC_WRITE,
+ 0, NULL, CREATE_ALWAYS, 0, NULL);
+
+ if (dst == INVALID_HANDLE_VALUE)
+ {
+ CloseHandle (src);
+ return FALSE;
+ }
+
+ return TCCopyFileBase (src, dst);
+}
+
+
+BOOL VerifyModuleSignature (const wchar_t* path)
+{
+#if defined(NDEBUG) && !defined (VC_SKIP_OS_DRIVER_REQ_CHECK)
+ BOOL bResult = FALSE;
+ HRESULT hResult;
+ GUID gActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+ WINTRUST_FILE_INFO fileInfo = {0};
+ WINTRUST_DATA WVTData = {0};
+ wchar_t filePath [TC_MAX_PATH + 1024];
+
+ // we check our own authenticode signature only starting from Windows 10 since this is
+ // the minimal supported OS apart from XP where we can't verify SHA256 signatures
+ if (!IsOSAtLeast (WIN_10))
+ return TRUE;
+
+ // Strip quotation marks (if any)
+ if (path [0] == L'"')
+ {
+ StringCbCopyW (filePath, sizeof(filePath), path + 1);
+ }
+ else
+ {
+ StringCbCopyW (filePath, sizeof(filePath), path);
+ }
+
+ // Strip quotation marks (if any)
+ if (filePath [wcslen (filePath) - 1] == L'"')
+ filePath [wcslen (filePath) - 1] = 0;
+
+ fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
+ fileInfo.pcwszFilePath = filePath;
+ fileInfo.hFile = NULL;
+
+ WVTData.cbStruct = sizeof(WINTRUST_DATA);
+ WVTData.dwUIChoice = WTD_UI_NONE;
+ WVTData.fdwRevocationChecks = WTD_REVOKE_NONE;
+ WVTData.dwUnionChoice = WTD_CHOICE_FILE;
+ WVTData.pFile = &fileInfo;
+ WVTData.dwStateAction = WTD_STATEACTION_VERIFY;
+ WVTData.dwProvFlags = WTD_REVOCATION_CHECK_NONE | WTD_CACHE_ONLY_URL_RETRIEVAL;
+
+ hResult = WinVerifyTrust(0, &gActionID, &WVTData);
+ if (0 == hResult)
+ {
+ PCRYPT_PROVIDER_DATA pProviderData = WTHelperProvDataFromStateData (WVTData.hWVTStateData);
+ if (pProviderData)
+ {
+ PCRYPT_PROVIDER_SGNR pProviderSigner = WTHelperGetProvSignerFromChain (pProviderData, 0, FALSE, 0);
+ if (pProviderSigner)
+ {
+ PCRYPT_PROVIDER_CERT pProviderCert = WTHelperGetProvCertFromChain (pProviderSigner, 0);
+ if (pProviderCert && (pProviderCert->pCert))
+ {
+ BYTE hashVal[64];
+ sha512 (hashVal, pProviderCert->pCert->pbCertEncoded, pProviderCert->pCert->cbCertEncoded);
+
+ if ( (0 == memcmp (hashVal, gpbSha512CodeSignCertFingerprint, 64))
+ || (0 == memcmp (hashVal, gpbSha512MSCodeSignCertFingerprint, 64))
+ )
+ {
+ bResult = TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ WVTData.dwUIChoice = WTD_UI_NONE;
+ WVTData.dwStateAction = WTD_STATEACTION_CLOSE;
+ WinVerifyTrust(0, &gActionID, &WVTData);
+
+ return bResult;
+#else
+ return TRUE;
+#endif
+}
+
+DWORD handleWin32Error (HWND hwndDlg, const char* srcPos)
+{
+#ifndef VC_COMREG
+ PWSTR lpMsgBuf;
+ DWORD dwError = GetLastError ();
+ wchar_t szErrorValue[32];
+ wchar_t* pszDesc;
+
+ if (Silent || dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE)
+ return dwError;
+
+ // Access denied
+ if (dwError == ERROR_ACCESS_DENIED && !IsAdmin ())
+ {
+ ErrorDirect ( AppendSrcPos (GetString ("ERR_ACCESS_DENIED"), srcPos).c_str (), hwndDlg);
+ SetLastError (dwError); // Preserve the original error code
+ return dwError;
+ }
+
+ FormatMessageW (
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ dwError,
+ MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+ (PWSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ if (lpMsgBuf)
+ pszDesc = (wchar_t*) lpMsgBuf;
+ else
+ {
+ StringCchPrintfW (szErrorValue, ARRAYSIZE (szErrorValue), L"Error 0x%.8X", dwError);
+ pszDesc = szErrorValue;
+ }
+
+ MessageBoxW (hwndDlg, AppendSrcPos (pszDesc, srcPos).c_str (), lpszTitle, ICON_HAND);
+ if (lpMsgBuf) LocalFree (lpMsgBuf);
+
+ // User-friendly hardware error explanation
+ if (IsDiskError (dwError))
+ Error ("ERR_HARDWARE_ERROR", hwndDlg);
+
+ // Device not ready
+ if (dwError == ERROR_NOT_READY)
+ HandleDriveNotReadyError(hwndDlg);
+
+ SetLastError (dwError); // Preserve the original error code
+
+ return dwError;
+#else
+ return GetLastError();
+#endif
+}
+
+int Error (char *stringId, HWND hwnd)
+{
+#ifndef VC_COMREG
+ if (Silent) return 0;
+ return MessageBoxW (hwnd, GetString (stringId), lpszTitle, MB_ICONERROR);
+#else
+ return 0;
+#endif
+}
+
+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;
+ case WIN_8: major = 6; minor = 2; break;
+ case WIN_8_1: major = 6; minor = 3; break;
+ case WIN_10: major = 10; minor = 0; break;
+
+ default:
+ TC_THROW_FATAL_EXCEPTION;
+ break;
+ }
+
+ return ((CurrentOSMajor << 16 | CurrentOSMinor << 8 | CurrentOSServicePack)
+ >= (major << 16 | minor << 8 | reqMinServicePack));
+}
+
+#ifdef SETUP_DLL
+static BOOL GetWindowVersionFromFile(DWORD* pdwMajor, DWORD* pdwMinor, DWORD* pdwBuildNumber)
+{
+ wchar_t dllPath[MAX_PATH];
+ BOOL bRet = FALSE;
+ LPBYTE versionInfo = NULL;
+ UINT size;
+ VS_FIXEDFILEINFO *vinfo;
+
+ /* Load dll explictely from System32 to avoid Dll hijacking attacks*/
+ if (!GetSystemDirectory(dllPath, MAX_PATH))
+ StringCbCopyW(dllPath, sizeof(dllPath), L"C:\\Windows\\System32");
+
+ StringCbCatW(dllPath, sizeof(dllPath), L"\\");
+ StringCbCatW(dllPath, sizeof(dllPath), L"Kernel32.dll");
+
+ size = GetFileVersionInfoSizeW(dllPath, NULL);
+ if (size)
+ {
+ versionInfo = (LPBYTE) TCalloc(size);
+ if (GetFileVersionInfo(dllPath, 0, size, versionInfo))
+ {
+
+ if (VerQueryValueW(versionInfo, L"\\", (LPVOID *)&vinfo, &size) && (size >=sizeof(VS_FIXEDFILEINFO)))
+ {
+ *pdwMajor = HIWORD(vinfo->dwProductVersionMS);
+ *pdwMinor = LOWORD(vinfo->dwProductVersionMS);
+ *pdwBuildNumber = HIWORD(vinfo->dwProductVersionLS);
+ bRet = TRUE;
+ }
+ }
+ }
+
+ if (versionInfo)
+ TCfree(versionInfo);
+ return bRet;
+}
+#endif
+
+/*
+ * Use RtlGetVersion to get Windows version because GetVersionEx is affected by application manifestation.
+ */
+typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
+
+static BOOL GetWindowsVersion(LPOSVERSIONINFOW lpVersionInformation)
+{
+ BOOL bRet = FALSE;
+#ifdef SETUP_DLL
+ DWORD dwMajor, dwMinor, dwBuildNumber;
+#endif
+ RtlGetVersionPtr RtlGetVersionFn = (RtlGetVersionPtr) GetProcAddress(GetModuleHandle (L"ntdll.dll"), "RtlGetVersion");
+ if (RtlGetVersionFn != NULL)
+ {
+ if (ERROR_SUCCESS == RtlGetVersionFn (lpVersionInformation))
+ bRet = TRUE;
+ }
+
+ if (!bRet)
+ bRet = GetVersionExW (lpVersionInformation);
+
+#ifdef SETUP_DLL
+ // we get real version from Kernel32.dll version since MSI always sets current version to 6.0
+ // https://stackoverflow.com/questions/49335885/windows-10-not-detecting-on-installshield/49343826#49343826
+ if (GetWindowVersionFromFile(&dwMajor, &dwMinor, &dwBuildNumber))
+ {
+ lpVersionInformation->dwMajorVersion = dwMajor;
+ lpVersionInformation->dwMinorVersion = dwMinor;
+ lpVersionInformation->dwBuildNumber = dwBuildNumber;
+ }
+#endif
+
+ return bRet;
+}
+
+
+void InitOSVersionInfo ()
+{
+ OSVERSIONINFOEXW os;
+ os.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
+
+ if (GetWindowsVersion ((LPOSVERSIONINFOW) &os) == FALSE)
+ AbortProcess ("NO_OS_VER");
+
+ CurrentOSMajor = os.dwMajorVersion;
+ CurrentOSMinor = os.dwMinorVersion;
+ CurrentOSServicePack = os.wServicePackMajor;
+ CurrentOSBuildNumber = os.dwBuildNumber;
+
+ 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)
+ {
+ if (os.wProductType == VER_NT_SERVER || os.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)
+ {
+ if (os.wProductType != VER_NT_WORKSTATION)
+ nCurrentOS = WIN_SERVER_2008;
+ else
+ nCurrentOS = WIN_VISTA;
+ }
+ else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 1)
+ nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2008_R2 : WIN_7);
+ else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 2)
+ nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2012 : WIN_8);
+ else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 3)
+ nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2012_R2 : WIN_8_1);
+ else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 10 && CurrentOSMinor == 0)
+ nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2016 : WIN_10);
+ 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;
+}
+
+#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)
+{
+ size_t j = (strlen (lpszText) + 1) * sizeof (char);
+ char *z = (char *) err_malloc (j);
+ memmove (z, lpszText, j);
+ return z;
+}
+
+void AbortProcessDirect (wchar_t *abortMsg)
+{
+ // Note that this function also causes localcleanup() to be called (see atexit())
+ MessageBeep (MB_ICONEXCLAMATION);
+ MessageBoxW (NULL, abortMsg, lpszTitle, ICON_HAND);
+ exit (1);
+}
+
+void AbortProcess (char *stringId)
+{
+ // Note that this function also causes localcleanup() to be called (see atexit())
+#ifndef VC_COMREG
+ AbortProcessDirect (GetString (stringId));
+#else
+ static wchar_t g_wszUnknown[1024];
+ StringCbPrintfW (g_wszUnknown, sizeof(g_wszUnknown), UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId);
+ AbortProcessDirect (g_wszUnknown);
+#endif
+}
+
+#ifndef VC_COMREG
+void AbortProcessSilent (void)
+{
+ // Note that this function also causes localcleanup() to be called (see atexit())
+ exit (1);
+}
+
void InitGlobalLocks ()
{
InitializeCriticalSection (&csWNetCalls);
@@ -603,11 +1325,11 @@ void LowerCaseCopy (wchar_t *lpszDest, const wchar_t *lpszSource)
void UpperCaseCopy (wchar_t *lpszDest, size_t cbDest, const wchar_t *lpszSource)
{
- if (lpszDest && cbDest)
+ if (lpszDest && (cbDest >= 2))
{
size_t i = wcslen (lpszSource);
- if (i >= cbDest)
- i = cbDest - 1;
+ if (i >= (cbDest/2))
+ i = (cbDest/2) - 1;
lpszDest[i] = 0;
i++;
@@ -753,131 +1475,6 @@ int RemoveFakeDosName (wchar_t *lpszDiskFile, wchar_t *lpszDosDevice)
}
-void AbortProcessDirect (wchar_t *abortMsg)
-{
- // Note that this function also causes localcleanup() to be called (see atexit())
- MessageBeep (MB_ICONEXCLAMATION);
- MessageBoxW (NULL, abortMsg, lpszTitle, ICON_HAND);
- FREE_DLL (hRichEditDll);
- FREE_DLL (hComctl32Dll);
- FREE_DLL (hSetupDll);
- FREE_DLL (hShlwapiDll);
- FREE_DLL (hProfApiDll);
- FREE_DLL (hUsp10Dll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hUXThemeDll);
- FREE_DLL (hUserenvDll);
- FREE_DLL (hRsaenhDll);
- FREE_DLL (himm32dll);
- FREE_DLL (hMSCTFdll);
- FREE_DLL (hfltlibdll);
- FREE_DLL (hframedyndll);
- FREE_DLL (hpsapidll);
- FREE_DLL (hsecur32dll);
- FREE_DLL (hnetapi32dll);
- FREE_DLL (hauthzdll);
- FREE_DLL (hxmllitedll);
- FREE_DLL (hmprdll);
- FREE_DLL (hsppdll);
- FREE_DLL (vssapidll);
- FREE_DLL (hvsstracedll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hcfgmgr32dll);
- FREE_DLL (hdevobjdll);
- FREE_DLL (hpowrprofdll);
- FREE_DLL (hsspiclidll);
- FREE_DLL (hcryptbasedll);
- FREE_DLL (hdwmapidll);
- FREE_DLL (hmsasn1dll);
- FREE_DLL (hcrypt32dll);
- FREE_DLL (hbcryptdll);
- FREE_DLL (hbcryptprimitivesdll);
- FREE_DLL (hMsls31);
- FREE_DLL (hntmartadll);
- FREE_DLL (hwinscarddll);
- FREE_DLL (hmsvcrtdll);
- FREE_DLL (hAdvapi32Dll);
-
- exit (1);
-}
-
-void AbortProcess (char *stringId)
-{
- // Note that this function also causes localcleanup() to be called (see atexit())
- AbortProcessDirect (GetString (stringId));
-}
-
-void AbortProcessSilent (void)
-{
- FREE_DLL (hRichEditDll);
- FREE_DLL (hComctl32Dll);
- FREE_DLL (hSetupDll);
- FREE_DLL (hShlwapiDll);
- FREE_DLL (hProfApiDll);
- FREE_DLL (hUsp10Dll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hUXThemeDll);
- FREE_DLL (hUserenvDll);
- FREE_DLL (hRsaenhDll);
- FREE_DLL (himm32dll);
- FREE_DLL (hMSCTFdll);
- FREE_DLL (hfltlibdll);
- FREE_DLL (hframedyndll);
- FREE_DLL (hpsapidll);
- FREE_DLL (hsecur32dll);
- FREE_DLL (hnetapi32dll);
- FREE_DLL (hauthzdll);
- FREE_DLL (hxmllitedll);
- FREE_DLL (hmprdll);
- FREE_DLL (hsppdll);
- FREE_DLL (vssapidll);
- FREE_DLL (hvsstracedll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hcfgmgr32dll);
- FREE_DLL (hdevobjdll);
- FREE_DLL (hpowrprofdll);
- FREE_DLL (hsspiclidll);
- FREE_DLL (hcryptbasedll);
- FREE_DLL (hdwmapidll);
- FREE_DLL (hmsasn1dll);
- FREE_DLL (hcrypt32dll);
- FREE_DLL (hbcryptdll);
- FREE_DLL (hbcryptprimitivesdll);
- FREE_DLL (hMsls31);
- FREE_DLL (hntmartadll);
- FREE_DLL (hwinscarddll);
- FREE_DLL (hmsvcrtdll);
- FREE_DLL (hAdvapi32Dll);
-
- // 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)
-{
- size_t 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
@@ -906,59 +1503,6 @@ BOOL IsDiskError (DWORD error)
return IsDiskReadError (error) || IsDiskWriteError (error);
}
-
-DWORD handleWin32Error (HWND hwndDlg, const char* srcPos)
-{
- PWSTR lpMsgBuf;
- DWORD dwError = GetLastError ();
- wchar_t szErrorValue[32];
- wchar_t* pszDesc;
-
- if (Silent || dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE)
- return dwError;
-
- // Access denied
- if (dwError == ERROR_ACCESS_DENIED && !IsAdmin ())
- {
- ErrorDirect ( AppendSrcPos (GetString ("ERR_ACCESS_DENIED"), srcPos).c_str (), hwndDlg);
- SetLastError (dwError); // Preserve the original error code
- return dwError;
- }
-
- FormatMessageW (
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- dwError,
- MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
- (PWSTR) &lpMsgBuf,
- 0,
- NULL
- );
-
- if (lpMsgBuf)
- pszDesc = (wchar_t*) lpMsgBuf;
- else
- {
- StringCchPrintfW (szErrorValue, ARRAYSIZE (szErrorValue), L"Error 0x%.8X", dwError);
- pszDesc = szErrorValue;
- }
-
- MessageBoxW (hwndDlg, AppendSrcPos (pszDesc, srcPos).c_str (), lpszTitle, ICON_HAND);
- if (lpMsgBuf) LocalFree (lpMsgBuf);
-
- // User-friendly hardware error explanation
- if (IsDiskError (dwError))
- Error ("ERR_HARDWARE_ERROR", hwndDlg);
-
- // Device not ready
- if (dwError == ERROR_NOT_READY)
- HandleDriveNotReadyError(hwndDlg);
-
- SetLastError (dwError); // Preserve the original error code
-
- return dwError;
-}
-
BOOL translateWin32Error (wchar_t *lpszMsgBuf, int nWSizeOfBuf)
{
DWORD dwError = GetLastError ();
@@ -1216,6 +1760,88 @@ void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT h
}
}
+// Resizes width of a checkbox according to actual width in pixels of its label text (font size is taken into account)
+void AccommodateCheckBoxTextWidth (HWND hwndDlg, UINT ctrlId)
+{
+ RECT rec;
+ HWND hwndCtrl = GetDlgItem (hwndDlg, ctrlId);
+ int width, origWidth, origHeight;
+ int horizSubOffset;
+ wchar_t text [MAX_URL_LENGTH];
+ HFONT hFont = (HFONT) SendDlgItemMessage (hwndDlg, ctrlId, WM_GETFONT, 0, 0);
+
+ // 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);
+
+ // add to width variable value the width of the checkbox square. We use SM_CXMENUCHECK which is a little larger than actual width
+ width += GetSystemMetrics(SM_CXMENUCHECK);
+
+
+ GetClientRect (hwndCtrl, &rec);
+ origWidth = rec.right;
+ origHeight = rec.bottom;
+
+ if (width >= 0
+ && (origWidth > width)) // The original width of the field is the maximum allowed size
+ {
+ horizSubOffset = origWidth - width;
+
+ // Resize the text field
+ SetWindowPos (hwndCtrl, 0, 0, 0,
+ origWidth - horizSubOffset,
+ origHeight,
+ SWP_NOMOVE | SWP_NOZORDER);
+
+ InvalidateRect (hwndCtrl, NULL, TRUE);
+ }
+}
+
+// makes controls contiguous by moving the second control right next to the first one horizontally
+void MakeControlsContiguous(HWND hwndDlg, UINT ctrl1ID, UINT ctrl2ID) {
+ HWND hwndCtrl1 = GetDlgItem(hwndDlg, ctrl1ID);
+ HWND hwndCtrl2 = GetDlgItem(hwndDlg, ctrl2ID);
+ RECT rect1, rect2;
+ POINT pt1, pt2;
+ int newLeftPosition;
+
+ // Exit silently if one or both controls are missing
+ if (!hwndCtrl1 || !hwndCtrl2) {
+ return;
+ }
+
+
+ GetWindowRect(hwndCtrl1, &rect1);
+ GetWindowRect(hwndCtrl2, &rect2);
+
+ // Convert the top-right point of the first control from screen to client coordinates
+ pt1.x = rect1.right;
+ pt1.y = rect1.top;
+ if (!ScreenToClient(hwndDlg, &pt1)) {
+ return; // Exit if the conversion fails
+ }
+
+ // Convert the top-left point of the second control from screen to client coordinates
+ pt2.x = rect2.left;
+ pt2.y = rect2.top;
+ if (!ScreenToClient(hwndDlg, &pt2)) {
+ return; // Exit if the conversion fails
+ }
+
+ // Ensure the second control is always placed to the right of the first one
+ newLeftPosition = pt1.x + 1;
+
+ if (pt2.x < pt1.x) { // if the second control is to the left of the first one
+ newLeftPosition += (pt1.x - pt2.x);
+ }
+
+ // Move the second control to its new position
+ SetWindowPos(hwndCtrl2, NULL, newLeftPosition, pt2.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+}
+
+
// Note that the user can still close the window by right-clicking its taskbar icon and selecting 'Close window', or by pressing Alt-F4, or using the Task Manager.
void DisableCloseButton (HWND hwndDlg)
{
@@ -1530,19 +2156,20 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
L"Based on TrueCrypt 7.1a, freely available at http://www.truecrypt.org/ .\r\n\r\n"
L"Portions of this software:\r\n"
- L"Copyright \xA9 2013-2021 IDRIX. All rights reserved.\r\n"
+ L"Copyright \xA9 2013-2023 IDRIX. All rights reserved.\r\n"
L"Copyright \xA9 2003-2012 TrueCrypt Developers Association. All Rights Reserved.\r\n"
L"Copyright \xA9 1998-2000 Paul Le Roux. All Rights Reserved.\r\n"
L"Copyright \xA9 1998-2008 Brian Gladman. All Rights Reserved.\r\n"
- L"Copyright \xA9 1995-2017 Jean-loup Gailly and Mark Adler.\r\n"
+ L"Copyright \xA9 1995-2023 Jean-loup Gailly and Mark Adler.\r\n"
L"Copyright \xA9 2016 Disk Cryptography Services for EFI (DCS), Alex Kolotnikov.\r\n"
- L"Copyright \xA9 1999-2017 Dieter Baron and Thomas Klausner.\r\n"
+ L"Copyright \xA9 1999-2023 Dieter Baron and Thomas Klausner.\r\n"
L"Copyright \xA9 2013, Alexey Degtyarev. All rights reserved.\r\n"
L"Copyright \xA9 1999-2016 Jack Lloyd. All rights reserved.\r\n"
- L"Copyright \xA9 2013-2019 Stephan Mueller <smueller@chronox.de>\r\n\r\n"
+ L"Copyright \xA9 2013-2019 Stephan Mueller <smueller@chronox.de>\r\n"
+ L"Copyright \xA9 1999-2023 Igor Pavlov\r\n\r\n"
L"This software as a whole:\r\n"
- L"Copyright \xA9 2013-2021 IDRIX. All rights reserved.\r\n\r\n"
+ L"Copyright \xA9 2013-2023 IDRIX. All rights reserved.\r\n\r\n"
L"An IDRIX Release");
@@ -1585,6 +2212,42 @@ BOOL CALLBACK AboutDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam
return 0;
}
+HWND CreateToolTip(int toolID, HWND hDlg, const char* strID)
+{
+ if (!toolID || !hDlg)
+ {
+ return FALSE;
+ }
+
+ // Create the tooltip.
+ HWND hwndTip = CreateWindowExW(NULL, TOOLTIPS_CLASS, NULL,
+ WS_POPUP | TTS_ALWAYSTIP | TTS_NOPREFIX | TTS_BALLOON,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ hDlg, NULL,
+ hInst, NULL);
+
+ if (!hwndTip)
+ {
+ return (HWND)NULL;
+ }
+
+ // Associate the tooltip with the tool.
+ TOOLINFOW toolInfo = { 0 };
+ toolInfo.cbSize = sizeof(toolInfo);
+ toolInfo.hwnd = hDlg;
+ toolInfo.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
+ toolInfo.uId = (UINT_PTR) GetDlgItem(hDlg, toolID);
+ toolInfo.lpszText = GetString(strID);
+
+ // set tooltip maximum width
+ SendMessage(hwndTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM) 300);
+
+ SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
+
+ return hwndTip;
+}
+
static HWND StaticModelessWaitDlgHandle = NULL;
@@ -1704,7 +2367,7 @@ void InitDialog (HWND hwndDlg)
{
StringCbCopyW ((WCHAR *)metric.lfMessageFont.lfFaceName, sizeof (metric.lfMessageFont.lfFaceName), font->FaceName);
}
- else if (IsOSAtLeast (WIN_VISTA))
+ else
{
// 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.
@@ -2699,6 +3362,24 @@ uint32 ReadEncryptionThreadPoolFreeCpuCountLimit ()
return count;
}
+BOOL ReadMemoryProtectionConfig ()
+{
+ DWORD config;
+
+ if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", VC_ENABLE_MEMORY_PROTECTION, &config))
+ {
+ // enabled by default
+ config = 1;
+ }
+ return (config)? TRUE: FALSE;
+}
+
+BOOL WriteMemoryProtectionConfig (BOOL bEnable)
+{
+ DWORD config = bEnable? 1: 0;
+
+ return WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", VC_ENABLE_MEMORY_PROTECTION, config);
+}
BOOL LoadSysEncSettings ()
{
@@ -2875,152 +3556,38 @@ void DoPostInstallTasks (HWND hwndDlg)
SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_REMOVE_ALL);
}
-#ifdef SETUP_DLL
-static BOOL GetWindowVersionFromFile(DWORD* pdwMajor, DWORD* pdwMinor, DWORD* pdwBuildNumber)
-{
- wchar_t dllPath[MAX_PATH];
- BOOL bRet = FALSE;
- LPBYTE versionInfo = NULL;
- UINT size;
- VS_FIXEDFILEINFO *vinfo;
-
- /* Load dll explictely from System32 to avoid Dll hijacking attacks*/
- if (!GetSystemDirectory(dllPath, MAX_PATH))
- StringCbCopyW(dllPath, sizeof(dllPath), L"C:\\Windows\\System32");
-
- StringCbCatW(dllPath, sizeof(dllPath), L"\\");
- StringCbCatW(dllPath, sizeof(dllPath), L"Kernel32.dll");
-
- size = GetFileVersionInfoSizeW(dllPath, NULL);
- if (size)
- {
- versionInfo = (LPBYTE) TCalloc(size);
- if (GetFileVersionInfo(dllPath, 0, size, versionInfo))
+#ifndef SETUP_DLL
+// Use an idea proposed in https://medium.com/@1ndahous3/safe-code-pitfalls-dll-side-loading-winapi-and-c-73baaf48bdf5
+// it allows to set safe DLL search mode for the entire process very early on, before even the CRT is initialized and global constructors are called
+#pragma comment(linker, "/ENTRY:CustomMainCrtStartup")
+extern "C" {
+ int wWinMainCRTStartup();
+ int APIENTRY CustomMainCrtStartup()
+ {
+ SetDefaultDllDirectoriesPtr SetDefaultDllDirectoriesFn = NULL;
+ SetDefaultDllDirectoriesFn = (SetDefaultDllDirectoriesPtr) GetProcAddress (GetModuleHandle(L"kernel32.dll"), "SetDefaultDllDirectories");
+ if (SetDefaultDllDirectoriesFn)
{
-
- if (VerQueryValueW(versionInfo, L"\\", (LPVOID *)&vinfo, &size) && (size >=sizeof(VS_FIXEDFILEINFO)))
- {
- *pdwMajor = HIWORD(vinfo->dwProductVersionMS);
- *pdwMinor = LOWORD(vinfo->dwProductVersionMS);
- *pdwBuildNumber = HIWORD(vinfo->dwProductVersionLS);
- bRet = TRUE;
- }
+ /* remove current directory from dll search path */
+ SetDllDirectoryW (L"");
+ // Force loading dlls from system32 directory only
+ SetDefaultDllDirectoriesFn (LOAD_LIBRARY_SEARCH_SYSTEM32);
}
- }
- if (versionInfo)
- TCfree(versionInfo);
- return bRet;
-}
-#endif
-
-/*
- * Use RtlGetVersion to get Windows version because GetVersionEx is affected by application manifestation.
- */
-typedef NTSTATUS (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
-
-static BOOL GetWindowsVersion(LPOSVERSIONINFOW lpVersionInformation)
-{
- BOOL bRet = FALSE;
-#ifdef SETUP_DLL
- DWORD dwMajor, dwMinor, dwBuildNumber;
-#endif
- RtlGetVersionPtr RtlGetVersionFn = (RtlGetVersionPtr) GetProcAddress(GetModuleHandle (L"ntdll.dll"), "RtlGetVersion");
- if (RtlGetVersionFn != NULL)
- {
- if (ERROR_SUCCESS == RtlGetVersionFn (lpVersionInformation))
- bRet = TRUE;
- }
+ // activate process mitigations (currently only ASLR, dynamic code and extensions points)
+ ActivateProcessMitigations();
- if (!bRet)
- bRet = GetVersionExW (lpVersionInformation);
-
-#ifdef SETUP_DLL
- // we get real version from Kernel32.dll version since MSI always sets current version to 6.0
- // https://stackoverflow.com/questions/49335885/windows-10-not-detecting-on-installshield/49343826#49343826
- if (GetWindowVersionFromFile(&dwMajor, &dwMinor, &dwBuildNumber))
- {
- lpVersionInformation->dwMajorVersion = dwMajor;
- lpVersionInformation->dwMinorVersion = dwMinor;
- lpVersionInformation->dwBuildNumber = dwBuildNumber;
- }
+#ifndef SETUP
+ // call ActivateMemoryProtection if corresponding setting has been enabled (default is enabled)
+ if (ReadMemoryProtectionConfig())
+ {
+ ActivateMemoryProtection();
+ }
#endif
-
- return bRet;
-}
-
-
-void InitOSVersionInfo ()
-{
- OSVERSIONINFOEXW os;
- os.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW);
-
- if (GetWindowsVersion ((LPOSVERSIONINFOW) &os) == FALSE)
- AbortProcess ("NO_OS_VER");
-
- CurrentOSMajor = os.dwMajorVersion;
- CurrentOSMinor = os.dwMinorVersion;
- CurrentOSServicePack = os.wServicePackMajor;
- CurrentOSBuildNumber = os.dwBuildNumber;
-
- 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)
- {
- if (os.wProductType == VER_NT_SERVER || os.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)
- {
- if (os.wProductType != VER_NT_WORKSTATION)
- nCurrentOS = WIN_SERVER_2008;
- else
- nCurrentOS = WIN_VISTA;
- }
- else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 1)
- nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2008_R2 : WIN_7);
- else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 2)
- nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2012 : WIN_8);
- else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 6 && CurrentOSMinor == 3)
- nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2012_R2 : WIN_8_1);
- else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && CurrentOSMajor == 10 && CurrentOSMinor == 0)
- nCurrentOS = ((os.wProductType != VER_NT_WORKSTATION) ? WIN_SERVER_2016 : WIN_10);
- 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;
-}
-
-static void LoadSystemDll (LPCTSTR szModuleName, HMODULE *pHandle, BOOL bIgnoreError, const char* srcPos)
-{
- wchar_t dllPath[MAX_PATH];
-
- /* Load dll explictely from System32 to avoid Dll hijacking attacks*/
- if (!GetSystemDirectory(dllPath, MAX_PATH))
- StringCbCopyW(dllPath, sizeof(dllPath), L"C:\\Windows\\System32");
-
- StringCbCatW(dllPath, sizeof(dllPath), L"\\");
- StringCbCatW(dllPath, sizeof(dllPath), szModuleName);
-
- if (((*pHandle = LoadLibrary(dllPath)) == NULL) && !bIgnoreError)
- {
- // This error is fatal
- handleWin32Error (NULL, srcPos);
- AbortProcess ("INIT_DLL");
+ return wWinMainCRTStartup();
}
}
+#endif
/* InitApp - initialize the application, this function is called once in the
applications WinMain function, but before the main dialog has been created */
@@ -3028,167 +3595,61 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
{
WNDCLASSW wc;
char langId[6];
- InitCommonControlsPtr InitCommonControlsFn = NULL;
+ SetDefaultDllDirectoriesPtr SetDefaultDllDirectoriesFn = NULL;
+#if !defined(SETUP)
wchar_t modPath[MAX_PATH];
-
- GetModuleFileNameW (NULL, modPath, ARRAYSIZE (modPath));
-
- /* remove current directory from dll search path */
- SetDllDirectoryFn = (SetDllDirectoryPtr) GetProcAddress (GetModuleHandle(L"kernel32.dll"), "SetDllDirectoryW");
- SetSearchPathModeFn = (SetSearchPathModePtr) GetProcAddress (GetModuleHandle(L"kernel32.dll"), "SetSearchPathMode");
- SetDefaultDllDirectoriesFn = (SetDefaultDllDirectoriesPtr) GetProcAddress (GetModuleHandle(L"kernel32.dll"), "SetDefaultDllDirectories");
-
- if (SetDllDirectoryFn)
- SetDllDirectoryFn (L"");
- if (SetSearchPathModeFn)
- SetSearchPathModeFn (BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT);
- if (SetDefaultDllDirectoriesFn)
- SetDefaultDllDirectoriesFn (LOAD_LIBRARY_SEARCH_SYSTEM32);
-
- InitOSVersionInfo();
-
- VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin));
-
- InitGlobalLocks ();
-
- LoadSystemDll (L"msvcrt.dll", &hmsvcrtdll, TRUE, SRC_POS);
- LoadSystemDll (L"ntmarta.dll", &hntmartadll, TRUE, SRC_POS);
- LoadSystemDll (L"MPR.DLL", &hmprdll, TRUE, SRC_POS);
-#ifdef SETUP
- if (IsOSAtLeast (WIN_7))
- {
- LoadSystemDll (L"ProfApi.DLL", &hProfApiDll, TRUE, SRC_POS);
- LoadSystemDll (L"cryptbase.dll", &hcryptbasedll, TRUE, SRC_POS);
- LoadSystemDll (L"sspicli.dll", &hsspiclidll, TRUE, SRC_POS);
- }
#endif
- LoadSystemDll (L"psapi.dll", &hpsapidll, TRUE, SRC_POS);
- LoadSystemDll (L"secur32.dll", &hsecur32dll, TRUE, SRC_POS);
- LoadSystemDll (L"msasn1.dll", &hmsasn1dll, TRUE, SRC_POS);
- LoadSystemDll (L"Usp10.DLL", &hUsp10Dll, TRUE, SRC_POS);
- if (IsOSAtLeast (WIN_7))
- LoadSystemDll (L"dwmapi.dll", &hdwmapidll, TRUE, SRC_POS);
- LoadSystemDll (L"UXTheme.dll", &hUXThemeDll, TRUE, SRC_POS);
+ INITCOMMONCONTROLSEX InitCtrls;
- LoadSystemDll (L"msls31.dll", &hMsls31, TRUE, SRC_POS);
- LoadSystemDll (L"SETUPAPI.DLL", &hSetupDll, FALSE, SRC_POS);
- LoadSystemDll (L"SHLWAPI.DLL", &hShlwapiDll, FALSE, SRC_POS);
+ InitOSVersionInfo();
- LoadSystemDll (L"userenv.dll", &hUserenvDll, TRUE, SRC_POS);
- LoadSystemDll (L"rsaenh.dll", &hRsaenhDll, TRUE, SRC_POS);
-
-#ifdef SETUP
- if (nCurrentOS < WIN_7)
+ if (!IsOSAtLeast (WIN_7))
{
- if (nCurrentOS == WIN_XP)
- {
- LoadSystemDll (L"imm32.dll", &himm32dll, TRUE, SRC_POS);
- LoadSystemDll (L"MSCTF.dll", &hMSCTFdll, TRUE, SRC_POS);
- LoadSystemDll (L"fltlib.dll", &hfltlibdll, TRUE, SRC_POS);
- LoadSystemDll (L"wbem\\framedyn.dll", &hframedyndll, TRUE, SRC_POS);
- }
-
- if (IsOSAtLeast (WIN_VISTA))
- {
- LoadSystemDll (L"netapi32.dll", &hnetapi32dll, TRUE, SRC_POS);
- LoadSystemDll (L"authz.dll", &hauthzdll, TRUE, SRC_POS);
- LoadSystemDll (L"xmllite.dll", &hxmllitedll, TRUE, SRC_POS);
- }
- }
-
- if (IsOSAtLeast (WIN_VISTA))
- {
- LoadSystemDll (L"atl.dll", &hsppdll, TRUE, SRC_POS);
- LoadSystemDll (L"vsstrace.dll", &hvsstracedll, TRUE, SRC_POS);
- LoadSystemDll (L"vssapi.dll", &vssapidll, TRUE, SRC_POS);
- LoadSystemDll (L"spp.dll", &hsppdll, TRUE, SRC_POS);
+ // abort using a message that says that VeraCrypt can run only on Windows 7 and later and that it is officially supported only on Windows 10 and later
+ AbortProcessDirect(L"VeraCrypt requires at least Windows 7 to run.");
}
-#endif
- LoadSystemDll (L"crypt32.dll", &hcrypt32dll, TRUE, SRC_POS);
-
- if (IsOSAtLeast (WIN_7))
+ SetDefaultDllDirectoriesFn = (SetDefaultDllDirectoriesPtr) GetProcAddress (GetModuleHandle(L"kernel32.dll"), "SetDefaultDllDirectories");
+ if (!SetDefaultDllDirectoriesFn)
{
- LoadSystemDll (L"CryptSP.dll", &hCryptSpDll, TRUE, SRC_POS);
-
- LoadSystemDll (L"cfgmgr32.dll", &hcfgmgr32dll, TRUE, SRC_POS);
- LoadSystemDll (L"devobj.dll", &hdevobjdll, TRUE, SRC_POS);
- LoadSystemDll (L"powrprof.dll", &hpowrprofdll, TRUE, SRC_POS);
-
- LoadSystemDll (L"bcrypt.dll", &hbcryptdll, TRUE, SRC_POS);
- LoadSystemDll (L"bcryptprimitives.dll", &hbcryptprimitivesdll, TRUE, SRC_POS);
- }
+ // This can happen only if KB2533623 is missing from Windows 7
+ AbortProcessDirect(L"VeraCrypt requires KB2533623 to be installed on Windows 7 and Windows Server 2008 R2 in order to run.");
+ }
-#ifndef SETUP
- LoadSystemDll (L"WINSCARD.DLL", &hwinscarddll, TRUE, SRC_POS);
-#endif
+ VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin));
- LoadSystemDll (L"COMCTL32.DLL", &hComctl32Dll, FALSE, SRC_POS);
+ InitGlobalLocks ();
- // call InitCommonControls function
- InitCommonControlsFn = (InitCommonControlsPtr) GetProcAddress (hComctl32Dll, "InitCommonControls");
- ImageList_AddFn = (ImageList_AddPtr) GetProcAddress (hComctl32Dll, "ImageList_Add");
- ImageList_CreateFn = (ImageList_CreatePtr) GetProcAddress (hComctl32Dll, "ImageList_Create");
-
- if (InitCommonControlsFn && ImageList_AddFn && ImageList_CreateFn)
- {
- InitCommonControlsFn();
- }
- else
- AbortProcess ("INIT_DLL");
+ // call InitCommonControlsEx function to initialize the common controls
+ InitCtrls.dwSize = sizeof (InitCtrls);
+ InitCtrls.dwICC = ICC_WIN95_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_NATIVEFNTCTL_CLASS | ICC_STANDARD_CLASSES | ICC_LINK_CLASS;
+ InitCommonControlsEx (&InitCtrls);
- LoadSystemDll (L"Riched20.dll", &hRichEditDll, FALSE, SRC_POS);
- LoadSystemDll (L"Advapi32.dll", &hAdvapi32Dll, FALSE, SRC_POS);
+ // Load RichEdit library in order to be able to use RichEdit20W class
+ LoadLibraryEx (L"Riched20.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
#if !defined(SETUP)
+ GetModuleFileNameW (NULL, modPath, ARRAYSIZE (modPath));
if (!VerifyModuleSignature (modPath))
- AbortProcess ("DIST_PACKAGE_CORRUPTED");
+ AbortProcessDirect (L"This distribution package is damaged. Please try downloading it again (preferably from the official VeraCrypt website at https://www.veracrypt.fr).");
#endif
- // Get SetupAPI functions pointers
- SetupCloseInfFileFn = (SetupCloseInfFilePtr) GetProcAddress (hSetupDll, "SetupCloseInfFile");
- SetupDiOpenClassRegKeyFn = (SetupDiOpenClassRegKeyPtr) GetProcAddress (hSetupDll, "SetupDiOpenClassRegKey");
- SetupInstallFromInfSectionWFn = (SetupInstallFromInfSectionWPtr) GetProcAddress (hSetupDll, "SetupInstallFromInfSectionW");
- SetupOpenInfFileWFn = (SetupOpenInfFileWPtr) GetProcAddress (hSetupDll, "SetupOpenInfFileW");
-
- if (!SetupCloseInfFileFn || !SetupDiOpenClassRegKeyFn || !SetupInstallFromInfSectionWFn || !SetupOpenInfFileWFn)
- AbortProcess ("INIT_DLL");
-
- // Get SHDeleteKeyW,SHStrDupW, UrlUnescapeW functions pointers
- SHDeleteKeyWFn = (SHDeleteKeyWPtr) GetProcAddress (hShlwapiDll, "SHDeleteKeyW");
- SHStrDupWFn = (SHStrDupWPtr) GetProcAddress (hShlwapiDll, "SHStrDupW");
- UrlUnescapeWFn = (UrlUnescapeWPtr) GetProcAddress(hShlwapiDll, "UrlUnescapeW");
- if (!SHDeleteKeyWFn || !SHStrDupWFn || !UrlUnescapeWFn)
- AbortProcess ("INIT_DLL");
-
- if (IsOSAtLeast (WIN_VISTA))
- {
- /* Get ChangeWindowMessageFilter used to enable some messages bypasss UIPI (User Interface Privilege Isolation) */
- ChangeWindowMessageFilterFn = (ChangeWindowMessageFilterPtr) GetProcAddress (GetModuleHandle (L"user32.dll"), "ChangeWindowMessageFilter");
#ifndef SETUP
- /* enable drag-n-drop when we are running elevated */
- AllowMessageInUIPI (WM_DROPFILES);
- AllowMessageInUIPI (WM_COPYDATA);
- AllowMessageInUIPI (WM_COPYGLOBALDATA);
+ /* enable drag-n-drop when we are running elevated */
+ AllowMessageInUIPI (WM_DROPFILES);
+ AllowMessageInUIPI (WM_COPYDATA);
+ AllowMessageInUIPI (WM_COPYGLOBALDATA);
#endif
- }
-
- // Get CreateProcessWithTokenW function pointer
- CreateProcessWithTokenWPtr = (CreateProcessWithTokenWFn) GetProcAddress(hAdvapi32Dll, "CreateProcessWithTokenW");
/* Save the instance handle for later */
hInst = hInstance;
SetErrorMode (SetErrorMode (0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
- CoInitialize (NULL);
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
#ifndef SETUP
// Application ID
- typedef HRESULT (WINAPI *SetAppId_t) (PCWSTR appID);
- SetAppId_t setAppId = (SetAppId_t) GetProcAddress (GetModuleHandle (L"shell32.dll"), "SetCurrentProcessExplicitAppUserModelID");
-
- if (setAppId)
- setAppId (TC_APPLICATION_ID);
+ SetCurrentProcessExplicitAppUserModelID (TC_APPLICATION_ID);
#endif
// Language
@@ -3259,30 +3720,35 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
RemoteSession = GetSystemMetrics (SM_REMOTESESSION) != 0;
- // OS version check: from version 1.25, only Windows XP, Windows 10 and Windows 11 are supported because of new driver signing requirements
- if (!(IsOSVersionAtLeast(WIN_10, 0) || (nCurrentOS == WIN_XP) || (nCurrentOS == WIN_XP64)))
+#ifndef VC_SKIP_OS_DRIVER_REQ_CHECK
+ if (!IsSupportedOS())
{
MessageBoxW (NULL, GetString ("UNSUPPORTED_OS"), lpszTitle, MB_ICONSTOP);
exit (1);
}
- else
+#else
+ // in TESTSIGNING mode, we support only Windows 7 and Windows 8/8.1
+ if (
+#ifndef SETUP
+ IsOSVersionAtLeast(WIN_10, 0)
+#else
+ || (IsOSVersionAtLeast(WIN_10, 0) && !bMakePackage)
+#endif
+ )
{
- // Service pack check & warnings about critical MS issues
- switch (nCurrentOS)
- {
- case WIN_XP:
- if (CurrentOSServicePack < 1)
- {
- HKEY k;
- // PE environment does not report version of SP
- if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\minint", 0, KEY_READ, &k) != ERROR_SUCCESS)
- Warning ("LARGE_IDE_WARNING_XP", NULL);
- else
- RegCloseKey (k);
- }
- break;
- }
+ MessageBoxW (NULL, L"TESTSIGNING version of VeraCrypt targets only Windows Vista, Windows 7 and Windows 8/8.1.\n\nPlease use the standard version of VeraCrypt instead.", lpszTitle, MB_ICONSTOP);
+ exit (1);
}
+ else if ( !IsTestSigningModeEnabled()
+#ifdef SETUP
+ && !bMakePackage
+#endif
+ )
+ {
+ MessageBoxW (NULL, L"Test-Signing Mode, which is required to run VeraCrypt TESTSIGNING binaries, is not enabled in Windows.\n\nExecution aborted!", lpszTitle, MB_ICONSTOP);
+ exit (1);
+ }
+#endif
/* Get the attributes for the standard dialog class */
if ((GetClassInfoW (hInst, WINDOWS_DIALOG_CLASS, &wc)) == 0)
@@ -3329,106 +3795,21 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
#ifndef SETUP
#ifdef _WIN64
- if (IsOSAtLeast (WIN_7))
+ EnableRamEncryption ((ReadDriverConfigurationFlags() & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION) ? TRUE : FALSE);
+ if (IsRamEncryptionEnabled())
{
- EnableRamEncryption ((ReadDriverConfigurationFlags() & VC_DRIVER_CONFIG_ENABLE_RAM_ENCRYPTION) ? TRUE : FALSE);
- if (IsRamEncryptionEnabled())
- {
- if (!InitializeSecurityParameters(GetAppRandomSeed))
- AbortProcess("OUTOFMEMORY");
- }
+ if (!InitializeSecurityParameters(GetAppRandomSeed))
+ AbortProcess("OUTOFMEMORY");
}
#endif
if (!EncryptionThreadPoolStart (ReadEncryptionThreadPoolFreeCpuCountLimit()))
{
handleWin32Error (NULL, SRC_POS);
- FREE_DLL (hRichEditDll);
- FREE_DLL (hComctl32Dll);
- FREE_DLL (hSetupDll);
- FREE_DLL (hShlwapiDll);
- FREE_DLL (hProfApiDll);
- FREE_DLL (hUsp10Dll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hUXThemeDll);
- FREE_DLL (hUserenvDll);
- FREE_DLL (hRsaenhDll);
- FREE_DLL (himm32dll);
- FREE_DLL (hMSCTFdll);
- FREE_DLL (hfltlibdll);
- FREE_DLL (hframedyndll);
- FREE_DLL (hpsapidll);
- FREE_DLL (hsecur32dll);
- FREE_DLL (hnetapi32dll);
- FREE_DLL (hauthzdll);
- FREE_DLL (hxmllitedll);
- FREE_DLL (hmprdll);
- FREE_DLL (hsppdll);
- FREE_DLL (vssapidll);
- FREE_DLL (hvsstracedll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hcfgmgr32dll);
- FREE_DLL (hdevobjdll);
- FREE_DLL (hpowrprofdll);
- FREE_DLL (hsspiclidll);
- FREE_DLL (hcryptbasedll);
- FREE_DLL (hdwmapidll);
- FREE_DLL (hmsasn1dll);
- FREE_DLL (hcrypt32dll);
- FREE_DLL (hbcryptdll);
- FREE_DLL (hbcryptprimitivesdll);
- FREE_DLL (hMsls31);
- FREE_DLL (hntmartadll);
- FREE_DLL (hwinscarddll);
- FREE_DLL (hmsvcrtdll);
- FREE_DLL (hAdvapi32Dll);
exit (1);
}
#endif
}
-void FinalizeApp (void)
-{
- FREE_DLL (hRichEditDll);
- FREE_DLL (hComctl32Dll);
- FREE_DLL (hSetupDll);
- FREE_DLL (hShlwapiDll);
- FREE_DLL (hProfApiDll);
- FREE_DLL (hUsp10Dll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hUXThemeDll);
- FREE_DLL (hUserenvDll);
- FREE_DLL (hRsaenhDll);
- FREE_DLL (himm32dll);
- FREE_DLL (hMSCTFdll);
- FREE_DLL (hfltlibdll);
- FREE_DLL (hframedyndll);
- FREE_DLL (hpsapidll);
- FREE_DLL (hsecur32dll);
- FREE_DLL (hnetapi32dll);
- FREE_DLL (hauthzdll);
- FREE_DLL (hxmllitedll);
- FREE_DLL (hmprdll);
- FREE_DLL (hsppdll);
- FREE_DLL (vssapidll);
- FREE_DLL (hvsstracedll);
- FREE_DLL (hCryptSpDll);
- FREE_DLL (hcfgmgr32dll);
- FREE_DLL (hdevobjdll);
- FREE_DLL (hpowrprofdll);
- FREE_DLL (hsspiclidll);
- FREE_DLL (hcryptbasedll);
- FREE_DLL (hdwmapidll);
- FREE_DLL (hmsasn1dll);
- FREE_DLL (hcrypt32dll);
- FREE_DLL (hbcryptdll);
- FREE_DLL (hbcryptprimitivesdll);
- FREE_DLL (hMsls31);
- FREE_DLL (hntmartadll);
- FREE_DLL (hwinscarddll);
- FREE_DLL (hmsvcrtdll);
- FREE_DLL (hAdvapi32Dll);
-}
-
void InitHelpFileName (void)
{
wchar_t *lpszTmp;
@@ -3564,24 +3945,21 @@ BOOL GetSysDevicePaths (HWND hwndDlg)
StringCchCopyW (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))
{
- // Find extra boot partition
- foreach (const HostDevice &drive, GetAvailableHostDevices (false, false))
+ if (drive.ContainsSystem)
{
- if (drive.ContainsSystem)
+ foreach (const HostDevice &sysDrivePartition, drive.Partitions)
{
- foreach (const HostDevice &sysDrivePartition, drive.Partitions)
+ if (sysDrivePartition.Bootable)
{
- if (sysDrivePartition.Bootable)
- {
- if (sysDrivePartition.Size <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE)
- ExtraBootPartitionDevicePath = sysDrivePartition.Path;
- break;
- }
+ if (sysDrivePartition.Size <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE)
+ ExtraBootPartitionDevicePath = sysDrivePartition.Path;
+ break;
}
- break;
}
+ break;
}
}
@@ -4507,7 +4885,6 @@ static int DriverLoad ()
BOOL DriverUnload ()
{
- MOUNT_LIST_STRUCT driver;
int refCount;
int volumesMounted;
DWORD dwResult;
@@ -4532,13 +4909,6 @@ BOOL DriverUnload ()
// 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)
@@ -4705,9 +5075,6 @@ load:
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)
{
@@ -4719,10 +5086,16 @@ load:
if (IsNonInstallMode () && CreateDriverSetupMutex () && DriverUnload () && nLoadRetryCount++ < 3)
goto load;
- CloseDriverSetupMutex ();
- CloseHandle (hDriver);
- hDriver = INVALID_HANDLE_VALUE;
- return ERR_DRIVER_VERSION;
+#ifdef TCMOUNT
+ // don't fail in case of service. This solves issues during upgrade when system encryption is enabled
+ if (!ServiceMode)
+#endif
+ {
+ CloseDriverSetupMutex ();
+ CloseHandle (hDriver);
+ hDriver = INVALID_HANDLE_VALUE;
+ return ERR_DRIVER_VERSION;
+ }
}
#else
if (!bResult)
@@ -4749,144 +5122,139 @@ void ResetCurrentDirectory ()
}
-BOOL BrowseFiles (HWND hwndDlg, char *stringId, wchar_t *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter)
+BOOL BrowseFiles (HWND hwndDlg, char *stringId, wchar_t *lpszFileName, BOOL keepHistory, BOOL saveMode)
{
- return BrowseFilesInDir (hwndDlg, stringId, NULL, lpszFileName, keepHistory, saveMode, browseFilter);
+ return BrowseFilesInDir (hwndDlg, stringId, NULL, lpszFileName, keepHistory, saveMode, NULL);
}
-
-BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, wchar_t *initialDir, wchar_t *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter, const wchar_t *initialFileName, const wchar_t *defaultExtension)
+BOOL BrowseFilesInDir(HWND hwndDlg, char *stringId, wchar_t *initialDir, wchar_t *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 };
+ IFileDialog *pfd = NULL;
+ HRESULT hr;
wchar_t filter[1024];
BOOL status = FALSE;
- CoInitialize (NULL);
-
- ZeroMemory (&ofn, sizeof (ofn));
- *lpszFileName = 0;
-
- if (initialDir)
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (FAILED(hr))
{
- ofn.lpstrInitialDir = initialDir;
+ return FALSE;
}
- if (initialFileName)
- StringCchCopyW (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)
+ // Choose between the File Open or File Save dialog depending on the saveMode.
+ if (saveMode)
{
- if (!GetOpenFileNameW (&ofn))
- goto ret;
+ hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
}
else
{
- if (!GetSaveFileNameW (&ofn))
- goto ret;
+ hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
}
- SystemFileSelectorCallPending = FALSE;
+ if (SUCCEEDED(hr))
+ {
+ // Set the options for the dialog.
+ DWORD dwFlags;
+ hr = pfd->GetOptions(&dwFlags);
+ if (SUCCEEDED(hr))
+ {
+ dwFlags |= FOS_NOCHANGEDIR | FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST | FOS_FORCEFILESYSTEM | FOS_NOVALIDATE;
+ if (!keepHistory)
+ dwFlags |= FOS_DONTADDTORECENT;
+ if (saveMode)
+ dwFlags |= FOS_NOTESTFILECREATE | FOS_OVERWRITEPROMPT | FOS_DEFAULTNOMINIMODE;
+ hr = pfd->SetOptions(dwFlags);
+ }
- StringCchCopyW (lpszFileName, MAX_PATH, file);
+ // Set the initial directory, if provided.
+ if (initialDir)
+ {
+ IShellItem *psi;
+ hr = SHCreateItemFromParsingName(initialDir, NULL, IID_PPV_ARGS(&psi));
+ if (SUCCEEDED(hr))
+ {
+ pfd->SetFolder(psi);
+ psi->Release();
+ }
+ }
- if (!keepHistory)
- CleanLastVisitedMRU ();
+ // Set the initial file name, if provided.
+ if (initialFileName)
+ {
+ pfd->SetFileName(initialFileName);
+ }
- status = TRUE;
+ // Set the title.
+ pfd->SetTitle(GetString(stringId));
-ret:
- SystemFileSelectorCallPending = FALSE;
- ResetCurrentDirectory();
- CoUninitialize();
+ // Set the default extension.
+ if (defaultExtension)
+ {
+ pfd->SetDefaultExtension(defaultExtension);
+ }
- return status;
-}
+ // Prepare the filter
+ COMDLG_FILTERSPEC filterSpec[5];
+ UINT cfilterSpec = 0;
+ if (!browseFilter)
+ {
+ 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);
+ browseFilter = filter;
+ }
-static wchar_t SelectMultipleFilesPath[131072];
-static int SelectMultipleFilesOffset;
+ // Assume browseFilter is a formatted wide string like L"Text Files (*.txt)\0*.txt\0"
+ // loop over all the filters in the string and add them to filterSpec array
+ while (*browseFilter)
+ {
+ filterSpec[cfilterSpec].pszName = browseFilter;
+ browseFilter += wcslen(browseFilter) + 1;
+ filterSpec[cfilterSpec].pszSpec = browseFilter;
+ browseFilter += wcslen(browseFilter) + 1;
+ cfilterSpec++;
-BOOL SelectMultipleFiles (HWND hwndDlg, const char *stringId, wchar_t *lpszFileName, size_t cbFileName,BOOL keepHistory)
-{
- OPENFILENAMEW ofn;
- wchar_t filter[1024];
- BOOL status = FALSE;
+ if (cfilterSpec >= ARRAYSIZE(filterSpec))
+ break;
+ }
- CoInitialize (NULL);
-
- ZeroMemory (&ofn, sizeof (ofn));
-
- SelectMultipleFilesPath[0] = 0;
- *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 = SelectMultipleFilesPath;
- ofn.nMaxFile = 0xffff * 2; // The size must not exceed 0xffff*2 due to a bug in Windows 2000 and XP SP1
- ofn.lpstrTitle = GetString (stringId);
- ofn.Flags = OFN_HIDEREADONLY
- | OFN_EXPLORER
- | OFN_PATHMUSTEXIST
- | OFN_ALLOWMULTISELECT
- | (keepHistory ? 0 : OFN_DONTADDTORECENT);
-
- if (!keepHistory)
- CleanLastVisitedMRU ();
+ // Set the file types filter.
+ hr = pfd->SetFileTypes(cfilterSpec, filterSpec);
+ hr = pfd->SetFileTypeIndex(1);
- SystemFileSelectorCallerThreadId = GetCurrentThreadId();
- SystemFileSelectorCallPending = TRUE;
+ if (!keepHistory)
+ CleanLastVisitedMRU();
- if (!GetOpenFileNameW (&ofn))
- goto ret;
+ SystemFileSelectorCallerThreadId = GetCurrentThreadId();
+ SystemFileSelectorCallPending = TRUE;
- SystemFileSelectorCallPending = FALSE;
+ // Show the dialog.
+ hr = pfd->Show(hwndDlg);
- if (SelectMultipleFilesPath[ofn.nFileOffset - 1] != 0)
- {
- // Single file selected
- StringCbCopyW (lpszFileName, cbFileName, SelectMultipleFilesPath);
- SelectMultipleFilesOffset = 0;
- SecureZeroMemory (SelectMultipleFilesPath, sizeof (SelectMultipleFilesPath));
- }
- else
- {
- // Multiple files selected
- SelectMultipleFilesOffset = ofn.nFileOffset;
- SelectMultipleFilesNext (lpszFileName, cbFileName);
- }
+ // Obtain the result if the user clicked the "OK" button.
+ if (SUCCEEDED(hr))
+ {
+ IShellItem *pItem;
+ hr = pfd->GetResult(&pItem);
+ if (SUCCEEDED(hr))
+ {
+ PWSTR pszFilePath;
+ hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
+ if (SUCCEEDED(hr))
+ {
+ StringCchCopyW(lpszFileName, MAX_PATH, pszFilePath);
+ CoTaskMemFree(pszFilePath);
+ status = TRUE;
+ }
+ pItem->Release();
+ }
+ }
- if (!keepHistory)
- CleanLastVisitedMRU ();
+ pfd->Release();
+
+ if (!keepHistory)
+ CleanLastVisitedMRU();
+ }
- status = TRUE;
-
-ret:
SystemFileSelectorCallPending = FALSE;
ResetCurrentDirectory();
CoUninitialize();
@@ -4894,101 +5262,173 @@ ret:
return status;
}
-
-BOOL SelectMultipleFilesNext (wchar_t *lpszFileName, size_t cbFileName)
+BOOL SelectMultipleFiles(HWND hwndDlg, const char *stringId, BOOL keepHistory, std::vector<std::wstring> &filesList)
{
- if (SelectMultipleFilesOffset == 0)
+ IFileOpenDialog *pfd = NULL;
+ HRESULT hr;
+ BOOL status = FALSE;
+
+ filesList.clear();
+
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (FAILED(hr))
+ {
return FALSE;
+ }
- StringCbCopyW (lpszFileName, cbFileName,SelectMultipleFilesPath);
- lpszFileName[TC_MAX_PATH - 1] = 0;
+ // Create the File Open Dialog object.
+ hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
+ if (SUCCEEDED(hr))
+ {
+ DWORD dwFlags;
+ hr = pfd->GetOptions(&dwFlags);
+ if (SUCCEEDED(hr))
+ {
+ dwFlags |= FOS_ALLOWMULTISELECT | FOS_NOCHANGEDIR | FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST | FOS_FORCEFILESYSTEM | FOS_NOVALIDATE;
+ if (!keepHistory)
+ dwFlags |= FOS_DONTADDTORECENT;
- if (lpszFileName[wcslen (lpszFileName) - 1] != L'\\')
- StringCbCatW (lpszFileName, cbFileName,L"\\");
+ hr = pfd->SetOptions(dwFlags);
+ }
- StringCbCatW (lpszFileName, cbFileName,SelectMultipleFilesPath + SelectMultipleFilesOffset);
+ // Set the title and filter
+ pfd->SetTitle(GetString(stringId));
- SelectMultipleFilesOffset += (int) wcslen (SelectMultipleFilesPath + SelectMultipleFilesOffset) + 1;
- if (SelectMultipleFilesPath[SelectMultipleFilesOffset] == 0)
- {
- SelectMultipleFilesOffset = 0;
- SecureZeroMemory (SelectMultipleFilesPath, sizeof (SelectMultipleFilesPath));
- }
+ wchar_t allFilesfilter[512];
+ wchar_t volumesfilter[512];
- return TRUE;
-}
+ StringCbPrintfW(allFilesfilter, sizeof(allFilesfilter), L"%ls (*.*)", GetString("ALL_FILES"));
+ StringCbPrintfW(volumesfilter, sizeof(volumesfilter), L"%ls (*.hc)", GetString("TC_VOLUMES"));
+ COMDLG_FILTERSPEC rgSpec[] =
+ {
+ {allFilesfilter, L"*.*"},
+ {volumesfilter, L"*.hc"}};
+ hr = pfd->SetFileTypes(ARRAYSIZE(rgSpec), rgSpec);
-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. */
- SendMessageW (hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)pData);
- break;
- }
+ if (!keepHistory)
+ CleanLastVisitedMRU();
- case BFFM_SELCHANGED:
- {
- wchar_t szDir[TC_MAX_PATH];
+ // Show the dialog
+ hr = pfd->Show(hwndDlg);
+ if (SUCCEEDED(hr))
+ {
+ IShellItemArray *psiaResults;
+ hr = pfd->GetResults(&psiaResults);
+ if (SUCCEEDED(hr))
+ {
+ DWORD count;
+ hr = psiaResults->GetCount(&count);
+ if (SUCCEEDED(hr))
+ {
+ for (DWORD i = 0; i < count; ++i)
+ {
+ IShellItem *psi;
+ hr = psiaResults->GetItemAt(i, &psi);
+ if (SUCCEEDED(hr))
+ {
+ PWSTR pszFilePath;
+ hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
+ if (SUCCEEDED(hr))
+ {
+ filesList.push_back(pszFilePath);
+ CoTaskMemFree(pszFilePath);
+ }
+ psi->Release();
+ }
+ }
- /* Set the status window to the currently selected path. */
- if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szDir))
- {
- SendMessage (hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
- }
- break;
- }
+ status = TRUE;
+ }
+ psiaResults->Release();
+ }
+ }
- default:
- break;
+ if (!keepHistory)
+ CleanLastVisitedMRU();
+
+ pfd->Release();
}
- return 0;
+ CoUninitialize();
+ return status;
}
-
-BOOL BrowseDirectories (HWND hwndDlg, char *lpszTitle, wchar_t *dirName)
+BOOL BrowseDirectories(HWND hwndDlg, char *lpszTitle, wchar_t *dirName, const wchar_t *initialDir)
{
- BROWSEINFOW bi;
- LPITEMIDLIST pidl;
- LPMALLOC pMalloc;
- BOOL bOK = FALSE;
+ IFileDialog *pfd = NULL;
+ HRESULT hr;
+ BOOL bOK = FALSE;
- CoInitialize (NULL);
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (FAILED(hr))
+ {
+ return FALSE;
+ }
- if (SUCCEEDED (SHGetMalloc (&pMalloc)))
+ hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
+ if (SUCCEEDED(hr))
{
- 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;
+ // Set the options on the dialog.
+ DWORD dwFlags;
+ hr = pfd->GetOptions(&dwFlags);
+ if (SUCCEEDED(hr))
+ {
+ dwFlags |= FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | FOS_NOCHANGEDIR; // Important to enable folder-picking mode
+ hr = pfd->SetOptions(dwFlags);
+ }
+
+ // Set the title.
+ if (lpszTitle)
+ {
+ pfd->SetTitle(GetString(lpszTitle));
+ }
+
+ IShellItem *psi;
+ if (initialDir)
+ {
+ // Set the initial directory, if provided.
+ hr = SHCreateItemFromParsingName(initialDir, NULL, IID_PPV_ARGS(&psi));
+ }
+ else
+ {
+ // set folder to "This PC" shel item
+ hr = SHCreateItemInKnownFolder(FOLDERID_ComputerFolder, 0, NULL, IID_PPV_ARGS(&psi));
+ }
+ if (SUCCEEDED(hr))
+ {
+ pfd->SetFolder(psi);
+ psi->Release();
+ }
- pidl = SHBrowseForFolderW (&bi);
- if (pidl != NULL)
+ // Show the dialog.
+ hr = pfd->Show(hwndDlg);
+ if (SUCCEEDED(hr))
{
- if (SHGetPathFromIDList(pidl, dirName))
+ // Obtain the result when the user clicks the "OK" button.
+ // The result is an IShellItem object.
+ IShellItem *pItem;
+ hr = pfd->GetResult(&pItem);
+ if (SUCCEEDED(hr))
{
- bOK = TRUE;
+ PWSTR pszFolderPath;
+ hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFolderPath);
+ if (SUCCEEDED(hr))
+ {
+ StringCchCopyW(dirName, MAX_PATH, pszFolderPath);
+ CoTaskMemFree(pszFolderPath);
+ bOK = TRUE;
+ }
+ pItem->Release();
}
-
- pMalloc->Free (pidl);
- pMalloc->Release();
}
+ pfd->Release();
}
CoUninitialize();
-
return bOK;
}
-
std::wstring GetWrongPasswordErrorMessage (HWND hwndDlg)
{
WCHAR szTmp[8192];
@@ -5125,11 +5565,6 @@ void handleError (HWND hwndDlg, int code, const char* srcPos)
// A non-error
break;
- case ERR_UNSUPPORTED_TRUECRYPT_FORMAT:
- StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("UNSUPPORTED_TRUECRYPT_FORMAT"), (code >> 24), (code >> 16) & 0x000000FF);
- MessageBoxW (hwndDlg, AppendSrcPos (szTmp, srcPos).c_str(), lpszTitle, ICON_HAND);
- break;
-
#ifndef SETUP
case ERR_RAND_INIT_FAILED:
StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("INIT_RAND"), SRC_POS, GetLastError ());
@@ -5708,11 +6143,13 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
*/
{
BYTE digest [MAX_DIGESTSIZE];
- WHIRLPOOL_CTX wctx;
- RMD160_CTX rctx;
+ #ifndef WOLFCRYPT_BACKEND
+ WHIRLPOOL_CTX wctx;
+ STREEBOG_CTX stctx;
+ blake2s_state bctx;
+ #endif
sha512_ctx s2ctx;
sha256_ctx s256ctx;
- STREEBOG_CTX stctx;
int hid, i;
@@ -5737,11 +6174,11 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
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);
+ #ifndef WOLFCRYPT_BACKEND
+ case BLAKE2S:
+ blake2s_init(&bctx);
+ blake2s_update(&bctx, lpTestBuffer, benchmarkBufferSize);
+ blake2s_final(&bctx, (unsigned char *) digest);
break;
case WHIRLPOOL:
@@ -5757,7 +6194,8 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
break;
}
- }
+ #endif
+ }
if (QueryPerformanceCounter (&performanceCountEnd) == 0)
goto counter_error;
@@ -5798,37 +6236,38 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg)
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, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
+ derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), 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, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
+ derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), 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, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
+ #ifndef WOLFCRYPT_BACKEND
+ case BLAKE2S:
+ /* PKCS-5 test with HMAC-BLAKE2s used as the PRF */
+ derive_key_blake2s ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), 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, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
+ derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
break;
case STREEBOG:
/* PKCS-5 test with HMAC-STREEBOG used as the PRF */
- derive_key_streebog("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, FALSE, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
+ derive_key_streebog("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE);
break;
}
- }
+ #endif
+ }
if (QueryPerformanceCounter (&performanceCountEnd) == 0)
goto counter_error;
benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart;
benchmarkTable[benchmarkTotalItems].id = thid;
- benchmarkTable[benchmarkTotalItems].decSpeed = get_pkcs5_iteration_count(thid, benchmarkPim, FALSE, benchmarkPreBoot);
+ benchmarkTable[benchmarkTotalItems].decSpeed = get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot);
benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (unsigned __int64) (1000 * ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart / 2));
if (benchmarkPreBoot)
{
@@ -6460,6 +6899,7 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
case WM_INITDIALOG:
{
HWND hComboBox = GetDlgItem (hwndDlg, IDC_PRF_ID);
+ HWND hSizeUnit = GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE_UNIT);
HCRYPTPROV hRngProv = NULL;
VirtualLock (randPool, sizeof(randPool));
@@ -6489,6 +6929,16 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
}
SelectAlgo (hComboBox, &hash_algo);
+ // populate keyfiles size unit combo
+ SendMessage (hSizeUnit, CB_RESETCONTENT, 0, 0);
+ AddComboPair (hSizeUnit, GetString ("BYTES"), 0);
+ AddComboPair (hSizeUnit, GetString ("KB"), 1);
+ AddComboPair (hSizeUnit, GetString ("MB"), 2);
+ AddComboPair (hSizeUnit, GetString ("GB"), 3);
+
+ // set default keyfiles size unit
+ SendMessage (hSizeUnit, CB_SETCURSEL, 0, 0);
+
SetCheckBox (hwndDlg, IDC_DISPLAY_POOL_CONTENTS, bDisplayPoolContents);
hEntropyBar = GetDlgItem (hwndDlg, IDC_ENTROPY_BAR);
SendMessage (hEntropyBar, PBM_SETRANGE32, 0, maxEntropyLevel);
@@ -6512,6 +6962,8 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
SetWindowText(GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), L"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);
+
+ ToHyperlink (hwndDlg, IDC_LINK_KEYFILES_EXTENSIONS_WARNING);
return 1;
}
@@ -6596,6 +7048,13 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
if (lw == IDC_KEYFILES_RANDOM_SIZE)
{
EnableWindow(GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), !GetCheckBox (hwndDlg, IDC_KEYFILES_RANDOM_SIZE));
+ EnableWindow(GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE_UNIT), !GetCheckBox (hwndDlg, IDC_KEYFILES_RANDOM_SIZE));
+ }
+
+ if (lw == IDC_LINK_KEYFILES_EXTENSIONS_WARNING)
+ {
+ Applink ("keyfilesextensions");
+ return 1;
}
if (lw == IDC_GENERATE_AND_SAVE_KEYFILE)
@@ -6606,7 +7065,10 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
wchar_t szFileName [2*TC_MAX_PATH + 16];
unsigned char *keyfile = NULL;
int fhKeyfile = -1, status;
- long keyfilesCount = 0, keyfilesSize = 0, i;
+ long keyfilesCount = 0, i;
+ unsigned long long keyfilesSize = 0, remainingBytes = 0;
+ int selectedUnitIndex, selectedUnitFactor, loopIndex, rndBytesLength;
+ DWORD dwLastError = 0;
wchar_t* fileExtensionPtr = 0;
wchar_t szSuffix[32];
BOOL bRandomSize = GetCheckBox (hwndDlg, IDC_KEYFILES_RANDOM_SIZE);
@@ -6628,7 +7090,16 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
szNumber[0] = 0;
keyfilesSize = wcstoul(szNumber, NULL, 0);
- if (keyfilesSize < 64 || keyfilesSize > 1024*1024)
+ // multiply by the unit factor
+ selectedUnitIndex = ComboBox_GetCurSel (GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE_UNIT));
+ if (selectedUnitIndex != CB_ERR)
+ {
+ selectedUnitFactor = (CK_SLOT_ID) ComboBox_GetItemData (GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE_UNIT), selectedUnitIndex);
+ for (loopIndex = 0; loopIndex < selectedUnitFactor; loopIndex++)
+ keyfilesSize *= 1024ULL;
+ }
+
+ if (keyfilesSize < 64)
{
Warning("KEYFILE_INCORRECT_SIZE", hwndDlg);
SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) GetDlgItem (hwndDlg, IDC_KEYFILES_SIZE), TRUE);
@@ -6657,7 +7128,7 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
fileExtensionPtr = wcsrchr(szFileBaseName, L'.');
/* Select directory */
- if (!BrowseDirectories (hwndDlg, "SELECT_KEYFILE_GENERATION_DIRECTORY", szDirName))
+ if (!BrowseDirectories (hwndDlg, "SELECT_KEYFILE_GENERATION_DIRECTORY", szDirName, NULL))
return 1;
if (szDirName[wcslen(szDirName) - 1] != L'\\' && szDirName[wcslen(szDirName) - 1] != L'/')
@@ -6665,7 +7136,7 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
WaitCursor();
- keyfile = (unsigned char*) TCalloc( bRandomSize? KEYFILE_MAX_READ_LEN : keyfilesSize );
+ keyfile = (unsigned char*) TCalloc(KEYFILE_MAX_READ_LEN);
for (i= 0; i < keyfilesCount; i++)
{
@@ -6728,32 +7199,46 @@ BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP
return 1;
}
- /* since keyfilesSize < 1024 * 1024, we mask with 0x000FFFFF */
- keyfilesSize = (long) (((unsigned long) keyfilesSize) & 0x000FFFFF);
+ /* since random keyfilesSize < 1024 * 1024, we mask with 0x000FFFFF */
+ keyfilesSize = (unsigned long long) (((unsigned long) keyfilesSize) & 0x000FFFFF);
keyfilesSize %= ((KEYFILE_MAX_READ_LEN - 64) + 1);
keyfilesSize += 64;
+
}
- /* Generate the keyfile */
- if (!RandgetBytesFull (hwndDlg, keyfile, keyfilesSize, TRUE, TRUE))
- {
- _close (fhKeyfile);
- DeleteFile (szFileName);
- TCfree(keyfile);
- NormalCursor();
- return 1;
- }
+ remainingBytes = keyfilesSize;
+
+ do {
+ rndBytesLength = (int) min (remainingBytes, (unsigned long long) KEYFILE_MAX_READ_LEN);
+
+ /* Generate the keyfile */
+ if (!RandgetBytesFull (hwndDlg, keyfile, rndBytesLength, TRUE, TRUE))
+ {
+ _close (fhKeyfile);
+ DeleteFile (szFileName);
+ TCfree(keyfile);
+ NormalCursor();
+ return 1;
+ }
- /* Write the keyfile */
- status = _write (fhKeyfile, keyfile, keyfilesSize);
- burn (keyfile, keyfilesSize);
+ /* Write the keyfile */
+ status = _write (fhKeyfile, keyfile, rndBytesLength);
+ } while (status != -1 && (remainingBytes -= (unsigned long long) rndBytesLength) > 0);
+
+ /* save last error code */
+ if (status == -1)
+ dwLastError = GetLastError();
+
+ burn (keyfile, KEYFILE_MAX_READ_LEN);
_close (fhKeyfile);
if (status == -1)
{
TCfree(keyfile);
NormalCursor();
+ /* restore last error code */
+ SetLastError(dwLastError);
handleWin32Error (hwndDlg, SRC_POS);
return 1;
}
@@ -7192,9 +7677,6 @@ ResetCipherTest(HWND hwndDlg, int idTestCipher)
SetWindowText(GetDlgItem(hwndDlg, IDC_CIPHERTEXT), L"0000000000000000");
if (idTestCipher == AES || idTestCipher == SERPENT || idTestCipher == TWOFISH || idTestCipher == CAMELLIA
-#if defined(CIPHER_GOST89)
- || idTestCipher == GOST89
-#endif
|| idTestCipher == KUZNYECHIK
)
{
@@ -7491,15 +7973,6 @@ BOOL CheckFileExtension (wchar_t *fileName)
return FALSE;
}
-BOOL IsTrueCryptFileExtension (wchar_t *fileName)
-{
- wchar_t *ext = wcsrchr (fileName, L'.');
- if (ext && !_wcsicmp (ext, L".tc"))
- return TRUE;
- else
- return FALSE;
-}
-
void CorrectFileName (wchar_t* fileName)
{
/* replace '/' by '\' */
@@ -7728,7 +8201,7 @@ void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap)
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.
+ else if (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)
@@ -8143,7 +8616,6 @@ int MountVolume (HWND hwndDlg,
Password *password,
int pkcs5,
int pim,
- BOOL truecryptMode,
BOOL cachePassword,
BOOL cachePim,
BOOL sharedAccess,
@@ -8183,7 +8655,7 @@ int MountVolume (HWND hwndDlg,
}
// If using cached passwords, check cache status first
- if (password == NULL && IsPasswordCacheEmpty ())
+ if (password == NULL && (mountOptions->SkipCachedPasswords || IsPasswordCacheEmpty ()))
return 0;
ZeroMemory (&mount, sizeof (mount));
@@ -8224,7 +8696,6 @@ retry:
else
mount.bMountManager = TRUE;
mount.pkcs5_prf = pkcs5;
- mount.bTrueCryptMode = truecryptMode;
mount.VolumePim = pim;
wstring path = volumePath;
@@ -8291,47 +8762,44 @@ retry:
mount.BytesPerPhysicalSector = bps;
}
- if (IsOSAtLeast (WIN_VISTA))
+ if ( (wcslen(root) >= 2)
+ && (root[1] == L':')
+ && (towupper(root[0]) >= L'A' && towupper(root[0]) <= L'Z')
+ )
{
- if ( (wcslen(root) >= 2)
- && (root[1] == L':')
- && (towupper(root[0]) >= L'A' && towupper(root[0]) <= L'Z')
- )
- {
- wstring drivePath = L"\\\\.\\X:";
- HANDLE dev = INVALID_HANDLE_VALUE;
- VOLUME_DISK_EXTENTS extents = {0};
- DWORD dwResult = 0;
- drivePath[4] = root[0];
+ wstring drivePath = L"\\\\.\\X:";
+ HANDLE dev = INVALID_HANDLE_VALUE;
+ VOLUME_DISK_EXTENTS extents = {0};
+ DWORD dwResult = 0;
+ drivePath[4] = root[0];
- if ((dev = CreateFile (drivePath.c_str(),0, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
+ if ((dev = CreateFile (drivePath.c_str(),0, 0, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)
+ {
+ if (DeviceIoControl (dev, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &extents, sizeof(extents), &dwResult, NULL))
{
- if (DeviceIoControl (dev, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &extents, sizeof(extents), &dwResult, NULL))
+ if (extents.NumberOfDiskExtents > 0)
{
- if (extents.NumberOfDiskExtents > 0)
+ STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR accessDesc;
+ STORAGE_ADAPTER_DESCRIPTOR adapterDesc;
+
+ if (GetPhysicalDriveStorageInformation (extents.Extents[0].DiskNumber, &accessDesc, &adapterDesc))
{
- STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR accessDesc;
- STORAGE_ADAPTER_DESCRIPTOR adapterDesc;
+ if (accessDesc.Size >= sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR))
+ {
+ mount.BytesPerSector = accessDesc.BytesPerLogicalSector;
+ mount.BytesPerPhysicalSector = accessDesc.BytesPerPhysicalSector;
+ }
- if (GetPhysicalDriveStorageInformation (extents.Extents[0].DiskNumber, &accessDesc, &adapterDesc))
+ if (adapterDesc.Size >= sizeof (STORAGE_ADAPTER_DESCRIPTOR))
{
- if (accessDesc.Size >= sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR))
- {
- mount.BytesPerSector = accessDesc.BytesPerLogicalSector;
- mount.BytesPerPhysicalSector = accessDesc.BytesPerPhysicalSector;
- }
-
- if (adapterDesc.Size >= sizeof (STORAGE_ADAPTER_DESCRIPTOR))
- {
- mount.MaximumTransferLength = adapterDesc.MaximumTransferLength;
- mount.MaximumPhysicalPages = adapterDesc.MaximumPhysicalPages;
- mount.AlignmentMask = adapterDesc.AlignmentMask;
- }
+ mount.MaximumTransferLength = adapterDesc.MaximumTransferLength;
+ mount.MaximumPhysicalPages = adapterDesc.MaximumPhysicalPages;
+ mount.AlignmentMask = adapterDesc.AlignmentMask;
}
}
}
- CloseHandle (dev);
}
+ CloseHandle (dev);
}
}
@@ -8345,8 +8813,7 @@ retry:
{
if (mount.wszVolume == NULL || swscanf_s ((const wchar_t *) mount.wszVolume,
WIDE("\\Device\\Harddisk%d\\Partition"),
- &mount.nPartitionInInactiveSysEncScopeDriveNo,
- sizeof(mount.nPartitionInInactiveSysEncScopeDriveNo)) != 1)
+ &mount.nPartitionInInactiveSysEncScopeDriveNo) != 1)
{
if (!quiet)
Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg);
@@ -8380,7 +8847,6 @@ retry:
burn (&mount.VolumePassword, sizeof (mount.VolumePassword));
burn (&mount.ProtectedHidVolPassword, sizeof (mount.ProtectedHidVolPassword));
burn (&mount.pkcs5_prf, sizeof (mount.pkcs5_prf));
- burn (&mount.bTrueCryptMode, sizeof (mount.bTrueCryptMode));
burn (&mount.ProtectedHidVolPkcs5Prf, sizeof (mount.ProtectedHidVolPkcs5Prf));
SetLastError (dwLastError);
@@ -8539,6 +9005,17 @@ retry:
}
}
+ if (mount.VolumeMountedReadOnlyAfterPartialSysEnc
+ && !Silent
+ && bDevice)
+ {
+ wchar_t msg[1024];
+ wchar_t mountPoint[] = { L'A' + (wchar_t) driveNo, L':', 0 };
+ StringCbPrintfW (msg, sizeof(msg), GetString ("PARTIAL_SYSENC_MOUNT_READONLY"), mountPoint);
+
+ WarningDirect (msg, hwndDlg);
+ }
+
if (mount.wszLabel[0] && !mount.bDriverSetLabel)
{
// try setting the drive label on user-mode using registry
@@ -8625,12 +9102,9 @@ retry:
goto retry;
}
- if (IsOSAtLeast (WIN_7))
- {
- // Undo SHCNE_DRIVEREMOVED
- wchar_t root[] = { (wchar_t) nDosDriveNo + L'A', L':', L'\\', 0 };
- SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL);
- }
+ // Undo SHCNE_DRIVEREMOVED
+ wchar_t root[] = { (wchar_t) nDosDriveNo + L'A', L':', L'\\', 0 };
+ SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL);
return FALSE;
}
@@ -8830,9 +9304,6 @@ BOOL IsUacSupported ()
HKEY hkey;
DWORD value = 1, size = sizeof (DWORD);
- if (!IsOSAtLeast (WIN_VISTA))
- return FALSE;
-
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
{
if (RegQueryValueEx (hkey, L"EnableLUA", 0, 0, (LPBYTE) &value, &size) != ERROR_SUCCESS)
@@ -9145,198 +9616,6 @@ HANDLE DismountDrive (wchar_t *devName, wchar_t *devicePath)
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, int64 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, (size_t) strLen) == 0)
- return i;
- }
-
- return -1;
-}
-
-// Returns TRUE if the file or directory exists (both may be enclosed in quotation marks).
-BOOL FileExists (const wchar_t *filePathPtr)
-{
- wchar_t filePath [TC_MAX_PATH * 2 + 1];
-
- // Strip quotation marks (if any)
- if (filePathPtr [0] == L'"')
- {
- StringCbCopyW (filePath, sizeof(filePath), filePathPtr + 1);
- }
- else
- {
- StringCbCopyW (filePath, sizeof(filePath), filePathPtr);
- }
-
- // Strip quotation marks (if any)
- if (filePath [wcslen (filePath) - 1] == L'"')
- filePath [wcslen (filePath) - 1] = 0;
-
- return (_waccess (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 wchar_t *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 TCCopyFileBase (HANDLE src, HANDLE dst)
-{
- __int8 *buffer;
- FILETIME fileTime;
- DWORD bytesRead, bytesWritten;
- BOOL res;
-
- 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;
- }
- }
-
- if (GetFileTime (src, NULL, NULL, &fileTime))
- SetFileTime (dst, NULL, NULL, &fileTime);
-
- CloseHandle (src);
- CloseHandle (dst);
-
- free (buffer);
- return res != 0;
-}
-
-BOOL TCCopyFile (wchar_t *sourceFileName, wchar_t *destinationFile)
-{
- HANDLE src, dst;
-
- src = CreateFileW (sourceFileName,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
-
- if (src == INVALID_HANDLE_VALUE)
- return FALSE;
-
- dst = CreateFileW (destinationFile,
- GENERIC_WRITE,
- 0, NULL, CREATE_ALWAYS, 0, NULL);
-
- if (dst == INVALID_HANDLE_VALUE)
- {
- CloseHandle (src);
- return FALSE;
- }
-
- return TCCopyFileBase (src, dst);
-}
-
BOOL DecompressZipToDir (const unsigned char *inputBuffer, DWORD inputLength, const wchar_t *destinationDir, ProgressFn progressFnPtr, HWND hwndDlg)
{
BOOL res = TRUE;
@@ -9394,79 +9673,6 @@ BOOL DecompressZipToDir (const unsigned char *inputBuffer, DWORD inputLength, co
return res;
}
-// 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 wchar_t *destinationFile, DWORD inputLength, BOOL bAppend, BOOL bRenameIfFailed)
-{
- HANDLE dst;
- DWORD bytesWritten;
- BOOL res = TRUE;
- DWORD dwLastError = 0;
-
- dst = CreateFile (destinationFile,
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
-
- dwLastError = GetLastError();
- if (!bAppend && bRenameIfFailed && (dst == INVALID_HANDLE_VALUE) && (GetLastError () == ERROR_SHARING_VIOLATION))
- {
- wchar_t renamedPath[TC_MAX_PATH + 1];
- StringCbCopyW (renamedPath, sizeof(renamedPath), destinationFile);
- StringCbCatW (renamedPath, sizeof(renamedPath), VC_FILENAME_RENAMED_SUFFIX);
-
- /* rename the locked file in order to be able to create a new one */
- if (MoveFileEx (destinationFile, renamedPath, MOVEFILE_REPLACE_EXISTING))
- {
- dst = CreateFile (destinationFile,
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
- dwLastError = GetLastError();
- if (dst == INVALID_HANDLE_VALUE)
- {
- /* restore the original file name */
- MoveFileEx (renamedPath, destinationFile, MOVEFILE_REPLACE_EXISTING);
- }
- else
- {
- /* delete the renamed file when the machine reboots */
- MoveFileEx (renamedPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
- }
- }
- }
-
- if (dst == INVALID_HANDLE_VALUE)
- {
- SetLastError (dwLastError);
- handleWin32Error (MainDlg, SRC_POS);
- 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, SRC_POS);
- }
-
- CloseHandle (dst);
-
- if (!res && !bAppend)
- _wremove (destinationFile);
-
- return res;
-}
-
-
// Proper flush for Windows systems. Returns TRUE if successful.
BOOL TCFlushFile (FILE *f)
{
@@ -9764,12 +9970,12 @@ void CleanLastVisitedMRU (void)
GetModuleFileNameW (NULL, exeFilename, sizeof (exeFilename) / sizeof(exeFilename[0]));
strToMatch = wcsrchr (exeFilename, L'\\') + 1;
- StringCbPrintfW (regPath, sizeof(regPath), L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisited%sMRU", IsOSAtLeast (WIN_VISTA) ? L"Pidl" : L"");
+ StringCbCopyW (regPath, sizeof(regPath), L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU");
- for (id = (IsOSAtLeast (WIN_VISTA) ? 0 : L'a'); id <= (IsOSAtLeast (WIN_VISTA) ? 1000 : L'z'); id++)
+ for (id = 0; id <= 1000; id++)
{
*strTmp = 0;
- StringCbPrintfW (key, sizeof(key), (IsOSAtLeast (WIN_VISTA) ? L"%d" : L"%c"), id);
+ StringCbPrintfW (key, sizeof(key), L"%d", id);
if ((len = ReadRegistryBytes (regPath, key, (char *) strTmp, sizeof (strTmp))) > 0)
{
@@ -9785,48 +9991,26 @@ void CleanLastVisitedMRU (void)
DeleteRegistryValue (regPath, key);
// Remove ID from MRUList
- if (IsOSAtLeast (WIN_VISTA))
- {
- int *p = (int *)buf;
- int *pout = (int *)bufout;
- int l;
-
- l = len = ReadRegistryBytes (L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", L"MRUListEx", buf, sizeof (buf));
- while (l > 0)
- {
- l -= sizeof (int);
-
- if (*p == id)
- {
- p++;
- len -= sizeof (int);
- continue;
- }
- *pout++ = *p++;
- }
+ int *p = (int *)buf;
+ int *pout = (int *)bufout;
+ int l;
- WriteRegistryBytes (L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", L"MRUListEx", bufout, len);
- }
- else
+ l = len = ReadRegistryBytes (L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", L"MRUListEx", buf, sizeof (buf));
+ while (l > 0)
{
- wchar_t *p = (wchar_t*) buf;
- wchar_t *pout = (wchar_t*) bufout;
+ l -= sizeof (int);
- ReadRegistryString (L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", L"MRUList", L"", (wchar_t*) buf, sizeof (buf));
- while (*p)
+ if (*p == id)
{
- if (*p == id)
- {
- p++;
- continue;
- }
- *pout++ = *p++;
+ p++;
+ len -= sizeof (int);
+ continue;
}
- *pout++ = 0;
-
- WriteRegistryString (L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU", L"MRUList", (wchar_t*) bufout);
+ *pout++ = *p++;
}
+ WriteRegistryBytes (L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRU", L"MRUListEx", bufout, len);
+
break;
}
}
@@ -9909,191 +10093,6 @@ int GetDriverRefCount ()
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 (const wchar_t *filePath, unsigned __int32 *result, __int64 fileOffset)
-{
- DWORD 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 (const wchar_t *filePath, int *result, __int64 fileOffset)
-{
- DWORD 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 wchar_t *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 (const wchar_t *fileName, __int64 fileOffset, DWORD count)
-{
- char *buf;
- DWORD bytesRead = 0;
- LARGE_INTEGER seekOffset, seekOffsetNew;
- BOOL bStatus;
-
- 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;
- }
-
- bStatus = ReadFile (h, buf, count, &bytesRead, NULL);
-
- CloseHandle (h);
-
- if (!bStatus || (bytesRead != count))
- {
- free (buf);
- return NULL;
- }
-
- return buf;
-}
-
-
-// Returns -1 if there is an error, or the size of the file.
-__int64 GetFileSize64 (const wchar_t *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;
-}
-
wchar_t *GetModPath (wchar_t *path, int maxSize)
{
@@ -10192,7 +10191,7 @@ void TaskBarIconDisplayBalloonTooltip (HWND hwnd, wchar_t *headline, wchar_t *te
tnid.uFlags = NIF_INFO;
tnid.dwInfoFlags = (warning ? NIIF_WARNING : NIIF_INFO);
- tnid.uTimeout = (IsOSAtLeast (WIN_VISTA) ? 1000 : 5000); // in ms
+ tnid.uTimeout = 1000; // in ms
StringCbCopyW (tnid.szInfoTitle, sizeof(tnid.szInfoTitle), headline);
StringCbCopyW (tnid.szInfo, sizeof(tnid.szInfo),text);
@@ -10296,13 +10295,6 @@ int WarningDirect (const wchar_t *warnMsg, HWND hwnd)
return MessageBoxW (hwnd, warnMsg, lpszTitle, MB_ICONWARNING);
}
-
-int Error (char *stringId, HWND hwnd)
-{
- if (Silent) return 0;
- return MessageBoxW (hwnd, GetString (stringId), lpszTitle, MB_ICONERROR);
-}
-
int ErrorRetryCancel (char *stringId, HWND hwnd)
{
if (Silent) return 0;
@@ -10781,47 +10773,29 @@ void DebugMsgBox (char *format, ...)
MessageBoxA (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)
+BOOL IsSupportedOS ()
{
- /* When updating this function, update IsOSAtLeast() in Ntdriver.c too. */
-
- if (CurrentOSMajor <= 0)
- TC_THROW_FATAL_EXCEPTION;
-
- int major = 0, minor = 0;
-
- switch (reqMinOS)
+ BOOL bRet = FALSE;
+#ifdef SETUP
+ static const wchar_t* szWin7KBs[] = {L"KB3033929", L"KB4474419"};
+ static const wchar_t* szWinVistaKBs[] = {L"KB4039648", L"KB4474419"};
+ if (IsOSAtLeast(WIN_8))
+ bRet = TRUE;
+ else if (IsOSAtLeast(WIN_7))
{
- 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;
- case WIN_8: major = 6; minor = 2; break;
- case WIN_8_1: major = 6; minor = 3; break;
- case WIN_10: major = 10; minor = 0; break;
-
- default:
- TC_THROW_FATAL_EXCEPTION;
- break;
+ if (OneOfKBsInstalled(szWin7KBs, 2))
+ bRet = TRUE;
+ else
+ MessageBoxW (NULL, L"SHA-2 support missing from Windows.\n\nPlease Install KB3033929 or KB4474419", lpszTitle, MB_ICONWARNING);
}
+#else
+ if (IsOSAtLeast(WIN_7))
+ bRet = TRUE;
+#endif
- return ((CurrentOSMajor << 16 | CurrentOSMinor << 8 | CurrentOSServicePack)
- >= (major << 16 | minor << 8 | reqMinServicePack));
+ return bRet;
}
-
BOOL Is64BitOs()
{
#ifdef _WIN64
@@ -11153,6 +11127,10 @@ void Applink (const char *dest)
{
StringCbCopyW (page, sizeof (page),L"Keyfiles.html");
}
+ else if (strcmp(dest, "keyfilesextensions") == 0)
+ {
+ StringCbCopyW (page, sizeof (page),L"Avoid%20Third-Party%20File%20Extensions.html");
+ }
else if (strcmp(dest, "introcontainer") == 0)
{
StringCbCopyW (page, sizeof (page),L"Creating%20New%20Volumes.html");
@@ -11238,6 +11216,10 @@ void Applink (const char *dest)
{
StringCbCopyW (page, sizeof (page),L"Personal%20Iterations%20Multiplier%20%28PIM%29.html");
}
+ else if (strcmp(dest, "memoryprotection") == 0)
+ {
+ StringCbCopyW (page, sizeof (page),L"VeraCrypt%20Memory%20Protection.html");
+ }
else
{
StringCbCopyW (url, sizeof (url),TC_APPLINK);
@@ -11246,11 +11228,25 @@ void Applink (const char *dest)
if (buildUrl)
{
+ // in case of setup, open the online documentation if we are connected to Internet because existing documentation may be outdated
+#ifdef SETUP
+ if (IsInternetConnected())
+ {
+ StringCbPrintfW (url, sizeof (url), L"https://www.veracrypt.fr/en/%s", page);
+ buildUrl = FALSE;
+ }
+ else
+ {
+ StringCbPrintfW (url, sizeof (url), L"file:///%sdocs/html/en/%s", installDir, page);
+ CorrectURL (url);
+ }
+#else
StringCbPrintfW (url, sizeof (url), L"file:///%sdocs/html/en/%s", installDir, page);
CorrectURL (url);
+#endif
}
- if (IsOSAtLeast (WIN_VISTA) && IsAdmin ())
+ if (IsAdmin ())
{
int openDone = 0;
if (buildUrl)
@@ -11260,7 +11256,7 @@ void Applink (const char *dest)
StringCbCopyW (pageFileName, sizeof(pageFileName), page);
/* remove escape sequences from the page name before calling FileExists function */
- if (S_OK == UrlUnescapeWFn (pageFileName, pageFileName, &cchUnescaped, URL_UNESCAPE_INPLACE))
+ if (S_OK == UrlUnescapeW (pageFileName, pageFileName, &cchUnescaped, URL_UNESCAPE_INPLACE))
{
std::wstring pageFullPath = installDir;
pageFullPath += L"docs\\html\\en\\";
@@ -11332,8 +11328,6 @@ void HandleDriveNotReadyError (HWND hwnd)
{
Warning ("SYS_AUTOMOUNT_DISABLED", hwnd);
}
- else if (nCurrentOS == WIN_VISTA && CurrentOSServicePack < 1)
- Warning ("SYS_ASSIGN_DRIVE_LETTER", hwnd);
else
Warning ("DEVICE_NOT_READY_ERROR", hwnd);
@@ -11348,7 +11342,8 @@ BOOL CALLBACK CloseTCWindowsEnum (HWND hwnd, LPARAM lParam)
{
wchar_t name[1024] = { 0 };
GetWindowText (hwnd, name, ARRAYSIZE (name) - 1);
- if (hwnd != MainDlg && wcsstr (name, L"VeraCrypt"))
+ // check if the window is a VeraCrypt window, excluding current process main dialog and VeraCrypt Setup window
+ if (hwnd != MainDlg && wcsstr (name, L"VeraCrypt") && !wcsstr (name, L"VeraCrypt Setup"))
{
PostMessage (hwnd, TC_APPMSG_CLOSE_BKG_TASK, 0, 0);
@@ -11425,7 +11420,7 @@ void ReportUnexpectedState (const char *techInfo)
#ifndef SETUP
-int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password *password, int pkcs5_prf, int pim, BOOL truecryptMode, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader)
+int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password *password, int pkcs5_prf, int pim, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader)
{
int status = ERR_PARAMETER_INCORRECT;
int volumeType;
@@ -11600,7 +11595,7 @@ int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password
}
// Decrypt volume header
- status = ReadVolumeHeader (FALSE, buffer, password, pkcs5_prf, pim, truecryptMode, &context->CryptoInfo, NULL);
+ status = ReadVolumeHeader (FALSE, buffer, password, pkcs5_prf, pim, &context->CryptoInfo, NULL);
if (status == ERR_PASSWORD_WRONG)
continue; // Try next volume type
@@ -11929,11 +11924,11 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA
WaitCursor();
finally_do ({ NormalCursor(); });
- list <SecurityTokenInfo> tokens;
+ list <shared_ptr<TokenInfo>> tokens;
try
{
- tokens = SecurityToken::GetAvailableTokens();
+ tokens = Token::GetAvailableTokens();
}
catch (Exception &e)
{
@@ -11947,12 +11942,12 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA
return 1;
}
- foreach (const SecurityTokenInfo &token, tokens)
+ foreach (const shared_ptr<TokenInfo> token, tokens)
{
wstringstream tokenLabel;
- tokenLabel << L"[" << token.SlotId << L"] " << token.Label;
+ tokenLabel << L"[" << token->SlotId << L"] " << token->Label;
- AddComboPair (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token.SlotId);
+ AddComboPair (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), tokenLabel.str().c_str(), token->SlotId);
}
ComboBox_SetCurSel (GetDlgItem (hwndDlg, IDC_SELECTED_TOKEN), 0);
@@ -12006,7 +12001,7 @@ static BOOL CALLBACK NewSecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPA
}
-static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
+static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <shared_ptr<TokenKeyfile>> &keyfiles)
{
HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
LVITEMW lvItem;
@@ -12014,18 +12009,18 @@ static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <Securit
ListView_DeleteAllItems (tokenListControl);
- foreach (const SecurityTokenKeyfile &keyfile, keyfiles)
+ foreach (const shared_ptr<TokenKeyfile> keyfile, keyfiles)
{
memset (&lvItem, 0, sizeof(lvItem));
lvItem.mask = LVIF_TEXT;
lvItem.iItem = line++;
wstringstream s;
- s << keyfile.SlotId;
+ s << keyfile->Token->SlotId;
ListItemAdd (tokenListControl, lvItem.iItem, (wchar_t *) s.str().c_str());
- ListSubItemSet (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile.Token.Label.c_str());
- ListSubItemSet (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile.Id.c_str());
+ ListSubItemSet (tokenListControl, lvItem.iItem, 1, (wchar_t *) keyfile->Token->Label.c_str());
+ ListSubItemSet (tokenListControl, lvItem.iItem, 2, (wchar_t *) keyfile->Id.c_str());
}
BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
@@ -12034,10 +12029,10 @@ static void SecurityTokenKeyfileDlgFillList (HWND hwndDlg, const vector <Securit
}
-static list <SecurityTokenKeyfile> SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector <SecurityTokenKeyfile> &keyfiles)
+static list <shared_ptr<TokenKeyfile>> SecurityTokenKeyfileDlgGetSelected (HWND hwndDlg, const vector <shared_ptr<TokenKeyfile>> &keyfiles)
{
HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
- list <SecurityTokenKeyfile> selectedKeyfiles;
+ list <shared_ptr<TokenKeyfile>> selectedKeyfiles;
int itemId = -1;
while ((itemId = ListView_GetNextItem (tokenListControl, itemId, LVIS_SELECTED)) != -1)
@@ -12051,8 +12046,8 @@ static list <SecurityTokenKeyfile> SecurityTokenKeyfileDlgGetSelected (HWND hwnd
BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
- static list <SecurityTokenKeyfilePath> *selectedTokenKeyfiles;
- static vector <SecurityTokenKeyfile> keyfiles;
+ static list <TokenKeyfilePath> *selectedTokenKeyfiles;
+ static vector <shared_ptr<TokenKeyfile>> keyfiles;
WORD lw = LOWORD (wParam);
@@ -12060,7 +12055,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
case WM_INITDIALOG:
{
- selectedTokenKeyfiles = (list <SecurityTokenKeyfilePath> *) lParam;
+ selectedTokenKeyfiles = (list <TokenKeyfilePath> *) lParam;
LVCOLUMNW LvCol;
HWND tokenListControl = GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST);
@@ -12095,7 +12090,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
WaitCursor();
finally_do ({ NormalCursor(); });
- keyfiles = SecurityToken::GetAvailableKeyfiles();
+ keyfiles = Token::GetAvailableKeyfiles(EMVSupportEnabled? true : false);
}
catch (UserAbort&)
{
@@ -12123,9 +12118,9 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
if (selectedTokenKeyfiles)
{
- foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ foreach (const shared_ptr<TokenKeyfile> &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
{
- selectedTokenKeyfiles->push_back (SecurityTokenKeyfilePath (keyfile));
+ selectedTokenKeyfiles->push_back (TokenKeyfilePath (*keyfile));
}
}
@@ -12136,8 +12131,19 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
if (msg == WM_NOTIFY && ((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
{
BOOL selected = (ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_TOKEN_FILE_LIST), -1, LVIS_SELECTED) != -1);
+ BOOL deletable = selected;
+ // Multiple key files can be selected.
+ // Therefore, if one of them is not deletable, it means the delete button must be disabled for all.
+ foreach (const shared_ptr<TokenKeyfile> &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ {
+ if (!keyfile->Token->isEditable())
+ {
+ deletable = false;
+ break;
+ }
+ }
EnableWindow (GetDlgItem (hwndDlg, IDC_EXPORT), selected);
- EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), selected);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_DELETE), deletable);
return 1;
}
@@ -12153,7 +12159,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
wchar_t keyfilePath[TC_MAX_PATH];
- if (BrowseFiles (hwndDlg, "SELECT_KEYFILE", keyfilePath, bHistory, FALSE, NULL))
+ if (BrowseFiles (hwndDlg, "SELECT_KEYFILE", keyfilePath, bHistory, FALSE))
{
DWORD keyfileSize;
byte *keyfileData = (byte *) LoadFile (keyfilePath, &keyfileSize);
@@ -12184,7 +12190,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
SecurityToken::CreateKeyfile (newParams.SlotId, keyfileDataVector, newParams.Name);
- keyfiles = SecurityToken::GetAvailableKeyfiles();
+ keyfiles = Token::GetAvailableKeyfiles(EMVSupportEnabled? true : false);
SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
}
catch (Exception &e)
@@ -12212,11 +12218,11 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
{
try
{
- foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ foreach (const shared_ptr<TokenKeyfile> &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
{
wchar_t keyfilePath[TC_MAX_PATH];
- if (!BrowseFiles (hwndDlg, "OPEN_TITLE", keyfilePath, bHistory, TRUE, NULL))
+ if (!BrowseFiles (hwndDlg, "OPEN_TITLE", keyfilePath, bHistory, TRUE))
break;
{
@@ -12225,7 +12231,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
vector <byte> keyfileData;
- SecurityToken::GetKeyfileData (keyfile, keyfileData);
+ keyfile->GetKeyfileData (keyfileData);
if (keyfileData.empty())
{
@@ -12261,12 +12267,12 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam
WaitCursor();
finally_do ({ NormalCursor(); });
- foreach (const SecurityTokenKeyfile &keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
+ foreach (const shared_ptr<TokenKeyfile> keyfile, SecurityTokenKeyfileDlgGetSelected (hwndDlg, keyfiles))
{
- SecurityToken::DeleteKeyfile (keyfile);
+ SecurityToken::DeleteKeyfile (dynamic_cast<SecurityTokenKeyfile&>(*keyfile.get()));
}
- keyfiles = SecurityToken::GetAvailableKeyfiles();
+ keyfiles = Token::GetAvailableKeyfiles(EMVSupportEnabled? true : false);
SecurityTokenKeyfileDlgFillList (hwndDlg, keyfiles);
}
catch (Exception &e)
@@ -13231,11 +13237,6 @@ BOOL IsWindowsIsoBurnerAvailable ()
{
wchar_t path[MAX_PATH*2] = { 0 };
- if (!IsOSAtLeast (WIN_7))
- {
- return FALSE;
- }
-
if (SUCCEEDED(SHGetFolderPath (NULL, CSIDL_SYSTEM, NULL, 0, path)))
{
StringCbCatW (path, MAX_PATH*2, L"\\" ISO_BURNER_TOOL);
@@ -13509,36 +13510,36 @@ void RegisterDriverInf (bool registerFilter, const string& filter, const string&
infFile.Write ((byte *) infTxt.c_str(), (DWORD) infTxt.size());
infFile.Close();
- HINF hInf = SetupOpenInfFileWFn (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
+ HINF hInf = SetupOpenInfFileW (infFileName.c_str(), NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
throw_sys_if (hInf == INVALID_HANDLE_VALUE);
- finally_do_arg (HINF, hInf, { SetupCloseInfFileFn (finally_arg); });
+ finally_do_arg (HINF, hInf, { SetupCloseInfFile (finally_arg); });
- throw_sys_if (!SetupInstallFromInfSectionWFn (ParentWindow, hInf, L"veracrypt", SPINST_REGISTRY, regKey, NULL, 0, NULL, NULL, NULL, NULL));
+ throw_sys_if (!SetupInstallFromInfSectionW (ParentWindow, hInf, L"veracrypt", SPINST_REGISTRY, regKey, NULL, 0, NULL, NULL, NULL, NULL));
}
HKEY OpenDeviceClassRegKey (const GUID *deviceClassGuid)
{
- return SetupDiOpenClassRegKeyFn (deviceClassGuid, KEY_READ | KEY_WRITE);
+ return SetupDiOpenClassRegKey (deviceClassGuid, KEY_READ | KEY_WRITE);
}
LSTATUS DeleteRegistryKey (HKEY hKey, LPCTSTR keyName)
{
- return SHDeleteKeyWFn(hKey, keyName);
+ return SHDeleteKeyW(hKey, keyName);
}
HIMAGELIST CreateImageList(int cx, int cy, UINT flags, int cInitial, int cGrow)
{
- return ImageList_CreateFn(cx, cy, flags, cInitial, cGrow);
+ return ImageList_Create(cx, cy, flags, cInitial, cGrow);
}
int AddBitmapToImageList(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
{
- return ImageList_AddFn(himl, hbmImage, hbmMask);
+ return ImageList_Add(himl, hbmImage, hbmMask);
}
HRESULT VCStrDupW(LPCWSTR psz, LPWSTR *ppwsz)
{
- return SHStrDupWFn (psz, ppwsz);
+ return SHStrDupW (psz, ppwsz);
}
@@ -13561,16 +13562,13 @@ void ProcessEntropyEstimate (HWND hProgress, DWORD* pdwInitialValue, DWORD dwCou
else
*pdwEntropy = dwMaxLevel;
- if (IsOSAtLeast (WIN_VISTA))
- {
- int state = PBST_ERROR;
- if (*pdwEntropy >= (dwMaxLevel/2))
- state = PBST_NORMAL;
- else if (*pdwEntropy >= (dwMaxLevel/4))
- state = PBST_PAUSED;
+ int state = PBST_ERROR;
+ if (*pdwEntropy >= (dwMaxLevel/2))
+ state = PBST_NORMAL;
+ else if (*pdwEntropy >= (dwMaxLevel/4))
+ state = PBST_PAUSED;
- SendMessage (hProgress, PBM_SETSTATE, state, 0);
- }
+ SendMessage (hProgress, PBM_SETSTATE, state, 0);
SendMessage (hProgress, PBM_SETPOS,
(WPARAM) (*pdwEntropy),
@@ -13580,10 +13578,8 @@ void ProcessEntropyEstimate (HWND hProgress, DWORD* pdwInitialValue, DWORD dwCou
void AllowMessageInUIPI (UINT msg)
{
- if (ChangeWindowMessageFilterFn)
- {
- ChangeWindowMessageFilterFn (msg, MSGFLT_ADD);
- }
+ /* ChangeWindowMessageFilter is used to enable some messages bypasss UIPI (User Interface Privilege Isolation) */
+ ChangeWindowMessageFilter (msg, MSGFLT_ADD);
}
BOOL IsRepeatedByteArray (byte value, const byte* buffer, size_t bufferSize)
@@ -13699,7 +13695,45 @@ BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable)
tkp.Privileges[0].Attributes = bEnable? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;
bRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, NULL);
- if (!bRet)
+ dwLastError = GetLastError ();
+ if ( ERROR_SUCCESS != dwLastError)
+ {
+ bRet = FALSE;
+ }
+ }
+ else
+ dwLastError = GetLastError ();
+
+ CloseHandle(hToken);
+ }
+ else
+ dwLastError = GetLastError ();
+
+ SetLastError (dwLastError);
+
+ return bRet;
+}
+
+BOOL IsPrivilegeEnabled (LPTSTR szPrivilegeName)
+{
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tkp;
+ BOOL bRet = FALSE;
+ DWORD dwLastError = 0;
+
+ if (OpenProcessToken(GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+ &hToken))
+ {
+ if (LookupPrivilegeValue(NULL, szPrivilegeName,
+ &tkp.Privileges[0].Luid))
+ {
+ DWORD dwSize = sizeof (tkp);
+ if (GetTokenInformation (hToken, TokenPrivileges, &tkp, dwSize, &dwSize))
+ {
+ bRet = (tkp.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) != 0;
+ }
+ else
dwLastError = GetLastError ();
}
else
@@ -13753,7 +13787,7 @@ static BOOL GenerateRandomString (HWND hwndDlg, LPTSTR szName, DWORD maxCharsCou
bRet = RandgetBytesFull (hwndDlg, indexes, maxCharsCount + 1, TRUE, TRUE);
if (bRet)
{
- static LPCTSTR chars = _T("0123456789@#$%^&_-*abcdefghijklmnopqrstuvwxyz");
+ static LPCTSTR chars = _T("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
DWORD i, charsLen = (DWORD) _tcslen (chars);
DWORD effectiveLen = (indexes[0] % (64 - 16)) + 16; // random length between 16 to 64
effectiveLen = (effectiveLen > maxCharsCount)? maxCharsCount : effectiveLen;
@@ -13794,13 +13828,14 @@ typedef struct
DLGPROC lpDialogFunc;
LPARAM dwInitParam;
INT_PTR retValue;
+ BOOL bDlgDisplayed; // set to TRUE if the dialog was displayed on secure desktop
} SecureDesktopThreadParam;
typedef struct
{
LPCWSTR szVCDesktopName;
HDESK hVcDesktop;
- volatile BOOL* pbStopMonitoring;
+ HANDLE hStopEvent; // event to signal when to stop monitoring
} SecureDesktopMonitoringThreadParam;
#define SECUREDESKTOP_MONOTIR_PERIOD 500
@@ -13812,11 +13847,12 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
SecureDesktopMonitoringThreadParam* pMonitorParam = (SecureDesktopMonitoringThreadParam*) lpThreadParameter;
if (pMonitorParam)
{
- volatile BOOL* pbStopMonitoring = pMonitorParam->pbStopMonitoring;
+ HANDLE hStopEvent = pMonitorParam->hStopEvent;
LPCWSTR szVCDesktopName = pMonitorParam->szVCDesktopName;
HDESK hVcDesktop = pMonitorParam->hVcDesktop;
- while (!*pbStopMonitoring)
+ // loop until the stop event is signaled
+ while (WaitForSingleObject (hStopEvent, SECUREDESKTOP_MONOTIR_PERIOD) == WAIT_TIMEOUT)
{
// check that our secure desktop is still the input desktop
// otherwise, switch to it
@@ -13833,7 +13869,9 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
{
if (GetUserObjectInformation (currentDesk, UOI_NAME, szName, dwLen, &dwLen))
{
- if (0 != _wcsicmp (szName, szVCDesktopName))
+ if (0 == _wcsicmp(szName, L"Default")) // default input desktop for the interactive window station
+ bPerformSwitch = TRUE;
+ else if (0 != _wcsicmp (szName, szVCDesktopName))
bPerformSwitch = TRUE;
}
free (szName);
@@ -13844,61 +13882,78 @@ static unsigned int __stdcall SecureDesktopMonitoringThread( LPVOID lpThreadPara
if (bPerformSwitch)
SwitchDesktop (hVcDesktop);
-
- Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
}
}
return 0;
}
-static DWORD WINAPI SecureDesktopThread(LPVOID lpThreadParameter)
+static unsigned int __stdcall SecureDesktopThread( LPVOID lpThreadParameter )
{
- volatile BOOL bStopMonitoring = FALSE;
HANDLE hMonitoringThread = NULL;
unsigned int monitoringThreadID = 0;
SecureDesktopThreadParam* pParam = (SecureDesktopThreadParam*) lpThreadParameter;
SecureDesktopMonitoringThreadParam monitorParam;
- HDESK hOriginalDesk = GetThreadDesktop (GetCurrentThreadId ());
BOOL bNewDesktopSet = FALSE;
+ HDESK hSecureDesk;
+ DWORD desktopAccess = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS;
+
+ hSecureDesk = CreateDesktop (pParam->szDesktopName, NULL, NULL, 0, desktopAccess, NULL);
+ if (!hSecureDesk)
+ {
+ return 0;
+ }
+
+ StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), pParam->szDesktopName);
+ pParam->hDesk = hSecureDesk;
// wait for SwitchDesktop to succeed before using it for current thread
while (true)
{
- if (SwitchDesktop (pParam->hDesk))
+ if (SwitchDesktop (hSecureDesk))
{
- bNewDesktopSet = TRUE;
break;
}
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
}
+ bNewDesktopSet = SetThreadDesktop (hSecureDesk);
+
if (bNewDesktopSet)
{
- SetThreadDesktop (pParam->hDesk);
-
// create the thread that will ensure that VeraCrypt secure desktop has always user input
- monitorParam.szVCDesktopName = pParam->szDesktopName;
- monitorParam.hVcDesktop = pParam->hDesk;
- monitorParam.pbStopMonitoring = &bStopMonitoring;
- hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
- }
+ // this is done only if the stop event is created successfully
+ HANDLE hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (hStopEvent)
+ {
+ monitorParam.szVCDesktopName = pParam->szDesktopName;
+ monitorParam.hVcDesktop = hSecureDesk;
+ monitorParam.hStopEvent = hStopEvent;
+ hMonitoringThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopMonitoringThread, (LPVOID) &monitorParam, 0, &monitoringThreadID);
+ }
- pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
- NULL, pParam->lpDialogFunc, pParam->dwInitParam);
+ pParam->retValue = DialogBoxParamW (pParam->hInstance, pParam->lpTemplateName,
+ NULL, pParam->lpDialogFunc, pParam->dwInitParam);
- if (hMonitoringThread)
- {
- bStopMonitoring = TRUE;
+ if (hMonitoringThread)
+ {
+ // notify the monitoring thread to stop
+ SetEvent(hStopEvent);
- WaitForSingleObject (hMonitoringThread, INFINITE);
- CloseHandle (hMonitoringThread);
- }
+ WaitForSingleObject (hMonitoringThread, INFINITE);
+ CloseHandle (hMonitoringThread);
+ }
- if (bNewDesktopSet)
+ if (hStopEvent)
+ {
+ CloseHandle (hStopEvent);
+ }
+
+ pParam->bDlgDisplayed = TRUE;
+ }
+ else
{
- SetThreadDesktop (hOriginalDesk);
- SwitchDesktop (hOriginalDesk);
+ pParam->bDlgDisplayed = FALSE;
}
return 0;
@@ -13949,17 +14004,36 @@ INT_PTR SecureDesktopDialogBoxParam(
if (bEffectiveUseSecureDesktop && !IsThreadInSecureDesktop(GetCurrentThreadId()))
{
+ BOOL bRandomNameGenerated = FALSE;
+ HDESK existedDesk = NULL;
EnterCriticalSection (&csSecureDesktop);
bSecureDesktopOngoing = TRUE;
finally_do ({ bSecureDesktopOngoing = FALSE; LeaveCriticalSection (&csSecureDesktop); });
- if (GenerateRandomString (hWndParent, szDesktopName, 64))
+ // ensure that the randomly generated name is not already used
+ do
+ {
+ if (existedDesk)
+ {
+ CloseDesktop (existedDesk);
+ existedDesk = NULL;
+ }
+ if (GenerateRandomString (hWndParent, szDesktopName, 64))
+ {
+ existedDesk = OpenDesktop (szDesktopName, 0, FALSE, GENERIC_READ);
+ if (!existedDesk)
+ {
+ bRandomNameGenerated = TRUE;
+ }
+ }
+ } while (existedDesk);
+
+ if (bRandomNameGenerated)
{
map<DWORD, BOOL> ctfmonBeforeList, ctfmonAfterList;
- DWORD desktopAccess = DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS;
- HDESK hSecureDesk;
+ HDESK hOriginalDesk = NULL;
+ SecureDesktopThreadParam param;
- HDESK hInputDesk = NULL;
// wait for the input desktop to be available before switching to
// secure desktop. Under Windows 10, the user session can be started
@@ -13967,59 +14041,66 @@ INT_PTR SecureDesktopDialogBoxParam(
// case, we wait for the user to be really authenticated before starting
// secure desktop mechanism
- while (!(hInputDesk = OpenInputDesktop (0, TRUE, GENERIC_READ)))
+ while (!(hOriginalDesk = OpenInputDesktop (0, TRUE, GENERIC_ALL)))
{
Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
}
-
- CloseDesktop (hInputDesk);
// get the initial list of ctfmon.exe processes before creating new desktop
GetCtfMonProcessIdList (ctfmonBeforeList);
- hSecureDesk = CreateDesktop (szDesktopName, NULL, NULL, 0, desktopAccess, NULL);
- if (hSecureDesk)
- {
- SecureDesktopThreadParam param;
-
- param.hDesk = hSecureDesk;
- param.szDesktopName = szDesktopName;
- param.hInstance = hInstance;
- param.lpTemplateName = lpTemplateName;
- param.lpDialogFunc = lpDialogFunc;
- param.dwInitParam = dwInitParam;
- param.retValue = 0;
-
- HANDLE hThread = ::CreateThread (NULL, 0, SecureDesktopThread, (LPVOID) &param, 0, NULL);
- if (hThread)
- {
- StringCbCopy(SecureDesktopName, sizeof (SecureDesktopName), szDesktopName);
+ param.hDesk = NULL;
+ param.szDesktopName = szDesktopName;
+ param.hInstance = hInstance;
+ param.lpTemplateName = lpTemplateName;
+ param.lpDialogFunc = lpDialogFunc;
+ param.dwInitParam = dwInitParam;
+ param.retValue = 0;
+ param.bDlgDisplayed = FALSE;
- WaitForSingleObject (hThread, INFINITE);
- CloseHandle (hThread);
+ // use _beginthreadex instead of CreateThread because lpDialogFunc may be using the C runtime library
+ HANDLE hThread = (HANDLE) _beginthreadex (NULL, 0, SecureDesktopThread, (LPVOID) &param, 0, NULL);
+ if (hThread)
+ {
+ WaitForSingleObject (hThread, INFINITE);
+ CloseHandle (hThread);
+ if (param.bDlgDisplayed)
+ {
+ // dialog box was indeed displayed in Secure Desktop
retValue = param.retValue;
bSuccess = TRUE;
}
+ }
- CloseDesktop (hSecureDesk);
+ if (param.hDesk)
+ {
+ while (!SwitchDesktop (hOriginalDesk))
+ {
+ Sleep (SECUREDESKTOP_MONOTIR_PERIOD);
+ }
- // get the new list of ctfmon.exe processes in order to find the ID of the
- // ctfmon.exe instance that corresponds to the desktop we create so that
- // we can kill it, otherwise it would remain running
- GetCtfMonProcessIdList (ctfmonAfterList);
+ SetThreadDesktop (hOriginalDesk);
- for (map<DWORD, BOOL>::iterator It = ctfmonAfterList.begin();
- It != ctfmonAfterList.end(); It++)
+ CloseDesktop (param.hDesk);
+ }
+
+ // get the new list of ctfmon.exe processes in order to find the ID of the
+ // ctfmon.exe instance that corresponds to the desktop we create so that
+ // we can kill it, otherwise it would remain running
+ GetCtfMonProcessIdList (ctfmonAfterList);
+
+ for (map<DWORD, BOOL>::iterator It = ctfmonAfterList.begin();
+ It != ctfmonAfterList.end(); It++)
+ {
+ if (ctfmonBeforeList[It->first] != TRUE)
{
- if (ctfmonBeforeList[It->first] != TRUE)
- {
- // Kill process
- KillProcess (It->first);
- }
+ // Kill process
+ KillProcess (It->first);
}
}
+ CloseDesktop(hOriginalDesk);
burn (szDesktopName, sizeof (szDesktopName));
}
}
@@ -14035,135 +14116,6 @@ INT_PTR SecureDesktopDialogBoxParam(
#endif
-#ifdef NDEBUG
-static BOOL InitializeWintrust()
-{
- if (!hWinTrustLib)
- {
- wchar_t szPath[MAX_PATH] = {0};
-
- if (GetSystemDirectory(szPath, MAX_PATH))
- StringCchCatW (szPath, MAX_PATH, L"\\Wintrust.dll");
- else
- StringCchCopyW (szPath, MAX_PATH, L"C:\\Windows\\System32\\Wintrust.dll");
-
- hWinTrustLib = LoadLibrary (szPath);
- if (hWinTrustLib)
- {
- WinVerifyTrustFn = (WINVERIFYTRUST) GetProcAddress (hWinTrustLib, "WinVerifyTrust");
- WTHelperProvDataFromStateDataFn = (WTHELPERPROVDATAFROMSTATEDATA) GetProcAddress (hWinTrustLib, "WTHelperProvDataFromStateData");
- WTHelperGetProvSignerFromChainFn = (WTHELPERGETPROVSIGNERFROMCHAIN) GetProcAddress (hWinTrustLib, "WTHelperGetProvSignerFromChain");
- WTHelperGetProvCertFromChainFn = (WTHELPERGETPROVCERTFROMCHAIN) GetProcAddress (hWinTrustLib, "WTHelperGetProvCertFromChain");
-
- if ( !WinVerifyTrustFn
- || !WTHelperProvDataFromStateDataFn
- || !WTHelperGetProvSignerFromChainFn
- || !WTHelperGetProvCertFromChainFn)
- {
- FreeLibrary (hWinTrustLib);
- hWinTrustLib = NULL;
- }
-
- }
- }
-
- if (hWinTrustLib)
- return TRUE;
- else
- return FALSE;
-}
-
-static void FinalizeWintrust()
-{
- if (hWinTrustLib)
- {
- FreeLibrary (hWinTrustLib);
- hWinTrustLib = NULL;
- }
-}
-
-#endif
-
-BOOL VerifyModuleSignature (const wchar_t* path)
-{
-#ifdef NDEBUG
- BOOL bResult = FALSE;
- HRESULT hResult;
- GUID gActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
- WINTRUST_FILE_INFO fileInfo = {0};
- WINTRUST_DATA WVTData = {0};
- wchar_t filePath [TC_MAX_PATH + 1024];
-
- // we check our own authenticode signature only starting from Windows 10 since this is
- // the minimal supported OS apart from XP where we can't verify SHA256 signatures
- if (!IsOSAtLeast (WIN_10))
- return TRUE;
-
- // Strip quotation marks (if any)
- if (path [0] == L'"')
- {
- StringCbCopyW (filePath, sizeof(filePath), path + 1);
- }
- else
- {
- StringCbCopyW (filePath, sizeof(filePath), path);
- }
-
- // Strip quotation marks (if any)
- if (filePath [wcslen (filePath) - 1] == L'"')
- filePath [wcslen (filePath) - 1] = 0;
-
- if (!InitializeWintrust ())
- return FALSE;
-
- fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
- fileInfo.pcwszFilePath = filePath;
- fileInfo.hFile = NULL;
-
- WVTData.cbStruct = sizeof(WINTRUST_DATA);
- WVTData.dwUIChoice = WTD_UI_NONE;
- WVTData.fdwRevocationChecks = WTD_REVOKE_NONE;
- WVTData.dwUnionChoice = WTD_CHOICE_FILE;
- WVTData.pFile = &fileInfo;
- WVTData.dwStateAction = WTD_STATEACTION_VERIFY;
- WVTData.dwProvFlags = WTD_REVOCATION_CHECK_NONE | WTD_CACHE_ONLY_URL_RETRIEVAL;
-
- hResult = WinVerifyTrustFn(0, &gActionID, &WVTData);
- if (0 == hResult)
- {
- PCRYPT_PROVIDER_DATA pProviderData = WTHelperProvDataFromStateDataFn (WVTData.hWVTStateData);
- if (pProviderData)
- {
- PCRYPT_PROVIDER_SGNR pProviderSigner = WTHelperGetProvSignerFromChainFn (pProviderData, 0, FALSE, 0);
- if (pProviderSigner)
- {
- PCRYPT_PROVIDER_CERT pProviderCert = WTHelperGetProvCertFromChainFn (pProviderSigner, 0);
- if (pProviderCert && (pProviderCert->pCert))
- {
- BYTE hashVal[64];
- sha512 (hashVal, pProviderCert->pCert->pbCertEncoded, pProviderCert->pCert->cbCertEncoded);
-
- if (0 == memcmp (hashVal, gpbSha256CodeSignCertFingerprint, 64))
- {
- bResult = TRUE;
- }
- }
- }
- }
- }
-
- WVTData.dwUIChoice = WTD_UI_NONE;
- WVTData.dwStateAction = WTD_STATEACTION_CLOSE;
- WinVerifyTrustFn(0, &gActionID, &WVTData);
-
- FinalizeWintrust ();
-
- return bResult;
-#else
- return TRUE;
-#endif
-}
-
void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, BOOL* pbInstallPathDetermined)
{
HKEY hkey;
@@ -14243,37 +14195,26 @@ void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, B
BOOL GetSetupconfigLocation (wchar_t* path, DWORD cchSize)
{
- wchar_t szShell32Path[MAX_PATH] = {0};
- HMODULE hShell32 = NULL;
BOOL bResult = FALSE;
path[0] = 0;
- if (GetSystemDirectory(szShell32Path, MAX_PATH))
- StringCchCatW (szShell32Path, MAX_PATH, L"\\Shell32.dll");
- else
- StringCchCopyW (szShell32Path, MAX_PATH, L"C:\\Windows\\System32\\Shell32.dll");
-
- hShell32 = LoadLibrary (szShell32Path);
- if (hShell32)
+ wchar_t* pszUsersPath = NULL;
+ if (S_OK == SHGetKnownFolderPath (FOLDERID_UserProfiles, 0, NULL, &pszUsersPath))
{
- SHGETKNOWNFOLDERPATH SHGetKnownFolderPathFn = (SHGETKNOWNFOLDERPATH) GetProcAddress (hShell32, "SHGetKnownFolderPath");
- if (SHGetKnownFolderPathFn)
- {
- wchar_t* pszUsersPath = NULL;
- if (S_OK == SHGetKnownFolderPathFn (FOLDERID_UserProfiles, 0, NULL, &pszUsersPath))
- {
- StringCchPrintfW (path, cchSize, L"%s\\Default\\AppData\\Local\\Microsoft\\Windows\\WSUS\\", pszUsersPath);
- CoTaskMemFree (pszUsersPath);
- bResult = TRUE;
- }
- }
- FreeLibrary (hShell32);
+ StringCchPrintfW (path, cchSize, L"%s\\Default\\AppData\\Local\\Microsoft\\Windows\\WSUS\\", pszUsersPath);
+ CoTaskMemFree (pszUsersPath);
+ bResult = TRUE;
}
if (!bResult && CurrentOSMajor >= 10)
{
- StringCchPrintfW (path, cchSize, L"%c:\\Users\\Default\\AppData\\Local\\Microsoft\\Windows\\WSUS\\", szShell32Path[0]);
+ wchar_t szSys32Path[MAX_PATH];
+ if (!GetSystemDirectory (szSys32Path, ARRAYSIZE (szSys32Path)))
+ {
+ StringCchCopy(szSys32Path, ARRAYSIZE (szSys32Path), L"C:\\Windows\\System32");
+ }
+ StringCchPrintfW (path, cchSize, L"%c:\\Users\\Default\\AppData\\Local\\Microsoft\\Windows\\WSUS\\", szSys32Path[0]);
bResult = TRUE;
}
@@ -14303,7 +14244,7 @@ BOOL BufferHasPattern (const unsigned char* buffer, size_t bufferLen, const void
*
* Reduce current user acess rights for this process to the minimum in order to forbid non-admin users from reading the process memory.
*/
-BOOL EnableProcessProtection()
+BOOL ActivateMemoryProtection()
{
BOOL bSuccess = FALSE;
@@ -14318,7 +14259,10 @@ BOOL EnableProcessProtection()
// Acces mask
DWORD dwAccessMask = SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE; // same as protected process
-
+
+ if (MemoryProtectionActivated)
+ return TRUE;
+
if (IsAdmin ())
{
// if we are running elevated, we allow CreateProcessXXX calls alongside PROCESS_DUP_HANDLE and PROCESS_QUERY_INFORMATION in order to be able
@@ -14381,6 +14325,9 @@ BOOL EnableProcessProtection()
NULL // do not change SACL
))? TRUE: FALSE;
+ if (bSuccess)
+ MemoryProtectionActivated = TRUE;
+
Cleanup:
if (pACL != NULL) {
@@ -14396,6 +14343,92 @@ Cleanup:
return bSuccess;
}
+// define missing structures Windows 8
+#if (_WIN32_WINNT < 0x0602)
+
+typedef struct _PROCESS_MITIGATION_ASLR_POLICY {
+ union {
+ DWORD Flags;
+ struct {
+ DWORD EnableBottomUpRandomization : 1;
+ DWORD EnableForceRelocateImages : 1;
+ DWORD EnableHighEntropy : 1;
+ DWORD DisallowStrippedImages : 1;
+ DWORD ReservedFlags : 28;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+} PROCESS_MITIGATION_ASLR_POLICY, *PPROCESS_MITIGATION_ASLR_POLICY;
+
+typedef struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY {
+ union {
+ DWORD Flags;
+ struct {
+ DWORD DisableExtensionPoints : 1;
+ DWORD ReservedFlags : 31;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+} PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY, *PPROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY;
+
+typedef struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY {
+ union {
+ DWORD Flags;
+ struct {
+ DWORD ProhibitDynamicCode : 1;
+ DWORD AllowThreadOptOut : 1;
+ DWORD AllowRemoteDowngrade : 1;
+ DWORD AuditProhibitDynamicCode : 1;
+ DWORD ReservedFlags : 28;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+} PROCESS_MITIGATION_DYNAMIC_CODE_POLICY, *PPROCESS_MITIGATION_DYNAMIC_CODE_POLICY;
+
+typedef enum _PROCESS_MITIGATION_POLICY {
+ ProcessDEPPolicy,
+ ProcessASLRPolicy,
+ ProcessDynamicCodePolicy,
+ ProcessStrictHandleCheckPolicy,
+ ProcessSystemCallDisablePolicy,
+ ProcessMitigationOptionsMask,
+ ProcessExtensionPointDisablePolicy,
+ ProcessControlFlowGuardPolicy,
+ ProcessSignaturePolicy,
+ ProcessFontDisablePolicy,
+ ProcessImageLoadPolicy,
+ ProcessSystemCallFilterPolicy,
+ ProcessPayloadRestrictionPolicy,
+ ProcessChildProcessPolicy,
+ ProcessSideChannelIsolationPolicy,
+ ProcessUserShadowStackPolicy,
+ MaxProcessMitigationPolicy
+} PROCESS_MITIGATION_POLICY, *PPROCESS_MITIGATION_POLICY;
+
+#endif
+
+void ActivateProcessMitigations()
+{
+ // we load the function pointer of SetProcessMitigationPolicy dynamically because we are building with Windows 7 SDK that does not have the definition of this function
+ typedef BOOL (WINAPI *SetProcessMitigationPolicyFunc) (PROCESS_MITIGATION_POLICY MitigationPolicy, PVOID lpBuffer, SIZE_T dwLength);
+ SetProcessMitigationPolicyFunc SetProcessMitigationPolicyPtr = (SetProcessMitigationPolicyFunc) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "SetProcessMitigationPolicy");
+ if (SetProcessMitigationPolicyPtr)
+ {
+ PROCESS_MITIGATION_ASLR_POLICY aslrPolicy = { 0 };
+ PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dynCodePolicy = { 0 };
+ PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY extensionPointDisablePolicy = { 0 };
+
+ aslrPolicy.EnableBottomUpRandomization = TRUE;
+ aslrPolicy.EnableForceRelocateImages = TRUE;
+ aslrPolicy.EnableHighEntropy = TRUE;
+
+ dynCodePolicy.ProhibitDynamicCode = TRUE;
+
+ extensionPointDisablePolicy.DisableExtensionPoints = TRUE;
+
+ SetProcessMitigationPolicyPtr (ProcessASLRPolicy, &aslrPolicy, sizeof (aslrPolicy));
+ SetProcessMitigationPolicyPtr (ProcessDynamicCodePolicy, &dynCodePolicy, sizeof (dynCodePolicy));
+ SetProcessMitigationPolicyPtr (ProcessExtensionPointDisablePolicy, &extensionPointDisablePolicy, sizeof (extensionPointDisablePolicy));
+ }
+}
+
// Based on sample code from:
// https://blogs.msdn.microsoft.com/aaron_margosis/2009/06/06/faq-how-do-i-start-a-program-as-the-desktop-user-from-an-elevated-app/
// start a program non-elevated as the desktop user from an elevated app
@@ -14416,12 +14449,6 @@ static bool RunAsDesktopUser(
SecureZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
- // locate CreateProcessWithTokenW in Advapi32.dll
- if (!CreateProcessWithTokenWPtr)
- {
- return false;
- }
-
if (!ImpersonateSelf (SecurityImpersonation))
{
return false;
@@ -14438,7 +14465,10 @@ static bool RunAsDesktopUser(
LookupPrivilegeValueW(NULL, SE_INCREASE_QUOTA_NAME, &tkp.Privileges[0].Luid);
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- SetThreadToken (NULL, NULL);
+ if (!SetThreadToken(NULL, NULL))
+ {
+ goto cleanup;
+ }
AdjustTokenPrivileges(hThreadToken, FALSE, &tkp, 0, NULL, NULL);
dwLastErr = GetLastError();
@@ -14496,7 +14526,7 @@ static bool RunAsDesktopUser(
}
// Start the target process with the new token.
- ret = CreateProcessWithTokenWPtr(
+ ret = CreateProcessWithTokenW(
hPrimaryToken,
0,
szApp,
@@ -14524,7 +14554,10 @@ cleanup:
if (hPrimaryToken) CloseHandle(hPrimaryToken);
if (hShellProcess) CloseHandle(hShellProcess);
if (hThreadToken) CloseHandle(hThreadToken);
- RevertToSelf ();
+
+ if (!RevertToSelf())
+ return false;
+
if (!retval)
SetLastError (dwLastErr);
return retval;
@@ -14551,6 +14584,98 @@ BOOL IsElevated()
return bReturn;
}
+// Based on code from:
+// https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/Win7Samples/winui/shell/appplatform/ExecInExplorer/ExecInExplorer.cpp
+HRESULT GetShellViewForDesktop(REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ IShellWindows *psw;
+ HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw));
+ if (SUCCEEDED(hr))
+ {
+ HWND hwnd;
+ IDispatch* pdisp;
+ VARIANT vEmpty = {}; // VT_EMPTY
+ if (S_OK == psw->FindWindowSW(&vEmpty, &vEmpty, SWC_DESKTOP, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp))
+ {
+ IShellBrowser *psb;
+ hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb));
+ if (SUCCEEDED(hr))
+ {
+ IShellView *psv;
+ hr = psb->QueryActiveShellView(&psv);
+ if (SUCCEEDED(hr))
+ {
+ hr = psv->QueryInterface(riid, ppv);
+ psv->Release();
+ }
+ psb->Release();
+ }
+ pdisp->Release();
+ }
+ else
+ {
+ hr = E_FAIL;
+ }
+ psw->Release();
+ }
+ return hr;
+}
+
+HRESULT GetShellDispatchFromView(IShellView *psv, REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+
+ IDispatch *pdispBackground;
+ HRESULT hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground));
+ if (SUCCEEDED(hr))
+ {
+ IShellFolderViewDual *psfvd;
+ hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd));
+ if (SUCCEEDED(hr))
+ {
+ IDispatch *pdisp;
+ hr = psfvd->get_Application(&pdisp);
+ if (SUCCEEDED(hr))
+ {
+ hr = pdisp->QueryInterface(riid, ppv);
+ pdisp->Release();
+ }
+ psfvd->Release();
+ }
+ pdispBackground->Release();
+ }
+ return hr;
+}
+
+HRESULT ShellExecInExplorerProcess(PCWSTR pszFile)
+{
+ IShellView *psv;
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ HRESULT hr = GetShellViewForDesktop(IID_PPV_ARGS(&psv));
+ if (SUCCEEDED(hr))
+ {
+ IShellDispatch2 *psd;
+ hr = GetShellDispatchFromView(psv, IID_PPV_ARGS(&psd));
+ if (SUCCEEDED(hr))
+ {
+ BSTR bstrFile = SysAllocString(pszFile);
+ hr = bstrFile ? S_OK : E_OUTOFMEMORY;
+ if (SUCCEEDED(hr))
+ {
+ VARIANT vtEmpty = {}; // VT_EMPTY
+ hr = psd->ShellExecuteW(bstrFile, vtEmpty, vtEmpty, vtEmpty, vtEmpty);
+ SysFreeString(bstrFile);
+ }
+ psd->Release();
+ }
+ psv->Release();
+ }
+ CoUninitialize();
+ return hr;
+}
+
// This function always loads a URL in a non-privileged mode
// If current process has admin privileges, we execute the command "rundll32 url.dll,FileProtocolHandler URL" as non-elevated
// Use this security mechanism only starting from Windows Vista and only if we can get the window of the Shell's desktop since
@@ -14558,7 +14683,8 @@ BOOL IsElevated()
// then we can't protect the user in such non standard environment
void SafeOpenURL (LPCWSTR szUrl)
{
- if (IsOSAtLeast (WIN_VISTA) && IsAdmin () && IsElevated() && GetShellWindow())
+ BOOL bFallback = TRUE;
+ if (IsUacSupported() && IsAdmin () && IsElevated() && GetShellWindow())
{
WCHAR szRunDllPath[TC_MAX_PATH];
WCHAR szUrlDllPath[TC_MAX_PATH];
@@ -14572,11 +14698,23 @@ void SafeOpenURL (LPCWSTR szUrl)
StringCbPrintfW(szUrlDllPath, sizeof(szUrlDllPath), L"%s\\%s", szSystemPath, L"url.dll");
StringCchPrintfW(szCommandLine, 1024, L"%s %s,FileProtocolHandler %s", szRunDllPath, szUrlDllPath, szUrl);
- RunAsDesktopUser (NULL, szCommandLine);
+ if (RunAsDesktopUser (NULL, szCommandLine))
+ {
+ bFallback = FALSE;
+ }
+ else
+ {
+ // fallback to IShellDispatch2::ShellExecuteW
+ if (SUCCEEDED(ShellExecInExplorerProcess(szUrl)))
+ {
+ bFallback = FALSE;
+ }
+ }
delete [] szCommandLine;
}
- else
+
+ if (bFallback)
{
ShellExecuteW (NULL, L"open", szUrl, NULL, NULL, SW_SHOWNORMAL);
}
@@ -14686,69 +14824,49 @@ BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter)
{
HRESULT hr;
BitLockerEncryptionStatus blStatus = BL_Status_Unknown;
- wchar_t szDllPath[MAX_PATH] = { 0 };
- HMODULE hShell32 = NULL;
+ wchar_t szDllPath[MAX_PATH] = { 0 };
+ HMODULE hPropsys = NULL;
- CoInitialize(NULL);
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (GetSystemDirectory(szDllPath, MAX_PATH))
- StringCchCatW(szDllPath, MAX_PATH, L"\\Shell32.dll");
+ StringCchCatW(szDllPath, MAX_PATH, L"\\Propsys.dll");
else
- StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Shell32.dll");
+ StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Propsys.dll");
- hShell32 = LoadLibrary(szDllPath);
- if (hShell32)
+ hPropsys = LoadLibrary(szDllPath);
+ if (hPropsys)
{
- SHCreateItemFromParsingNameFn SHCreateItemFromParsingNamePtr = (SHCreateItemFromParsingNameFn)GetProcAddress(hShell32, "SHCreateItemFromParsingName");
- if (SHCreateItemFromParsingNamePtr)
+ PSGetPropertyKeyFromNameFn PSGetPropertyKeyFromNamePtr = (PSGetPropertyKeyFromNameFn)GetProcAddress(hPropsys, "PSGetPropertyKeyFromName");
+ if (PSGetPropertyKeyFromNamePtr)
{
- HMODULE hPropsys = NULL;
-
- if (GetSystemDirectory(szDllPath, MAX_PATH))
- StringCchCatW(szDllPath, MAX_PATH, L"\\Propsys.dll");
- else
- StringCchCopyW(szDllPath, MAX_PATH, L"C:\\Windows\\System32\\Propsys.dll");
-
- hPropsys = LoadLibrary(szDllPath);
- if (hPropsys)
- {
- PSGetPropertyKeyFromNameFn PSGetPropertyKeyFromNamePtr = (PSGetPropertyKeyFromNameFn)GetProcAddress(hPropsys, "PSGetPropertyKeyFromName");
- if (PSGetPropertyKeyFromNamePtr)
- {
- WCHAR parsingName[3] = {driveLetter, L':', 0};
- IShellItem2* drive = NULL;
- hr = SHCreateItemFromParsingNamePtr(parsingName, NULL, IID_PPV_ARGS(&drive));
+ WCHAR parsingName[3] = {driveLetter, L':', 0};
+ IShellItem2* drive = NULL;
+ hr = SHCreateItemFromParsingName(parsingName, NULL, IID_PPV_ARGS(&drive));
+ if (SUCCEEDED(hr)) {
+ PROPERTYKEY pKey;
+ hr = PSGetPropertyKeyFromNamePtr(L"System.Volume.BitLockerProtection", &pKey);
+ if (SUCCEEDED(hr)) {
+ PROPVARIANT prop;
+ PropVariantInit(&prop);
+ hr = drive->GetProperty(pKey, &prop);
if (SUCCEEDED(hr)) {
- PROPERTYKEY pKey;
- hr = PSGetPropertyKeyFromNamePtr(L"System.Volume.BitLockerProtection", &pKey);
- if (SUCCEEDED(hr)) {
- PROPVARIANT prop;
- PropVariantInit(&prop);
- hr = drive->GetProperty(pKey, &prop);
- if (SUCCEEDED(hr)) {
- int status = prop.intVal;
- if (status == BL_State_FullyEncrypted || status == BL_State_DecryptionInProgress || status == BL_State_DecryptionSuspended)
- blStatus = BL_Status_Protected;
- else
- blStatus = BL_Status_Unprotected;
- }
- }
+ int status = prop.intVal;
+ if (status == BL_State_FullyEncrypted || status == BL_State_DecryptionInProgress || status == BL_State_DecryptionSuspended)
+ blStatus = BL_Status_Protected;
+ else
+ blStatus = BL_Status_Unprotected;
}
- if (drive)
- drive->Release();
}
-
- FreeLibrary(hPropsys);
}
- }
- else
- {
- blStatus = BL_Status_Unprotected; // before Vista, there was no Bitlocker
+ if (drive)
+ drive->Release();
}
- FreeLibrary(hShell32);
+ FreeLibrary(hPropsys);
}
+
CoUninitialize();
return blStatus;
}
@@ -14827,7 +14945,7 @@ ULONG GenericDropTarget::Release(void)
BOOL GenericDropTarget::Register(HWND hWnd)
{
if(NULL == hWnd)
- return E_FAIL;
+ return FALSE;
OleInitialize(NULL);
@@ -15048,7 +15166,7 @@ DWORD PasswordEditDropTarget::GotEnter(void)
HWND hChild = WindowFromPoint (m_DropPoint);
// check that we are on password edit control (we use maximum length to correctly identify password fields since they don't always have ES_PASSWORD style (if the the user checked show password)
if (hChild && GetClassName (hChild, szClassName, ARRAYSIZE (szClassName)) && (0 == _tcsicmp (szClassName, _T("EDIT")))
- && (dwStyles = GetWindowLong (hChild, GWL_STYLE)) && !(dwStyles & ES_NUMBER)
+ && (dwStyles = GetWindowLongPtr (hChild, GWL_STYLE)) && !(dwStyles & ES_NUMBER)
&& (maxLen = (int) SendMessage (hChild, EM_GETLIMITTEXT, 0, 0)) && (maxLen == MAX_PASSWORD || maxLen == MAX_LEGACY_PASSWORD)
)
{
@@ -15073,7 +15191,7 @@ void PasswordEditDropTarget::GotDrop(CLIPFORMAT format)
int maxLen;
HWND hChild = WindowFromPoint (m_DropPoint);
if (hChild && GetClassName (hChild, szClassName, ARRAYSIZE (szClassName)) && (0 == _tcsicmp (szClassName, _T("EDIT")))
- && (dwStyles = GetWindowLong (hChild, GWL_STYLE)) && !(dwStyles & ES_NUMBER)
+ && (dwStyles = GetWindowLongPtr (hChild, GWL_STYLE)) && !(dwStyles & ES_NUMBER)
&& (maxLen = (int) SendMessage (hChild, EM_GETLIMITTEXT, 0, 0)) && (maxLen == MAX_PASSWORD || maxLen == MAX_LEGACY_PASSWORD)
)
{
@@ -15157,6 +15275,33 @@ void PasswordEditDropTarget::GotDrop(CLIPFORMAT format)
}
+// check if the PC is connected to the internet using INetworkListManager interface
+BOOL IsInternetConnected()
+{
+ HRESULT hr;
+ BOOL isConnected = FALSE;
+ INetworkListManager* pNetworkListManager = nullptr;
+
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (SUCCEEDED(hr))
+ {
+ hr = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pNetworkListManager));
+ if (SUCCEEDED(hr))
+ {
+ VARIANT_BOOL isConnectedVariant;
+ hr = pNetworkListManager->get_IsConnectedToInternet(&isConnectedVariant);
+ if (SUCCEEDED(hr))
+ {
+ isConnected = isConnectedVariant == VARIANT_TRUE;
+ }
+ pNetworkListManager->Release();
+ }
+ CoUninitialize();
+ }
+
+ return isConnected;
+}
+
/*
* Query the status of Hibernate and Fast Startup
*/
@@ -15233,3 +15378,301 @@ BOOL GetHibernateStatus (BOOL& bHibernateEnabled, BOOL& bHiberbootEnabled)
return bResult;
}
+/* return TRUE if Windows is in Test Signing mode */
+/* ref: https://social.msdn.microsoft.com/Forums/Windowsapps/en-US/e6c1be93-7003-4594-b8e4-18ab4a75d273/detecting-testsigning-onoff-via-api */
+BOOL IsTestSigningModeEnabled ()
+{
+ BOOL bEnabled = FALSE;
+ NtQuerySystemInformationFn NtQuerySystemInformationPtr = (NtQuerySystemInformationFn) GetProcAddress (GetModuleHandle (L"ntdll.dll"), "NtQuerySystemInformation");
+ if(NtQuerySystemInformationPtr)
+ {
+ SYSTEM_CODEINTEGRITY_INFORMATION info = {0};
+ ULONG cbReturnedData = 0;
+ info.Length = sizeof(info);
+ if ( (NtQuerySystemInformationPtr((SYSTEM_INFORMATION_CLASS) SYSTEMCODEINTEGRITYINFORMATION, &info, sizeof(info), &cbReturnedData) >= 0)
+ && (cbReturnedData == sizeof(info))
+ )
+ {
+ if ((info.CodeIntegrityOptions & (CODEINTEGRITY_OPTION_TESTSIGN | CODEINTEGRITY_OPTION_ENABLED)) == (CODEINTEGRITY_OPTION_TESTSIGN | CODEINTEGRITY_OPTION_ENABLED))
+ {
+ bEnabled = TRUE;
+ }
+ }
+ }
+
+ return bEnabled;
+}
+
+// Adapted from https://docs.microsoft.com/en-us/windows/win32/wmisdk/example-creating-a-wmi-application
+bool GetKbList (std::vector<std::wstring>& kbList)
+{
+ HRESULT hres;
+ kbList.clear();
+
+ // Initialize COM.
+ hres = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (FAILED(hres))
+ {
+ return false;
+ }
+
+ // Initialize
+ hres = CoInitializeSecurity(
+ NULL,
+ -1, // COM negotiates service
+ NULL, // Authentication services
+ NULL, // Reserved
+ RPC_C_AUTHN_LEVEL_DEFAULT, // authentication
+ RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation
+ NULL, // Authentication info
+ EOAC_NONE, // Additional capabilities
+ NULL // Reserved
+ );
+
+
+ if (FAILED(hres))
+ {
+ CoUninitialize();
+ return false;
+ }
+
+ // Obtain the initial locator to Windows Management
+ // on a particular host computer.
+ IWbemLocator *pLoc = 0;
+
+ hres = CoCreateInstance(
+ CLSID_WbemLocator,
+ 0,
+ CLSCTX_INPROC_SERVER,
+ IID_IWbemLocator, (LPVOID *) &pLoc);
+
+ if (FAILED(hres))
+ {
+ CoUninitialize();
+ return false;
+ }
+
+ IWbemServices *pSvc = 0;
+
+ // Connect to the root\cimv2 namespace with the
+ // current user and obtain pointer pSvc
+ // to make IWbemServices calls.
+
+ hres = pLoc->ConnectServer(
+
+ _bstr_t(L"ROOT\\CIMV2"), // WMI namespace
+ NULL, // User name
+ NULL, // User password
+ 0, // Locale
+ NULL, // Security flags
+ 0, // Authority
+ 0, // Context object
+ &pSvc // IWbemServices proxy
+ );
+
+ if (FAILED(hres))
+ {
+ pLoc->Release();
+ CoUninitialize();
+ return false;
+ }
+
+ // Set the IWbemServices proxy so that impersonation
+ // of the user (client) occurs.
+ hres = CoSetProxyBlanket(
+
+ pSvc, // the proxy to set
+ RPC_C_AUTHN_WINNT, // authentication service
+ RPC_C_AUTHZ_NONE, // authorization service
+ NULL, // Server principal name
+ RPC_C_AUTHN_LEVEL_CALL, // authentication level
+ RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
+ NULL, // client identity
+ EOAC_NONE // proxy capabilities
+ );
+
+ if (FAILED(hres))
+ {
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return false;
+ }
+
+
+ // Use the IWbemServices pointer to make requests of WMI.
+ // Make requests here:
+
+ // query for all installed KBs
+ IEnumWbemClassObject* pEnumerator = NULL;
+ hres = pSvc->ExecQuery(
+ bstr_t("WQL"),
+ bstr_t("SELECT * FROM Win32_QuickFixEngineering"),
+ WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
+ NULL,
+ &pEnumerator);
+
+ if (FAILED(hres))
+ {
+ pSvc->Release();
+ pLoc->Release();
+ CoUninitialize();
+ return false;
+ }
+ else
+ {
+ IWbemClassObject *pclsObj;
+ ULONG uReturn = 0;
+
+ while (pEnumerator)
+ {
+ hres = pEnumerator->Next(WBEM_INFINITE, 1,
+ &pclsObj, &uReturn);
+
+ if(0 == uReturn)
+ {
+ break;
+ }
+
+ VARIANT vtProp;
+
+ // Get the value of the "hotfixid" property
+ hres = pclsObj->Get(L"hotfixid", 0, &vtProp, 0, 0);
+ if (SUCCEEDED(hres) && (V_VT(&vtProp) == VT_BSTR))
+ {
+ kbList.push_back(vtProp.bstrVal);
+ }
+ VariantClear(&vtProp);
+
+ pclsObj->Release();
+ pclsObj = NULL;
+ }
+
+ }
+
+ // Cleanup
+ // ========
+
+ pSvc->Release();
+ pLoc->Release();
+ pEnumerator->Release();
+
+ CoUninitialize();
+
+ return true;
+}
+
+bool OneOfKBsInstalled (const wchar_t* szKBs[], int count)
+{
+ std::vector<std::wstring> kbList;
+ bool bRet = GetKbList(kbList);
+ if (bRet)
+ {
+ // at least one of the given KBs must be present
+ bool bFound = false;
+
+ for (size_t j = 0; j < kbList.size(); j++)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (_wcsicmp(szKBs[i], kbList[j].c_str()) == 0)
+ {
+ bFound = true;
+ break;
+ }
+ }
+
+ if (bFound)
+ {
+ break;
+ }
+ }
+
+ bRet = bFound;
+ }
+
+ return bRet;
+}
+
+DWORD SendServiceNotification (DWORD dwNotificationCmd)
+{
+ DWORD dwRet = ERROR_INVALID_PARAMETER;
+ // We only support clearing keys on new device insertion
+ if (VC_DRIVER_CONFIG_CLEAR_KEYS_ON_NEW_DEVICE_INSERTION == dwNotificationCmd)
+ {
+ DWORD dwServiceControlCode = VC_SERVICE_CONTROL_BUILD_DEVICE_LIST;
+ // send this control code to VeraCrypt SystemFavorites service
+ SC_HANDLE hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
+ if (hSCManager != NULL)
+ {
+ SC_HANDLE hService = OpenService (hSCManager, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (hService != NULL)
+ {
+ SERVICE_STATUS ss;
+ if (ControlService (hService, dwServiceControlCode, &ss))
+ dwRet = ERROR_SUCCESS;
+ else
+ dwRet = GetLastError ();
+ CloseServiceHandle (hService);
+ }
+ else
+ dwRet = GetLastError ();
+ CloseServiceHandle (hSCManager);
+ }
+ else
+ dwRet = GetLastError ();
+ }
+
+ return dwRet;
+}
+
+DWORD FastResizeFile (const wchar_t* filePath, __int64 fileSize)
+{
+ DWORD dwRet = ERROR_INVALID_PARAMETER;
+ if (filePath && fileSize > 0)
+ {
+ // we set required privileges to speedup file creation before we create the file so that the file handle inherits the privileges
+ BOOL bPrivilegesSet = IsPrivilegeEnabled (SE_MANAGE_VOLUME_NAME);
+ if (!bPrivilegesSet && !SetPrivilege(SE_MANAGE_VOLUME_NAME, TRUE))
+ {
+ dwRet = GetLastError ();
+ }
+ else
+ {
+ HANDLE dev = CreateFile (filePath, GENERIC_WRITE | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (dev != INVALID_HANDLE_VALUE)
+ {
+ LARGE_INTEGER liSize;
+ liSize.QuadPart = fileSize;
+ // Preallocate the file with desired size
+ if (!SetFilePointerEx (dev, liSize, NULL, FILE_BEGIN)
+ || !SetEndOfFile (dev))
+ {
+ dwRet = GetLastError ();
+ }
+ else
+ {
+ if (!SetFileValidData (dev, fileSize))
+ {
+ dwRet = GetLastError ();
+ }
+ else
+ {
+ dwRet = ERROR_SUCCESS;
+ }
+ }
+
+ FlushFileBuffers (dev);
+ CloseHandle (dev);
+ }
+ else
+ dwRet = GetLastError ();
+
+ if (!bPrivilegesSet)
+ SetPrivilege(SE_MANAGE_VOLUME_NAME, FALSE);
+ }
+ }
+
+ return dwRet;
+}
+#endif // VC_COMREG