From 4519bb494e7c88890aa0022d4aaabffb0b6d8faf Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Mon, 16 Apr 2018 23:48:54 +0200 Subject: Windows: implement compatibility for Windows 10 major updates using ReflectDrivers mechanism whose support started from Windows 10 version 1607. --- src/Common/BaseCom.cpp | 24 ++++++++ src/Common/BaseCom.h | 1 + src/Common/BootEncryption.cpp | 59 ++++++++++++++++++++ src/Common/BootEncryption.h | 2 +- src/Common/Dlgcode.c | 125 ++++++++++++++++++++++++++++++++++++++++++ src/Common/Dlgcode.h | 3 + 6 files changed, 213 insertions(+), 1 deletion(-) (limited to 'src/Common') diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp index e8c75a68..738e44cf 100644 --- a/src/Common/BaseCom.cpp +++ b/src/Common/BaseCom.cpp @@ -429,5 +429,29 @@ DWORD BaseCom::WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMe return ERROR_EXCEPTION_IN_SERVICE; } + return ERROR_SUCCESS; +} + +DWORD BaseCom::UpdateSetupConfigFile (BOOL bForInstall) +{ + try + { + BootEncryption bootEnc (NULL); + bootEnc.UpdateSetupConfigFile (bForInstall? true : false); + } + catch (SystemException &) + { + return GetLastError(); + } + catch (Exception &e) + { + e.Show (NULL); + return ERROR_EXCEPTION_IN_SERVICE; + } + catch (...) + { + return ERROR_EXCEPTION_IN_SERVICE; + } + return ERROR_SUCCESS; } \ No newline at end of file diff --git a/src/Common/BaseCom.h b/src/Common/BaseCom.h index e91f75af..eb89dd8e 100644 --- a/src/Common/BaseCom.h +++ b/src/Common/BaseCom.h @@ -117,6 +117,7 @@ public: static DWORD RestoreEfiSystemLoader (); static DWORD GetEfiBootDeviceNumber (BSTR* pSdn); static DWORD WriteEfiBootSectorUserConfig (DWORD userConfig, BSTR customUserMessage, int pim, int hashAlg); + static DWORD UpdateSetupConfigFile (BOOL bForInstall); }; diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index 55eafb75..b57f5c28 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -396,6 +396,18 @@ namespace VeraCrypt } } + static void UpdateSetupConfigFile (bool bForInstall) + { + Elevate(); + + DWORD result = ElevatedComInstance->UpdateSetupConfigFile (bForInstall ? TRUE : FALSE); + if (result != ERROR_SUCCESS) + { + SetLastError (result); + throw SystemException(SRC_POS); + } + } + static void Release () { if (--ReferenceCount == 0 && ElevatedComInstance) @@ -470,6 +482,7 @@ namespace VeraCrypt static void RestoreEfiSystemLoader () { throw ParameterIncorrect (SRC_POS); } static void GetEfiBootDeviceNumber (PSTORAGE_DEVICE_NUMBER pSdn) { throw ParameterIncorrect (SRC_POS); } static void WriteEfiBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim, int hashAlg) { throw ParameterIncorrect (SRC_POS); } + static void UpdateSetupConfigFile (bool bForInstall) { throw ParameterIncorrect (SRC_POS); } }; #endif // SETUP @@ -2685,6 +2698,27 @@ namespace VeraCrypt return conf.Save (path.c_str(), hwndDlg); } + void BootEncryption::UpdateSetupConfigFile (bool bForInstall) + { + // starting from Windows 10 1607 (Build 14393), ReflectDrivers in Setupconfig.ini is supported + if (IsOSVersionAtLeast (WIN_10, 0) && CurrentOSBuildNumber >= 14393) + { + wchar_t szInstallPath [TC_MAX_PATH]; + wchar_t szSetupconfigLocation [TC_MAX_PATH + 20]; + + if (bForInstall) + GetInstallationPath (NULL, szInstallPath, ARRAYSIZE (szInstallPath), NULL); + if (GetSetupconfigLocation (szSetupconfigLocation, ARRAYSIZE (szSetupconfigLocation))) + { + ::CreateDirectoryW (szSetupconfigLocation, NULL); + + StringCchCatW (szSetupconfigLocation, ARRAYSIZE (szSetupconfigLocation), L"SetupConfig.ini"); + + WritePrivateProfileStringW (L"SetupConfig", L"ReflectDrivers", bForInstall? szInstallPath : NULL, szSetupconfigLocation); + } + } + } + void BootEncryption::InstallBootLoader (bool preserveUserConfig, bool hiddenOSCreation, int pim, int hashAlg) { Device device (GetSystemDriveConfiguration().DevicePath); @@ -2851,6 +2885,15 @@ namespace VeraCrypt device.SeekAt (TC_SECTOR_SIZE_BIOS); device.Write (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, sizeof (bootLoaderBuf) - TC_SECTOR_SIZE_BIOS); } + + if (!IsAdmin() && IsUacSupported()) + { + Elevator::UpdateSetupConfigFile (true); + } + else + { + UpdateSetupConfigFile (true); + } } #ifndef SETUP @@ -3786,6 +3829,22 @@ namespace VeraCrypt device.SeekAt (0); device.Write (bootLoaderBuf, sizeof (bootLoaderBuf)); } + + // starting from Windows 10 1607 (Build 14393), ReflectDrivers in Setupconfig.ini is supported + if (IsOSVersionAtLeast (WIN_10, 0) && CurrentOSBuildNumber >= 14393) + { + wchar_t szSetupconfigLocation [TC_MAX_PATH + 20]; + + if (GetSetupconfigLocation (szSetupconfigLocation, ARRAYSIZE (szSetupconfigLocation))) + { + StringCchCatW (szSetupconfigLocation, ARRAYSIZE (szSetupconfigLocation), L"SetupConfig.ini"); + + if (FileExists (szSetupconfigLocation)) + { + WritePrivateProfileStringW (L"SetupConfig", L"ReflectDrivers", NULL, szSetupconfigLocation); + } + } + } } #endif // SETUP diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h index f63ec541..6eb42b50 100644 --- a/src/Common/BootEncryption.h +++ b/src/Common/BootEncryption.h @@ -310,7 +310,7 @@ namespace VeraCrypt void GetEfiBootDeviceNumber (PSTORAGE_DEVICE_NUMBER pSdn); void BackupSystemLoader (); void RestoreSystemLoader (); - + void UpdateSetupConfigFile (bool bForInstall); protected: static const uint32 RescueIsoImageSize = 1835008; // Size of ISO9660 image with bootable emulated 1.44MB floppy disk image diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 347f1207..03e0d6c8 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -147,6 +147,7 @@ OSVersionEnum nCurrentOS = WIN_UNKNOWN; int CurrentOSMajor = 0; int CurrentOSMinor = 0; int CurrentOSServicePack = 0; +int CurrentOSBuildNumber = 0; BOOL RemoteSession = FALSE; BOOL UacElevated = FALSE; @@ -344,6 +345,13 @@ static unsigned char gpbSha1CodeSignCertFingerprint[64] = { 0x40, 0xCE, 0x17, 0x6C }; +typedef HRESULT (WINAPI *SHGETKNOWNFOLDERPATH) ( + _In_ REFKNOWNFOLDERID rfid, + _In_ DWORD dwFlags, + _In_opt_ HANDLE hToken, + _Out_ PWSTR *ppszPath +); + /* Windows dialog class */ #define WINDOWS_DIALOG_CLASS L"#32770" @@ -2663,6 +2671,7 @@ void InitOSVersionInfo () 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; @@ -13520,3 +13529,119 @@ BOOL VerifyModuleSignature (const wchar_t* path) return bResult; } + +void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, BOOL* pbInstallPathDetermined) +{ + HKEY hkey; + BOOL bInstallPathDetermined = FALSE; + wchar_t path[MAX_PATH+20]; + ITEMIDLIST *itemList; + + memset (szInstallPath, 0, cchSize * sizeof (wchar_t)); + + // Determine if VeraCrypt is already installed and try to determine its "Program Files" location + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", 0, KEY_READ | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS) + { + /* Default 'UninstallString' registry strings written by VeraCrypt: + ------------------------------------------------------------------------------------ + 5.0+ "C:\Program Files\VeraCrypt\VeraCrypt Setup.exe" /u + */ + + wchar_t rv[MAX_PATH*4]; + DWORD size = sizeof (rv); + if (RegQueryValueEx (hkey, L"UninstallString", 0, 0, (LPBYTE) &rv, &size) == ERROR_SUCCESS && wcsrchr (rv, L'/')) + { + size_t len = 0; + + // Cut and paste the location (path) where VeraCrypt is installed to InstallationPath + if (rv[0] == L'"') + { + len = wcsrchr (rv, L'/') - rv - 2; + StringCchCopyNW (szInstallPath, cchSize, rv + 1, len); + szInstallPath [len] = 0; + bInstallPathDetermined = TRUE; + + if (szInstallPath [wcslen (szInstallPath) - 1] != L'\\') + { + len = wcsrchr (szInstallPath, L'\\') - szInstallPath; + szInstallPath [len] = 0; + } + } + + } + RegCloseKey (hkey); + } + + if (!bInstallPathDetermined) + { + /* VeraCrypt is not installed or it wasn't possible to determine where it is installed. */ + + // Default "Program Files" path. + SHGetSpecialFolderLocation (hwndDlg, CSIDL_PROGRAM_FILES, &itemList); + SHGetPathFromIDList (itemList, path); + + if (Is64BitOs()) + { + // Use a unified default installation path (registry redirection of %ProgramFiles% does not work if the installation path is user-selectable) + wstring s = path; + size_t p = s.find (L" (x86)"); + if (p != wstring::npos) + { + s = s.substr (0, p); + if (_waccess (s.c_str(), 0) != -1) + StringCbCopyW (path, sizeof (path), s.c_str()); + } + } + + StringCbCatW (path, sizeof(path), L"\\VeraCrypt\\"); + StringCbCopyW (szInstallPath, cchSize, path); + } + + // Make sure the path ends with a backslash + if (szInstallPath [wcslen (szInstallPath) - 1] != L'\\') + { + StringCbCatW (szInstallPath, cchSize, L"\\"); + } + + if (pbInstallPathDetermined) + *pbInstallPathDetermined = bInstallPathDetermined; +} + +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) + { + 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); + } + + if (!bResult && CurrentOSMajor >= 10) + { + StringCchPrintfW (path, cchSize, L"%c:\\Users\\Default\\AppData\\Local\\Microsoft\\Windows\\WSUS\\", szShell32Path[0]); + bResult = TRUE; + } + + return bResult; +} diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 5d10db35..ea2828fd 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -135,6 +135,7 @@ extern OSVersionEnum nCurrentOS; extern int CurrentOSMajor; extern int CurrentOSMinor; extern int CurrentOSServicePack; +extern int CurrentOSBuildNumber; extern BOOL RemoteSession; extern HANDLE hDriver; extern HINSTANCE hInst; @@ -529,6 +530,8 @@ BOOL RaisePrivileges(void); BOOL DeleteDirectory (const wchar_t* szDirName); INT_PTR SecureDesktopDialogBoxParam (HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM); BOOL VerifyModuleSignature (const wchar_t* path); +void GetInstallationPath (HWND hwndDlg, wchar_t* szInstallPath, DWORD cchSize, BOOL* pbInstallPathDetermined); +BOOL GetSetupconfigLocation (wchar_t* path, DWORD cchSize); #ifdef __cplusplus } -- cgit v1.2.3