From ee79ff0579e25eca9189d72019e5361404437794 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Mon, 22 Mar 2021 07:59:32 +0100 Subject: [PATCH] Windows: first implementation of MSI installer for silent mode deployment (ACCEPTLICENSE=YES must be set in msiexec command line) --- src/Common/Dlgcode.c | 43 +- src/Release/Setup Files/Custom_InstallDir.wxs | 83 + .../Setup Files/Custom_InstallDirDlg.wxs | 45 + src/Release/Setup Files/Product64.wxs | 1709 ++++++++ src/Release/Setup Files/Strings-en.wxl | 24 + src/Release/Setup Files/build_msi_x64.bat | 178 + src/Setup/Setup.vcxproj | 3 +- src/SetupDLL/ComSetup.cpp | 114 + src/SetupDLL/ComSetup.h | 22 + src/SetupDLL/ComSetup.rgs | 92 + src/SetupDLL/Dir.c | 110 + src/SetupDLL/Dir.h | 23 + src/SetupDLL/Portable.manifest | 33 + src/SetupDLL/Portable.rc | 291 ++ src/SetupDLL/Portable.vcxproj | 281 ++ src/SetupDLL/Portable.vcxproj.filters | 154 + src/SetupDLL/Portable.vcxproj.user | 3 + src/SetupDLL/Resource.h | 81 + src/SetupDLL/Setup.c | 3620 +++++++++++++++++ src/SetupDLL/Setup.h | 137 + src/SetupDLL/Setup.ico | Bin 0 -> 370070 bytes src/SetupDLL/Setup.manifest | 33 + src/SetupDLL/Setup.rc | 367 ++ src/SetupDLL/Setup.vcxproj.filters | 162 + src/SetupDLL/Setup.vcxproj.user | 3 + src/SetupDLL/SetupDLL.def | 7 + src/SetupDLL/SetupDLL.vcproj | 484 +++ src/SetupDLL/SetupDLL.vcxproj | 279 ++ src/SetupDLL/SetupDLL.vcxproj.filters | 150 + src/SetupDLL/SetupDLL.vcxproj.user | 3 + src/SetupDLL/VeraCrypt_setup.bmp | Bin 0 -> 49398 bytes src/SetupDLL/VeraCrypt_setup_background.bmp | Bin 0 -> 822 bytes src/Signing/sign-sha256.bat | 27 +- src/Signing/sign.bat | 38 +- src/Signing/sign_test.bat | 33 +- src/Signing/sign_test_debug.bat | 33 +- src/VeraCrypt.sln | 100 + 37 files changed, 8713 insertions(+), 52 deletions(-) create mode 100644 src/Release/Setup Files/Custom_InstallDir.wxs create mode 100644 src/Release/Setup Files/Custom_InstallDirDlg.wxs create mode 100644 src/Release/Setup Files/Product64.wxs create mode 100644 src/Release/Setup Files/Strings-en.wxl create mode 100644 src/Release/Setup Files/build_msi_x64.bat create mode 100644 src/SetupDLL/ComSetup.cpp create mode 100644 src/SetupDLL/ComSetup.h create mode 100644 src/SetupDLL/ComSetup.rgs create mode 100644 src/SetupDLL/Dir.c create mode 100644 src/SetupDLL/Dir.h create mode 100644 src/SetupDLL/Portable.manifest create mode 100644 src/SetupDLL/Portable.rc create mode 100644 src/SetupDLL/Portable.vcxproj create mode 100644 src/SetupDLL/Portable.vcxproj.filters create mode 100644 src/SetupDLL/Portable.vcxproj.user create mode 100644 src/SetupDLL/Resource.h create mode 100644 src/SetupDLL/Setup.c create mode 100644 src/SetupDLL/Setup.h create mode 100644 src/SetupDLL/Setup.ico create mode 100644 src/SetupDLL/Setup.manifest create mode 100644 src/SetupDLL/Setup.rc create mode 100644 src/SetupDLL/Setup.vcxproj.filters create mode 100644 src/SetupDLL/Setup.vcxproj.user create mode 100644 src/SetupDLL/SetupDLL.def create mode 100644 src/SetupDLL/SetupDLL.vcproj create mode 100644 src/SetupDLL/SetupDLL.vcxproj create mode 100644 src/SetupDLL/SetupDLL.vcxproj.filters create mode 100644 src/SetupDLL/SetupDLL.vcxproj.user create mode 100644 src/SetupDLL/VeraCrypt_setup.bmp create mode 100644 src/SetupDLL/VeraCrypt_setup_background.bmp diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 179ea217..2e0b507a 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -9523,8 +9523,11 @@ BOOL PrintHardCopyTextUTF16 (wchar_t *text, wchar_t *title, size_t textByteLen) BOOL IsNonInstallMode () { - HKEY hkey; + HKEY hkey, hkeybis; DWORD dw; + WCHAR szBuffer[512]; + DWORD dwBufferSize = sizeof(szBuffer); + std::wstring msiProductGUID; if (bPortableModeConfirmed) return TRUE; @@ -9582,6 +9585,29 @@ BOOL IsNonInstallMode () CloseHandle (hDriverTmp); } + // The following test checks whether the MSI is installed, which means we're not in portable mode. + // The ProductGUID is read from registry. + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt_MSI", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS || + RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt_MSI", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) + { + if (ERROR_SUCCESS == RegQueryValueExW(hkey, L"ProductGuid", 0, NULL, (LPBYTE)szBuffer, &dwBufferSize)) + { + msiProductGUID = szBuffer; + + std::wstring regKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"; + regKey += msiProductGUID; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey.c_str(), 0, KEY_READ | KEY_WOW64_32KEY, &hkeybis) == ERROR_SUCCESS || + RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKey.c_str(), 0, KEY_READ, &hkeybis) == ERROR_SUCCESS) + { + RegCloseKey(hkeybis); + return FALSE; + } + } + + RegCloseKey(hkey); + } + // The following test may be unreliable in some cases (e.g. after the user selects restore "Last Known Good // Configuration" from the Windows boot menu). if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", 0, KEY_READ | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS) @@ -11335,12 +11361,21 @@ BYTE *MapResource (wchar_t *resourceType, int resourceId, PDWORD size) { HGLOBAL hResL; HRSRC hRes; + HINSTANCE hResInst = NULL; - hRes = FindResource (NULL, MAKEINTRESOURCE(resourceId), resourceType); - hResL = LoadResource (NULL, hRes); +#ifdef SETUP_DLL + // In case we're being called from the SetupDLL project, FindResource() + // and LoadResource() with NULL will fail since we're in a DLL. We need + // to call them with the HINSTANCE of the DLL instead, which we set in + // Setup.c of SetupDLL, DllMain() function. + hResInst = hInst; +#endif + + hRes = FindResource (hResInst, MAKEINTRESOURCE(resourceId), resourceType); + hResL = LoadResource (hResInst, hRes); if (size != NULL) - *size = SizeofResource (NULL, hRes); + *size = SizeofResource (hResInst, hRes); return (BYTE *) LockResource (hResL); } diff --git a/src/Release/Setup Files/Custom_InstallDir.wxs b/src/Release/Setup Files/Custom_InstallDir.wxs new file mode 100644 index 00000000..3c9563fd --- /dev/null +++ b/src/Release/Setup Files/Custom_InstallDir.wxs @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + "1"]]> + + 1 + + NOT Installed + Installed AND PATCH + + 1 + + 1 + LicenseAccepted = "1" + + 1 + 1 + NOT WIXUI_DONTVALIDATEPATH + "1"]]> + WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1" + 1 + 1 + + NOT Installed + Installed AND NOT PATCH + Installed AND PATCH + + 1 + + 1 + 1 + 1 + + + + + + + diff --git a/src/Release/Setup Files/Custom_InstallDirDlg.wxs b/src/Release/Setup Files/Custom_InstallDirDlg.wxs new file mode 100644 index 00000000..1893801b --- /dev/null +++ b/src/Release/Setup Files/Custom_InstallDirDlg.wxs @@ -0,0 +1,45 @@ + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Release/Setup Files/Product64.wxs b/src/Release/Setup Files/Product64.wxs new file mode 100644 index 00000000..7bd7388b --- /dev/null +++ b/src/Release/Setup Files/Product64.wxs @@ -0,0 +1,1709 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 602) + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSTALLDESKTOPSHORTCUT + + + + + + + + + + + + + + + + + + INSTALLSTARTMENUSHORTCUT + + + + + + + + + + + + + INSTALLSTARTMENUSHORTCUT + + + + + + + + + + + + + INSTALLSTARTMENUSHORTCUT + + + + + + + + + + + + + + + + + + + + + + REGISTERVCFILEEXT + + + + + + + + + + + + REGISTERVCFILEEXT + + + + + + + + + + + REGISTERVCFILEEXT + + + + + + + + + + + REGISTERVCFILEEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + REINSTALL OR UPGRADINGPRODUCTCODE OR REMOVE~="ALL" + + + + + + + "YES" AND NOT Installed ]]> + + + REINSTALL OR UPGRADINGPRODUCTCODE OR REMOVE~="ALL" + + + + + (NOT Installed AND NOT REMOVE) OR REINSTALL + + + (NOT Installed AND NOT REMOVE) OR REINSTALL + + + (NOT Installed AND NOT REMOVE) OR REINSTALL + + + (NOT Installed AND NOT REMOVE) OR REINSTALL + + + + + REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE + + + REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE + + + REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE + + + REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE + + + (NOT Installed AND NOT REMOVE) OR REINSTALL OR (REMOVE~="ALL" AND NOT UPGRADINGPRODUCTCODE) + + + + + + ISREBOOTREQUIRED = "1" + + + + + + \ No newline at end of file diff --git a/src/Release/Setup Files/Strings-en.wxl b/src/Release/Setup Files/Strings-en.wxl new file mode 100644 index 00000000..48946057 --- /dev/null +++ b/src/Release/Setup Files/Strings-en.wxl @@ -0,0 +1,24 @@ + + + 1033 + A newer version is already installed + This 32-bit installer can only run on at least Windows Vista + This is a 32-bit installer that cannot be run under 64-bit Windows + This is a 64-bit installer that cannot be run under 32-bit Windows + + Choose which options to enable then click Next to proceed. + + Install for all users + Add VeraCrypt icon to desktop + Add VeraCrypt to Start Menu + Associate the .hc file extension with VeraCrypt + + Please close all open VeraCrypt windows first. + + Please accept the license agreement by passing ACCEPTLICENSE=YES during installation. + + VeraCrypt + VeraCrypt Expander + VeraCrypt Website + + \ No newline at end of file diff --git a/src/Release/Setup Files/build_msi_x64.bat b/src/Release/Setup Files/build_msi_x64.bat new file mode 100644 index 00000000..476625b0 --- /dev/null +++ b/src/Release/Setup Files/build_msi_x64.bat @@ -0,0 +1,178 @@ +::------------------------------------ +::Define search paths here for Wix ToolSet and SDK (and SignTool optionnally) +::------------------------------------ + +@set SEARCH_WIX_PATH=C:\Program Files (x86)\WiX Toolset v3.11\bin + +@set SEARCH_VC_DIR_PLATFORMSDK_1=C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86 +@set SEARCH_VC_DIR_PLATFORMSDK_2=C:\Program Files (x86)\Windows Kits\10\bin\x86 +@set SEARCH_VC_DIR_PLATFORMSDK_3=C:\Program Files\Microsoft Platform SDK\bin +@set SEARCH_VC_DIR_PLATFORMSDK_4=C:\Program Files (x86)\Windows Kits\8.1\bin\x86 +@set SEARCH_VC_DIR_PLATFORMSDK_5=C:\Program Files (x86)\Windows Kits\8.0\bin\x86 +@set SEARCH_VC_DIR_PLATFORMSDK_6=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\bin + +::end of search paths + +set MSI_BUILDPATH=%~dp0 +cd %MSI_BUILDPATH% + +::------------------------------------ +:: Look for msitran.exe and msidb.exe +::------------------------------------ + +@echo [INFO] Define default value for VC_DIR_PLATFORMSDK if not defined yet +@echo [INFO] Input VC_DIR_PLATFORMSDK=%VC_DIR_PLATFORMSDK% +@set FILE_TO_FIND="msitran.exe" "msidb.exe" +@echo [INFO] Looking for files: %FILE_TO_FIND% + +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@set VC_DIR_PLATFORMSDK=%SEARCH_VC_DIR_PLATFORMSDK_1% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@set VC_DIR_PLATFORMSDK=%SEARCH_VC_DIR_PLATFORMSDK_2% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@set VC_DIR_PLATFORMSDK=%SEARCH_VC_DIR_PLATFORMSDK_3% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@rem paths for Windows 8 SDK are slightly different +@set FILE_TO_FIND="msitran.exe" "msidb.exe" + +@set VC_DIR_PLATFORMSDK=%SEARCH_VC_DIR_PLATFORMSDK_4% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@set VC_DIR_PLATFORMSDK=%SEARCH_VC_DIR_PLATFORMSDK_5% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@set VC_DIR_PLATFORMSDK=%SEARCH_VC_DIR_PLATFORMSDK_6% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_PLATFORMSDK%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_mssdk +@echo Not found in "%VC_DIR_PLATFORMSDK%" + +@echo [ERROR] MS Platform SDK 2008, Windows SDK v7.1, or Windows SDK 8.0/8.1/10 could not be found +@echo If the path is not any of the above, +@echo please define VC_DIR_PLATFORMSDK environment variable. +@exit /B 1 + +:found_mssdk +@echo Found in "%VC_DIR_PLATFORMSDK%" + +::------------------------------------ +:: Look for candle.exe (and light.exe obviously) +::------------------------------------ + +@echo [INFO] Check if WiX is installed +@echo [INFO] Default value for VC_DIR_WIX is set to %WIX% +@set VC_DIR_WIX=%WIX% +@set FILE_TO_FIND="candle.exe" +@echo [INFO] Looking for files: %FILE_TO_FIND% + +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_WIX%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_wix +@echo Not found in "%VC_DIR_WIX%" + +@set VC_DIR_WIX=%SEARCH_WIX_PATH% +@set FILE_NOT_FOUND= +@for %%i in (%FILE_TO_FIND%) do @if not exist "%VC_DIR_WIX%\%%~i" set FILE_NOT_FOUND=%%~i +@if "%FILE_NOT_FOUND%"=="" goto found_wix +@echo Not found in "%VC_DIR_WIX%" + +@echo [ERROR] WiX could not be found +@echo Please install Wix3 +@exit /B 1 + +:found_wix +@echo Found in "%VC_DIR_WIX%" + +::------------------------------------ +:: Create a MSI installer for each language +:: We make use of -sice:ICE09 to silence ICE09 warnings generated because we install non-permanent elements to 'SystemFolder' +::------------------------------------ +@echo [INFO] Creating msi 64-bit installers + +@echo [INFO] Making the en-us version in %cd%\out\64\en-us\ +"%VC_DIR_WIX%\candle.exe" -dLang=en -arch x64 -ext WixUIExtension -ext WiXUtilExtension Product64.wxs -out out\64\en-us\Product.wixobj +@if NOT "%ERRORLEVEL%" == "0" goto msi_failed +"%VC_DIR_WIX%\candle.exe" -dLang=en -arch x64 -ext WixUIExtension -ext WiXUtilExtension Custom_InstallDir.wxs -out out\64\en-us\Custom_InstallDir.wixobj +@if NOT "%ERRORLEVEL%" == "0" goto msi_failed +"%VC_DIR_WIX%\candle.exe" -dLang=en -arch x64 -ext WixUIExtension -ext WiXUtilExtension Custom_InstallDirDlg.wxs -out out\64\en-us\Custom_InstallDirDlg.wixobj +@if NOT "%ERRORLEVEL%" == "0" goto msi_failed +"%VC_DIR_WIX%\Light.exe" -ext WixUIExtension -ext WiXUtilExtension -cultures:en-us -loc Strings-en.wxl out\64\en-us\Product.wixobj out\64\en-us\Custom_InstallDirDlg.wixobj out\64\en-us\Custom_InstallDir.wixobj -out out\64\en-us\VeraCrypt_%1_Setup_en-us.msi -pdbout out\64\en-us\VeraCrypt_%1_Setup_en-us.wixpdb -sice:ICE09 +@if NOT "%ERRORLEVEL%" == "0" goto msi_failed + +::------------------------------------ +:: Join the language specific MSIs together +::------------------------------------ +@echo [INFO] Joining msi 64-bit installers into 1 64-bit installer + +@set OUT_PATH=%cd%\out\64\ +@echo [INFO] OUT_PATH=%OUT_PATH% + +@set MSI_FILE_IN=VeraCrypt_%1_Setup +@set MSI_FILE_OUT=VeraCrypt_%1_Setup_x64 + +:: Check if all the MSI files were built +@set LANG=en-us +@IF NOT EXIST "%OUT_PATH%\%LANG%\%MSI_FILE_IN%_%LANG%.msi" goto NOT_%LANG% + +:: Take all the MSI files and process +@set LANG=en-us +@copy /Y "%OUT_PATH%\%LANG%\%MSI_FILE_IN%_%LANG%.msi" "%OUT_PATH%\%MSI_FILE_OUT%.msi" + +::------------------------------------ +:: Add all available LCIDs +::------------------------------------ +"%VC_DIR_PLATFORMSDK%\MsiInfo.Exe" "%OUT_PATH%\%MSI_FILE_OUT%.msi" /p x64;1033 +@if NOT "%ERRORLEVEL%" == "0" goto comb_msi_failed + +::------------------------------------ +:: Copy to bin and remove out +::------------------------------------ +mkdir bin +@copy /Y "%OUT_PATH%\%MSI_FILE_OUT%.msi" "%cd%\bin\%MSI_FILE_OUT%.msi" +@set LANG=en-us +@copy /Y "%OUT_PATH%\%LANG%\%MSI_FILE_IN%_%LANG%.msi" "%cd%\bin\%MSI_FILE_IN%_x64_%LANG%.msi" +@rmdir /S /Q "%cd%\out" + +goto END + +:msi_failed +@echo [ERR ] failed to create the MSI +@exit /B 1 + +:comb_msi_failed +@echo [ERR ] failed to combine the language specific MSI's +@exit /B 1 + +:NOT_en-us +@echo [ERR ] Missing file '%OUT_PATH%\%LANG%\%MSI_FILE_IN%_%LANG%.msi' +@exit /B 1 + +:NOT_lv-lv +@echo [ERR ] Missing file '%OUT_PATH%\%LANG%\%MSI_FILE_IN%_%LANG%.msi' +@exit /B 1 + +@echo [INFO] Done creating multi-lang msi installers +:END +@echo end \ No newline at end of file diff --git a/src/Setup/Setup.vcxproj b/src/Setup/Setup.vcxproj index 922d3018..30c7e167 100644 --- a/src/Setup/Setup.vcxproj +++ b/src/Setup/Setup.vcxproj @@ -104,6 +104,7 @@ md "..\Debug\Setup Files" 2>NUL: copy Debug\VeraCryptSetup.exe "..\Debug\Setup Files\VeraCrypt Setup.exe" >NUL: +copy Debug\VeraCryptSetup.exe "..\Debug\Setup Files\VeraCrypt COMReg.exe" >NUL: @@ -142,7 +143,7 @@ copy Debug\VeraCryptSetup.exe "..\Debug\Setup Files\VeraCrypt Setup.exe" >NUL Setup.manifest;%(AdditionalManifestFiles) - copy Release\VeraCryptSetup.exe "..\Release\Setup Files\VeraCrypt Setup.exe" + copy Release\VeraCryptSetup.exe "..\Release\Setup Files\VeraCrypt Setup.exe" && copy Release\VeraCryptSetup.exe "..\Release\Setup Files\VeraCrypt COMReg.exe" diff --git a/src/SetupDLL/ComSetup.cpp b/src/SetupDLL/ComSetup.cpp new file mode 100644 index 00000000..07c3360a --- /dev/null +++ b/src/SetupDLL/ComSetup.cpp @@ -0,0 +1,114 @@ +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2017 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#define TC_MAIN_COM_VERSION_MAJOR 2 +#define TC_MAIN_COM_VERSION_MINOR 11 + +#define TC_FORMAT_COM_VERSION_MAJOR 2 +#define TC_FORMAT_COM_VERSION_MINOR 9 + +#include +#include +#include +#include +#include "ComSetup.h" +#include "Dlgcode.h" +#include "Resource.h" +#include "../Mount/MainCom_i.c" +#include "../Format/FormatCom_i.c" + +/* + * Same as RegisterComServers() in Setup project, but + * instead of using GetModuleFileNameW() to get this + * DLL's path as setupModule which will not work because + * the DLL is embedded in the binary of the MSI, + * we ship the empty version of 'VeraCrypt Setup.exe' + * as 'VeraCrypt COMReg.exe' and use it. + */ +extern "C" BOOL RegisterComServers (wchar_t *modulePath) +{ + BOOL ret = TRUE; + wchar_t mainModule[1024], formatModule[1024], setupModule[1024]; + CComPtr tl, tl2; + + wsprintfW (mainModule, L"%sVeraCrypt.exe", modulePath); + wsprintfW (formatModule, L"%sVeraCrypt Format.exe", modulePath); + wsprintfW (setupModule, L"%sVeraCrypt COMReg.exe", modulePath); + + UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR, 0, SYS_WIN32); + UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR, 0, SYS_WIN32); + // unregister older versions that may still exist + for (WORD i = 7; i >= 1; i--) + UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR-i, 0, SYS_WIN32); + for (WORD i = 5; i >= 1; i--) + UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR-i, 0, SYS_WIN32); + + CRegObject ro; + HRESULT r; + + if (!SUCCEEDED (r = ro.FinalConstruct ()) + || !SUCCEEDED (r = ro.AddReplacement (L"MAIN_MODULE", mainModule)) + || !SUCCEEDED (r = ro.AddReplacement (L"FORMAT_MODULE", formatModule)) + || !SUCCEEDED (r = ro.ResourceRegister (setupModule, IDR_COMREG, L"REGISTRY")) + || !SUCCEEDED (r = LoadTypeLib (mainModule, &tl)) + || !SUCCEEDED (r = RegisterTypeLib (tl, mainModule, 0)) + || !SUCCEEDED (r = LoadTypeLib (formatModule, &tl2)) + || !SUCCEEDED (r = RegisterTypeLib (tl2, formatModule, 0))) + { + MessageBox (MainDlg, _com_error (r).ErrorMessage(), _T(TC_APP_NAME), MB_ICONERROR); + ret = FALSE; + } + + ro.FinalRelease (); + return ret; +} + +/* + * Same as UnregisterComServers() in Setup project, but + * instead of using GetModuleFileNameW() to get this + * DLL's path as setupModule which will not work because + * the DLL is embedded in the binary of the MSI, + * we ship the empty version of 'VeraCrypt Setup.exe' + * as 'VeraCrypt COMReg.exe' and use it. + */ +extern "C" BOOL UnregisterComServers (wchar_t *modulePath) +{ + BOOL ret; + + if (UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR, 0, SYS_WIN32) != S_OK) + return FALSE; + if (UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR, 0, SYS_WIN32) != S_OK) + return FALSE; + + // unregister older versions that may still exist + for (WORD i = 7; i >= 1; i--) + UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR-i, 0, SYS_WIN32); + for (WORD i = 5; i >= 1; i--) + UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR-i, 0, SYS_WIN32); + + wchar_t module[1024]; + HRESULT r; + CRegObject ro; + ro.FinalConstruct (); + + wsprintfW (module, L"%sVeraCrypt.exe", modulePath); + ro.AddReplacement (L"MAIN_MODULE", module); + + wsprintfW (module, L"%sVeraCrypt Format.exe", modulePath); + ro.AddReplacement (L"FORMAT_MODULE", module); + + wsprintfW (module, L"%sVeraCrypt COMReg.exe", modulePath); + ret = SUCCEEDED(r = ro.ResourceUnregister (module, IDR_COMREG, L"REGISTRY")); + + ro.FinalRelease (); + return ret; +} diff --git a/src/SetupDLL/ComSetup.h b/src/SetupDLL/ComSetup.h new file mode 100644 index 00000000..85d0f249 --- /dev/null +++ b/src/SetupDLL/ComSetup.h @@ -0,0 +1,22 @@ +/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2017 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL RegisterComServers (wchar_t *modulePath); +BOOL UnregisterComServers (wchar_t *modulePath); + +#ifdef __cplusplus +} +#endif diff --git a/src/SetupDLL/ComSetup.rgs b/src/SetupDLL/ComSetup.rgs new file mode 100644 index 00000000..b8201c10 --- /dev/null +++ b/src/SetupDLL/ComSetup.rgs @@ -0,0 +1,92 @@ +HKCR +{ + ForceRemove VeraCrypt.1 = s 'VeraCrypt class' + { + CLSID = s '{FE8B3B95-C80C-41f7-830F-FBA271C26F7E}' + } + + ForceRemove VeraCrypt = s 'VeraCrypt class' + { + CLSID = s '{FE8B3B95-C80C-41f7-830F-FBA271C26F7E}' + CurVer = s 'VeraCrypt.1' + } + + NoRemove CLSID + { + ForceRemove {FE8B3B95-C80C-41f7-830F-FBA271C26F7E} = s 'VeraCrypt class' + { + ProgID = s 'VeraCrypt.1' + VersionIndependentProgID = s 'VeraCrypt' + LocalServer32 = s '"%MAIN_MODULE%"' + + TypeLib = s '{9ACF6176-5FC4-4690-A025-B3306A50EB6A}' + + Elevation + { + val Enabled = d 1 + val IconReference = s '@%MAIN_MODULE%,-501' + } + + val AppId = s '{FE8B3B95-C80C-41f7-830F-FBA271C26F7E}' + val LocalizedString = s '@%MAIN_MODULE%,-110' + } + } + + NoRemove AppId + { + ForceRemove {FE8B3B95-C80C-41f7-830F-FBA271C26F7E} = s 'VeraCrypt class' + { + val AccessPermission = b 010004803000000040000000000000001400000002001c000100000000001400070000000101000000000005040000000102000000000005200000002002000001020000000000052000000020020000 + } + + ForceRemove VeraCrypt.exe + { + val AppId = s '{FE8B3B95-C80C-41f7-830F-FBA271C26F7E}' + } + } + + ForceRemove VeraCryptFormat.1 = s 'VeraCryptFormat class' + { + CLSID = s '{A96D3797-9F31-49f4-A0CE-9657392CF789}' + } + + ForceRemove VeraCryptFormat = s 'VeraCryptFormat class' + { + CLSID = s '{A96D3797-9F31-49f4-A0CE-9657392CF789}' + CurVer = s 'VeraCryptFormat.1' + } + + NoRemove CLSID + { + ForceRemove {A96D3797-9F31-49f4-A0CE-9657392CF789} = s 'VeraCryptFormat class' + { + ProgID = s 'VeraCryptFormat.1' + VersionIndependentProgID = s 'VeraCryptFormat' + LocalServer32 = s '"%FORMAT_MODULE%"' + + TypeLib = s '{56327DDA-F1A7-4e13-B128-520D129BDEF6}' + + Elevation + { + val Enabled = d 1 + val IconReference = s '@%FORMAT_MODULE%,-501' + } + + val AppId = s '{A96D3797-9F31-49f4-A0CE-9657392CF789}' + val LocalizedString = s '@%FORMAT_MODULE%,-112' + } + } + + NoRemove AppId + { + ForceRemove {A96D3797-9F31-49f4-A0CE-9657392CF789} = s 'VeraCryptFormat class' + { + val AccessPermission = b 010004803000000040000000000000001400000002001c000100000000001400070000000101000000000005040000000102000000000005200000002002000001020000000000052000000020020000 + } + + ForceRemove 'VeraCrypt Format.exe' + { + val AppId = s '{A96D3797-9F31-49f4-A0CE-9657392CF789}' + } + } +} \ No newline at end of file diff --git a/src/SetupDLL/Dir.c b/src/SetupDLL/Dir.c new file mode 100644 index 00000000..2d4feecd --- /dev/null +++ b/src/SetupDLL/Dir.c @@ -0,0 +1,110 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + governed by the TrueCrypt License 3.0, also from the source code of + Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux + and which is governed by the 'License Agreement for Encryption for the Masses' + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2017 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. */ + +#include "Tcdefs.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "Dir.h" + +/* create full directory tree. returns 0 for success, -1 if failure */ +int +mkfulldir (wchar_t *oriPath, BOOL bCheckonly) +{ + struct _stat st; + wchar_t *uniq_file; + wchar_t path [TC_MAX_PATH]; + + StringCbCopyW (path, TC_MAX_PATH, oriPath); + + if (wcslen (path) == 3 && path[1] == L':') + goto is_root; /* keep final slash in root if present */ + + /* strip final forward or backslash if we have one! */ + uniq_file = wcsrchr (path, L'\\'); + if (uniq_file && uniq_file[1] == L'\0') + uniq_file[0] = L'\0'; + else + { + uniq_file = wcsrchr (path, L'/'); + if (uniq_file && uniq_file[1] == L'\0') + uniq_file[0] = L'\0'; + } + + is_root: + if (bCheckonly) + return _wstat (path, &st); + + if (_wstat (path, &st)) + return mkfulldir_internal (path); + else + return 0; +} + + +int +mkfulldir_internal (wchar_t *path) +{ + wchar_t *token; + struct _stat st; + static wchar_t tokpath[_MAX_PATH]; + static wchar_t trail[_MAX_PATH]; + + StringCbCopyW (tokpath, _MAX_PATH, path); + trail[0] = L'\0'; + + token = wcstok (tokpath, L"\\/"); + + if (tokpath[0] == L'\\' && tokpath[1] == L'\\') + { /* unc */ + trail[0] = tokpath[0]; + trail[1] = tokpath[1]; + trail[2] = L'\0'; + if (token) + { + StringCbCatW (trail, _MAX_PATH, token); + StringCbCatW (trail, _MAX_PATH, L"\\"); + token = wcstok (NULL, L"\\/"); + if (token) + { /* get share name */ + StringCbCatW (trail, _MAX_PATH, token); + StringCbCatW (trail, _MAX_PATH, L"\\"); + } + token = wcstok (NULL, L"\\/"); + } + } + + if (tokpath[1] == L':') + { /* drive letter */ + StringCbCatW (trail, _MAX_PATH, tokpath); + StringCbCatW (trail, _MAX_PATH, L"\\"); + token = wcstok (NULL, L"\\/"); + } + + while (token != NULL) + { + int x; + StringCbCatW (trail, _MAX_PATH, token); + x = _wmkdir (trail); + StringCbCatW (trail, _MAX_PATH, L"\\"); + token = wcstok (NULL, L"\\/"); + } + + return _wstat (path, &st); +} diff --git a/src/SetupDLL/Dir.h b/src/SetupDLL/Dir.h new file mode 100644 index 00000000..fb9dfc6b --- /dev/null +++ b/src/SetupDLL/Dir.h @@ -0,0 +1,23 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + governed by the TrueCrypt License 3.0, also from the source code of + Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux + and which is governed by the 'License Agreement for Encryption for the Masses' + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2017 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. */ + +#ifdef __cplusplus +extern "C" { +#endif + +int mkfulldir ( wchar_t *path , BOOL bCheckonly ); +int mkfulldir_internal ( wchar_t *path ); + +#ifdef __cplusplus +} +#endif diff --git a/src/SetupDLL/Portable.manifest b/src/SetupDLL/Portable.manifest new file mode 100644 index 00000000..5d4cb896 --- /dev/null +++ b/src/SetupDLL/Portable.manifest @@ -0,0 +1,33 @@ + + + + + + + + + + + + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/SetupDLL/Portable.rc b/src/SetupDLL/Portable.rc new file mode 100644 index 00000000..6ffc03c7 --- /dev/null +++ b/src/SetupDLL/Portable.rc @@ -0,0 +1,291 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" +#include "..\\common\\resource.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,24,25,0 + PRODUCTVERSION 1,24,25,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "IDRIX" + VALUE "FileDescription", "VeraCrypt Portable" + VALUE "FileVersion", "1.24-Update9" + VALUE "LegalTrademarks", "VeraCrypt" + VALUE "OriginalFilename", "VeraCrypt Portable.exe" + VALUE "ProductName", "VeraCrypt" + VALUE "ProductVersion", "1.24-Update9" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// HEADER +// + +IDR_SETUP_RSRC_HEADER HEADER "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +///////////////////////////////////////////////////////////////////////////// +// +// LANGUAGES +// + +IDR_LANG_AR LANGUAGES "..\\..\\Translations\\Language.ar.xml" +IDR_LANG_CS LANGUAGES "..\\..\\Translations\\Language.cs.xml" +IDR_LANG_DE LANGUAGES "..\\..\\Translations\\Language.de.xml" +IDR_LANG_ES LANGUAGES "..\\..\\Translations\\Language.es.xml" +IDR_LANG_FR LANGUAGES "..\\..\\Translations\\Language.fr.xml" +IDR_LANG_IT LANGUAGES "..\\..\\Translations\\Language.it.xml" +IDR_LANG_JA LANGUAGES "..\\..\\Translations\\Language.ja.xml" +IDR_LANG_NL LANGUAGES "..\\..\\Translations\\Language.nl.xml" +IDR_LANG_PL LANGUAGES "..\\..\\Translations\\Language.pl.xml" +IDR_LANG_RO LANGUAGES "..\\..\\Translations\\Language.ro.xml" +IDR_LANG_RU LANGUAGES "..\\..\\Translations\\Language.ru.xml" +IDR_LANG_VI LANGUAGES "..\\..\\Translations\\Language.vi.xml" +IDR_LANG_ZHCN LANGUAGES "..\\..\\Translations\\Language.zh-cn.xml" +IDR_LANG_ZHHK LANGUAGES "..\\..\\Translations\\Language.zh-hk.xml" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_INFO_PAGE_DLG DIALOGEX 0, 0, 217, 156 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "",IDC_BOX_HELP,0,10,217,146 +END + +IDD_INTRO_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_LICENSE_TEXT,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x2804,0,23,345,108 + CONTROL "",IDC_AGREE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,2,137,126,10 + LTEXT "",IDC_BOX_HELP,0,0,346,22 +END + +IDD_INSTL_DLG DIALOGEX 0, 0, 374, 231 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "VeraCrypt Portable Wizard" +CLASS "VeraCryptCustomDlg" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "&Help",IDHELP,150,211,50,14 + PUSHBUTTON "",IDC_PREV,209,211,50,14 + DEFPUSHBUTTON "",IDC_NEXT,259,211,50,14 + PUSHBUTTON "Cancel",IDCANCEL,317,211,50,14 + LTEXT "",IDC_BOX_TITLE,11,5,324,12,0,WS_EX_TRANSPARENT + CONTROL 107,IDC_BITMAP_SETUP_WIZARD,"Static",SS_BITMAP | SS_NOTIFY,139,3,228,30 + CONTROL 109,IDC_SETUP_WIZARD_BKG,"Static",SS_BITMAP,0,0,11,10 + CONTROL "",IDC_SETUP_WIZARD_GFX_AREA,"Static",SS_GRAYRECT | NOT WS_VISIBLE,0,0,378,36,WS_EX_TRANSPARENT | WS_EX_STATICEDGE + CONTROL "",IDC_HR_BOTTOM,"Static",SS_ETCHEDHORZ,67,204,306,1,WS_EX_STATICEDGE + CONTROL "",IDC_HR,"Static",SS_ETCHEDHORZ,0,35,399,1,WS_EX_STATICEDGE + LTEXT "VeraCrypt Portable",IDC_STATIC,4,200,62,8,WS_DISABLED + LTEXT "",IDC_BOX_INFO,18,18,317,13,0,WS_EX_TRANSPARENT + LTEXT "",IDC_MAIN_CONTENT_CANVAS,0,36,374,164 + LTEXT "",IDC_POS_BOX,14,42,346,155,0,WS_EX_TRANSPARENT +END + +IDD_EXTRACTION_OPTIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Bro&wse...",IDC_BROWSE,277,32,62,14 + EDITTEXT IDC_DESTINATION,6,33,264,12,ES_AUTOHSCROLL + LTEXT "Please select or type the location where you want to place the extracted files:",IDT_EXTRACT_DESTINATION,6,15,333,17 + CONTROL "&Open the destination location when finished",IDC_OPEN_CONTAINING_FOLDER, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,91,318,16 + LTEXT "",IDC_BOX_HELP,6,56,333,32 +END + +IDD_PROGRESS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LISTBOX IDC_LOG_WINDOW,0,1,345,131,LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL + CONTROL "",IDC_PROGRESS_BAR,"msctls_progress32",PBS_SMOOTH | WS_BORDER,0,139,345,12 +END + +IDD_DONATIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +EXSTYLE WS_EX_TRANSPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Donate now...",IDC_DONATE,124,94,96,14 +END + +IDD_INSTALL_LANGUAGE DIALOGEX 0, 0, 213, 87 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "VeraCrypt Setup Wizard" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,102,66,50,14 + PUSHBUTTON "Cancel",IDCANCEL,156,66,50,14 + ICON 501,IDC_STATIC,10,10,32,32 + LTEXT "Select the language to use during the installation:",IDC_SELECT_LANGUAGE_LABEL,42,13,157,26 + COMBOBOX IDC_LANGUAGES_LIST,42,44,164,155,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SETUP ICON "Setup.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""..\\\\common\\\\resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""..\\\\common\\\\common.rc""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_INFO_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 210 + TOPMARGIN, 7 + BOTTOMMARGIN, 149 + END + + IDD_INTRO_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 145 + END + + IDD_INSTL_DLG, DIALOG + BEGIN + END + + IDD_EXTRACTION_OPTIONS_PAGE_DLG, DIALOG + BEGIN + RIGHTMARGIN, 343 + BOTTOMMARGIN, 147 + END + + IDD_PROGRESS_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 145 + END + + IDD_DONATIONS_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 147 + END + + IDD_INSTALL_LANGUAGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 206 + TOPMARGIN, 7 + BOTTOMMARGIN, 80 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_SETUP_WIZARD BITMAP "VeraCrypt_setup.bmp" +IDB_SETUP_WIZARD_BKG BITMAP "VeraCrypt_setup_background.bmp" +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "..\\common\\common.rc" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/SetupDLL/Portable.vcxproj b/src/SetupDLL/Portable.vcxproj new file mode 100644 index 00000000..e864515b --- /dev/null +++ b/src/SetupDLL/Portable.vcxproj @@ -0,0 +1,281 @@ + + + + + Debug + Win32 + + + ReleaseCustomEFI + Win32 + + + Release + Win32 + + + + {60698D56-DB83-4D19-9C87-9DFB6A6F8C87} + Portable + Win32Proj + + + + Application + Unicode + Windows7.1SDK + + + Application + Unicode + Windows7.1SDK + + + Application + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + PortableDebug\ + PortableDebug\ + true + true + true + PortableRelease\ + PortableRelease\ + PortableRelease\ + PortableRelease\ + false + false + true + true + VeraCryptPortable + VeraCryptPortable + VeraCryptPortable + + + + Disabled + ..\Common;..\Crypto;..\;..\PKCS11;..\Common\zlib;..\Common\libzip;%(AdditionalIncludeDirectories) + SETUP;PORTABLE;WIN32;HAVE_CONFIG_H;ZIP_STATIC;DEBUG;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;_ATL_NO_DEFAULT_LIBS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level4 + EditAndContinue + 4057;4100;4127;4201;4505;4701;4706;4131;%(DisableSpecificWarnings) + + + /NODEFAULTLIB:LIBCMTD %(AdditionalOptions) + libcmtd.lib;atlsd.lib;mpr.lib;..\Common\Debug\Zip.lib;..\Crypto\Debug\crypto.lib;%(AdditionalDependencies) + $(OutDir)VeraCryptPortable.exe + AsInvoker + user32.dll;gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;mpr.dll;%(DelayLoadDLLs) + true + $(OutDir)Portable.pdb + Windows + false + true + MachineX86 + + + Portable.manifest;%(AdditionalManifestFiles) + + + md "..\Debug\Setup Files" 2>NUL: +copy PortableDebug\VeraCryptPortable.exe "..\Debug\Setup Files\VeraCrypt Portable.exe" >NUL: + + + + + + /w34189 %(AdditionalOptions) + MaxSpeed + ..\Common;..\Crypto;..\;..\PKCS11;..\Common\zlib;..\Common\libzip;%(AdditionalIncludeDirectories) + SETUP;PORTABLE;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;_ATL_NO_DEFAULT_LIBS;%(PreprocessorDefinitions) + MultiThreaded + true + + + All + $(IntDir) + Level4 + ProgramDatabase + 4057;4100;4127;4201;4505;4701;4706;4131;%(DisableSpecificWarnings) + + + /IGNORE:4089 %(AdditionalOptions) + mpr.lib;..\Common\Release\Zip.lib;..\Crypto\Release\crypto.lib;%(AdditionalDependencies) + $(OutDir)VeraCryptPortable.exe + AsInvoker + user32.dll;gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;mpr.dll;%(DelayLoadDLLs) + true + true + Windows + true + true + true + true + MachineX86 + + + Portable.manifest;%(AdditionalManifestFiles) + + + copy PortableRelease\VeraCryptPortable.exe "..\Release\Setup Files\VeraCrypt Portable.exe" + + + + + /w34189 %(AdditionalOptions) + MaxSpeed + ..\Common;..\Crypto;..\;..\PKCS11;..\Common\zlib;..\Common\libzip;%(AdditionalIncludeDirectories) + SETUP;PORTABLE;VC_EFI_CUSTOM_MODE;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;_ATL_NO_DEFAULT_LIBS;%(PreprocessorDefinitions) + MultiThreaded + true + + + All + $(IntDir) + Level4 + ProgramDatabase + 4057;4100;4127;4201;4505;4701;4706;4131;%(DisableSpecificWarnings) + + + /IGNORE:4089 %(AdditionalOptions) + mpr.lib;..\Common\Release\Zip.lib;..\Crypto\Release\crypto.lib;%(AdditionalDependencies) + $(OutDir)VeraCryptPortable.exe + AsInvoker + user32.dll;gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;mpr.dll;%(DelayLoadDLLs) + true + true + Windows + true + true + true + true + MachineX86 + + + Portable.manifest;%(AdditionalManifestFiles) + + + copy PortableRelease\VeraCryptPortable.exe "..\Release\Setup Files\VeraCrypt Portable.exe" + + + VC_EFI_CUSTOM_MODE;%(PreprocessorDefinitions) + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + + + + + + {8b7f059f-e4c7-4e11-88f5-ee8b8433072e} + false + + + {9715ff1d-599b-4bbc-ad96-bef6e08ff827} + false + + + {9dc1abe2-d18b-48fb-81d2-8c50adc57bcf} + false + + + {e4c40f94-e7f9-4981-86e4-186b46f993f3} + false + + + + + + \ No newline at end of file diff --git a/src/SetupDLL/Portable.vcxproj.filters b/src/SetupDLL/Portable.vcxproj.filters new file mode 100644 index 00000000..855ecc00 --- /dev/null +++ b/src/SetupDLL/Portable.vcxproj.filters @@ -0,0 +1,154 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {876C2050-1694-4F32-AF5D-491C6A43A799} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + {17370B4B-2D76-41A9-9828-015FB30054F6} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + + + Resource Files\Common + + + Resource Files + + + \ No newline at end of file diff --git a/src/SetupDLL/Portable.vcxproj.user b/src/SetupDLL/Portable.vcxproj.user new file mode 100644 index 00000000..ace9a86a --- /dev/null +++ b/src/SetupDLL/Portable.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/SetupDLL/Resource.h b/src/SetupDLL/Resource.h new file mode 100644 index 00000000..8882d67b --- /dev/null +++ b/src/SetupDLL/Resource.h @@ -0,0 +1,81 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Setup.rc +// +#define IDR_COMREG 10 +#define IDR_LANG_AR 20 +#define IDR_LANG_CS 21 +#define IDR_LANG_DE 22 +#define IDR_LANG_ES 23 +#define IDR_LANG_FR 24 +#define IDR_LANG_IT 25 +#define IDR_LANG_JA 26 +#define IDR_LANG_NL 27 +#define IDR_LANG_PL 28 +#define IDR_LANG_RO 29 +#define IDR_LANG_RU 30 +#define IDR_LANG_VI 31 +#define IDR_LANG_ZHCN 32 +#define IDR_LANG_ZHHK 33 +#define IDD_INSTALL 101 +#define IDD_INSTALL_OPTIONS_PAGE_DLG 102 +#define IDD_UNINSTALL 103 +#define IDI_SETUP 104 +#define IDR_SETUP_RSRC_HEADER 105 +#define IDD_EXTRACTION_OPTIONS_PAGE_DLG 106 +#define IDB_SETUP_WIZARD 107 +#define IDD_INTRO_PAGE_DLG 108 +#define IDB_SETUP_WIZARD_BKG 109 +#define IDD_INFO_PAGE_DLG 110 +#define IDD_INSTL_DLG 111 +#define IDD_WIZARD_MODE_PAGE_DLG 112 +#define IDD_PROGRESS_PAGE_DLG 113 +#define IDD_DONATIONS_PAGE_DLG 114 +#define IDD_INSTALL_LANGUAGE 115 +#define IDC_DESTINATION 1000 +#define IDC_BOX_TITLE 1001 +#define IDC_BROWSE 1002 +#define IDC_BOX_INFO 1003 +#define IDC_LICENSE 1004 +#define IDC_BOX_HELP 1005 +#define IDC_LICENSE_TEXT 1006 +#define IDC_BOX_HELP2 1007 +#define IDC_FILE_TYPE 1008 +#define IDT_UNINSTALL_DIR 1009 +#define IDC_PROG_GROUP 1010 +#define IDC_SYSTEM_RESTORE 1011 +#define IDC_DESKTOP_ICON 1012 +#define IDC_ALL_USERS 1013 +#define IDT_INSTALL_DESTINATION 1014 +#define IDC_UNINSTALL 1015 +#define IDC_PROGRESS_BAR 1016 +#define IDC_LOG_WINDOW 1017 +#define IDC_SETUP_WIZARD_BKG 1018 +#define IDC_SETUP_WIZARD_GFX_AREA 1019 +#define IDC_HR 1020 +#define IDC_OPEN_CONTAINING_FOLDER 1021 +#define IDC_AGREE 1022 +#define IDC_HR_BOTTOM 1023 +#define IDC_WIZARD_MODE_INSTALL 1024 +#define IDC_WIZARD_MODE_EXTRACT_ONLY 1025 +#define IDC_NEXT 1026 +#define IDC_PREV 1027 +#define IDT_EXTRACT_DESTINATION 1028 +#define IDC_POS_BOX 1029 +#define IDC_BITMAP_SETUP_WIZARD 1030 +#define IDC_MAIN_CONTENT_CANVAS 1031 +#define IDC_DONATE 1032 +#define IDC_LANGUAGES_LIST 1033 +#define IDC_SELECT_LANGUAGE_LABEL 1034 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 116 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1035 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/SetupDLL/Setup.c b/src/SetupDLL/Setup.c new file mode 100644 index 00000000..14bdefd4 --- /dev/null +++ b/src/SetupDLL/Setup.c @@ -0,0 +1,3620 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + governed by the TrueCrypt License 3.0, also from the source code of + Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux + and which is governed by the 'License Agreement for Encryption for the Masses' + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2017 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. */ + +#include "Tcdefs.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Apidrvr.h" +#include "BootEncryption.h" +#include "Boot/Windows/BootCommon.h" +#include "Combo.h" +#include "ComSetup.h" +#include "Dlgcode.h" +#include "Language.h" +#include "Registry.h" +#include "Resource.h" + +#include "Dir.h" +#include "Setup.h" + +#include "../Common/Resource.h" + +#pragma comment(lib, "Shlwapi.lib") + +using namespace VeraCrypt; + +#pragma warning( disable : 4201 ) +#pragma warning( disable : 4115 ) + +#include + +#pragma warning( default : 4201 ) +#pragma warning( default : 4115 ) + +#include + +#include +#include +#include + +#include +#if !defined(va_copy) +#define va_copy(d, s) ((d) = (s)) +#endif + +typedef enum +{ + MSI_INFO_LEVEL = 0, + MSI_WARNING_LEVEL, + MSI_ERROR_LEVEL +} eMSILogLevel; + +#define WAIT_PERIOD 3 + +extern HMODULE hRichEditDll; +extern HMODULE hComctl32Dll; +extern HMODULE hSetupDll; +extern HMODULE hShlwapiDll; +extern HMODULE hProfApiDll; +extern HMODULE hUsp10Dll; +extern HMODULE hCryptSpDll; +extern HMODULE hUXThemeDll; +extern HMODULE hUserenvDll; +extern HMODULE hRsaenhDll; +extern HMODULE himm32dll; +extern HMODULE hMSCTFdll; +extern HMODULE hfltlibdll; +extern HMODULE hframedyndll; +extern HMODULE hpsapidll; +extern HMODULE hsecur32dll; +extern HMODULE hnetapi32dll; +extern HMODULE hauthzdll; +extern HMODULE hxmllitedll; +extern HMODULE hmprdll; +extern HMODULE hsppdll; +extern HMODULE vssapidll; +extern HMODULE hvsstracedll; +extern HMODULE hcfgmgr32dll; +extern HMODULE hdevobjdll; +extern HMODULE hpowrprofdll; +extern HMODULE hsspiclidll; +extern HMODULE hcryptbasedll; +extern HMODULE hdwmapidll; +extern HMODULE hmsasn1dll; +extern HMODULE hcrypt32dll; +extern HMODULE hbcryptdll; +extern HMODULE hbcryptprimitivesdll; +extern HMODULE hMsls31; +extern HMODULE hntmartadll; +extern HMODULE hwinscarddll; +extern HMODULE hmsvcrtdll; +extern HMODULE hWinTrustLib; +extern HMODULE hAdvapi32Dll; + +#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); + +// 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 + ); + +extern SetDllDirectoryPtr SetDllDirectoryFn; +extern SetSearchPathModePtr SetSearchPathModeFn; +extern SetDefaultDllDirectoriesPtr SetDefaultDllDirectoriesFn; + +extern ImageList_CreatePtr ImageList_CreateFn; +extern ImageList_AddPtr ImageList_AddFn; + +extern SetupCloseInfFilePtr SetupCloseInfFileFn; +extern SetupDiOpenClassRegKeyPtr SetupDiOpenClassRegKeyFn; +extern SetupInstallFromInfSectionWPtr SetupInstallFromInfSectionWFn; +extern SetupOpenInfFileWPtr SetupOpenInfFileWFn; +extern SHDeleteKeyWPtr SHDeleteKeyWFn; +extern SHStrDupWPtr SHStrDupWFn; +extern ChangeWindowMessageFilterPtr ChangeWindowMessageFilterFn; +extern CreateProcessWithTokenWFn CreateProcessWithTokenWPtr; + +wchar_t InstallationPath[TC_MAX_PATH]; + +BOOL bUninstall = FALSE; +BOOL bDowngrade = FALSE; +BOOL bUninstallInProgress = FALSE; +BOOL PortableMode = FALSE; +BOOL UnloadDriver = TRUE; + +BOOL Rollback = FALSE; +BOOL bReinstallMode = FALSE; +BOOL bUpgrade = FALSE; +BOOL bPossiblyFirstTimeInstall = FALSE; +BOOL bDevm = FALSE; +BOOL SystemEncryptionUpdate = FALSE; +BOOL bRestartRequired = FALSE; +BOOL bDisableSwapFiles = FALSE; +BOOL bSystemRestore = TRUE; +HMODULE volatile SystemRestoreDll = 0; + +BOOL bPromptFastStartup = FALSE; +BOOL bPromptReleaseNotes = FALSE; +BOOL bPromptTutorial = FALSE; +BOOL bUpdateRescueDisk = FALSE; +BOOL bRepairMode = FALSE; +BOOL bUserSetLanguage = FALSE; + +/* +BOOL bMakePackage = FALSE; +BOOL bDone = FALSE; + +BOOL bForAllUsers = TRUE; +BOOL bRegisterFileExt = TRUE; +BOOL bAddToStartMenu = TRUE; +BOOL bDesktopIcon = TRUE; +BOOL bDesktopIconStatusDetermined = FALSE; + +*/ + +/* **************************************************************************** */ + +/* Defined in this file, but a little bit late */ +BOOL IsSystemRestoreEnabled (); + +/* + * Same as in Setup.c + */ +BOOL ForceCopyFile (LPCWSTR szSrcFile, LPCWSTR szDestFile) +{ + BOOL bRet = CopyFileW (szSrcFile, szDestFile, FALSE); + if (!bRet) + { + wstring renamedPath = szDestFile; + renamedPath += VC_FILENAME_RENAMED_SUFFIX; + + /* rename the locked file in order to be able to create a new one */ + if (MoveFileExW (szDestFile, renamedPath.c_str(), MOVEFILE_REPLACE_EXISTING)) + { + bRet = CopyFileW (szSrcFile, szDestFile, FALSE); + if (bRet) + { + /* delete the renamed file when the machine reboots */ + MoveFileEx (renamedPath.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + } + else + { + /* restore the original file name */ + MoveFileEx (renamedPath.c_str(), szDestFile, MOVEFILE_REPLACE_EXISTING); + } + } + } + + return bRet; +} + +/* + * Same as in Setup.c + */ +BOOL ForceDeleteFile (LPCWSTR szFileName) +{ + if (!DeleteFile (szFileName)) + { + /* delete the renamed file when the machine reboots */ + return MoveFileEx (szFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + } + else + return TRUE; +} + +/* + * Same as in Setup.c + */ +BOOL StatDeleteFile (wchar_t *lpszFile, BOOL bCheckForOldFile) +{ + struct __stat64 st; + + if (bCheckForOldFile) + { + wchar_t szOldPath[MAX_PATH + 1]; + StringCbCopyW (szOldPath, sizeof(szOldPath), lpszFile); + StringCbCatW (szOldPath, sizeof(szOldPath), VC_FILENAME_RENAMED_SUFFIX); + + if (_wstat64 (szOldPath, &st) == 0) + { + ForceDeleteFile (szOldPath); + } + } + + if (_wstat64 (lpszFile, &st) == 0) + return ForceDeleteFile (lpszFile); + else + return TRUE; +} + +/* + * Same as in Setup.c + */ +BOOL StatRemoveDirectory (wchar_t *lpszDir) +{ + struct __stat64 st; + + if (_wstat64 (lpszDir, &st) == 0) + { + return DeleteDirectory (lpszDir); + } + else + return TRUE; +} + +/* + * Same as in Setup.c + */ +void StatusMessage (HWND hwndDlg, char *stringId) +{ + if (Rollback) + return; + + SendMessageW (GetDlgItem (hwndDlg, IDC_LOG_WINDOW), LB_ADDSTRING, 0, (LPARAM) GetString (stringId)); + + SendDlgItemMessage (hwndDlg, IDC_LOG_WINDOW, LB_SETTOPINDEX, + SendDlgItemMessage (hwndDlg, IDC_LOG_WINDOW, LB_GETCOUNT, 0, 0) - 1, 0); +} + +/* + * Same as in Setup.c + */ +void DetermineUpgradeDowngradeStatus (BOOL bCloseDriverHandle, LONG *driverVersionPtr) +{ + LONG driverVersion = VERSION_NUM; + int status = 0; + + if (hDriver == INVALID_HANDLE_VALUE) + status = DriverAttach(); + + if ((status == 0) && (hDriver != INVALID_HANDLE_VALUE)) + { + DWORD dwResult; + BOOL bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &driverVersion, sizeof (driverVersion), &dwResult, NULL); + + if (!bResult) + bResult = DeviceIoControl (hDriver, TC_IOCTL_LEGACY_GET_DRIVER_VERSION, NULL, 0, &driverVersion, sizeof (driverVersion), &dwResult, NULL); + + + bUpgrade = (bResult && driverVersion <= VERSION_NUM); + bDowngrade = (bResult && driverVersion > VERSION_NUM); + bReinstallMode = (bResult && driverVersion == VERSION_NUM); + + PortableMode = DeviceIoControl (hDriver, TC_IOCTL_GET_PORTABLE_MODE_STATUS, NULL, 0, NULL, 0, &dwResult, NULL); + + if (bCloseDriverHandle) + { + CloseHandle (hDriver); + hDriver = INVALID_HANDLE_VALUE; + } + } + + *driverVersionPtr = driverVersion; +} + +/* + * Same as in Setup.c + */ +BOOL IsSystemRestoreEnabled () +{ + BOOL bEnabled = FALSE; + HKEY hKey; + DWORD dwValue = 0, cbValue = sizeof (DWORD); + wchar_t szRegPath[MAX_PATH]; + GetRestorePointRegKeyName (szRegPath, sizeof (szRegPath)); + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szRegPath, 0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) + { + if (IsOSAtLeast (WIN_VISTA)) + { + if ( (ERROR_SUCCESS == RegQueryValueEx (hKey, L"RPSessionInterval", NULL, NULL, (LPBYTE) &dwValue, &cbValue)) + && (dwValue == 1) + ) + { + bEnabled = TRUE; + } + } + else + { + if ( (ERROR_SUCCESS == RegQueryValueEx (hKey, L"DisableSR", NULL, NULL, (LPBYTE) &dwValue, &cbValue)) + && (dwValue == 0) + ) + { + bEnabled = TRUE; + } + } + + + RegCloseKey (hKey); + } + + return bEnabled; +} + +/* + * Same as in Setup.c + */ +static void RecursiveSetOwner (HKEY hKey, PSECURITY_DESCRIPTOR pSD) +{ + LSTATUS status = 0; + DWORD dwIndex = 0, dwMaxNameLen = 0, dwNameLen = 0, numberSubKeys = 0; + HKEY hSubKey; + + if ( (ERROR_SUCCESS == status) && (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, NULL, &numberSubKeys, &dwMaxNameLen, NULL, NULL, NULL, NULL, NULL, NULL)) + && (numberSubKeys >= 1) + ) + { + dwMaxNameLen++; + wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; + while (true) + { + dwNameLen = dwMaxNameLen; + status = RegEnumKeyExW (hKey, dwIndex++, szNameValue, &dwNameLen, NULL, NULL, NULL, NULL); + if (status == ERROR_SUCCESS) + { + status = RegOpenKeyExW (hKey, szNameValue, 0, WRITE_OWNER | KEY_READ , &hSubKey); + if (ERROR_SUCCESS == status) + { + RecursiveSetOwner (hSubKey, pSD); + RegCloseKey(hSubKey); + } + } + else + break; + } + delete [] szNameValue; + } + + RegSetKeySecurity (hKey, OWNER_SECURITY_INFORMATION, pSD); +} + +/* + * Same as in Setup.c + */ +static void RecursiveSetDACL (HKEY hKey, const wchar_t* SubKeyName, PSECURITY_DESCRIPTOR pSD) +{ + HKEY hSubKey; + DWORD dwIndex = 0, dwMaxNameLen = 0, dwNameLen = 0, numberSubKeys = 0; + LSTATUS status = RegOpenKeyExW(hKey, SubKeyName, 0, WRITE_DAC | KEY_READ /*| ACCESS_SYSTEM_SECURITY*/, &hSubKey); + if (status == ERROR_SUCCESS) + { + status = RegSetKeySecurity (hSubKey, DACL_SECURITY_INFORMATION, pSD); + if (status == ERROR_SUCCESS) + { + RegCloseKey(hSubKey); + status = RegOpenKeyExW(hKey, SubKeyName, 0, WRITE_DAC | KEY_READ , &hSubKey); + } + + if ( (ERROR_SUCCESS == status) + && (ERROR_SUCCESS == RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &numberSubKeys, &dwMaxNameLen, NULL, NULL, NULL, NULL, NULL, NULL)) + && (numberSubKeys >= 1) + ) + { + dwMaxNameLen++; + wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; + while (true) + { + dwNameLen = dwMaxNameLen; + status = RegEnumKeyExW (hSubKey, dwIndex++, szNameValue, &dwNameLen, NULL, NULL, NULL, NULL); + if (status == ERROR_SUCCESS) + { + RecursiveSetDACL (hSubKey, szNameValue, pSD); + } + else + break; + } + delete [] szNameValue; + } + } +} + +/* + * Same as in Setup.c + */ +static void AllowKeyAccess(HKEY Key,const wchar_t* SubKeyName) +{ + LSTATUS RegResult; + HKEY SvcKey = NULL; + DWORD dwLength = 0; + HANDLE Token = NULL; + PTOKEN_USER pTokenUser = NULL; + std::string sNewSD; + + RegResult = RegOpenKeyExW(Key, SubKeyName, 0, WRITE_OWNER | KEY_READ, &SvcKey); + if (RegResult==ERROR_SUCCESS) + { + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token)) + { + if (!GetTokenInformation(Token, TokenUser, pTokenUser, 0, &dwLength)) + { + if (GetLastError() ==ERROR_INSUFFICIENT_BUFFER) + { + pTokenUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); + if (pTokenUser) + { + if (GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, &dwLength)) + { + SECURITY_DESCRIPTOR SecDesc; + if ( InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION) + && SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE) // NULL DACL: full access to everyone + && SetSecurityDescriptorOwner(&SecDesc, pTokenUser->User.Sid, FALSE) + ) + { + RecursiveSetOwner(SvcKey, &SecDesc); + } + } + + } + } + } + } + RegCloseKey(SvcKey); + } + + if (pTokenUser) + { + PSID pSid = pTokenUser->User.Sid; + DWORD dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + ::GetLengthSid(pSid) - sizeof(DWORD); + PACL pDacl = (PACL) new BYTE[dwAclSize]; + if (pDacl) + { + if (TRUE == ::InitializeAcl(pDacl, dwAclSize, ACL_REVISION)) + { + if (TRUE == AddAccessAllowedAceEx(pDacl, ACL_REVISION, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, WRITE_DAC | KEY_ALL_ACCESS, pSid)) + { + SECURITY_DESCRIPTOR SecDesc; + if (TRUE == ::InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION)) + { + if (TRUE == ::SetSecurityDescriptorDacl(&SecDesc, TRUE, pDacl, FALSE)) + { + RecursiveSetDACL (Key, SubKeyName, &SecDesc); + } + } + } + } + delete [] pDacl; + } + } + + if (pTokenUser) + HeapFree(GetProcessHeap(), 0, pTokenUser); + if (Token) + CloseHandle(Token); +} + +/* + * Same as in Setup.c + */ +void SearchAndDeleteRegistrySubString (HKEY hKey, const wchar_t *subKey, const wchar_t *str, BOOL bEnumSubKeys, const wchar_t* enumMatchSubStr) +{ + HKEY hSubKey = 0; + LSTATUS status = 0; + DWORD dwIndex = 0, dwType, dwValueNameLen, dwDataLen; + std::list subKeysList; + size_t subStringLength = str? wcslen(str) : 0; + + if (bEnumSubKeys) + { + DWORD dwMaxNameLen = 0; + if (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwMaxNameLen, NULL, NULL, NULL, NULL, NULL, NULL)) + { + dwMaxNameLen++; + wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; + dwIndex = 0; + while (true) + { + dwValueNameLen = dwMaxNameLen; + status = RegEnumKeyExW (hKey, dwIndex++, szNameValue, &dwValueNameLen, NULL, NULL, NULL, NULL); + if (status == ERROR_SUCCESS) + { + if (enumMatchSubStr && !wcsstr(szNameValue, enumMatchSubStr)) + continue; + std::wstring entryName = szNameValue; + entryName += L"\\"; + entryName += subKey; + entryName += L"\\"; + subKeysList.push_back(entryName); + } + else + break; + } + delete [] szNameValue; + } + } + else + { + subKeysList.push_back(subKey); + } + + for (std::list::iterator ItSubKey = subKeysList.begin(); ItSubKey != subKeysList.end(); ItSubKey++) + { + // if the string to search for is empty, delete the sub key, otherwise, look for matching value and delete them + if (subStringLength == 0) + { + if (ERROR_ACCESS_DENIED == DeleteRegistryKey (hKey, ItSubKey->c_str())) + { + // grant permission to delete + AllowKeyAccess (hKey, ItSubKey->c_str()); + + // try again + DeleteRegistryKey (hKey, ItSubKey->c_str()); + } + } + else + { + if (RegOpenKeyExW (hKey, ItSubKey->c_str(), 0, KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS) + { + DWORD dwMaxNameLen = 0, dwMaxDataLen = 0; + if (ERROR_SUCCESS == RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwMaxNameLen, &dwMaxDataLen, NULL, NULL)) + { + dwMaxNameLen++; + wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; + LPBYTE pbData = new BYTE[dwMaxDataLen]; + + std::list foundEntries; + dwIndex = 0; + do + { + dwValueNameLen = dwMaxNameLen; + dwDataLen = dwMaxDataLen; + status = RegEnumValueW(hSubKey, dwIndex++, szNameValue, &dwValueNameLen, NULL, &dwType, pbData, &dwDataLen); + if (status == ERROR_SUCCESS) + { + if ( (wcslen(szNameValue) >= subStringLength && wcsstr(szNameValue, str)) + || (dwType == REG_SZ && wcslen((wchar_t*) pbData) >= subStringLength && wcsstr((wchar_t*) pbData, str)) + ) + { + foundEntries.push_back(szNameValue); + } + } + } while ((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)); // we ignore ERROR_MORE_DATA errors since + // we are sure to use the correct sizes + + // delete the entries + if (!foundEntries.empty()) + { + for (std::list::iterator It = foundEntries.begin(); + It != foundEntries.end(); It++) + { + RegDeleteValueW (hSubKey, It->c_str()); + } + } + + delete [] szNameValue; + delete [] pbData; + } + + + RegCloseKey (hSubKey); + } + } + } +} + +/* **************************************************************************** */ + +// Adds a line to the log file of the installer. +void MSILog(MSIHANDLE hInstall, eMSILogLevel level, const wchar_t* zcFormat, ...) +{ + std::wstring wszMessage; + + // initialize use of the variable argument array + va_list vaArgs; + va_start(vaArgs, zcFormat); + + // reliably acquire the size + // from a copy of the variable argument array + // and a functionally reliable call to mock the formatting + va_list vaArgsCopy; + va_copy(vaArgsCopy, vaArgs); + const int iLen = vswprintf(NULL, 0, zcFormat, vaArgsCopy); + va_end(vaArgsCopy); + + // return a formatted string without risking memory mismanagement + // and without assuming any compiler or platform specific behavior + std::vector zc(iLen + 1); + vswprintf(zc.data(), zc.size(), zcFormat, vaArgs); + va_end(vaArgs); + + wszMessage.assign(zc.data(), iLen); + +#ifdef TEST_HARNESS + if (!hInstall) + { + MessageBox(NULL, pszMessage, wszMessage.c_str(), 0); + return; + } +#endif + + PMSIHANDLE hRecord = MsiCreateRecord(1); + // field 0 is the template + MsiRecordSetString(hRecord, 0, (level == MSI_INFO_LEVEL) ? L"VeraCryptCustomAction_INFO: [1]" : ((level == MSI_WARNING_LEVEL) ? L"VeraCryptCustomAction_WARNING: [1]" : L"VeraCryptCustomAction_ERROR: [1]")); + // field 1, to be placed in [1] placeholder + MsiRecordSetString(hRecord, 1, wszMessage.c_str()); + // send message to running installer + MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRecord); +} + +// Adds a line to the log file of the installer and shows a popup. +// Since MsiProcessMessage() takes the UILEVEL into account, +// this won't cause a deadlock in case of a silent install. +void MSILogAndShow(MSIHANDLE hInstall, eMSILogLevel level, const wchar_t* zcFormat, ...) +{ + std::wstring wszMessage; + + // initialize use of the variable argument array + va_list vaArgs; + va_start(vaArgs, zcFormat); + + // reliably acquire the size + // from a copy of the variable argument array + // and a functionally reliable call to mock the formatting + va_list vaArgsCopy; + va_copy(vaArgsCopy, vaArgs); + const int iLen = vswprintf(NULL, 0, zcFormat, vaArgsCopy); + va_end(vaArgsCopy); + + // return a formatted string without risking memory mismanagement + // and without assuming any compiler or platform specific behavior + std::vector zc(iLen + 1); + vswprintf(zc.data(), zc.size(), zcFormat, vaArgs); + va_end(vaArgs); + + wszMessage.assign(zc.data(), iLen); + +#ifdef TEST_HARNESS + if (!hInstall) + { + MessageBox(NULL, pszMessage, wszMessage.c_str(), 0); + return; + } +#endif + + PMSIHANDLE hRecord0 = MsiCreateRecord(1); + // field 0 is the template + MsiRecordSetString(hRecord0, 0, (level == MSI_INFO_LEVEL) ? L"VeraCryptCustomAction_INFO: [1]" : ((level == MSI_WARNING_LEVEL) ? L"VeraCryptCustomAction_WARNING: [1]" : L"VeraCryptCustomAction_ERROR: [1]")); + // field 1, to be placed in [1] placeholder + MsiRecordSetString(hRecord0, 1, wszMessage.c_str()); + // send message to running installer + MsiProcessMessage(hInstall, INSTALLMESSAGE_INFO, hRecord0); + + PMSIHANDLE hRecord1 = MsiCreateRecord(0); + MsiRecordSetString(hRecord1, 0, wszMessage.c_str()); + if (level == MSI_INFO_LEVEL) + MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO + MB_OK), hRecord1); + else if (level == MSI_WARNING_LEVEL) + MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord1); + else + MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_ERROR + MB_OK), hRecord1); +} + +/* **************************************************************************** */ + +/* + * Defined in Dlgcode.c. + */ +extern void ExceptionHandlerThread (void *threadArg); +extern LONG __stdcall ExceptionHandler (EXCEPTION_POINTERS *ep); +extern void InvalidParameterHandler (const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t reserved); +extern BOOL SystemFileSelectorCallPending; +extern DWORD SystemFileSelectorCallerThreadId; + +/* **************************************************************************** */ + +/* + * Same as in Dlgcode.c, Applink() , but + * removed unnecessary code. + */ +void Applink_Dll (MSIHANDLE hInstaller, const char *dest) +{ + wchar_t url [MAX_URL_LENGTH] = {0}; + wchar_t page[TC_MAX_PATH] = {0}; + wchar_t installDir[TC_MAX_PATH] = {0}; + BOOL buildUrl = TRUE; + int r; + + StringCbCopyW (installDir, sizeof (installDir), InstallationPath); + + if (strcmp(dest, "donate") == 0) + { + StringCbCopyW (page, sizeof (page),L"Donation.html"); + } + else if (strcmp(dest, "main") == 0) + { + StringCbCopyW (url, sizeof (url), TC_HOMEPAGE); + buildUrl = FALSE; + } + else if (strcmp(dest,"localizations") == 0) + { + StringCbCopyW (page, sizeof (page),L"Language%20Packs.html"); + } + else if (strcmp(dest, "beginnerstutorial") == 0 || strcmp(dest,"tutorial") == 0) + { + StringCbCopyW (page, sizeof (page),L"Beginner%27s%20Tutorial.html"); + } + else if (strcmp(dest, "releasenotes") == 0 || strcmp(dest, "history") == 0) + { + StringCbCopyW (page, sizeof (page),L"Release%20Notes.html"); + } + else if (strcmp(dest, "hwacceleration") == 0) + { + StringCbCopyW (page, sizeof (page),L"Hardware%20Acceleration.html"); + } + else if (strcmp(dest, "parallelization") == 0) + { + StringCbCopyW (page, sizeof (page),L"Parallelization.html"); + } + else if (strcmp(dest, "help") == 0) + { + StringCbCopyW (page, sizeof (page),L"Documentation.html"); + } + else if (strcmp(dest, "onlinehelp") == 0) + { + StringCbCopyW (url, sizeof (url),L"https://www.veracrypt.fr/en/Documentation.html"); + buildUrl = FALSE; + } + else if (strcmp(dest, "keyfiles") == 0) + { + StringCbCopyW (page, sizeof (page),L"Keyfiles.html"); + } + else if (strcmp(dest, "introcontainer") == 0) + { + StringCbCopyW (page, sizeof (page),L"Creating%20New%20Volumes.html"); + } + else if (strcmp(dest, "introsysenc") == 0) + { + StringCbCopyW (page, sizeof (page),L"System%20Encryption.html"); + } + else if (strcmp(dest, "hiddensysenc") == 0) + { + StringCbCopyW (page, sizeof (page),L"VeraCrypt%20Hidden%20Operating%20System.html"); + } + else if (strcmp(dest, "sysencprogressinfo") == 0) + { + StringCbCopyW (page, sizeof (page),L"System%20Encryption.html"); + } + else if (strcmp(dest, "hiddenvolume") == 0) + { + StringCbCopyW (page, sizeof (page),L"Hidden%20Volume.html"); + } + else if (strcmp(dest, "aes") == 0) + { + StringCbCopyW (page, sizeof (page),L"AES.html"); + } + else if (strcmp(dest, "serpent") == 0) + { + StringCbCopyW (page, sizeof (page),L"Serpent.html"); + } + else if (strcmp(dest, "twofish") == 0) + { + StringCbCopyW (page, sizeof (page),L"Twofish.html"); + } + else if (strcmp(dest, "kuznyechik") == 0) + { + StringCbCopyW (page, sizeof (page),L"Kuznyechik.html"); + } + else if (strcmp(dest, "camellia") == 0) + { + StringCbCopyW (page, sizeof (page),L"Camellia.html"); + } + else if (strcmp(dest, "cascades") == 0) + { + StringCbCopyW (page, sizeof (page),L"Cascades.html"); + } + else if (strcmp(dest, "hashalgorithms") == 0) + { + StringCbCopyW (page, sizeof (page),L"Hash%20Algorithms.html"); + } + else if (strcmp(dest, "isoburning") == 0) + { + StringCbCopyW (url, sizeof (url),L"https://cdburnerxp.se/en/home"); + buildUrl = FALSE; + } + else if (strcmp(dest, "sysfavorites") == 0) + { + StringCbCopyW (page, sizeof (page),L"System%20Favorite%20Volumes.html"); + } + else if (strcmp(dest, "favorites") == 0) + { + StringCbCopyW (page, sizeof (page),L"Favorite%20Volumes.html"); + } + else if (strcmp(dest, "hiddenvolprotection") == 0) + { + StringCbCopyW (page, sizeof (page),L"Protection%20of%20Hidden%20Volumes.html"); + } + else if (strcmp(dest, "faq") == 0) + { + StringCbCopyW (page, sizeof (page),L"FAQ.html"); + } + else if (strcmp(dest, "downloads") == 0) + { + StringCbCopyW (page, sizeof (page),L"Downloads.html"); + } + else if (strcmp(dest, "news") == 0) + { + StringCbCopyW (page, sizeof (page),L"News.html"); + } + else if (strcmp(dest, "contact") == 0) + { + StringCbCopyW (page, sizeof (page),L"Contact.html"); + } + else if (strcmp(dest, "pim") == 0) + { + StringCbCopyW (page, sizeof (page),L"Personal%20Iterations%20Multiplier%20%28PIM%29.html"); + } + else + { + StringCbCopyW (url, sizeof (url),TC_APPLINK); + buildUrl = FALSE; + } + + if (buildUrl) + { + StringCbPrintfW (url, sizeof (url), L"file:///%sdocs/html/en/%s", installDir, page); + CorrectURL (url); + } + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Applink_Dll: url(%s)", url); + + if (IsAdmin ()) + { + // TODO: FileExists always returns FALSE + // This is due to the fact that waccess does not like url encoded as 'file:///%sdocs/html/en/%s'. + // It fails with '0x0000007B: The filename, directory name, or volume label syntax is incorrect.'. + if (buildUrl && !FileExists (url)) + { + // fallbacl to online resources + StringCbPrintfW (url, sizeof (url), L"https://www.veracrypt.fr/en/%s", page); + SafeOpenURL (url); + } + else + { + SafeOpenURL (url); + } + } + else + { + r = (int) ShellExecuteW (NULL, L"open", url, NULL, NULL, SW_SHOWNORMAL); + + if (((r == ERROR_FILE_NOT_FOUND) || (r == ERROR_PATH_NOT_FOUND)) && buildUrl) + { + // fallbacl to online resources + StringCbPrintfW (url, sizeof (url), L"https://www.veracrypt.fr/en/%s", page); + ShellExecuteW (NULL, L"open", url, NULL, NULL, SW_SHOWNORMAL); + } + } +} + +/* + * Same as in Dlgcode.c, CheckCapsLock(), but + * replaced MessageBoxW() with MSILogAndShow(). + */ +BOOL CheckCapsLock_Dll (MSIHANDLE hInstaller, BOOL quiet) +{ + if ((GetKeyState(VK_CAPITAL) & 1) != 0) + { + MSILogAndShow(hInstaller, MSI_WARNING_LEVEL, GetString ("CAPSLOCK_ON")); + return TRUE; + } + return FALSE; +} + +/* + * Same as in Dlgcode.c, GetWrongPasswordErrorMessage(), but + * replaced CheckCapsLock() with CheckCapsLock_Dll(). + */ +std::wstring GetWrongPasswordErrorMessage_Dll (MSIHANDLE hInstaller) +{ + WCHAR szTmp[8192]; + + StringCbPrintfW (szTmp, sizeof(szTmp), GetString (KeyFilesEnable ? "PASSWORD_OR_KEYFILE_WRONG" : "PASSWORD_WRONG")); + if (CheckCapsLock_Dll (hInstaller, TRUE)) + StringCbCatW (szTmp, sizeof(szTmp), GetString ("PASSWORD_WRONG_CAPSLOCK_ON")); + + wstring msg = szTmp; + return msg; +} + +/* + * Same as in Dlgcode.c, HandleDriveNotReadyError(), but + * replaced Warning() with MSILogAndShow(). + */ +void HandleDriveNotReadyError_Dll (MSIHANDLE hInstaller) +{ + HKEY hkey = 0; + DWORD value = 0, size = sizeof (DWORD); + + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\MountMgr", + 0, KEY_READ, &hkey) != ERROR_SUCCESS) + return; + + if (RegQueryValueEx (hkey, L"NoAutoMount", 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS + && value != 0) + { + MSILogAndShow (hInstaller, MSI_WARNING_LEVEL, GetString("SYS_AUTOMOUNT_DISABLED")); + } + else if (nCurrentOS == WIN_VISTA && CurrentOSServicePack < 1) + MSILogAndShow (hInstaller, MSI_WARNING_LEVEL, GetString("SYS_ASSIGN_DRIVE_LETTER")); + else + MSILogAndShow (hInstaller, MSI_WARNING_LEVEL, GetString("DEVICE_NOT_READY_ERROR")); + + RegCloseKey (hkey); +} + +/* + * Same as in Dlgcode.c, handleWin32Error(), but + * replaced ErrorDirect(), Error() and MessageBoxW with MSILogAndShow(), + * replaced HandleDriveNotReadyError() with HandleDriveNotReadyError_Dll(). + */ +DWORD handleWin32Error_Dll (MSIHANDLE hInstaller, const char* srcPos) +{ + PWSTR lpMsgBuf; + DWORD dwError = GetLastError (); + wchar_t szErrorValue[32]; + wchar_t* pszDesc; + + if (dwError == 0 || dwError == ERROR_INVALID_WINDOW_HANDLE) + return dwError; + + // Access denied + if (dwError == ERROR_ACCESS_DENIED && !IsAdmin ()) + { + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("ERR_ACCESS_DENIED"), srcPos).c_str ()); + 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; + } + + MSILogAndShow (hInstaller, MSI_INFO_LEVEL, AppendSrcPos (pszDesc, srcPos).c_str ()); + if (lpMsgBuf) LocalFree (lpMsgBuf); + + // User-friendly hardware error explanation + if (IsDiskError (dwError)) + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString("ERR_HARDWARE_ERROR")); + + // Device not ready + if (dwError == ERROR_NOT_READY) + HandleDriveNotReadyError_Dll(hInstaller); + + SetLastError (dwError); // Preserve the original error code + + return dwError; +} + +/* + * Same as in Dlgcode.c, handleError(), but + * replaced ErrorDirect(), Error() and MessageBoxW with MSILogAndShow(), + * replaced handleWin32Error() with handleWin32Error_Dll(). + */ +void handleError_Dll (MSIHANDLE hInstaller, int code, const char* srcPos) +{ + WCHAR szTmp[4096]; + + switch (code & 0x0000FFFF) + { + case ERR_OS_ERROR: + handleWin32Error_Dll (hInstaller, srcPos); + break; + case ERR_OUTOFMEMORY: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("OUTOFMEMORY"), srcPos).c_str()); + break; + + case ERR_PASSWORD_WRONG: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetWrongPasswordErrorMessage_Dll (hInstaller).c_str(), srcPos).c_str()); + break; + + case ERR_DRIVE_NOT_FOUND: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("NOT_FOUND"), srcPos).c_str()); + break; + case ERR_FILES_OPEN: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("OPENFILES_DRIVER"), srcPos).c_str()); + break; + case ERR_FILES_OPEN_LOCK: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("OPENFILES_LOCK"), srcPos).c_str()); + break; + case ERR_VOL_SIZE_WRONG: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("VOL_SIZE_WRONG"), srcPos).c_str()); + break; + case ERR_COMPRESSION_NOT_SUPPORTED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("COMPRESSION_NOT_SUPPORTED"), srcPos).c_str()); + break; + case ERR_PASSWORD_CHANGE_VOL_TYPE: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("WRONG_VOL_TYPE"), srcPos).c_str()); + break; + case ERR_VOL_SEEKING: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("VOL_SEEKING"), srcPos).c_str()); + break; + case ERR_CIPHER_INIT_FAILURE: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("ERR_CIPHER_INIT_FAILURE"), srcPos).c_str()); + break; + case ERR_CIPHER_INIT_WEAK_KEY: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("ERR_CIPHER_INIT_WEAK_KEY"), srcPos).c_str()); + break; + case ERR_VOL_ALREADY_MOUNTED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("VOL_ALREADY_MOUNTED"), srcPos).c_str()); + break; + case ERR_FILE_OPEN_FAILED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("FILE_OPEN_FAILED"), srcPos).c_str()); + break; + case ERR_VOL_MOUNT_FAILED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("VOL_MOUNT_FAILED"), srcPos).c_str()); + break; + case ERR_NO_FREE_DRIVES: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("NO_FREE_DRIVES"), srcPos).c_str()); + break; + case ERR_ACCESS_DENIED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("ACCESS_DENIED"), srcPos).c_str()); + break; + + case ERR_DRIVER_VERSION: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString("DRIVER_VERSION")); + break; + + case ERR_NEW_VERSION_REQUIRED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (GetString ("NEW_VERSION_REQUIRED"), srcPos).c_str()); + break; + + case ERR_SELF_TESTS_FAILED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString("ERR_SELF_TESTS_FAILED")); + break; + + case ERR_VOL_FORMAT_BAD: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString ("ERR_VOL_FORMAT_BAD")); + break; + + case ERR_ENCRYPTION_NOT_COMPLETED: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString ("ERR_ENCRYPTION_NOT_COMPLETED")); + break; + + case ERR_NONSYS_INPLACE_ENC_INCOMPLETE: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString ("ERR_NONSYS_INPLACE_ENC_INCOMPLETE")); + break; + + case ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString ("ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG")); + break; + + case ERR_PARAMETER_INCORRECT: + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString ("ERR_PARAMETER_INCORRECT")); + break; + + case ERR_USER_ABORT: + case ERR_DONT_REPORT: + // A non-error + break; + + case ERR_UNSUPPORTED_TRUECRYPT_FORMAT: + StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("UNSUPPORTED_TRUECRYPT_FORMAT"), (code >> 24), (code >> 16) & 0x000000FF); + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (szTmp, srcPos).c_str()); + break; + + default: + StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("ERR_UNKNOWN"), code); + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, AppendSrcPos (szTmp, srcPos).c_str()); + } +} + +/* + * Same as in Dlgcode.c, LoadSystemDll() , but + * replaced AbortProcess() with MSILogAndShow() + return, + */ +static void LoadSystemDll_Dll (MSIHANDLE hInstaller, 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_Dll (hInstaller, srcPos); + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString ("INIT_DLL")); + } +} + +/* + * Same as in Dlgcode.c, handleWin32Error(), but + * replaced AbortProcess() with MSILogAndShow() + return, + */ +BOOL IsPagingFileActive_Dll (MSIHANDLE hInstaller, BOOL checkNonWindowsPartitionsOnly) +{ + // GlobalMemoryStatusEx() cannot be used to determine if a paging file is active + + wchar_t data[65536]; + DWORD size = sizeof (data); + + if (IsPagingFileWildcardActive()) + return TRUE; + + if (ReadLocalMachineRegistryMultiString (L"System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", L"PagingFiles", data, &size) + && size > 24 && !checkNonWindowsPartitionsOnly) + return TRUE; + + if (!IsAdmin()) + { + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString("UAC_INIT_ERROR")); + return FALSE; + } + + for (wchar_t drive = L'C'; drive <= L'Z'; ++drive) + { + // Query geometry of the drive first to prevent "no medium" pop-ups + wstring drivePath = L"\\\\.\\X:"; + drivePath[4] = drive; + + if (checkNonWindowsPartitionsOnly) + { + wchar_t sysDir[MAX_PATH]; + if (GetSystemDirectory (sysDir, ARRAYSIZE (sysDir)) != 0 && towupper (sysDir[0]) == drive) + continue; + } + + HANDLE handle = CreateFile (drivePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + + if (handle == INVALID_HANDLE_VALUE) + continue; + + BYTE dgBuffer[256]; + DWORD dwResult; + + if (!DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, dgBuffer, sizeof (dgBuffer), &dwResult, NULL) + && !DeviceIoControl (handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, dgBuffer, sizeof (dgBuffer), &dwResult, NULL)) + { + CloseHandle (handle); + continue; + } + + CloseHandle (handle); + + // Test if a paging file exists and is locked by another process + wstring path = L"X:\\pagefile.sys"; + path[0] = drive; + + handle = CreateFile (path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + + if (handle != INVALID_HANDLE_VALUE) + CloseHandle (handle); + else if (GetLastError() == ERROR_SHARING_VIOLATION) + return TRUE; + } + + return FALSE; +} + +/* + * Same as in Dlgcode.c, DoDriverInstall(), but + * replaced StatusMessage() with MSILog(). + */ +BOOL DoDriverInstall_Dll (MSIHANDLE hInstaller) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin DoDriverInstall_Dll"); + + SC_HANDLE hManager, hService = NULL; + BOOL bOK = FALSE, bRet; + +#ifdef SETUP + if (SystemEncryptionUpdate) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"SystemEncryptionUpdate == TRUE"); + bOK = TRUE; + goto end; + } +#endif + + hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hManager == NULL) + goto error; + +#ifdef SETUP + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("INSTALLING_DRIVER")); +#endif + + hService = CreateService (hManager, L"veracrypt", L"veracrypt", + SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_SYSTEM_START, SERVICE_ERROR_NORMAL, + L"System32\\drivers\\veracrypt.sys", + NULL, NULL, NULL, NULL, NULL); + + if (hService == NULL) + goto error; + else + CloseServiceHandle (hService); + + hService = OpenService (hManager, L"veracrypt", SERVICE_ALL_ACCESS); + if (hService == NULL) + goto error; + +#ifdef SETUP + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("STARTING_DRIVER")); +#endif + + bRet = StartService (hService, 0, NULL); + if (bRet == FALSE) + goto error; + + bOK = TRUE; + +error: + if (bOK == FALSE && GetLastError () != ERROR_SERVICE_ALREADY_RUNNING) + { + handleWin32Error_Dll (hInstaller, SRC_POS); + MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, GetString("DRIVER_INSTALL_FAILED")); + } + else + bOK = TRUE; + + if (hService != NULL) + CloseServiceHandle (hService); + + if (hManager != NULL) + CloseServiceHandle (hManager); + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End DoDriverInstall_Dll"); + return bOK; +} + +/* **************************************************************************** */ + +/* + * Same as in Setup.c, StartStopService(), but + * replaced StatusMessage() with MSILog(). + */ +BOOL StartStopService_Dll (MSIHANDLE hInstaller, wchar_t *lpszService, BOOL bStart, DWORD argc, LPCWSTR* argv) +{ + SC_HANDLE hManager, hService = NULL; + BOOL bOK = FALSE, bRet; + SERVICE_STATUS status = {0}; + int x; + DWORD dwExpectedState = bStart? SERVICE_RUNNING : SERVICE_STOPPED; + + hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hManager == NULL) + goto error; + + hService = OpenService (hManager, lpszService, SERVICE_ALL_ACCESS); + if (hService == NULL) + goto error; + + if (bStart) + MSILog(hInstaller, MSI_INFO_LEVEL, L"STARTING %s", lpszService); + else + MSILog(hInstaller, MSI_INFO_LEVEL, L"STOPPING %s", lpszService); + + if (bStart) + { + if (!StartService (hService, argc, argv) && (GetLastError () != ERROR_SERVICE_ALREADY_RUNNING)) + goto error; + } + else + ControlService (hService, SERVICE_CONTROL_STOP, &status); + + for (x = 0; x < WAIT_PERIOD; x++) + { + bRet = QueryServiceStatus (hService, &status); + if (bRet != TRUE) + goto error; + + if (status.dwCurrentState == dwExpectedState) + break; + + Sleep (1000); + } + + bRet = QueryServiceStatus (hService, &status); + if (bRet != TRUE) + goto error; + + if (status.dwCurrentState != dwExpectedState) + goto error; + + bOK = TRUE; + +error: + + if (bOK == FALSE && GetLastError () == ERROR_SERVICE_DOES_NOT_EXIST) + { + bOK = TRUE; + } + + if (hService != NULL) + CloseServiceHandle (hService); + + if (hManager != NULL) + CloseServiceHandle (hManager); + + return bOK; +} + +/* + * Same as in Setup.c, SetSystemRestorePoint(), but + * replaced StatusMessage() with MSILog(). + */ +static void SetSystemRestorePoint_Dll (MSIHANDLE hInstaller, BOOL finalize) +{ + static RESTOREPOINTINFO RestPtInfo; + static STATEMGRSTATUS SMgrStatus; + static BOOL failed = FALSE; + static BOOL (__stdcall *_SRSetRestorePoint)(PRESTOREPOINTINFO, PSTATEMGRSTATUS); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin SetSystemRestorePoint_Dll"); + + if (!SystemRestoreDll) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"SystemRestoreDll NULL"); + goto end; + } + + _SRSetRestorePoint = (BOOL (__stdcall *)(PRESTOREPOINTINFO, PSTATEMGRSTATUS))GetProcAddress (SystemRestoreDll,"SRSetRestorePointW"); + if (_SRSetRestorePoint == 0) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"_SRSetRestorePoint NULL"); + FreeLibrary (SystemRestoreDll); + SystemRestoreDll = 0; + goto end; + } + + if (!finalize) + { + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("CREATING_SYS_RESTORE")); + + RestPtInfo.dwEventType = BEGIN_SYSTEM_CHANGE; + RestPtInfo.dwRestorePtType = bUninstall ? APPLICATION_UNINSTALL : APPLICATION_INSTALL | DEVICE_DRIVER_INSTALL; + RestPtInfo.llSequenceNumber = 0; + StringCbCopyW (RestPtInfo.szDescription, sizeof(RestPtInfo.szDescription), bUninstall ? L"VeraCrypt uninstallation" : L"VeraCrypt installation"); + + if(!_SRSetRestorePoint (&RestPtInfo, &SMgrStatus)) + { + MSILog (hInstaller, MSI_ERROR_LEVEL, GetString("FAILED_SYS_RESTORE")); + failed = TRUE; + } + } + else if (!failed) + { + RestPtInfo.dwEventType = END_SYSTEM_CHANGE; + RestPtInfo.llSequenceNumber = SMgrStatus.llSequenceNumber; + + if(!_SRSetRestorePoint(&RestPtInfo, &SMgrStatus)) + { + MSILog (hInstaller, MSI_ERROR_LEVEL, GetString("FAILED_SYS_RESTORE")); + } + } + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End SetSystemRestorePoint_Dll"); +} + +/* + * Same as in Setup.c, DoDriverUnload(), but + * replaced AbortProcess() and AbortProcessSilent() with MSILogAndShow() + return, + * replaced Error(), MessageBoxW() with MSILogAndShow(), + * replaced StatusMessage() with MSILog(), + * replaced handleWin32Error() with handleWin32Error_Dll(). + */ +BOOL DoDriverUnload_Dll (MSIHANDLE hInstaller, HWND hwnd) +{ + BOOL bOK = TRUE; + int status = 0; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin DoDriverUnload_Dll"); + + status = DriverAttach (); + if (status != 0) + { + if (status == ERR_OS_ERROR && GetLastError () != ERROR_FILE_NOT_FOUND) + { + handleWin32Error_Dll (hInstaller, SRC_POS); + MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, GetString("NODRIVER")); + bOK = FALSE; + goto end; + } + + if (status != ERR_OS_ERROR) + { + handleError_Dll (hInstaller, status, SRC_POS); + MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, GetString("NODRIVER")); + bOK = FALSE; + goto end; + } + } + + if (hDriver != INVALID_HANDLE_VALUE) + { + MOUNT_LIST_STRUCT driver; + LONG driverVersion = VERSION_NUM; + int refCount; + DWORD dwResult; + BOOL bResult; + + // Try to determine if it's upgrade (and not reinstall, downgrade, or first-time install). + DetermineUpgradeDowngradeStatus (FALSE, &driverVersion); + + // Test for encrypted boot drive + try + { + BootEncryption bootEnc (hwnd); + if (bootEnc.GetDriverServiceStartType() == SERVICE_BOOT_START) + { + try + { + // Check hidden OS update consistency + if (IsHiddenOSRunning()) + { + if (bootEnc.GetInstalledBootLoaderVersion() != VERSION_NUM) + { + if (AskWarnNoYes ("UPDATE_TC_IN_DECOY_OS_FIRST", hwnd) == IDNO) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"User denied request"); + bOK = FALSE; + goto end; + } + } + } + } + catch (...) { } + + if (bUninstallInProgress && !bootEnc.GetStatus().DriveMounted) + { + try { bootEnc.RegisterFilterDriver (false, BootEncryption::DriveFilter); } catch (...) { } + try { bootEnc.RegisterFilterDriver (false, BootEncryption::VolumeFilter); } catch (...) { } + try { bootEnc.RegisterFilterDriver (false, BootEncryption::DumpFilter); } catch (...) { } + bootEnc.SetDriverServiceStartType (SERVICE_SYSTEM_START); + } + else if (bUninstallInProgress || bDowngrade) + { + MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, (bDowngrade ? GetString("SETUP_FAILED_BOOT_DRIVE_ENCRYPTED_DOWNGRADE") : GetString("SETUP_FAILED_BOOT_DRIVE_ENCRYPTED"))); + bOK = FALSE; + goto end; + } + else + { + if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1) + { + MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, GetString("SYS_ENCRYPTION_UPGRADE_UNSUPPORTED_ON_VISTA_SP0")); + bOK = FALSE; + goto end; + } + + SystemEncryptionUpdate = TRUE; + PortableMode = FALSE; + } + } + } + catch (...) { } + + if (!bUninstall + && (bUpgrade || SystemEncryptionUpdate) + && (!bDevm || SystemEncryptionUpdate)) + { + UnloadDriver = FALSE; + } + + if (PortableMode && !SystemEncryptionUpdate) + UnloadDriver = TRUE; + + if (UnloadDriver) + { + int volumesMounted = 0; + + // Check 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) + { + bOK = FALSE; + MSILogAndShow(hInstaller, MSI_WARNING_LEVEL, GetString ("DISMOUNT_ALL_FIRST")); + } + } + else + { + bOK = FALSE; + handleWin32Error_Dll (hInstaller, SRC_POS); + } + } + + // Try to close all open TC windows + if (bOK) + { + BOOL TCWindowClosed = FALSE; + + EnumWindows (CloseTCWindowsEnum, (LPARAM) &TCWindowClosed); + + if (TCWindowClosed) + Sleep (2000); + } + + // Test for any applications attached to driver + if (!bUpgrade) + { + bResult = DeviceIoControl (hDriver, TC_IOCTL_GET_DEVICE_REFCOUNT, &refCount, sizeof (refCount), &refCount, + sizeof (refCount), &dwResult, NULL); + + if (bOK && bResult && refCount > 1) + { + MSILogAndShow(hInstaller, MSI_WARNING_LEVEL, GetString ("CLOSE_TC_FIRST")); + bOK = FALSE; + } + } + + if (!bOK || UnloadDriver) + { + CloseHandle (hDriver); + hDriver = INVALID_HANDLE_VALUE; + } + } + else + { + // Note that the driver may have already been unloaded during this session (e.g. retry after an error, etc.) so it is not + // guaranteed that the user is installing VeraCrypt for the first time now (we also cannot know if the user has already + // installed and used VeraCrypt on another system before). + bPossiblyFirstTimeInstall = TRUE; + } + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End DoDriverUnload_Dll"); + return bOK; +} + +/* + * Same as in Setup.c, DoServiceUninstall(), but + * replaced AbortProcess() and AbortProcessSilent() with MSILogAndShow() + return, + * replaced Error(), MessageBoxW() with MSILogAndShow(), + * replaced StatusMessage() with MSILog(), + * replaced handleWin32Error() with handleWin32Error_Dll(). + */ +BOOL DoServiceUninstall_Dll (MSIHANDLE hInstaller, HWND hwndDlg, wchar_t *lpszService) +{ + SC_HANDLE hManager, hService = NULL; + BOOL bOK = FALSE, bRet; + SERVICE_STATUS status; + BOOL firstTry = TRUE; + int x; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin DoServiceUninstall_Dll"); + + memset (&status, 0, sizeof (status)); /* Keep VC6 quiet */ + +retry: + + hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hManager == NULL) + goto error; + + hService = OpenService (hManager, lpszService, SERVICE_ALL_ACCESS); + if (hService == NULL) + goto error; + + if (wcscmp (L"veracrypt", lpszService) == 0) + { + try + { + BootEncryption bootEnc (hwndDlg); + if (bootEnc.GetDriverServiceStartType() == SERVICE_BOOT_START) + { + try { bootEnc.RegisterFilterDriver (false, BootEncryption::DriveFilter); } catch (...) { } + try { bootEnc.RegisterFilterDriver (false, BootEncryption::VolumeFilter); } catch (...) { } + try { bootEnc.RegisterFilterDriver (false, BootEncryption::DumpFilter); } catch (...) { } + } + } + catch (...) { } + + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("STOPPING_DRIVER")); + } + else + MSILog (hInstaller, MSI_INFO_LEVEL, L"STOPPING %s", lpszService); + + for (x = 0; x < WAIT_PERIOD; x++) + { + bRet = QueryServiceStatus (hService, &status); + if (bRet != TRUE) + goto error; + + if (status.dwCurrentState != SERVICE_START_PENDING && + status.dwCurrentState != SERVICE_STOP_PENDING && + status.dwCurrentState != SERVICE_CONTINUE_PENDING) + break; + + Sleep (1000); + } + + if (status.dwCurrentState != SERVICE_STOPPED) + { + bRet = ControlService (hService, SERVICE_CONTROL_STOP, &status); + if (bRet == FALSE) + goto try_delete; + + for (x = 0; x < WAIT_PERIOD; x++) + { + bRet = QueryServiceStatus (hService, &status); + if (bRet != TRUE) + goto error; + + if (status.dwCurrentState != SERVICE_START_PENDING && + status.dwCurrentState != SERVICE_STOP_PENDING && + status.dwCurrentState != SERVICE_CONTINUE_PENDING) + break; + + Sleep (1000); + } + + if (status.dwCurrentState != SERVICE_STOPPED && status.dwCurrentState != SERVICE_STOP_PENDING) + goto error; + } + +try_delete: + + if (wcscmp (L"veracrypt", lpszService) == 0) + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("REMOVING_DRIVER")); + else + MSILog (hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", lpszService); + + if (hService != NULL) + { + CloseServiceHandle (hService); + hService = NULL; + } + + if (hManager != NULL) + { + CloseServiceHandle (hManager); + hManager = NULL; + } + + hManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hManager == NULL) + goto error; + + hService = OpenService (hManager, lpszService, SERVICE_ALL_ACCESS); + if (hService == NULL) + goto error; + + bRet = DeleteService (hService); + if (bRet == FALSE) + { + if (firstTry && GetLastError () == ERROR_SERVICE_MARKED_FOR_DELETE) + { + // Second try for an eventual no-install driver instance + CloseServiceHandle (hService); + CloseServiceHandle (hManager); + hService = NULL; + hManager = NULL; + + Sleep(1000); + firstTry = FALSE; + goto retry; + } + + goto error; + } + + bOK = TRUE; + +error: + + if (bOK == FALSE && GetLastError ()!= ERROR_SERVICE_DOES_NOT_EXIST) + { + handleWin32Error_Dll (hInstaller, SRC_POS); + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString("DRIVER_UINSTALL_FAILED")); + } + else + bOK = TRUE; + + if (hService != NULL) + CloseServiceHandle (hService); + + if (hManager != NULL) + CloseServiceHandle (hManager); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"End DoServiceUninstall_Dll"); + return bOK; +} + +/* + * Same as in Setup.c, DoRegUninstall(), but + * replaced StatusMessage() with MSILog(), + * removed unnecessary code that is done by MSI. + */ +BOOL DoRegUninstall_Dll (MSIHANDLE hInstaller, BOOL bRemoveDeprecated) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin DoRegUninstall_Dll"); + + wchar_t regk [64]; + typedef LSTATUS (WINAPI *RegDeleteKeyExWFn) (HKEY hKey,LPCWSTR lpSubKey,REGSAM samDesired,WORD Reserved); + RegDeleteKeyExWFn RegDeleteKeyExWPtr = NULL; + HMODULE hAdvapiDll = LoadLibrary (L"Advapi32.dll"); + if (hAdvapiDll) + { + RegDeleteKeyExWPtr = (RegDeleteKeyExWFn) GetProcAddress(hAdvapiDll, "RegDeleteKeyExW"); + } + + // Unregister COM servers + if (!bRemoveDeprecated && IsOSAtLeast (WIN_VISTA)) + { + if (!UnregisterComServers (InstallationPath)) + MSILog (hInstaller, MSI_ERROR_LEVEL, GetString("COM_DEREG_FAILED")); + } + + if (!bRemoveDeprecated) + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("REMOVING_REG")); + + /* The following is done by MSI, so we skip it */ + /* + if (RegDeleteKeyExWPtr) + { + RegDeleteKeyExWPtr (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", KEY_WOW64_32KEY, 0); + RegDeleteKeyExWPtr (HKEY_CURRENT_USER, L"Software\\VeraCrypt", KEY_WOW64_32KEY, 0); + } + else + { + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt"); + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\VeraCrypt"); + } + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume\\Shell\\open\\command"); + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume\\Shell\\open"); + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume\\Shell"); + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume\\DefaultIcon"); + RegDeleteKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\VeraCryptVolume"); + */ + + if (!bRemoveDeprecated) + { + HKEY hKey; + + GetStartupRegKeyName (regk, sizeof(regk)); + DeleteRegistryValue (regk, L"VeraCrypt"); + + // The following is done by MSI, so we skip it + // DeleteRegistryKey (HKEY_LOCAL_MACHINE, L"Software\\Classes\\.hc"); + + // enable the SE_TAKE_OWNERSHIP_NAME privilege for this operation + SetPrivilege (SE_TAKE_OWNERSHIP_NAME, TRUE); + + // clean MuiCache list from VeraCrypt entries + SearchAndDeleteRegistrySubString (HKEY_CLASSES_ROOT, L"Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache", L"VeraCrypt", FALSE, NULL); + + // clean other VeraCrypt entries from all users + SearchAndDeleteRegistrySubString (HKEY_USERS, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.hc", NULL, TRUE, NULL); + SearchAndDeleteRegistrySubString (HKEY_USERS, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Compatibility Assistant\\Persisted", L"VeraCrypt", TRUE, NULL); + SearchAndDeleteRegistrySubString (HKEY_USERS, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage\\NewShortcuts", L"VeraCrypt", TRUE, NULL); + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_ALL_ACCESS | WRITE_DAC | WRITE_OWNER, &hKey) == ERROR_SUCCESS) + { + SearchAndDeleteRegistrySubString (hKey, L"Enum\\Root\\LEGACY_VERACRYPT", NULL, TRUE, L"ControlSet"); + SearchAndDeleteRegistrySubString (hKey, L"services\\veracrypt", NULL, TRUE, L"ControlSet"); + RegCloseKey(hKey); + } + + // disable the SE_TAKE_OWNERSHIP_NAME privilege for this operation + SetPrivilege (SE_TAKE_OWNERSHIP_NAME, FALSE); + + // The following is done by MSI, so we skip it + //SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + if (hAdvapiDll) + FreeLibrary (hAdvapiDll); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"End DoRegUninstall_Dll"); + return TRUE; +} + +/* + * Same as in Setup.c, UpgradeBootLoader(), but + * replaced StatusMessage() with MSILog(). + */ +BOOL UpgradeBootLoader_Dll (MSIHANDLE hInstaller, HWND hwndDlg) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin UpgradeBootLoader_Dll"); + + BOOL bOK = FALSE; + + if (!SystemEncryptionUpdate) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"SystemEncryptionUpdate == FALSE"); + bOK = TRUE; + goto end; + } + + try + { + BootEncryption bootEnc (hwndDlg); + uint64 bootLoaderVersion = bootEnc.GetInstalledBootLoaderVersion(); + if ((bootLoaderVersion < VERSION_NUM) || (bReinstallMode && (bootLoaderVersion == VERSION_NUM))) + { + MSILog (hInstaller, MSI_INFO_LEVEL, GetString("INSTALLER_UPDATING_BOOT_LOADER")); + + bootEnc.InstallBootLoader (true); + + if (bootEnc.GetInstalledBootLoaderVersion() <= TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION) + { + bUpdateRescueDisk = TRUE; + MSILog (hInstaller, MSI_INFO_LEVEL, GetString(IsHiddenOSRunning() ? "BOOT_LOADER_UPGRADE_OK_HIDDEN_OS" : "BOOT_LOADER_UPGRADE_OK")); + } + } + bOK = TRUE; + goto end; + } + catch (Exception &e) + { + e.Show (hwndDlg); + } + catch (...) { } + + MSILog (hInstaller, MSI_ERROR_LEVEL, GetString("BOOT_LOADER_UPGRADE_FAILED")); + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End UpgradeBootLoader_Dll"); + return bOK; +} + +/* + * Same as Setup.c, function DoApplicationDataUninstall(), but + * replaced StatusMessage() and RemoveMessage() with MSILog(). + */ +BOOL DoApplicationDataUninstall_Dll (MSIHANDLE hInstaller) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin DoApplicationDataUninstall"); + + wchar_t path[MAX_PATH]; + wchar_t path2[MAX_PATH]; + BOOL bOK = TRUE; + + MSILog(hInstaller, MSI_INFO_LEVEL, GetString("REMOVING_APPDATA")); + + SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); + StringCbCatW (path, sizeof(path), L"\\VeraCrypt\\"); + + // Delete favorite volumes file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_FAVORITE_VOLUMES); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path2); + StatDeleteFile (path2, FALSE); + + // Delete keyfile defaults + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_DEFAULT_KEYFILES); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path2); + StatDeleteFile (path2, FALSE); + + // Delete history file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_HISTORY); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path2); + StatDeleteFile (path2, FALSE); + + // Delete configuration file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_CONFIGURATION); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path2); + StatDeleteFile (path2, FALSE); + + // Delete system encryption configuration file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path2); + StatDeleteFile (path2, FALSE); + + SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); + StringCbCatW (path, sizeof(path), L"\\VeraCrypt"); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path); + if (!StatRemoveDirectory (path)) + { + handleWin32Error_Dll (hInstaller, SRC_POS); + bOK = FALSE; + } + + // remove VeraCrypt under common appdata + if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path))) + { + StringCbCatW (path, sizeof(path), L"\\VeraCrypt"); + + // Delete original bootloader + StringCbPrintfW (path2, sizeof(path2), L"%s\\%s", path, TC_SYS_BOOT_LOADER_BACKUP_NAME); + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path2); + StatDeleteFile (path2, FALSE); + + // remove VeraCrypt folder + MSILog(hInstaller, MSI_INFO_LEVEL, L"REMOVING %s", path); + StatRemoveDirectory (path); + } + + MSILog(hInstaller, MSI_INFO_LEVEL, L"End DoApplicationDataUninstall"); + return bOK; +} + +/* + * Same as Setup.c, function DoUninstall(), but + * removed uninstall of files and registry as it will be + * done by MSI. + */ +BOOL DoUninstall_Dll (MSIHANDLE hInstaller, HWND hwndDlg) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin DoUninstall_Dll"); + + BOOL bOK = TRUE; + BOOL bTempSkipSysRestore = FALSE; + + if (DoDriverUnload_Dll (hInstaller, hwndDlg) == FALSE) + { + bOK = FALSE; + bTempSkipSysRestore = TRUE; // Volumes are possibly mounted; defer System Restore point creation for this uninstall attempt. + } + else + { + if (!Rollback && bSystemRestore && !bTempSkipSysRestore) + SetSystemRestorePoint_Dll (hInstaller, FALSE); + + if (DoServiceUninstall_Dll (hInstaller, hwndDlg, L"veracrypt") == FALSE) + { + bOK = FALSE; + } + else if (DoRegUninstall_Dll (hInstaller, FALSE) == FALSE) + { + bOK = FALSE; + } + /* Following skipped because done by MSI */ + /* + else if (DoFilesInstall ((HWND) hwndDlg, InstallationPath) == FALSE) + { + bOK = FALSE; + } + else if (DoShortcutsUninstall (hwndDlg, InstallationPath) == FALSE) + { + bOK = FALSE; + } + */ + else if (!DoApplicationDataUninstall_Dll (hInstaller)) + { + bOK = FALSE; + } + else + { + // Deprecated service + DoServiceUninstall_Dll (hInstaller, hwndDlg, L"VeraCryptService"); + } + } + + if (Rollback) + goto end; + + if (bSystemRestore && !bTempSkipSysRestore) + SetSystemRestorePoint_Dll (hInstaller, TRUE); + + if (!bOK) + bUninstallInProgress = FALSE; + +end: + + MSILog(hInstaller, MSI_INFO_LEVEL, L"End DoUninstall_Dll"); + return bOK; +} + +/* + * Same as Setup.c, function InitApp(), but + * replaced unnecessary calls, + * forced english as language, + * replaced LoadLanguageFile() with LoadLanguageFromResource() to be able to set bForceSilent. + */ +BOOL InitDll (MSIHANDLE hInstaller) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin InitDll"); + + BOOL bOK = TRUE; + InitCommonControlsPtr InitCommonControlsFn = NULL; + + /* 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(); + InitGlobalLocks (); + + LoadSystemDll_Dll (hInstaller, L"msvcrt.dll", &hmsvcrtdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"ntmarta.dll", &hntmartadll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"MPR.DLL", &hmprdll, TRUE, SRC_POS); + if (IsOSAtLeast (WIN_7)) + { + LoadSystemDll_Dll (hInstaller, L"ProfApi.DLL", &hProfApiDll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"cryptbase.dll", &hcryptbasedll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"sspicli.dll", &hsspiclidll, TRUE, SRC_POS); + } + LoadSystemDll_Dll (hInstaller, L"psapi.dll", &hpsapidll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"secur32.dll", &hsecur32dll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"msasn1.dll", &hmsasn1dll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"Usp10.DLL", &hUsp10Dll, TRUE, SRC_POS); + if (IsOSAtLeast (WIN_7)) + LoadSystemDll_Dll (hInstaller, L"dwmapi.dll", &hdwmapidll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"UXTheme.dll", &hUXThemeDll, TRUE, SRC_POS); + + LoadSystemDll_Dll (hInstaller, L"msls31.dll", &hMsls31, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"SETUPAPI.DLL", &hSetupDll, FALSE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"SHLWAPI.DLL", &hShlwapiDll, FALSE, SRC_POS); + + LoadSystemDll_Dll (hInstaller, L"userenv.dll", &hUserenvDll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"rsaenh.dll", &hRsaenhDll, TRUE, SRC_POS); + + if (nCurrentOS < WIN_7) + { + if (nCurrentOS == WIN_XP) + { + LoadSystemDll_Dll (hInstaller, L"imm32.dll", &himm32dll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"MSCTF.dll", &hMSCTFdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"fltlib.dll", &hfltlibdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"wbem\\framedyn.dll", &hframedyndll, TRUE, SRC_POS); + } + + if (IsOSAtLeast (WIN_VISTA)) + { + LoadSystemDll_Dll (hInstaller, L"netapi32.dll", &hnetapi32dll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"authz.dll", &hauthzdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"xmllite.dll", &hxmllitedll, TRUE, SRC_POS); + } + } + + if (IsOSAtLeast (WIN_VISTA)) + { + LoadSystemDll_Dll (hInstaller, L"atl.dll", &hsppdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"vsstrace.dll", &hvsstracedll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"vssapi.dll", &vssapidll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"spp.dll", &hsppdll, TRUE, SRC_POS); + } + + LoadSystemDll_Dll (hInstaller, L"crypt32.dll", &hcrypt32dll, TRUE, SRC_POS); + + if (IsOSAtLeast (WIN_7)) + { + LoadSystemDll_Dll (hInstaller, L"CryptSP.dll", &hCryptSpDll, TRUE, SRC_POS); + + LoadSystemDll_Dll (hInstaller, L"cfgmgr32.dll", &hcfgmgr32dll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"devobj.dll", &hdevobjdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"powrprof.dll", &hpowrprofdll, TRUE, SRC_POS); + + LoadSystemDll_Dll (hInstaller, L"bcrypt.dll", &hbcryptdll, TRUE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"bcryptprimitives.dll", &hbcryptprimitivesdll, TRUE, SRC_POS); + } + + LoadSystemDll_Dll (hInstaller, L"COMCTL32.DLL", &hComctl32Dll, FALSE, SRC_POS); + + // 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 + { + MSILog(hInstaller, MSI_ERROR_LEVEL, GetString("INIT_DLL")); + bOK = FALSE; + goto end; + } + + LoadSystemDll_Dll (hInstaller, L"Riched20.dll", &hRichEditDll, FALSE, SRC_POS); + LoadSystemDll_Dll (hInstaller, L"Advapi32.dll", &hAdvapi32Dll, FALSE, SRC_POS); + + // 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) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, GetString("INIT_DLL")); + bOK = FALSE; + goto end; + } + + // Get SHDeleteKeyW function pointer + SHDeleteKeyWFn = (SHDeleteKeyWPtr) GetProcAddress (hShlwapiDll, "SHDeleteKeyW"); + SHStrDupWFn = (SHStrDupWPtr) GetProcAddress (hShlwapiDll, "SHStrDupW"); + if (!SHDeleteKeyWFn || !SHStrDupWFn) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, GetString("INIT_DLL")); + bOK = FALSE; + goto end; + } + + 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"); + } + + // Get CreateProcessWithTokenW function pointer + CreateProcessWithTokenWPtr = (CreateProcessWithTokenWFn) GetProcAddress(hAdvapi32Dll, "CreateProcessWithTokenW"); + + SetErrorMode (SetErrorMode (0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + CoInitialize (NULL); + + // Force language to english to read strings from the default Language.xml embedded in the DLL. + SetPreferredLangId ("en"); + bUserSetLanguage = TRUE; + LoadLanguageFromResource (0, FALSE, TRUE); + + SetUnhandledExceptionFilter (ExceptionHandler); + _set_invalid_parameter_handler (InvalidParameterHandler); + RemoteSession = GetSystemMetrics (SM_REMOTESESSION) != 0; + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End InitDll"); + return bOK; +} + +/* **************************************************************************** */ + +/* + * Same as Setup.c, function wWinMain(), but + * replaced unnecessary calls. + * This should be called at the beginning of each operation (install, uninstall...), + * before atexit(VC_CustomAction_Cleanup()) call. + */ +BOOL VC_CustomAction_Init(MSIHANDLE hInstaller, const wchar_t* szInstallDir) +{ + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_Init"); + + BOOL bOK = TRUE; + + if (!InitDll(hInstaller)) + { + bOK = FALSE; + goto end; + } + + // System Restore + if (IsSystemRestoreEnabled ()) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"System Restore is enabled"); + + wchar_t dllPath[MAX_PATH]; + if (GetSystemDirectory (dllPath, MAX_PATH)) + { + StringCbCatW(dllPath, sizeof(dllPath), L"\\srclient.dll"); + } + else + StringCbCopyW(dllPath, sizeof(dllPath), L"C:\\Windows\\System32\\srclient.dll"); + SystemRestoreDll = LoadLibrary (dllPath); + } + else + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"System Restore is not enabled"); + SystemRestoreDll = 0; + } + + // Set InstallationPath + wcsncpy(InstallationPath, szInstallDir, min(wcslen(szInstallDir), ARRAYSIZE(InstallationPath))); + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_Init"); + return bOK; +} + +/* + * Same as Setup.c, function localcleanup(), but + * replaced unnecessary calls. + * This should be called at the beginning of each operation (install, uninstall...), + * as an argument to atexit() before VC_CustomAction_Init() call. + */ +void VC_CustomAction_Cleanup () +{ + //MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_Cleanup"); + + /* Cleanup the GDI fonts */ + if (hFixedFont != NULL) + DeleteObject (hFixedFont); + if (hFixedDigitFont != NULL) + DeleteObject (hFixedDigitFont); + if (hBoldFont != NULL) + DeleteObject (hBoldFont); + if (hTitleFont != NULL) + DeleteObject (hTitleFont); + if (hUserFont != NULL) + DeleteObject (hUserFont); + if (hUserUnderlineFont != NULL) + DeleteObject (hUserUnderlineFont); + if (hUserBoldFont != NULL) + DeleteObject (hUserBoldFont); + + /* Close the device driver handle */ + if (hDriver != INVALID_HANDLE_VALUE) + { + // Unload driver mode if possible (non-install mode) + if (IsNonInstallMode ()) + { + // If a dismount was forced in the lifetime of the driver, Windows may later prevent it to be loaded again from + // the same path. Therefore, the driver will not be unloaded even though it was loaded in non-install mode. + int driverUnloadDisabled; + DWORD dwResult; + + if (!DeviceIoControl (hDriver, TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED, NULL, 0, &driverUnloadDisabled, sizeof (driverUnloadDisabled), &dwResult, NULL)) + driverUnloadDisabled = 0; + + if (!driverUnloadDisabled) + DriverUnload (); + else + { + CloseHandle (hDriver); + hDriver = INVALID_HANDLE_VALUE; + } + } + else + { + CloseHandle (hDriver); + hDriver = INVALID_HANDLE_VALUE; + } + } + + CoUninitialize (); + + CloseSysEncMutex (); + + FinalizeGlobalLocks (); + + 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); + + //MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_Cleanup"); +} + +void Tokenize(const wchar_t* szInput, std::vector& szTokens) +{ + std::wstringstream check(szInput); + std::wstring intermediate; + while(std::getline(check, intermediate, L'?')) + { + szTokens.push_back(intermediate); + } +} + +/* + * Same as Setup.c, function DoInstall(), but + * without the actual installation, it only prepares the system + * before the installation (before DoFilesInstall). + * It runs as a Deferred CA. + */ +EXTERN_C UINT STDAPICALLTYPE VC_CustomAction_PreInstall(MSIHANDLE hInstaller) +{ + HWND hwndDlg = NULL; + std::wstring szValueBuf = L""; + DWORD cchValueBuf = 0; + UINT uiStat = 0; + HKEY hkey = 0; + DWORD dw = 0; + BootEncryption bootEnc(NULL); + std::wstring szInstallDir = L""; + UINT uiRet = ERROR_INSTALL_FAILURE; + BOOL bOK = TRUE; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_PreInstall"); + + // Get UILevel to see whether we're being installed silently or not. + // Also get INSTALLDIR to see where we're being installed. + // Since this is a Deferred CA, they are to be setup in its CustomActionData. + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), (LPWSTR)TEXT(""), &cchValueBuf); + if (ERROR_MORE_DATA == uiStat) + { + ++cchValueBuf; // add 1 for null termination + szValueBuf.resize(cchValueBuf); + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), &szValueBuf[0], &cchValueBuf); + if ((ERROR_SUCCESS == uiStat)) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: CustomActionData = '%s'", szValueBuf.c_str()); + + std::vector szTokens; + Tokenize(szValueBuf.c_str(), szTokens); + + for (size_t i = 0; i < szTokens.size(); i++) + { + std::wstring szToken = szTokens[i]; + + if (wcsncmp(szToken.c_str(), L"UILEVEL=", wcslen(L"UILEVEL=")) == 0) + { + size_t index0 = szToken.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + std::wstring uiLevel = szToken.substr(index0 + 1); + Silent = (stoi(uiLevel) <= 3); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: UILEVEL = '%s', bSilent = '%d'", uiLevel.c_str(), Silent); + } + } + else if (wcsncmp(szToken.c_str(), L"INSTALLDIR=", wcslen(L"INSTALLDIR=")) == 0) + { + size_t index0 = szToken.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + szInstallDir = szToken.substr(index0 + 1); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: INSTALLDIR = '%s'", szInstallDir.c_str()); + } + } + else if (wcsncmp(szToken.c_str(), L"REINSTALL=", wcslen(L"REINSTALL=")) == 0) + { + size_t index0 = szToken.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + std::wstring szReinstall = szToken.substr(index0 + 1); + bRepairMode = (wcslen(szReinstall.c_str()) != 0); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: REINSTALL = '%s', bRepairMode = '%s'", szReinstall.c_str(), bRepairMode ? L"TRUE" : L"FALSE"); + } + } + } + } + } + + // Get this MSI Installer HWND. + // There cannot be 2 MSIs or more running at the same time, so we're sure we'll get ours. + // This is only possible in case of non silent install. + hwndDlg = FindWindow(L"MsiDialogCloseClass", NULL); + if (!hwndDlg && !Silent) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreInstall: MsiDialogCloseClass not found"); + goto end; + } + + /* Start actual work */ + + if (!VC_CustomAction_Init(hInstaller, szInstallDir.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreInstall: VC_CustomAction_Init() failed"); + goto end; + } + atexit(VC_CustomAction_Cleanup); + + bootEnc.SetParentWindow(hwndDlg); + + if (DoDriverUnload_Dll (hInstaller, hwndDlg) == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreInstall: DoDriverUnload_Dll() failed"); + goto end; + } + + if (bSystemRestore) + { + SetSystemRestorePoint_Dll (hInstaller, FALSE); + } + + if (bDisableSwapFiles && IsPagingFileActive_Dll (hInstaller, FALSE)) + { + if (!DisablePagingFile()) + { + handleWin32Error_Dll (hInstaller, SRC_POS); + MSILogAndShow(hInstaller, MSI_ERROR_LEVEL, GetString("FAILED_TO_DISABLE_PAGING_FILES")); + } + else + { + bRestartRequired = TRUE; + } + } + + // Remove deprecated + DoServiceUninstall_Dll (hInstaller, hwndDlg, L"VeraCryptService"); + + if (!SystemEncryptionUpdate) + DoRegUninstall_Dll (hInstaller, TRUE); + + if (UnloadDriver && DoServiceUninstall_Dll(hInstaller, hwndDlg, L"veracrypt") == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreInstall: DoServiceUninstall_Dll(veracrypt) failed"); + bOK = FALSE; + } + + // uiRet = MsiSetProperty(hInstaller, TEXT("ISREBOOTREQUIRED"), TEXT("1")); + // Cannot do this because this is a Deferred CA (we need Deferred so that it runs with admin privileges). + // MsiGetProperty and MsiSetProperty properties cannot be used for deferred InstallScript custom actions, + // which do not have access to the active .msi database and do not recognize any Windows Installer properties. + // They can access only the information that has been written into the execution script (CustomActionData). + // Therefore, we set the values in RegKeys that are volatile. + if (bOK) + { + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) + { + RegSetValueEx (hkey, L"Silent", 0, REG_DWORD, (const BYTE*)(&Silent), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstall", 0, REG_DWORD, (const BYTE*)(&bUninstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDowngrade", 0, REG_DWORD, (const BYTE*)(&bDowngrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstallInProgress", 0, REG_DWORD, (const BYTE*)(&bUninstallInProgress), sizeof(BOOL)); + RegSetValueEx (hkey, L"PortableMode", 0, REG_DWORD, (const BYTE*)(&PortableMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"UnloadDriver", 0, REG_DWORD, (const BYTE*)(&UnloadDriver), sizeof(BOOL)); + + RegSetValueEx (hkey, L"Rollback", 0, REG_DWORD, (const BYTE*)(&Rollback), sizeof(BOOL)); + RegSetValueEx (hkey, L"bReinstallMode", 0, REG_DWORD, (const BYTE*)(&bReinstallMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpgrade", 0, REG_DWORD, (const BYTE*)(&bUpgrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPossiblyFirstTimeInstall", 0, REG_DWORD, (const BYTE*)(&bPossiblyFirstTimeInstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDevm", 0, REG_DWORD, (const BYTE*)(&bDevm), sizeof(BOOL)); + RegSetValueEx (hkey, L"SystemEncryptionUpdate", 0, REG_DWORD, (const BYTE*)(&SystemEncryptionUpdate), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRestartRequired", 0, REG_DWORD, (const BYTE*)(&bRestartRequired), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDisableSwapFiles", 0, REG_DWORD, (const BYTE*)(&bDisableSwapFiles), sizeof(BOOL)); + RegSetValueEx (hkey, L"bSystemRestore", 0, REG_DWORD, (const BYTE*)(&bSystemRestore), sizeof(BOOL)); + + RegSetValueEx (hkey, L"bPromptFastStartup", 0, REG_DWORD, (const BYTE*)(&bPromptFastStartup), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptReleaseNotes", 0, REG_DWORD, (const BYTE*)(&bPromptReleaseNotes), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptTutorial", 0, REG_DWORD, (const BYTE*)(&bPromptTutorial), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpdateRescueDisk", 0, REG_DWORD, (const BYTE*)(&bUpdateRescueDisk), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRepairMode", 0, REG_DWORD, (const BYTE*)(&bRepairMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUserSetLanguage", 0, REG_DWORD, (const BYTE*)(&bUserSetLanguage), sizeof(BOOL)); + + RegCloseKey (hkey); + + uiRet = ERROR_SUCCESS; + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_PreInstall: Could not write to registry"); + } + } + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_PreInstall"); + return uiRet; +} + +/* + * Same as Setup.c, function DoInstall(), but + * without the actual installation, it only performs + * post install operations (after DoRegInstall and last parts + * of DoFilesInstall / DoRegInstall). + * It also does the Fast Startup check, shows Release Notes and + * Beginner's Tutorial if needed and sets regkey accordingly. + * It runs as a Deferred CA. + */ +EXTERN_C UINT STDAPICALLTYPE VC_CustomAction_PostInstall(MSIHANDLE hInstaller) +{ + HWND hwndDlg = NULL; + std::wstring szValueBuf = L""; + DWORD cchValueBuf = 0; + UINT uiStat = 0; + HKEY hkey = 0; + DWORD dw = 0; + BootEncryption bootEnc(NULL); + std::wstring szInstallDir = L""; + UINT uiRet = ERROR_INSTALL_FAILURE; + BOOL bOK = TRUE; + WCHAR szCurrentDir[MAX_PATH]; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_PostInstall"); + + // Get INSTALLDIR to see where we're being installed. + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), (LPWSTR)TEXT(""), &cchValueBuf); + if (ERROR_MORE_DATA == uiStat) + { + ++cchValueBuf; // add 1 for null termination + szValueBuf.resize(cchValueBuf); + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), &szValueBuf[0], &cchValueBuf); + if ((ERROR_SUCCESS == uiStat)) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PostInstall: CustomActionData = '%s'", szValueBuf.c_str()); + if (wcsncmp(szValueBuf.c_str(), L"INSTALLDIR=", wcslen(L"INSTALLDIR=")) == 0) + { + size_t index0 = szValueBuf.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + szInstallDir = szValueBuf.substr(index0 + 1); + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PostInstall: INSTALLDIR = '%s'", szInstallDir.c_str()); + } + } + } + } + + // Read RegKeys previously setup by PreInstall + if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, KEY_READ, &hkey) == ERROR_SUCCESS) + { + DWORD cbValue = sizeof(DWORD); + DWORD dwValue = 0; + + RegQueryValueEx (hkey, L"Silent", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + Silent = (dwValue == 1); + RegQueryValueEx (hkey, L"bUninstall", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUninstall = (dwValue == 1); + RegQueryValueEx (hkey, L"bDowngrade", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDowngrade = (dwValue == 1); + RegQueryValueEx (hkey, L"bUninstallInProgress", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUninstallInProgress = (dwValue == 1); + RegQueryValueEx (hkey, L"PortableMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + PortableMode = (dwValue == 1); + RegQueryValueEx (hkey, L"UnloadDriver", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + UnloadDriver = (dwValue == 1); + + RegQueryValueEx (hkey, L"Rollback", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + Rollback = (dwValue == 1); + RegQueryValueEx (hkey, L"bReinstallMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bReinstallMode = (dwValue == 1); + RegQueryValueEx (hkey, L"bUpgrade", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUpgrade = (dwValue == 1); + RegQueryValueEx (hkey, L"bPossiblyFirstTimeInstall", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPossiblyFirstTimeInstall = (dwValue == 1); + RegQueryValueEx (hkey, L"bDevm", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDevm = (dwValue == 1); + RegQueryValueEx (hkey, L"SystemEncryptionUpdate", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + SystemEncryptionUpdate = (dwValue == 1); + RegQueryValueEx (hkey, L"bRestartRequired", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bRestartRequired = (dwValue == 1); + RegQueryValueEx (hkey, L"bDisableSwapFiles", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDisableSwapFiles = (dwValue == 1); + RegQueryValueEx (hkey, L"bSystemRestore", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bSystemRestore = (dwValue == 1); + + RegQueryValueEx (hkey, L"bPromptFastStartup", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptFastStartup = (dwValue == 1); + RegQueryValueEx (hkey, L"bPromptReleaseNotes", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptReleaseNotes = (dwValue == 1); + RegQueryValueEx (hkey, L"bPromptTutorial", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptTutorial = (dwValue == 1); + RegQueryValueEx (hkey, L"bUpdateRescueDisk", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUpdateRescueDisk = (dwValue == 1); + RegQueryValueEx (hkey, L"bRepairMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bRepairMode = (dwValue == 1); + RegQueryValueEx (hkey, L"bUserSetLanguage", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUserSetLanguage = (dwValue == 1); + + RegCloseKey (hkey); + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_PostInstall: Could not read from registry"); + goto end; + } + + // Get this MSI Installer HWND. + // There cannot be 2 MSIs or more running at the same time, so we're sure we'll get ours. + // This is only possible in case of non silent install. + hwndDlg = FindWindow(L"MsiDialogCloseClass", NULL); + if (!hwndDlg && !Silent) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: MsiDialogCloseClass not found"); + goto end; + } + + /* Start actual work */ + + if (!VC_CustomAction_Init(hInstaller, szInstallDir.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: VC_CustomAction_Init() failed"); + goto end; + } + atexit(VC_CustomAction_Cleanup); + bootEnc.SetParentWindow(hwndDlg); + + // Last part of DoFilesInstall() + { + BOOL bResult = FALSE; + WIN32_FIND_DATA f; + HANDLE h; + wchar_t szTmp[TC_MAX_PATH]; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szInstallDir.c_str(), L"VeraCrypt.exe"); + + if (Is64BitOs ()) + EnableWow64FsRedirection (FALSE); + + wstring servicePath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", false); + wstring serviceLegacyPath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", true); + wstring favoritesFile = GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false); + wstring favoritesLegacyFile = GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, true); + + if (Is64BitOs () + && FileExists (favoritesLegacyFile.c_str()) + && !FileExists (favoritesFile.c_str())) + { + // copy the favorites XML file to the native system directory + bResult = CopyFile (favoritesLegacyFile.c_str(), favoritesFile.c_str(), FALSE); + } + else + { + bResult = TRUE; + } + + if (bResult) + { + // Update the path of the service + BootEncryption BootEncObj (hwndDlg); + + try + { + if (BootEncObj.GetDriverServiceStartType() == SERVICE_BOOT_START) + { + uint32 driverFlags = ReadDriverConfigurationFlags (); + uint32 serviceFlags = BootEncObj.ReadServiceConfigurationFlags (); + + BootEncObj.UpdateSystemFavoritesService (); + + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: INSTALLING %s", servicePath.c_str()); + + // Tell the service not to update loader on stop + BootEncObj.SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER, true); + + if (StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, FALSE, 0, NULL)) + { + // we tell the service not to load system favorites on startup + LPCWSTR szArgs[2] = { TC_SYSTEM_FAVORITES_SERVICE_NAME, VC_SYSTEM_FAVORITES_SERVICE_ARG_SKIP_MOUNT}; + if (!CopyFile (szTmp, servicePath.c_str(), FALSE)) + ForceCopyFile (szTmp, servicePath.c_str()); + + StartStopService_Dll (hInstaller, TC_SYSTEM_FAVORITES_SERVICE_NAME, TRUE, 2, szArgs); + } + else + ForceCopyFile (szTmp, servicePath.c_str()); + + BootEncObj.SetDriverConfigurationFlag (driverFlags, true); + + // remove the service flag if it was set originally + if (!(serviceFlags & VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER)) + BootEncObj.SetServiceConfigurationFlag (VC_SYSTEM_FAVORITES_SERVICE_CONFIG_DONT_UPDATE_LOADER, false); + } + } + catch (...) {} + } + + if (Is64BitOs ()) + { + // delete files from legacy path + if (FileExists (favoritesLegacyFile.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: REMOVING %s", favoritesLegacyFile.c_str()); + ForceDeleteFile (favoritesLegacyFile.c_str()); + } + + if (FileExists (serviceLegacyPath.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: REMOVING %s", serviceLegacyPath.c_str()); + ForceDeleteFile (serviceLegacyPath.c_str()); + } + + EnableWow64FsRedirection (TRUE); + } + + if (bResult == FALSE) + { + LPVOID lpMsgBuf; + DWORD dwError = GetLastError (); + wchar_t szTmp2[700]; + wchar_t szErrorValue[16]; + wchar_t* pszDesc; + + FormatMessage ( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwError, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (wchar_t *) &lpMsgBuf, + 0, + NULL + ); + + if (lpMsgBuf) + pszDesc = (wchar_t*) lpMsgBuf; + else + { + StringCbPrintfW (szErrorValue, sizeof (szErrorValue), L"0x%.8X", dwError); + pszDesc = szErrorValue; + } + + if (bUninstall == FALSE) + StringCbPrintfW (szTmp2, sizeof(szTmp2), GetString ("INSTALL_OF_FAILED"), szTmp, pszDesc); + else + StringCbPrintfW (szTmp2, sizeof(szTmp2), GetString ("UNINSTALL_OF_FAILED"), szTmp, pszDesc); + + if (lpMsgBuf) LocalFree (lpMsgBuf); + + if (!Silent && MessageBoxW (hwndDlg, szTmp2, lpszTitle, MB_YESNO | MB_ICONHAND) != IDYES) + goto end; + } + + if (bUninstall == FALSE) + { + GetCurrentDirectory (MAX_PATH, szCurrentDir); // Save current dir since it will be changed + SetCurrentDirectory (szInstallDir.c_str()); + + // remove PDF from previous version if any + h = FindFirstFile (L"VeraCrypt User Guide*.pdf", &f); + + if (h != INVALID_HANDLE_VALUE) + { + do + { + StatDeleteFile (f.cFileName, TRUE); + } + while (FindNextFile(h, &f) != 0); + + FindClose (h); + } + + // remove language XML files from previous version if any + h = FindFirstFile (L"Language*.xml", &f); + + if (h != INVALID_HANDLE_VALUE) + { + do + { + StatDeleteFile (f.cFileName, TRUE); + } + while (FindNextFile(h, &f) != 0); + + FindClose (h); + } + + // remvove legacy files that are not needed anymore + for (int i = 0; i < sizeof (szLegacyFiles) / sizeof (szLegacyFiles[0]); i++) + { + StatDeleteFile (szLegacyFiles [i], TRUE); + } + + SetCurrentDirectory(szCurrentDir); + } + } + + // Last part of DoRegInstall() + { + // Register COM servers for UAC + if (IsOSAtLeast (WIN_VISTA)) + { + if (!RegisterComServers ((wchar_t*)szInstallDir.c_str())) + { + MSILogAndShow (hInstaller, MSI_ERROR_LEVEL, GetString("COM_REG_FAILED")); + goto end; + } + } + } + + if (UnloadDriver && DoDriverInstall_Dll(hInstaller) == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: DoDriverInstall_Dll() failed"); + bOK = FALSE; + } + else if (SystemEncryptionUpdate && UpgradeBootLoader_Dll(hInstaller, hwndDlg) == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostInstall: UpgradeBootLoader_Dll() failed"); + bOK = FALSE; + } + + // Shortcuts are installed by MSI, so we skip that. + + if (!UnloadDriver) + bRestartRequired = TRUE; + + try + { + bootEnc.RenameDeprecatedSystemLoaderBackup(); + } + catch (...) { } + + if (bSystemRestore) + SetSystemRestorePoint_Dll (hInstaller, TRUE); + + if (bOK) + { + MSILog(hInstaller, MSI_INFO_LEVEL, GetString("INSTALL_COMPLETED")); + } + else + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"Post install failed"); + if (!SystemEncryptionUpdate) + { + bUninstall = TRUE; + Rollback = TRUE; + Silent = TRUE; + + DoUninstall_Dll (hInstaller, hwndDlg); + + bUninstall = FALSE; + Rollback = FALSE; + Silent = FALSE; + + MSILog(hInstaller, MSI_INFO_LEVEL, GetString("ROLLBACK")); + } + else + { + MSILog(hInstaller, MSI_WARNING_LEVEL, GetString("SYS_ENC_UPGRADE_FAILED")); + } + } + + if (bOK && !bUninstall && !bDowngrade && !bRepairMode && !bDevm) + { + BOOL bHibernateEnabled = FALSE, bHiberbootEnabled = FALSE; + if (GetHibernateStatus (bHibernateEnabled, bHiberbootEnabled)) + { + if (bHiberbootEnabled) + { + bPromptFastStartup = TRUE; + } + } + + if (!IsHiddenOSRunning()) // A hidden OS user should not see the post-install notes twice (on decoy OS and then on hidden OS). + { + if (bRestartRequired || SystemEncryptionUpdate) + { + // Restart required + + if (bUpgrade) + { + SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_RELEASE_NOTES); + if (bUpdateRescueDisk) + { + SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_RESCUE_DISK); + } + } + else if (bPossiblyFirstTimeInstall) + { + SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_TUTORIAL); + } + } + else + { + // No restart will be required + + if (bUpgrade) + { + bPromptReleaseNotes = TRUE; + } + else if (bPossiblyFirstTimeInstall) + { + bPromptTutorial = TRUE; + } + } + } + } + + if (bOK) + { + // This is part of MainDialogProc, WM_CLOSE, after PostMessage (MainDlg, bOK ? TC_APPMSG_INSTALL_SUCCESS : TC_APPMSG_INSTALL_FAILURE, 0, 0); + + /* if user selected a language, use for GUI in the next run */ + if (bUserSetLanguage) + { + WCHAR langId[6]; + MultiByteToWideChar (CP_ACP, 0, GetPreferredLangId(), -1, langId, ARRAYSIZE (langId)); + WriteRegistryString (L"Software\\VeraCrypt", L"SetupUILanguage", langId); + } + + if (bPromptFastStartup && AskWarnYesNo ("CONFIRM_DISABLE_FAST_STARTUP", hwndDlg) == IDYES) + { + WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power", L"HiberbootEnabled", 0); + bRestartRequired = TRUE; + } + bPromptFastStartup = FALSE; + + if (bPromptReleaseNotes && AskYesNo ("AFTER_UPGRADE_RELEASE_NOTES", hwndDlg) == IDYES) + { + Applink_Dll (hInstaller, "releasenotes"); + } + bPromptReleaseNotes = FALSE; + + if (bPromptTutorial && AskYesNo ("AFTER_INSTALL_TUTORIAL", hwndDlg) == IDYES) + { + Applink_Dll (hInstaller, "beginnerstutorial"); + } + bPromptTutorial = FALSE; + + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) + { + RegSetValueEx (hkey, L"Silent", 0, REG_DWORD, (const BYTE*)(&Silent), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstall", 0, REG_DWORD, (const BYTE*)(&bUninstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDowngrade", 0, REG_DWORD, (const BYTE*)(&bDowngrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstallInProgress", 0, REG_DWORD, (const BYTE*)(&bUninstallInProgress), sizeof(BOOL)); + RegSetValueEx (hkey, L"PortableMode", 0, REG_DWORD, (const BYTE*)(&PortableMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"UnloadDriver", 0, REG_DWORD, (const BYTE*)(&UnloadDriver), sizeof(BOOL)); + + RegSetValueEx (hkey, L"Rollback", 0, REG_DWORD, (const BYTE*)(&Rollback), sizeof(BOOL)); + RegSetValueEx (hkey, L"bReinstallMode", 0, REG_DWORD, (const BYTE*)(&bReinstallMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpgrade", 0, REG_DWORD, (const BYTE*)(&bUpgrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPossiblyFirstTimeInstall", 0, REG_DWORD, (const BYTE*)(&bPossiblyFirstTimeInstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDevm", 0, REG_DWORD, (const BYTE*)(&bDevm), sizeof(BOOL)); + RegSetValueEx (hkey, L"SystemEncryptionUpdate", 0, REG_DWORD, (const BYTE*)(&SystemEncryptionUpdate), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRestartRequired", 0, REG_DWORD, (const BYTE*)(&bRestartRequired), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDisableSwapFiles", 0, REG_DWORD, (const BYTE*)(&bDisableSwapFiles), sizeof(BOOL)); + RegSetValueEx (hkey, L"bSystemRestore", 0, REG_DWORD, (const BYTE*)(&bSystemRestore), sizeof(BOOL)); + + RegSetValueEx (hkey, L"bPromptFastStartup", 0, REG_DWORD, (const BYTE*)(&bPromptFastStartup), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptReleaseNotes", 0, REG_DWORD, (const BYTE*)(&bPromptReleaseNotes), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptTutorial", 0, REG_DWORD, (const BYTE*)(&bPromptTutorial), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpdateRescueDisk", 0, REG_DWORD, (const BYTE*)(&bUpdateRescueDisk), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRepairMode", 0, REG_DWORD, (const BYTE*)(&bRepairMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUserSetLanguage", 0, REG_DWORD, (const BYTE*)(&bUserSetLanguage), sizeof(BOOL)); + + RegCloseKey (hkey); + + uiRet = ERROR_SUCCESS; + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_PostInstall: Could not write to registry"); + } + } +end: + + MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_PostInstall"); + return uiRet; +} + +/* + * Same as Setup.c, function DoUninstall(), but + * without the actual uninstall, it only prepares the system + * before the uninstall (before DoFilesInstall). + * It runs as a Deferred CA. + */ +EXTERN_C UINT STDAPICALLTYPE VC_CustomAction_PreUninstall(MSIHANDLE hInstaller) +{ + HWND hwndDlg = NULL; + std::wstring szValueBuf = L""; + DWORD cchValueBuf = 0; + UINT uiStat = 0; + HKEY hkey = 0; + DWORD dw = 0; + BootEncryption bootEnc(NULL); + std::wstring szInstallDir = L""; + UINT uiRet = ERROR_INSTALL_FAILURE; + BOOL bTempSkipSysRestore = FALSE; + BOOL bOK = TRUE; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_PreUninstall"); + + // Get UILevel to see whether we're being installed silently or not. + // Also get INSTALLDIR to see where we're being installed. + // Since this is a Deferred CA, they are to be setup in its CustomActionData. + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), (LPWSTR)TEXT(""), &cchValueBuf); + if (ERROR_MORE_DATA == uiStat) + { + ++cchValueBuf; // add 1 for null termination + szValueBuf.resize(cchValueBuf); + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), &szValueBuf[0], &cchValueBuf); + if ((ERROR_SUCCESS == uiStat)) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreUninstall: CustomActionData = '%s'", szValueBuf.c_str()); + + std::vector szTokens; + Tokenize(szValueBuf.c_str(), szTokens); + + for (size_t i = 0; i < szTokens.size(); i++) + { + std::wstring szToken = szTokens[i]; + + if (wcsncmp(szToken.c_str(), L"UILEVEL=", wcslen(L"UILEVEL=")) == 0) + { + size_t index0 = szToken.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + std::wstring uiLevel = szToken.substr(index0 + 1); + Silent = (stoi(uiLevel) <= 3); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: UILEVEL = '%s', bSilent = '%d'", uiLevel.c_str(), Silent); + } + } + else if (wcsncmp(szToken.c_str(), L"INSTALLDIR=", wcslen(L"INSTALLDIR=")) == 0) + { + size_t index0 = szToken.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + szInstallDir = szToken.substr(index0 + 1); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: INSTALLDIR = '%s'", szInstallDir.c_str()); + } + } + else if (wcsncmp(szToken.c_str(), L"REINSTALL=", wcslen(L"REINSTALL=")) == 0) + { + size_t index0 = szToken.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + std::wstring szReinstall = szToken.substr(index0 + 1); + bRepairMode = (wcslen(szReinstall.c_str()) != 0); + + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PreInstall: REINSTALL = '%s', bRepairMode = '%s'", szReinstall.c_str(), bRepairMode ? L"TRUE" : L"FALSE"); + } + } + } + } + } + + // Get this MSI Installer HWND. + // There cannot be 2 MSIs or more running at the same time, so we're sure we'll get ours. + // This is only possible in case of non silent install. + hwndDlg = FindWindow(L"MsiDialogCloseClass", NULL); + if (!hwndDlg && !Silent) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreUninstall: MsiDialogCloseClass not found"); + goto end; + } + + /* Start actual work */ + + bUninstall = TRUE; + if (!VC_CustomAction_Init(hInstaller, szInstallDir.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreUninstall: VC_CustomAction_Init() failed"); + goto end; + } + atexit(VC_CustomAction_Cleanup); + bootEnc.SetParentWindow(hwndDlg); + + if (DoDriverUnload_Dll(hInstaller, hwndDlg) == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreUninstall: DoDriverUnload_Dll() failed"); + bOK = FALSE; + bTempSkipSysRestore = TRUE; // Volumes are possibly mounted; defer System Restore point creation for this uninstall attempt. + } + else + { + if (!Rollback && bSystemRestore && !bTempSkipSysRestore) + SetSystemRestorePoint_Dll (hInstaller, FALSE); + + if (DoServiceUninstall_Dll (hInstaller, hwndDlg, L"veracrypt") == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreUninstall: DoServiceUninstall_Dll(veracrypt) failed"); + bOK = FALSE; + } + // DoRegUninstall_Dll removes regkeys that are not linked to MSI + // We need to do this in PreUninstall instead of in PostUninstall so that UnregisterComServers works, + // because in PostUninstall the "VeraCrypt COMReg.exe" is removed and UnregisterComServers will fail. + else if (DoRegUninstall_Dll (hInstaller, FALSE) == FALSE) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PreUninstall: DoRegUninstall_Dll() failed"); + bOK = FALSE; + } + } + + if (bOK) + { + // uiRet = MsiSetProperty(hInstaller, TEXT("ISREBOOTREQUIRED"), TEXT("1")); + // Cannot do this because this is a Deferred CA (we need Deferred so that it runs with admin privileges). + // MsiGetProperty and MsiSetProperty properties cannot be used for deferred InstallScript custom actions, + // which do not have access to the active .msi database and do not recognize any Windows Installer properties. + // They can access only the information that has been written into the execution script (CustomActionData). + // Therefore, we set the values in RegKeys that are volatile. + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) + { + RegSetValueEx (hkey, L"Silent", 0, REG_DWORD, (const BYTE*)(&Silent), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstall", 0, REG_DWORD, (const BYTE*)(&bUninstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDowngrade", 0, REG_DWORD, (const BYTE*)(&bDowngrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstallInProgress", 0, REG_DWORD, (const BYTE*)(&bUninstallInProgress), sizeof(BOOL)); + RegSetValueEx (hkey, L"PortableMode", 0, REG_DWORD, (const BYTE*)(&PortableMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"UnloadDriver", 0, REG_DWORD, (const BYTE*)(&UnloadDriver), sizeof(BOOL)); + + RegSetValueEx (hkey, L"Rollback", 0, REG_DWORD, (const BYTE*)(&Rollback), sizeof(BOOL)); + RegSetValueEx (hkey, L"bReinstallMode", 0, REG_DWORD, (const BYTE*)(&bReinstallMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpgrade", 0, REG_DWORD, (const BYTE*)(&bUpgrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPossiblyFirstTimeInstall", 0, REG_DWORD, (const BYTE*)(&bPossiblyFirstTimeInstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDevm", 0, REG_DWORD, (const BYTE*)(&bDevm), sizeof(BOOL)); + RegSetValueEx (hkey, L"SystemEncryptionUpdate", 0, REG_DWORD, (const BYTE*)(&SystemEncryptionUpdate), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRestartRequired", 0, REG_DWORD, (const BYTE*)(&bRestartRequired), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDisableSwapFiles", 0, REG_DWORD, (const BYTE*)(&bDisableSwapFiles), sizeof(BOOL)); + RegSetValueEx (hkey, L"bSystemRestore", 0, REG_DWORD, (const BYTE*)(&bSystemRestore), sizeof(BOOL)); + + RegSetValueEx (hkey, L"bPromptFastStartup", 0, REG_DWORD, (const BYTE*)(&bPromptFastStartup), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptReleaseNotes", 0, REG_DWORD, (const BYTE*)(&bPromptReleaseNotes), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptTutorial", 0, REG_DWORD, (const BYTE*)(&bPromptTutorial), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpdateRescueDisk", 0, REG_DWORD, (const BYTE*)(&bUpdateRescueDisk), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRepairMode", 0, REG_DWORD, (const BYTE*)(&bRepairMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUserSetLanguage", 0, REG_DWORD, (const BYTE*)(&bUserSetLanguage), sizeof(BOOL)); + + RegCloseKey (hkey); + + uiRet = ERROR_SUCCESS; + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_PreUninstall: Could not write to registry"); + } + } + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_PreUninstall"); + return uiRet; +} + +/* + * Same as Setup.c, function DoUninstall(), but + * without the actual installation, it only performs + * post install operations (after DoFilesInstall and last parts + * of DoFilesInstall / DoRegUninstall). + * It also sets regkey accordingly. + * It runs as a Deferred CA. + */ +EXTERN_C UINT STDAPICALLTYPE VC_CustomAction_PostUninstall(MSIHANDLE hInstaller) +{ + HWND hwndDlg = NULL; + std::wstring szValueBuf = L""; + DWORD cchValueBuf = 0; + UINT uiStat = 0; + HKEY hkey = 0; + DWORD dw = 0; + BootEncryption bootEnc(NULL); + std::wstring szInstallDir = L""; + UINT uiRet = ERROR_INSTALL_FAILURE; + BOOL bTempSkipSysRestore = FALSE; + BOOL bOK = TRUE; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_PostUninstall"); + + // Get INSTALLDIR to see where we're being installed. + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), (LPWSTR)TEXT(""), &cchValueBuf); + if (ERROR_MORE_DATA == uiStat) + { + ++cchValueBuf; // add 1 for null termination + szValueBuf.resize(cchValueBuf); + uiStat = MsiGetProperty(hInstaller, TEXT("CustomActionData"), &szValueBuf[0], &cchValueBuf); + if ((ERROR_SUCCESS == uiStat)) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PostUninstall: CustomActionData = '%s'", szValueBuf.c_str()); + if (wcsncmp(szValueBuf.c_str(), L"INSTALLDIR=", wcslen(L"INSTALLDIR=")) == 0) + { + size_t index0 = szValueBuf.find_first_of(L"="); + if (index0 != std::wstring::npos) + { + szInstallDir = szValueBuf.substr(index0 + 1); + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_PostUninstall: INSTALLDIR = '%s'", szInstallDir.c_str()); + } + } + } + } + + // Read RegKeys previously setup by PreInstall + if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, KEY_READ, &hkey) == ERROR_SUCCESS) + { + DWORD cbValue = sizeof(DWORD); + DWORD dwValue = 0; + + RegQueryValueEx (hkey, L"Silent", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + Silent = (dwValue == 1); + RegQueryValueEx (hkey, L"bUninstall", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUninstall = (dwValue == 1); + RegQueryValueEx (hkey, L"bDowngrade", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDowngrade = (dwValue == 1); + RegQueryValueEx (hkey, L"bUninstallInProgress", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUninstallInProgress = (dwValue == 1); + RegQueryValueEx (hkey, L"PortableMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + PortableMode = (dwValue == 1); + RegQueryValueEx (hkey, L"UnloadDriver", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + UnloadDriver = (dwValue == 1); + + RegQueryValueEx (hkey, L"Rollback", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + Rollback = (dwValue == 1); + RegQueryValueEx (hkey, L"bReinstallMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bReinstallMode = (dwValue == 1); + RegQueryValueEx (hkey, L"bUpgrade", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUpgrade = (dwValue == 1); + RegQueryValueEx (hkey, L"bPossiblyFirstTimeInstall", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPossiblyFirstTimeInstall = (dwValue == 1); + RegQueryValueEx (hkey, L"bDevm", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDevm = (dwValue == 1); + RegQueryValueEx (hkey, L"SystemEncryptionUpdate", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + SystemEncryptionUpdate = (dwValue == 1); + RegQueryValueEx (hkey, L"bRestartRequired", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bRestartRequired = (dwValue == 1); + RegQueryValueEx (hkey, L"bDisableSwapFiles", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDisableSwapFiles = (dwValue == 1); + RegQueryValueEx (hkey, L"bSystemRestore", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bSystemRestore = (dwValue == 1); + + RegQueryValueEx (hkey, L"bPromptFastStartup", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptFastStartup = (dwValue == 1); + RegQueryValueEx (hkey, L"bPromptReleaseNotes", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptReleaseNotes = (dwValue == 1); + RegQueryValueEx (hkey, L"bPromptTutorial", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptTutorial = (dwValue == 1); + RegQueryValueEx (hkey, L"bUpdateRescueDisk", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUpdateRescueDisk = (dwValue == 1); + RegQueryValueEx (hkey, L"bRepairMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bRepairMode = (dwValue == 1); + RegQueryValueEx (hkey, L"bUserSetLanguage", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUserSetLanguage = (dwValue == 1); + + RegCloseKey (hkey); + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_PostUninstall: Could not read from registry"); + goto end; + } + + // Get this MSI Installer HWND. + // There cannot be 2 MSIs or more running at the same time, so we're sure we'll get ours. + // This is only possible in case of non silent install. + hwndDlg = FindWindow(L"MsiDialogCloseClass", NULL); + if (!hwndDlg && !Silent) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: MsiDialogCloseClass not found"); + goto end; + } + + /* Start actual work */ + + bUninstall = TRUE; + if (!VC_CustomAction_Init(hInstaller, szInstallDir.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: VC_CustomAction_Init() failed"); + goto end; + } + atexit(VC_CustomAction_Cleanup); + bootEnc.SetParentWindow(hwndDlg); + + if (!DoApplicationDataUninstall_Dll (hInstaller)) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: DoApplicationDataUninstall_Dll() failed"); + bOK = FALSE; + } + else + { + // Deprecated service + DoServiceUninstall_Dll (hInstaller, hwndDlg, L"VeraCryptService"); + } + + // Last part of DoFilesInstall() + { + if (Is64BitOs ()) + EnableWow64FsRedirection (FALSE); + + wstring servicePath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", false); + wstring serviceLegacyPath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", true); + wstring favoritesFile = GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, false); + wstring favoritesLegacyFile = GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES, true); + + // delete all files related to system favorites service + if (FileExists (favoritesFile.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: REMOVING %s", favoritesFile.c_str()); + ForceDeleteFile (favoritesFile.c_str()); + } + + if (FileExists (servicePath.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: REMOVING %s", servicePath.c_str()); + ForceDeleteFile (servicePath.c_str()); + } + + if (Is64BitOs ()) + { + if (FileExists (favoritesLegacyFile.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: REMOVING %s", favoritesLegacyFile.c_str()); + ForceDeleteFile (favoritesLegacyFile.c_str()); + } + + if (FileExists (serviceLegacyPath.c_str())) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_PostUninstall: REMOVING %s", serviceLegacyPath.c_str()); + ForceDeleteFile (serviceLegacyPath.c_str()); + } + + EnableWow64FsRedirection (TRUE); + } + } + + if (bSystemRestore && !bTempSkipSysRestore) + SetSystemRestorePoint_Dll (hInstaller, TRUE); + + if (bOK) + { + // uiRet = MsiSetProperty(hInstaller, TEXT("ISREBOOTREQUIRED"), TEXT("1")); + // Cannot do this because this is a Deferred CA (we need Deferred so that it runs with admin privileges). + // MsiGetProperty and MsiSetProperty properties cannot be used for deferred InstallScript custom actions, + // which do not have access to the active .msi database and do not recognize any Windows Installer properties. + // They can access only the information that has been written into the execution script (CustomActionData). + // Therefore, we set the values in RegKeys that are volatile. + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) + { + RegSetValueEx (hkey, L"Silent", 0, REG_DWORD, (const BYTE*)(&Silent), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstall", 0, REG_DWORD, (const BYTE*)(&bUninstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDowngrade", 0, REG_DWORD, (const BYTE*)(&bDowngrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUninstallInProgress", 0, REG_DWORD, (const BYTE*)(&bUninstallInProgress), sizeof(BOOL)); + RegSetValueEx (hkey, L"PortableMode", 0, REG_DWORD, (const BYTE*)(&PortableMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"UnloadDriver", 0, REG_DWORD, (const BYTE*)(&UnloadDriver), sizeof(BOOL)); + + RegSetValueEx (hkey, L"Rollback", 0, REG_DWORD, (const BYTE*)(&Rollback), sizeof(BOOL)); + RegSetValueEx (hkey, L"bReinstallMode", 0, REG_DWORD, (const BYTE*)(&bReinstallMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpgrade", 0, REG_DWORD, (const BYTE*)(&bUpgrade), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPossiblyFirstTimeInstall", 0, REG_DWORD, (const BYTE*)(&bPossiblyFirstTimeInstall), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDevm", 0, REG_DWORD, (const BYTE*)(&bDevm), sizeof(BOOL)); + RegSetValueEx (hkey, L"SystemEncryptionUpdate", 0, REG_DWORD, (const BYTE*)(&SystemEncryptionUpdate), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRestartRequired", 0, REG_DWORD, (const BYTE*)(&bRestartRequired), sizeof(BOOL)); + RegSetValueEx (hkey, L"bDisableSwapFiles", 0, REG_DWORD, (const BYTE*)(&bDisableSwapFiles), sizeof(BOOL)); + RegSetValueEx (hkey, L"bSystemRestore", 0, REG_DWORD, (const BYTE*)(&bSystemRestore), sizeof(BOOL)); + + RegSetValueEx (hkey, L"bPromptFastStartup", 0, REG_DWORD, (const BYTE*)(&bPromptFastStartup), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptReleaseNotes", 0, REG_DWORD, (const BYTE*)(&bPromptReleaseNotes), sizeof(BOOL)); + RegSetValueEx (hkey, L"bPromptTutorial", 0, REG_DWORD, (const BYTE*)(&bPromptTutorial), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUpdateRescueDisk", 0, REG_DWORD, (const BYTE*)(&bUpdateRescueDisk), sizeof(BOOL)); + RegSetValueEx (hkey, L"bRepairMode", 0, REG_DWORD, (const BYTE*)(&bRepairMode), sizeof(BOOL)); + RegSetValueEx (hkey, L"bUserSetLanguage", 0, REG_DWORD, (const BYTE*)(&bUserSetLanguage), sizeof(BOOL)); + + RegCloseKey (hkey); + + uiRet = ERROR_SUCCESS; + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_PostUninstall: Could not write to registry"); + } + } + else + bUninstallInProgress = FALSE; + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_PostUninstall"); + return uiRet; +} + +/* Runs as a Commit CA : therefore, we can get / set properties that are defined in WiX. + * It sets ISREBOOTREQUIRED Wix Property accordingly and refreshes extensions list + * if REGISTERVCFILEEXT is set. + */ +EXTERN_C UINT STDAPICALLTYPE VC_CustomAction_DoChecks(MSIHANDLE hInstaller) +{ + HWND hwndDlg = NULL; + std::wstring szValueBuf = L""; + DWORD cchValueBuf = 0; + UINT uiStat = 0; + HKEY hkey = 0; + DWORD dw = 0; + std::wstring szInstallDir = L""; + BOOL bRefreshExts = FALSE; + UINT uiRet = ERROR_INSTALL_FAILURE; + + MSILog(hInstaller, MSI_INFO_LEVEL, L"Begin VC_CustomAction_DoChecks"); + + // Get WIXUI_INSTALLDIR to see where we're being installed + uiStat = MsiGetProperty(hInstaller, TEXT("APPLICATIONROOTFOLDER"), (LPWSTR)TEXT(""), &cchValueBuf); + if (ERROR_MORE_DATA == uiStat) + { + ++cchValueBuf; // add 1 for null termination + szValueBuf.resize(cchValueBuf); + uiStat = MsiGetProperty(hInstaller, TEXT("APPLICATIONROOTFOLDER"), &szValueBuf[0], &cchValueBuf); + if ((ERROR_SUCCESS == uiStat)) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_DoChecks: APPLICATIONROOTFOLDER = '%s'", szValueBuf.c_str()); + szInstallDir = szValueBuf; + } + } + + // Get REGISTERVCFILEEXT to see whether we should refresh extensions list. + szValueBuf.clear(); + cchValueBuf = 0; + uiStat = MsiGetProperty(hInstaller, TEXT("REGISTERVCFILEEXT"), (LPWSTR)TEXT(""), &cchValueBuf); + if (ERROR_MORE_DATA == uiStat) + { + ++cchValueBuf; // add 1 for null termination + szValueBuf.resize(cchValueBuf); + uiStat = MsiGetProperty(hInstaller, TEXT("REGISTERVCFILEEXT"), &szValueBuf[0], &cchValueBuf); + if ((ERROR_SUCCESS == uiStat)) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_DoChecks: REGISTERVCFILEEXT = '%s'", szValueBuf.c_str()); + bRefreshExts = (szValueBuf[0] == L'1'); + } + } + + // Read RegKeys previously setup by Pre/Post-Install + if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt\\Values", 0, KEY_READ, &hkey) == ERROR_SUCCESS) + { + DWORD cbValue = sizeof(DWORD); + DWORD dwValue = 0; + + RegQueryValueEx (hkey, L"Silent", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + Silent = (dwValue == 1); + RegQueryValueEx (hkey, L"bUninstall", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUninstall = (dwValue == 1); + RegQueryValueEx (hkey, L"bDowngrade", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDowngrade = (dwValue == 1); + RegQueryValueEx (hkey, L"bUninstallInProgress", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUninstallInProgress = (dwValue == 1); + RegQueryValueEx (hkey, L"PortableMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + PortableMode = (dwValue == 1); + RegQueryValueEx (hkey, L"UnloadDriver", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + UnloadDriver = (dwValue == 1); + + RegQueryValueEx (hkey, L"Rollback", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + Rollback = (dwValue == 1); + RegQueryValueEx (hkey, L"bReinstallMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bReinstallMode = (dwValue == 1); + RegQueryValueEx (hkey, L"bUpgrade", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUpgrade = (dwValue == 1); + RegQueryValueEx (hkey, L"bPossiblyFirstTimeInstall", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPossiblyFirstTimeInstall = (dwValue == 1); + RegQueryValueEx (hkey, L"bDevm", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDevm = (dwValue == 1); + RegQueryValueEx (hkey, L"SystemEncryptionUpdate", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + SystemEncryptionUpdate = (dwValue == 1); + RegQueryValueEx (hkey, L"bRestartRequired", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bRestartRequired = (dwValue == 1); + RegQueryValueEx (hkey, L"bDisableSwapFiles", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bDisableSwapFiles = (dwValue == 1); + RegQueryValueEx (hkey, L"bSystemRestore", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bSystemRestore = (dwValue == 1); + + RegQueryValueEx (hkey, L"bPromptFastStartup", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptFastStartup = (dwValue == 1); + RegQueryValueEx (hkey, L"bPromptReleaseNotes", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptReleaseNotes = (dwValue == 1); + RegQueryValueEx (hkey, L"bPromptTutorial", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bPromptTutorial = (dwValue == 1); + RegQueryValueEx (hkey, L"bUpdateRescueDisk", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUpdateRescueDisk = (dwValue == 1); + RegQueryValueEx (hkey, L"bRepairMode", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bRepairMode = (dwValue == 1); + RegQueryValueEx (hkey, L"bUserSetLanguage", NULL, NULL, (LPBYTE) &dwValue, &cbValue); + bUserSetLanguage = (dwValue == 1); + + RegCloseKey (hkey); + } + else + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"End VC_CustomAction_DoChecks: Could not read from registry"); + goto end; + } + + // Get this MSI Installer HWND. + // There cannot be 2 MSIs or more running at the same time, so we're sure we'll get ours. + // This is only possible in case of non silent install. + hwndDlg = FindWindow(L"MsiDialogCloseClass", NULL); + if (!hwndDlg && !Silent) + { + MSILog(hInstaller, MSI_ERROR_LEVEL, L"VC_CustomAction_DoChecks: MsiDialogCloseClass not found"); + goto end; + } + + /* Start actual work */ + + if (bRefreshExts) + { + MSILog(hInstaller, MSI_INFO_LEVEL, L"VC_CustomAction_DoChecks: Will refresh file extensions"); + SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + // Check if reboot was required by the pre/post-install and set Wix property ISREBOOTREQUIRED accordingly. + if (bRestartRequired) + { + uiRet = MsiSetProperty(hInstaller, L"ISREBOOTREQUIRED", L"1"); + } + else + { + uiRet = ERROR_SUCCESS; + } + + // Remove volatile regkeys + SHDeleteKey(HKEY_LOCAL_MACHINE, L"Software\\.VeraCrypt"); + +end: + MSILog(hInstaller, MSI_INFO_LEVEL, L"End VC_CustomAction_DoChecks"); + return uiRet; +} + +BOOL +WINAPI +DllMain( + HMODULE hInstDLL, + DWORD dwReason, + LPVOID lpvReserved) +{ + UNREFERENCED_PARAMETER(lpvReserved); + + /* Save the instance handle for later, + * especially for loading embedded Language.xml file + * in Dlgcode.c, MapResource() function. + */ + hInst = hInstDLL; + + return TRUE; +} \ No newline at end of file diff --git a/src/SetupDLL/Setup.h b/src/SetupDLL/Setup.h new file mode 100644 index 00000000..e38dd75a --- /dev/null +++ b/src/SetupDLL/Setup.h @@ -0,0 +1,137 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived from the source code of TrueCrypt 7.1a, which is + Copyright (c) 2003-2012 TrueCrypt Developers Association and which is + governed by the TrueCrypt License 3.0, also from the source code of + Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux + and which is governed by the 'License Agreement for Encryption for the Masses' + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2017 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. */ + +#ifndef SETUP_H +#define SETUP_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Specifies what files to install, where (determined by the prefix), and in what order +static wchar_t *szFiles[]= +{ + L"ALicense.txt", + L"ALICENSE", + L"ANOTICE", + L"AVeraCrypt.exe", + L"AVeraCryptExpander.exe", + L"AVeraCrypt Format.exe", + L"Averacrypt.inf", + L"Averacrypt.cat", + L"Averacrypt.sys", + L"Dveracrypt.sys", + L"AVeraCrypt Setup.exe", + L"XLanguages.zip", + L"Xdocs.zip", +}; + +// Specifies what files are included in self-extracting packages (no other files will be packaged or extracted). +static wchar_t *szCompressedFiles[]= +{ + L"License.txt", + L"LICENSE", + L"NOTICE", + L"VeraCrypt.exe", + L"VeraCryptExpander.exe", + L"VeraCrypt Format.exe", + L"VeraCrypt-x64.exe", + L"VeraCryptExpander-x64.exe", + L"VeraCrypt Format-x64.exe", + L"VeraCrypt-arm64.exe", + L"VeraCryptExpander-arm64.exe", + L"VeraCrypt Format-arm64.exe", + L"veracrypt.inf", + L"veracrypt.cat", + L"veracrypt.sys", + L"veracrypt-x64.cat", + L"veracrypt-x64.sys", + L"veracrypt-arm64.cat", + L"veracrypt-arm64.sys", + L"Languages.zip", + L"docs.zip" +}; + +// Specifies what legacy files to remove during install +static wchar_t *szLegacyFiles[]= +{ + L"VeraCrypt-x86.exe", + L"VeraCryptExpander-x86.exe", + L"VeraCrypt Format-x86.exe", + L"VeraCrypt-x64.exe", + L"VeraCryptExpander-x64.exe", + L"VeraCrypt Format-x64.exe", + L"veracrypt-x64.sys", +}; + +#define FILENAME_64BIT_DRIVER L"veracrypt-x64.sys" +#define NBR_COMPRESSED_FILES (sizeof(szCompressedFiles) / sizeof(szCompressedFiles[0])) + +void localcleanup (void); +BOOL StatDeleteFile ( wchar_t *lpszFile, BOOL bCheckForOldFile ); +BOOL StatRemoveDirectory ( wchar_t *lpszDir ); +HRESULT CreateLink ( wchar_t *lpszPathObj , wchar_t *lpszArguments , wchar_t *lpszPathLink ); +void GetProgramPath ( HWND hwndDlg , wchar_t *path ); +void StatusMessage (HWND hwndDlg, char *stringId); +void StatusMessageParam (HWND hwndDlg, char *stringId, const wchar_t *param); +void ClearLogWindow (HWND hwndDlg); +void RegMessage ( HWND hwndDlg , const wchar_t *txt ); +void RegRemoveMessage (HWND hwndDlg, const wchar_t *txt); +void _cdecl CopyMessage ( HWND hwndDlg , const wchar_t *txt ); +void RemoveMessage ( HWND hwndDlg , const wchar_t *txt ); +void IconMessage ( HWND hwndDlg , const wchar_t *txt ); +static int CALLBACK BrowseCallbackProc ( HWND hwnd , UINT uMsg , LPARAM lp , LPARAM pData ); +void LoadLicense ( HWND hwndDlg ); +void DetermineUpgradeDowngradeStatus (BOOL bCloseDriverHandle, LONG *driverVersionPtr); +BOOL DoFilesInstall ( HWND hwndDlg , wchar_t *szDestDir ); +BOOL DoRegInstall ( HWND hwndDlg , wchar_t *szDestDir , BOOL bInstallType ); +BOOL DoRegUninstall (HWND hwndDlg, BOOL bRemoveDeprecated); +BOOL DoServiceUninstall ( HWND hwndDlg , wchar_t *lpszService ); +BOOL DoDriverUnload ( HWND hwndDlg ); +BOOL DoShortcutsInstall ( HWND hwndDlg , wchar_t *szDestDir , BOOL bProgGroup, BOOL bDesktopIcon ); +BOOL DoShortcutsUninstall (HWND hwndDlg, wchar_t *szDestDir); +void OutcomePrompt ( HWND hwndDlg , BOOL bOK ); +void DoUninstall ( void *hwndDlg ); +void DoInstall ( void *hwndDlg ); +void SetInstallationPath (HWND hwndDlg); +BOOL UpgradeBootLoader (HWND hwndDlg); +BOOL CALLBACK InstallDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam ); +#ifdef VC_EFI_CUSTOM_MODE +BOOL CheckSecureBootCompatibility (HWND hWnd); +#endif + +extern BOOL bDevm; +extern BOOL Rollback; +extern BOOL bUpgrade; +extern BOOL bUpdateRescueDisk; +extern BOOL bPossiblyFirstTimeInstall; +extern BOOL bRepairMode; +extern BOOL bReinstallMode; +extern BOOL bSystemRestore; +extern BOOL bDisableSwapFiles; +extern BOOL bForAllUsers; +extern BOOL bRegisterFileExt; +extern BOOL bAddToStartMenu; +extern BOOL bDesktopIcon; +extern BOOL bDesktopIconStatusDetermined; +extern BOOL SystemEncryptionUpdate; +extern BOOL bRestartRequired; +extern HMODULE volatile SystemRestoreDll; +extern wchar_t InstallationPath[TC_MAX_PATH]; +extern wchar_t SetupFilesDir[TC_MAX_PATH]; + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef SETUP_H diff --git a/src/SetupDLL/Setup.ico b/src/SetupDLL/Setup.ico new file mode 100644 index 0000000000000000000000000000000000000000..8fd81cd3810d21fa5328848c92ab6d5140da58ba GIT binary patch literal 370070 zcmeF42e@5Twf*x{{M(XDpr)I2ukRn^deR1y@?=2s)}?%NFW3VEu@nkLVE8# zH@)}X6X_u9KYnZPaqhaCb8jvk^_=gUcdcDcx%=!f=9qJ?wN8Tu|JC554S4)lgN6;h z-S8s~&Q<^BoAd3D{a1s=+SjO2zP(?A2G4$by9Ph{QMTQF=LQWHUbtO@h7I%W&o*dq zYm@C7d{!;5cm78jH2A@j+co&MUQ;_7H26@qpUnmhbg=TMT!G3Js9b@{6{uW+$`z9{mOlo|D124 z@}E|&z`J_|%Hhk{OIu?z#jA16gj3u9Qy=?SJxdQ)@SD=XTblW(0yDhvI{d$UZuxYG=S8xlK!Sltc`Z1B*XO;=1=a;c9!URJ`jtoJ3jDiYf#N-%ZX4&c z#(Gi1gCTsXV{fpP>US_#8`i-)STExIf38!S%Og-<9nq`=0CvvLEL5BemF%bED5O&iTHK=kR=92To`xgHzxF zbOF2r52Shk9^n70@PIBt-cqJ9ls4u!TP?k{bk@7Odl%y zjqGsQk+P$5J4P*bY;N8@IzN7d+QVc#pV#7bc@MM!?{6OXmil~lViGiqV*;)L*MsZh zYsNK9udy~OkIEHz&#pjv@72~X;@nurmtn@cv0lVGJ`g<&4pO}1Bh$DY%-}y8%D~W0 zGO&(s$FGC+AIk8#sb2@{`1O5c`^vyNej7jjYZ;gYyWkv5A1C{*>_pi~vXf<}?6%u( z7aV^0;a7a=OJ6!`#~pXP^3qE$efpep&S|&jo_jXucz*5)YT*Z7i`V5nct76%XEHt; zpLJ(hLm4qaeY8M@2Xvt-k9YkFq!{PT(rx$a!aG)-dc`X=}XG;@h#*x7Qc%`1W#m z#|Qq83>>6*-$mQ_cJgTDeEXi-51xt|zMNkN>-hB=SpVMlzIW@{=bY2~qKhtCe90x3 zY`pEZ+g^F#fd@j@u3bY_RaKZYX;PRzeMVTgXi?a(VMExsX=C`uKmHNcuiqHv&07!# z4;~WkzyJPl#u;aX6HYkc^+t^v_0fBrCp%kqx(q%+NAUiK%MO+`lJVJpB7?{HKO4#_ zT0j?}@_0|LK#Fts-wC{1%Ny@#+%L=UbKK{(X?c7i`WWB-BN-UkL-upoFJ!-z;oJ9< z9Vi1&hsw~}*6?7hhF|~M*S>c7FMs*V*2f=z+>}56`OjN~@z?IX_ulaE!w-iZ-FrkF zgZBjs7K9ZmmWPcSH-_h)doH~2;tOHZrVU~4f|+6Rv@v1CxW1v^;BH~auzsOxYE@XZ zYIT@0WlCsrZ<8PnfdkM2TfY3|FW;cgaDnU`*%`7^W$*yH<2SMcWbhVRfd8|i1#}TA zk9YM77~jP<#XJ4f$K%_J{{3UxSJd;y`{#A+3o`I-EuZ3j2kqZcwzG`b9p9d6`800d zOUJ-SBia74G-k(_9w{rv>!%3of7oZAecBvz%rUd&m$%&fm%qIJ&_fS}cJ11QE?v5W z0RskvapT8@sZ*zh*>mQE#fuk&IrFB61&e2eMN4Oe$+L!pA(J|Uu0zES-7XK0biX1z z*yYl2Z~HUDUmyN$xZ(a|!fj8S6x#P{8u{Y&*Iy5#M~@DF{p(-Dl~-OFPCfP1s0H*H z`s?#uEIVHY51cL|E`Xc(?C6wzW$;>ETHrG}&h_THe^i#n1AJfU_o>awqjCjGS0KGN z+<&up|F~YQh*VzCDfE@ueq! z{p(-U(&Wiu`pl_e z*1W1PdQ!j8Yxtv~|G39PuaOUi)_raYkM+DdJkaUFa9@XWLgRL4$WB-P?9lA#^W*;e zJ6#Z(c04!k|NCPnhI`tc7TWi08kR3#9$tR=<)Apj_d7 z`mFE(alx6g-^=*?a2HzOKp8y8b*N|oU4+WxEnfj++-(u-Y}e)A|DTTIXNq{Ye^2#1 z{{5@6BHnk>K4Mz%UYnNROUKaijb!`DzyMnQ*E0Kd@J`JBTUpG{?Yr;3t(B9TFN{5R z!womQe#aemhGxy0g@+$`B8pezn6(&p`6~qS$9OK>aN`5VhQ32P zh1XttO?iUp@w1=--~d|Z1r9y*(5d<#E|py0|xZ{pHLW>qHLhIJ8qkr$!>)Ft!cW+sr zFmOn}FmQN}(0#z;q3yG`CI0;EsNL<$(ehvze{YO~Yqr5Y$1t>irvKT#BDb`EMdXhM zJ720eVrJO9d2{Hk&mvw5S6_W~#Qz`v_{Ycv|v#XI?|pUc2|F?L7GgZCq3_;%;%PW;9}b@pS?b{v0gKuLT zUvGmC@c-4u_NDQ-Il!&CA>)ILC&&dnGx&+{&wu_iYJkR#8;6^3zBwos30GZpRe%Hj z^rt`7rUlN?bvRx2X0!m`%eJ&Y@!rr=Dvy8BD^UC{y=}bH)`s~M@2RH8zvD-^k3KIe zhxhHZzoBeL8F=4S_FWlx|DkMm*&Z_R?%aGM_4k(@B(r}9??=f>c;D+6do?}ksG|le zSGM|^Yp!`!^>x+J9*8mYv(G*o`t|D{1`in=h7B7QwS13WT|>LhkAybenuIpJZjU$y zuf*nH-5MU;7JWJUI9`_-`_-=lAJpUl^MzYDfj+qc_+ayvO<~=-b@6{dr@&!1-gskB zy&>Y?xq&yS1&EQ}N?ySChVK>H%Hv<-3Z&mz+V^)_7vAgg@s8nByc5HJO-77qynjpm zon*%Q_tZDuf2uzBV-fEMYM=3rp09!T0}ni~)k!CvH0!j}PTzEmwDJAT?hnsA^Gp~y zYGfESYE&3KYIGPeVuWJ$F=6cZF=5cK-l1!sC&N?S?+A}{{Zqs)z8#!q7)8TpvATV6 zigV}c;0NdLc)mFx?R#I^`hBwZ@_S}Ef|M8hp40`V%o-7%fByOSKTub^=bn4Q?YG|^ z{_>Z<)K?3ftLt`#?9FHa=LJ5k=fUqElW`B!77tW-Ko{o&_DC^a>>Km;@3ci-U(UyK zKh)*p!TbNpYK!52pkw5siQ&=o9&1B>eqY%EvVmVx&pWyi>l-+ue;FFxY%Bf6h_ z^2xK#I`gdO$%B!j1Mg#$haa!n+k^=dl#ibjCd;Nwofw9W?h`uoelT1+KmJ+L#x33tE8djTYd$DAowz@Gr>VcVfCUFTnlc zdnmoPw7c?npRPdqJ(TPF`=T}O!TfeI`*&kL)%3>vXLVlcUHr00;cGv3MB9k=`LyWe>H@y8E3 z^UO0>pLgDQuYq^scgEI?m4BZwabooCjIWtCZCaQ)duo_aH7qyYId`{Qd8L4>#R(Q`7?B|4nKEz6)Zl+VTSB zv;Z7{@2F@2U4-}WVZ8H}?z=5w9;~N$=Q}Is<5NwK=7aOe2iI1I-&M!HBg0qxQ0AOn zxfnjhJ2|_E_n-XaCpVt(+usg4>#Va@pMU=O5%2ftKE}s^_ldcGpQ7=zV1D|HX|e9! zbI_CFu^!h&4W8ls(i-(N^gKQk9Fs$5ObvGXlP5>Jqt(d)yR-Evkpog5Nc-jaz#5?@ zFTe%n2>75jZZKD*$LXifNw@i&f4uECVZ!tQaee@K48|NjqHzgu04;S(<`yvS*!e-% z3b&yJ&eeBuhV1QX0XTqr%sk+G(X9?u9&hssq}S4Y+9KZh4vLsJ-itmS%%_?j%)|4w zX?pO!n~WI#$1=z8Y0hpx?Z=NeXJ@=03*JvW@x(#W@~bbn;KJ7~`@?17&O7f69XfOf zBSwzU*xB)l;T69N_l$jK-28+|V?xh>bCah^PZRe?aLGz-| z2lHS*<$(tud@#mGXn|XAy*1VfsS%(BJa(v_H3GE20W#+W;CH_JZ^_8*RJ4FD!h8I9 zyO{r!K5we)@$s(BIZw}bOWuy}d1o0h{C8#FmlZXAI;J+o`{6qGDA}<;{pn9{RBnFI zdFP(HT60+B-!BiE2N&nJ4jVQ+`uK64NgCY-@55Rvp<2|es+?pTUq7%TW^#ZMr znLm6^${#-8+>$=WeU4pt!$IM%ElvrqzWQodvSdm0^W;I${^kM4189Sy7I1#Bs09u= z%@4%xj%%?t{YhG5@f9`XiE5`BG^hF=P zlU}2&rvJ!CK2lfCu7vkJ_SoZwQ%*T$@P!v#xcbsdFZ(C=Tf}?oHerb7vyK|AdYtC7 zkgFdzR=AhHXS-+bPT{fkcZDWTUKa75#qL?$4%Qi4i_XVqGcJ~#7;|OlV>dl`Tn#f1 z5IbWvI6&M0Kh)TlXa@Mf`oP@axWO$v;d8tXZm@6-ANc)L2ap$FAIGQ_@*Pks^mu_(3us)_D?j|<51-U`f3fU* z*;%sFWGBj~yD+W_ey?Z&U4-}GQ5WW|?TdKdmaaGE|3{x6AKy^6qih!$K0ej-wbkJd z(s_r<(1u6Kj@e;{9WFfK#1pzJc3=F5%QC#9J6pAC6$TC*80+pMMpoD1$BflHSJmQs z_U;@WZ+}l{{P?BHkDVX$b=LA=9V7Pz7Qs3-Fmhn2nFCTDD8~iX2XI1>7fSqKPH+n! z0w2}!iWbmCsN<31 zJ?%TL2lK`~*ApY2FJj()KCRE8>&w;Vh~>T~L(@BNhmWsK(>sPg?&zbBZY3?hM85qM z#-iVG`yCPQ{rmUN@Gg9h6z0MCNX7KSrSp3{(>XlW_MULhW0!@d9WIFRJ9Rk5%(i;= zdd-o$IpQ5WUeox<8g}iyM}?B*JYYV61In3oL6IAZ{9taNH9xrJv(QgtiF9A&hnz2p zJi@k*`&hcqujzeh8~egMtv?I?|LD_y7V*y?I2OaN!vl;1Aopi2fd6-m03LuBI999` zdJHi-jl4jj1uoIOfEGAg_Iue$vQ!IDyJfrpc>(-KB`=_h@D?5^-szXae9_kzYjnl> zoOOK~$D`{V$CI}!=i?91{)1(|mX$R9!3Q7QNlyAx%=XJ`x zC;0#6!QUz2pL##|r`|`)cB%!4|Iz>Ofa3ydfpX)9&;f8kK?_`_`=FQ?_^tM#{SJ}s zDq~sjlBc z=Q5stFU9kX)b1xcP{wyjj2C_UF1ze<;o0Y$Jw!fX&9&ED`+7EC=E2aRW5Gb;NNe{z&yIFoUY$r z`wx;GDmzRT^YofO`lRx8i?6=s>Q@*?M$FhrHTXe;28S`DHEw>~*qEmS`}p`ieVz@E zx4u6#dGzYgv~4zq7A+6X+xNdE`gm$v+`HiY(!U-OYgp8=Fmr%gb3wXoK1ewMK7cD| z%?I?&6Yi(SInUdEj>1+5i`8ntP z`GD|?1FP{*?l08<)&WH=K-^!{0_Xwf2dxEoKJyA)E3AhWI92z~@v^$KKy7&eVpn`y zB`;7@?{hu4E?gh5kIpapd-8bbt2BpaZT|!9N88)a6U#S}uSeG#^HJAp{`>VB8#+ky z<2I8QCWqAWk(Lqj_;zaV6E)V3+8p`${#y5-E?roJ=^qY;Q`F&(834i2e-BHgt^15`2tR$U(^!briDjn(GzLw zemTvN@(IViooW*AGtZ>2!!bY4`_uFM-sR5o^Eh_ywfl!X57@Qj|B3a{`}q8#4ya8F z)TdSm_cLxt_eInJ)CmfCfx5H+_gPvaz!%|{Dq27np_Yeze-Zok`JdJE$mcnK&$WbC zcanj7`+8!qpUD_!yN_%?8QLB{59W{7Ix&qez4Ve^@LjtqXZKXI@Ib2@Li3K9)^Hc_ihZ*w^cE9DXTrj5(^%`nb=9L)=eW za|`>@bKIx3`FXW%o6p?(H96m0Mhh3Q@2o%V8}{74+W&)B;(OwJa{uH5z-_7r%mM6k zjezsPxod^46VOs4@VKFJwZcMP;7Q$M)&gg%@4Ud#>ir|4%hP*M@7vcwFoKZ>hhF4D1u%gME0G>%5=rVCC-4R1UYl;yBi|ivFSH zqb)<nxpTv^Wy`cC?P9GdHCq~AYgLXK9a?u#j=0?|p=FnAqo&8l6UQ^Yj{H0t z6-*i5VD_AAs_pEn_N%d7?%1}T!*QQe?)BK`bKK{BywA@~-#hK6=ef`S<9^!u|15Hj z_ZQogpLiX%Yj9J}l{NOmK{-d&*q`n*Pif!pFZ)$E^!VMQ|7R^A@M@n8rpX6b3pg)e z{L{h#t`QW+4HdP3#|`niJTF~ipiEu>E#Ml#>FTFi06)}7#y!ft%6)4sfIlOTRn!98 zX&?TuoEFgTf9;39Kr~JI;D6qVXPyLST`YWw%b(wxI zYLw=FJ_qK>?Xn&%!{QYr=|^E5joF&cvMAv%>(5%jw+xsnDv+ouOs-tK;~2 z#@I3bhIwg>PeFfjpMxRrcIK7)Mju3b#ubg?HZ6v4O7|DHeaz>(J?-*+;`7;dpVob! zm$twE!>{6TpF`{S^ZU@ImOek-PoL-V|Iw!Xbf2$*`GoU|`%?aJpL5)&_4AAS({s{( zdfq7)?;Vam>lYFKtON4cV~<4*kH1C-kmoD%Kz+49x%^;SD}+~W(HaBf1w3vj)dD~N z`OmxRKC~7%OMPpBW7PkRtUg-cGdhoZ|36I&82`jUX|6xTKe;}1KfWLQ|M1XXA9}Vh zKUC|$z07yh;-MDd>8GEL<7(GxohW`!X3d&4Veyj1Vb;u9Vc76tp<~x4!~IWP8=7~@ zbiK#fF%|_)kIv-&*87CBMwhEA%<;V{W~VZH#-}{kPis zbCgNki39n0_O(mqXpmrVt_OzNVNd3g@0k~L28BA1s7Zp z^MhKWVYz<0@Mhhc)&gg!Uz-*v<^_sc033jae`_tE|Br|9Z~y-Z?Sl)^MXv4tkNV%- zd+)s)X}(;i>#x6ID|sHi=QdiylJRv*mn@BQ!`H80A6Bkd5vFS1+`vHtL#y^J!aXf7 z4-a+uW30s!%j4r6$D=)sZLk*cVm#zHDPj615M!*-0pxVRE%5-_kNCbW9zYj39!T>7@Q3pPyrvB;05|Zu zXaVj$))+|V67ahu8aw#UiWU%3xA7>%0BQVh4e%+w1RQ_{_>#umHIueqgP%v^F;|v+ zJ?lX-7M!)ASFTzWCQq3h$K1E>_(-_-@hii_U9X6kC!S|4J>%QZ^!OX@EAH3gea|-c zT8b04!BG)Y-e)|zJ?`wE$8%|qJ?m%HcBcBZna``w@p9*~&(BpqzPGk%ZG1lW)0Y2> zW3~N%=9H96=$j*Gea(EXw~Oca`uaI+7kQ(&4?f`hek0q(`M>0G_&pF}JaoY0k3U{o z3j}`+R^fqiF@g0!kpsYWnisGZFbALs-~spnZm|~ddPCF+-h>vQMzF7pv4eGK0dVl| zt_8q9mgWFHamghYA9&rLuN!{D4cEWQ_wwYEPsX)snfnRmnFF?Z_39YYj~O>2bnX3A zc%xzCL2;=Rl^_df<^jTPe;yu`jSR;E4XjQ=+zJ2@n zdj;GdXaUCjgHw3GF+q_B(po{02Z$T+F{u`CJOCFs-ard*uC)Mp0XTs10*Myrru*7? zfwR@GZW)&P+Mlv~-4dfh$x9@#5H%r<9t!eLVM4dY{?v`M!+zzwYgFI519VjV1RFKjkMOHL&-alXee> zoxFSa^@%@@ecD5R`=hv>?xUX`^EqyPjBW4Zwf#I=wo~JM%Wd-+Ic7^gGdvMF!)?w} z{vY|DV?XCG`nKZrVt-xN(#KLhNqN@$%_k|3z!l_V7A=_ar-f!`@$%~O8AfZq!z z9zY8)FT*hbJU~of9w^2H@Ia~u=sO-LY5`sg^BM!h8@w)D!E+c-;&DUN2)3aGPSrin z*uf)YXn{tue|s&E>i(n;{>=fA2Xs9*as6k`oDuVQ(;ow@t{G2^g9Onok9I38DqFuFO9g6d=Pm7 zc!1w2#Anx)8%S%0;NKj;{-PFuORNRV1LzF20=X!1j2<@x2Nbk`YXleQelMp54%GhQ zcmZ@a{9UUNfX4)rdaL*B@n3o;Eb_p^k34)kygEv?yY=hVhZXw$$1273o%%eG zuVtD2b`-*b2(|7xye56Wc6?txOaA`eZ~ky=uJLy9|MLHr zw&`{7wJFz{FN&=>#MhbYZXTh9Gm6{nE1AA4`tUg4>$Bp0*8W+gJP+$0GY4bv;K6Y| z7QYKdJkYIMx0n|oCNK}wH#dL}$BG<)A4;_V9N-#(a|3LXFCfl!Agx z5ftYXQrAxN0*rf0YXtSp3xKN+)T0c?82_pt)uG=BHgNpQL%toi zX|cTzuC~1n+BNR;{!yA0bIW_ur%idpeLknT!n~1gn=8y6{@=|J z))(nDO8LQkUrTdlxwf`*_%6)9{(k&@nH%_ysTIy%FeUyD@PY*k;=ByjMrED`b1zwE z1uejD8}-m{nGq9E3no9vZyDA%H;~p0%>}fn7Vy|XYXLZ*s0D}#;1T~$8FfN(14&*0 zEpUnKd|5dyaDeus1(?UeIJa-hc92mAV=Qc~T0m<@qoMJoDXz5n<{xFS`sQDx%ro@5 zA4*=k^f|@fx1;5zYg{htyic1uCdT&U@rdck+2ae0b^CSeO70naJol3Qk$sl$W9#R5 zzsqkL6SQEwh%dImp)m`V!7Q!q=lks(us!$RB^v$zYqV2oUwXW3U$5uq#+L2e{2p%k zJmwaEF1P;db+svP_$97hepsHGYdVQ9U2D=B0N$~39Do)ek3fB) zoE9KQkk$&V1*jF)HeTREANtUFg2@@Obi9D`0@ebId)Y}=rxwuqvgFX-F%Hmcz2gtC zpWwgr`n`Mi*~E9bbm`K-Z#^)tj#@qIzcCJ%@!v;Q!^q%1!O0n*HlKa^AH1~Uo z5#tAp(T~^@mcek*_Sk2~fc^AWwVRLs>9zCi!O?feEQ4`P4t zKSTZj4q%OBa)GP|juzne3>_0VKloO21K`{okhW+9j^X321;_yq12`U_Wgi@2Ex@=T z*9z0TfaamPMo`QP94%n{T80+bTZR_+foxY52n08Kjj6u0P{Zg%@Mxl0}sIq}VsKYk6j92zoo=n#0Exj8FWt_WR*=-Mi;kMA$72PqCf2Y7ub){9_FneP|w zFJnEur+wek+RqwCw8kXu5B_iai0QPY|NT9-kH=`S-G1`F(dd77_iwympU?66ehr?- zzV!9s5%YmRi@C=9;B9~Il%v>Z9&q1$VBNsB`z3zJ`Jl)NMSd_Jm?OOHYwc}X?=wHp znj2`{Px--IZGHgz=zsLx!=0~+V}2O(!Tb&4e>lK8fZsr3tp>CJc|r05=7D!AH{kKa zsSYp?aIB~Whyk1zpk=$ZTA}j-T4Uh#U;XM=0|W)<1h^;KmpObKnp& zo@v2zYTx&*K z(8s`hIX*BKm>X!#3$^h<-xc zZhb!6?wczj2c+Ck;23`%J|BI5PV*BjT;Tts$P4~ItrJpi;9A(s0mW_eqAK;fix#T|9yLm8#lJ=WNEm?ix-6@%NB$V18$AKC1dP6?g#g1f5!29tw^x%wc;4- z>oumB%g22L4(w;$f^%aXoTgX@*Wdc~SHh0p`AWpNTlUl6Vb?F$I0n|)$8$Kx#_Oj2 z^gTFc&Pla_H3F?aD?H$Ba{{e-0X_ixjv>qo)&=H+qCQ}|xUU>1ST9&p!3(xDj!3zH zzPX@WYu(^u!~)=+oDQ`6$}fY)$)CvyYne)E7e0o#rT7z>cr2+#tl9@v%^V9l{(k3H5}fV{xDveRW~fiy4B zNZYJ`LtbDv**0qgI_D#@I&*_M{;ods#g;fn-_J@k+*0xTv^is9-jBE+pAYu!?`y-o z*OOzNj&vO<>IJMT!x#bXbz_hg+!~*>;1?WY-`x32(Y)=pw*5ZNYt+Ua)(ELKFb{2u z3(N~CCzuP&1K>XGn+L25($?C5Yhs=-_KR&@u>;4<3#GUruYs212J-^?pID9h9^1(8YbAdHPkps*H@R2#doZxt&oIWrQ&=z^X z9Dp96pXvgz4llq3<^cNE0@ed=%W**(CpeZ!V}`Wv91OSz^VDV-y8+J0-;m!Sw~K~j z94ECtVz;JkE(_~7tdG8*nm^h<#XlUt+78wNjt86<;9ep>n8pO=fp;S}0M@MsjDOm4 zS^&(aJOCdQYlU8Ki17mC1-79DJdc1HK_l6o+ika<*BYvi7Kj|cxFK;*$_4Kz_KPnD z{xSLfy{X^u-7Q_dBy<|2@so=4jeYBTYkV+|q4U9fihJ%W`+R%~m?-uNv7pwu&Hst~L z%?GI-FbAagFUJGs1nUCxLXij9wl457Z@V?-@$-z~g`44VVmflV;2*8V*llpnIal9v zbm-c*Wmu>%5t}kMq^&!DL>+^wmT5wO@*lYP1_uOlk*S|pz z5O;zzuwEYn`$aPc81Kc__(uoSr3KIdm~o%-K-2-$5wJq;u((~03*Z220O6iOVj%@yKvbi)%vnXP%C+JM+3< zR;{0yADxfiFZ%u>{%hlb_aip|&Qm>L4oKqxYJp%q%?*0Y0Q+1kWDK##4G|M0T41wk z1UCto&I_EOeykCE_`@GQQvH$^P`|dkz<=vlaUKC$pcE4%dO*AD_po2D?Q9>X65Sd!JJ^?PJ9lz zCdL#~Yeoy><5M0m)~yA+{f0J)5x_s3U>*Sf<^Z?OJvas^Y5~Ut<^Z>~;oq2diw>Yq z>zE+zm&3o~0{egS0Il~K^WdF49=e`dJ=Ykm#&30_>lw36?uPh`@5F0-Tygv1;pV2N zYh9-1;hA1Nl&hN>{rU?pycjlZ-mDzZ(y&BvJ-Ix`?A#k*zBd1F{L@lDO7#F*;JwZb z;KNfMC~|AXT>f`S%cyg+H}pzwc^w$TE=ksY8hL*=x< z|L7Q6;BzwO6u#xWfN`wXsQ1Ghz!QZ3dBkbUmM;tAX7-A?K72m@9<1B1N36?t6tQk? z@AWFdJ2_;q?)9d;euUSRNO4a*8hw#kYR>Qg_cl1KfpPGi`u-g6jvuT6Qrwrrzx{uT ze`DXRb%5I#1K{)R|I@aN76A8Xf|Lu)0oDOU{HHnq9!L%BgL^bRbvnjfM*l9nqvydo z>n=E!hnx8h;8l3`s=JN~ceJ=Tv}|=>7_Q$#B|Zns8#itW>(;M}dVR)>>9LNF7Sufv z>-V(8>+k?ZULQ?RE(SZL$SGrS?htEzOim~w!5Al(NS z*w2$M<$A!S#93%~@-yY|4zE(TZ@2ctd6i0|3Myk(##)C4Br^o~N3)X(BEe=SzAk_lzM{aA|`E zJKElJ1>Hu>=kv^sckWqYR_^n3El-2@g zs{cC~V+W6t9V**TwwKIWU}yFDeX?zh9|r$L4tQHUVEiv$yfFUOmbE?pyoO%SHM{+| z@of!noO2%==d||isee!B2z$Puu^w?RpAX)t5#sx4!9KpxMx6^B8t1jO#(&Z0JJvVe z?eneq%eA~;)B%nG@)+NGKW$UY!2EmW;)C%qnwK|fG@5>N z#Qz9vyFen5SA;Qh`Gl;Z)%1MovR zEr1Sy1DqdBYlVyfgVA)a+x&j*Ia-znu>5iSOm~5KCDDh(Bp=z1@wCa zuN`o}0i%Rb;(_yIXn|8@UT-YT4N@okuFUZOTEMx%PpV%o9x(RPR;Oy9OHt-Hc+#2&9qi(#Tk&SteZN-<`-~oIr z{@HjhVm|fx?!y5^-=E^$I-nf(9lxXNd2h4{+y{S>LnSv)+z!?mPszMV>T!&ZAie_Y z@F~|3f6sZ3b-gjP?|Fad*zNJqxm$-)tj;={tjmU9XPvz+UAo3&{iW}T*U@p~FyY?V zA3a967gk4N11UwSqJsSgv2> zf%h^uP#X`x2dNeS>*#;{KWiFV50Dq&80Rt%AC!l_cfBN-)z}LiY)23I&`_sCfdorC59(8#hj~mOzv;DU6ynukKRwqclV8J>EXj! zQxnX4T}^OL&JJ9Xlb?+5#l1BCq;`^$fi$m9Rv z^5>al@qqJyLt{QrxF3d9#|Cf!?_V7kNDJh(0(hWUD}a-j4^*F8!TXsTAg@PEU_Ahq z!M{0xW7Y!Z0c!!c08XHO$m{SNv_Lv;h`fNbz^kee3>7fV0mK806`(%w8yWFHxwQrO z?Oo~vpOt+|_Hmi(1LlA?ofEMCXIwV(I3`V+81G}(-@vx9x~&$!XG}Xjr!D8h@#8l8 z@glx!!+DB#W8HN!<3DZbgH`K%`+B$FJ@x&@zT2qvrRl*suf_j_E~5Scu8nzecFd8& zx064mW`c$%?@9iYu@l7lPjtIE^c?VH=rgcO7&y3Z^uu72TsxTRpRA|-tnkn8q=MB6 z6DR4nm8QhsSDH9!a%ruNh<(Lxn!g=wO!WO)e?$0>M%+)#Zw(OJoCk6apa#ggox}uS z)&6V}a{aD|kP11K_uu9DX?up+yAFNx;t#_-?yMH(N_5NYvgo&{Zho2s5EGC$%;JSiJ2*#(9&k)hP7e@kevoqm z;1>=k>H%{A$1u(_2Y`Ke07Dm83-Fw@R+!`kUfFlweftT6XUm)yEY=8rreo9yofm`y zJb$3pyddKPFrE7b4gmW$9gh#=pZk-T6u*yV2fy~WX$#JbP47=JnjSCiFK(w8eXD)2 zYD-_k`-laI&Cvl-zdLuI=kGXuc#QblC2i~jP0N0>gTmYuw1}vRJkj4Y>fMWu< zBCQpsTHwedk6iZI&wlm~0wNs193pc7vB0ln|0iP(QLP-%uwg^;g4@a7Fjh$W;D9O9q(B+I}M6X-J zm-2MNI<)@R6v9b0p?F`QFkpl+~ ziZL@fe}dw5us&;+*3f0G4A#zKy^QIsnK3;+AM6|dlP9yTUXFWVeggVoqQ>Hm&*J`Z z;6Gwt>utr@KhOQ;*sqCyV?Wmbs^#JH2TA{T>)I`@(~lOxcQw&Hj>c`(s#WOHRk4cV zkm&1UoiNJ*3>}iStnrr_nm|TAQI?J$A`e-vRzUuuKDC1PD>uM3a7T z;J1&`-$CPb;0@*yq`z0lJOb4T*N6iy6-cQIq-zQspl$L2j1e#gG*sU@pkCtzb$*=> z?pxx2zO(C^9uxIFnjB1d3_2LXyzLgO(Rb^y` zpiRI!wKwPEtFeAg=GT?8GuEAxr~bkDr(L>#IQNg5|9I0`;r7NihKC<*7CLln7qNgZ z$Jg?E$CD>dQhj|)yx)nX2M-z?^X%i4m#dO5pEFl$<1in7&fG9-w#MRt{fK*f{){ly zKA$yna^H{7&*FXIUmQTpA9cSuK)AR5kN6kg5I1D{Uv825QDkXRtr2y!0C>IOriMu@r~=K}bT_=C^FwIer(4#3b! z^{ExSm$?CaIQf3~5PTQ)fH}bNK&k~C52QRmtiU;Fs&p;^9B}yIhtCp79S5ZA3GAc& zzmPF+z;%I!>Zjv`hy~J|U^yM2Q_4TM_RRey-fP=)jQ()5dEqtfVT);N{V(a7O zT3!?5SlUmweLQ`>&rMtN0WDf3)$m2X9yNT9b>=mJb&qqvub+9v0pWtHj|^A;?aXl7 zJvZq4en7uv*IxPf0TCl;>G2bMzh+vS`#JhKVQ0+PG2($Kan9Vl`C1om{(>+^V=8A0 z_h3Gna6faVeZJPuE@}P@_fr(_$5>x{9Py9uk1@YBz~nF?=KQ4tS@IFlqw! z=^WyPEKit?DK3{MgcH!B^{EvU>xJ*ddIRQxR1Y`~poIs(x3vKA02~4b@cT#p4J2O2 zF#+?7`OQ++7ujc@eYy&v)C0gjb-_brXaL3t5eNKGMn2Hv1HSs{Pk;K0+OBV1K&QU( zA^v?W8~?K?H1BwM#6Q>r*Tl?NaV(qnn;+8FJVDF;bUW>*`1XFkFWWv2=KVVOb!v;$ zDAD57*on(MAI9@u@$=;1Vm@B$5s;6M8eUrdoU8W_7hQKmxc0U)!kta73oRbLU%yk; zUir8FF~-Fwj#bxt4t(_pu&zrX(%+*+` zx%1{ne~-_fIV<=1!vFNd@1yyN^)r*^C*K!yetGOK9>Dj*0h#|-E8Jr-4#@F8R({mJ zzZCO}kH`T!_Q&UECcNu^8G--T|H;_i)bGbJLGstMG2dT`^_}<6wSVsOBmU+0$z=@5 z@el6VHXp?OXa(&<8*D2!Ko@v^5%mK2fVP|!dEmXs4WQ+%2U7f(;{cBpAda$`2haoX z0CfV^AlE#<7ZnGbt@*>?|0o$XLGa&5wx`S*U>Efp%7_D)Gw^xYXJn-@LgjvgsJ694 zbiFrcB;?%*MV zOL%8Y+vtdqtQLn4Bwj^xla~X}i zUvvBqXbi*8zq9`K;BpeEIUwx&H%kJQ{T{*S=E@a33C^U*rRCn+MVse5c#S zKl{<{<@(hU>qpD-{3XAi`~2!WKl+|A|C!Iv;{2Lp0ApS+YJ7Y?v3#!WBj)9^ zbL>Z-p8NF-*I+-#xUMgG54eDRU_Y~gaSX#i)i$YbmN-J^Sr?cK;<#dc&T>3J4Kl@k zu@4u#m$?DrdvXKj0rY_50&{@#g606?0Pqj?xi9&RWdA-Yug82sX@D0#_qoq8Hjw!N z=>Pp?)B%_;i2o-KNDQ!(Z2OOY{Nrc<#s-lKtf2w4{gFnE8j%a278vV+xdw^>6hk}2`#zhXu>tx3Mw%U{%QvZ%m_xKs+7vi@WHv_hr>&Ccveru3< z?W|jaPbUYDPiMRwwRPfzU{_r+LWnx9&K^!YL0 zpXd4YzcA)!jBr0@bmspV^9P2|`;O^phhzD8Km0sn{Gu7}X!MBxET8ARJ~}>Hj&1N= z!no=J#yK?tj4?|C2GAcATW}vuxs-UEWAH;fKYJ~{Gu|)b0%-#AbCCzg4=}&T*e73z zdD|_yY>b>1yzy@523+S$^#It%oDYBl$Opgy_HMhm@%iGRtj4dgeZoFDe`5X#(jxf%@e?xLUmEA5|0l-#Ip$-G zAMs9JkFmZP?mfmQ`g`f?$bq^p;6ID;so7^Se)RX&_sZ3kaG&~m{JSjTUbr4OD8sig z@3w?>VV>M6_z|Fks+(3%6x z1MhZjpj@rMaRA)Far`_u2mfH6-%0P$qep2@hx{|YIj}^)#P2tfk^95<|CI57YIl?E zD%(+OhkWz%pa1+f)F%hV^A; zV}AduaN$+ri3hF=U3;__Zpo*EflTwFZ_}~vY-c`B_!rK}zoXx&r!5fYgXgvDHe|M* zc70g0Ze7HE3H#!LRjb#=b2)!S#Q(~u`O*Ev`z7ql_h)&&JlD5CnqU5ZF1lYaDsg|z z_2KtrrFcK$p4xs^=c}5E-$(Bg>x2I+=O1f)(f3#T{|x_mt}o{NCdBcBlhvQByaaW} zD%BscX;o9g^r=(A42{*Dq4oS`OwVkl+L<$^1=?9NWVF+&!pvzpw@TMbHg)pEP&H{n zm^?xC%<*Hx1l8)tt4=poyfJzd^Z%uxh7Xl7S6KPGVZ!I&LBgr5 zRQmnFe7}ArE`SHv#~LJkqxFq_w&4k$J8+=l1idEt24W9199%F;p9d}=FT;1wJqr&I z|J#aOz}SM62halW0PB`e?@E8KggO|nNj=i{7rY4{!Eby<#z})$a0`B|-<{LL#}gCa z?}-U);Gg~00F0+H{uyt@>!MxJ2Gjy}+G!`o0TAgxDsu)T59=CEPorm$YNZi8)OSi4>Z4~PTSL=F%S z>K~Y2aA_T^9%pP{N(%RgMHzCF1h}>3$hyD9DKfTAN4+Y ze(QbteXw83_2qd!;lHYiu|ip$pS&OA?5C=oF8t1#uK#bAbjxh<*_;_+(cD>K@w_=< z*@C%Y`QrIu)e?=NUA`!+U$r=FT)i}GUb8H0UAsK|W5bH@+{RV1)zO}(-Ml)`Mq9r! z{A2y{uyysauzA(euzvZ%uuiYFYQgNVY~GBpbnf)9V7lgmPMa9!R%!0eq_JVz#4%y& zgpr|Y+=wu7)UYsN)X*?~4jmMR57ro=K?A}NjUyeZc97bE{riQ1 z1BC5<#(9qYzQTXBzHyC$emb7%gnpSehQN5hhqcfZbs%c#2Dj@iZw&?0C+FQ z1^(Sa;(;_KfCt`<-zgv_upWR5F!0a*#~*(@jaPYwg zHy1j=y<>iA|HS>|{=X&rrec45|5s(i|DU)2|H@as^2u*};~O8>zI2YzhwEBLP%%JD z#{jcu&k9}pJrc*UlS^klORTer3m7ZIxOaGgx#_fCClsvX+i!mG_;7#QD?<1Fny=ow zb?DNgt#s*#sEJuucFo!~(r)PMP))bA&5mZSwADb#T6U^VYCY zwqes2ZEuM!{S6y83;#0VKjVQ6_tpUs|I+?Z_ou#}ct2uadY^nBF+aXv?-_M}j{W)i z9O(Y2_veHAEY~*+>_@+!*Sf`X!~-+Jve{K(>C7qOfbn6@ zl(Avvq|sr%+c2y+hwV@Ij^xzylhB+#$F?6Tk(- zl%pU|Kx{*tgC@XFGj|F6r&i#ns{ zh~vRC{u_NyoR8MW-@^ko`+xF)!~ozQJ;6FH#7<}p))dm1z>&f)^?rOl@jf|!`~7dK z{|&7j%Dh1Pex(gRhyN%3|AegQ|Dy)DDVY}#^7X%UE^7dPQ~&Gh)LXblvo$t#+@xWl zOMlISX#2--@l9Im`})JeO-)Y;cRYG_c(DC7;o-J_(>(PDLa#w>!l>~BgbUrj%NA>` z_zhu;em834#*JD}dQ)s!YZh%ry>^LwDr->Ak6LU&)ay%yIb!qm8#acm|9C#ymaWf+ z&0C)fo3}g{Hf{Y!*hITU?Pg4`zXcwE1LXUo|IhG`|AzxI9gu4P=>X#XHIDtI`(y0C zQvP4~$M-K?X6>Kl`_cXj!9G4;7Ja^a{~T)jbE);s7w(*k^gyH?dc;SAm+7W|#hYigzh^p!zCAjJ z-rco^N!O=CuP(G*LQl0lyLJxGbXUKd)->qRP3s)=2)%@@UeCY{886sB!UZu$pj^dJ zyq&pbN@r0`q`4EEV zJOK9L1Y!m7Pwc??;Gfs<|HU!+>eYfJu|Bwu@xI!IGHQP0{22fDl}~-@Q>pKF{vY2T z@&DcLe)ps5mvVr$;a}�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賠KUR5s~psO^6%1Z{7=$t+)vVV?2poAY(;EWk{%N( zNzchYOD|%|&(eG9FA9C8RTjtz0NDU2CkBG|`#a>MiXlfhuK&y`(rrRT=`+5LT)KQw zh7TVhqaXug$BvbeBS%XA{{1;71h#6`%ApIs_~HxN1;3zOs0*}Rz~4^0;Ca&p)_&J| zog8P(i+cSX{Ko%7Un)Bt{ha{&N#J{@rcOsbbs*zrSy4v+yKIV-$(xk_q1>c~4I84r z2S1oHX?oD|r7MLxeXZYeS?ND5Xx7U90b>?44;(tDZcxvOmC>)2rNf8{(thX#{fBX@UJ9qBY z_`S+5Kzmqqfvb3dRTr?mpY@;abEeeotRKfM-RD}bt8pBCtT_JeyYHrlZr3`U{Y|^A zWW0Ev)+k-N)X2JZ>a0b7-i@1?yGoxveP9a=hAtST zbOF-=0|rQ!E?peDpnUoA7ZW5%&=+msP8V3?1u@AkaPD`G=hW?tuYQF7rtOvx{#Z)% zc?QV0((5MI3&OIgkUxLkp4F=Txv+2Fe&?r5o))lZ0etQ?YsF{na#^-^n#^84Fksw* zwgJQD)DP-5rm}P%RY{tmkDK%;C4Y4*E)BYTi?oC^?om>j^eiRKdY3kUW19CZqmFIX z2XX<~XaTvPj4*9E05U>AP8=z=TMsI$KzUMSEVrOF^8qbm#`$L6fHLx1{laqN`VBSi zckbL-x_9qR&MRAR*sx&^UBK;Ly?O<8=+J?_qE#2vM%y{t1=IzMQCs5$F+mq-Jx{)? zen;Pagno_>y`BtuJstKL|IQ3Kpnfm*=_emoFI&Fs*cL5X>=-|8!ox)imx-V62HCjL zUwqatk_A4a11B%(7BGBHgP^XXD+hHLUQrr#FDdmq6_?uWib$1AlcbAw(m{31vme3$DrQ5|o|BkR1hco3f;aAk)CB_v4ixB#z&35#1U6{U zK%fgQK^OEvTm6DIqa0|vAQSSE0<;UrFY7#l*2Bn-)<5)4O%=c52qlSpggTHX~NLTXyW+BCGsn2hCkQG+^Z1rhz@i z{VpAbRg@;ZN=lt}#pKWC1>}!r1*Ce5f>OO@L8;NIu+(f_SZV;(TNc88A!8r;x=fXu z$JJ^>c>!9RsormkeG|2j)^1l6_baO8i>a}V6f&k!w|z0G+o71+XIif#V9KH1uhXFj z`oECeym?b5Oqif_KR8bNU&(=07tj_MJ$kg#2ec6|P6W|cwCVzIhq|B=+OY!Kwj!ll{v&j08P)bxn&gvT8|IPU8s?SX8|9U% zO$sPfX`ElGG|DGc8k@lO?|%h@$Nz?X19@=`1Hbb)6FlE}yDF|*)x2iaCi&%$rjR$_ zPsp53|7>0ma#&ERxdUXgnv%~#Ql&{=soT1g+`4^3rc9Zt>^<_Gb|B?|{ZCLHs0+yb z5hF$@8K5liSm=sC#*JX}N`(p)t|U#GbTHbpGWwr#KwUuF*jX2F+@(*g$Lf33(^)~{}Yr6#)z!CfbxL6Ao_|JBc)okYC-w( zw;p~rp;{C1ss2)RTp5KqRhql{kPvgYuB#r%E?nE2khLjM=o4AFDK9L z5AxqVFJRJ=&d}>sq-pO`QoU6H)uumG`$j5M%OMraKIHZfe|{t7|M*7ARn4aG{qJ9k z!f#(onP0z>GL^rQ(!XR4fl@zbl~O-vQF$uGzVk8MFY^n|t&9}c_zu_l?zgYxdtA5d z@7WaeJ(-sO17KZ%AF5?XJuN_eD?o-QUq;;_li06RD<|YNkCgr`olKhBPp)0PAqy5P zkXf^4$>hnCW!$)Nisy_4xsn6Qg;f{OHlWV{T@lE*k*N!=B}tNG5Zc?S3-p|#)h>uO zUGT#XKd}E}_3GVoEaPsld!KCDyEtIFPp8116RJqFzNMvF%lzPP4)p0aQnrfGw@lf$ zx=%~~ltqXVl`_k>6*I}V6*5ZE@)>}PQlxAKAiWeRmq7}DpH2#WmmWwb1p#ZS@=;!- zTzVX59A6aYIDl&vBYw!Ju3!Ae%u)hSDekN5K$+4qR0cAmy=|S+Qb;%%4ABrca+PlO|14{vXGB_APnOF@XAjpe|sHh%!RE zkTRg-M)VaCLze2*t2^t0iWnED3uqT;AAxp(Ll}!$t>i0_M)DL- zCAq%^iUCDaNv@(PC1(+5q)>UeSdKELJU$Q3%lmC=$y?k2ua~c68eAJFWuyg4rImuX zALWPlSMmZGQ?g>p9p%rE6+<4st(Z}YLpF<7z&=xp>`+FE|CmXtH!mu;?p&2)M~};v zEnCFjA3lwbk1SofROZf|E7PV;Q+6T8disCbHn7Tp)&N-(54GbemWnv6k|% zhYBf9e2cbX8xm~KLf~iq((L2Zs;}5@ISM70Zwe%nuk$67ukt35uYs@fB$2GSl1S#9 zi7iMZS#l=^l1LVmG0lqOzRH_aotrH`uaQ);;acAm#5IWm$t63kpQ8|DrEm&EPH@jW zT23G%tV>=%%SZv#PorQN=ou4ARv<5hp??ZPRtQ5!Wq>?qmO^Dy$$+uV<-bS&$&n*R zWZ%AhvUBH7B?rE~zOri7Dp|aEvCN)58@Az;5ViqzKW#+H0rdb=t1e&+S;viNA0mcq z)ddaFx0N6R%0~d-IY*KT_yW2?`3T5!*abK)(&S*&*dcH3*s=5UnR6#)%;F|NUB_2c zF;vFa+aQio13ntLLH@FTvZGH3_8I#yQ;tNEAzMO8_tlq@{_8I#?NT0Zhak5Fz3mPs!qf5{;Gk8YNGcOS^{6UXJ) zv14-JzyaB_XOHaIu|qa(+9d1Nt&^22R|@B#XU?3dYyb1dV3RIyRURT*n#oRzUQ`cBjZnQ|tQR2kz-YO`-sXNr&g&n0=f&m?);cnZnV z#FL~zGVB{b8Ownb=|5NJ^PDu9;~Vlp*?^2#Wr8x5F+1b}@}+eM^$GPw);xwhC|v`c zL%pM9g1Q27L0#bhb%v8{P+llI*>QZn;%TJpZ`q|th1AlnPc;b$43O*Bugke}=j7C> zQ*!+Hait6P@82)Gckh<%+qcVx4I5Ho=9wrAr?K6EkDK(ts@{0YHWfI$qIdv z4YEQz-gB*O3_(Sn-VMiK^?*|qGC>l`9B@oH zbm)-m-McqTwt1nK4AZ&@0rqu z&}FnC=^s>Le|PXe1*N3Zz?w37&Jgk2uns!@r1JGooji^H+@bi* zzP@_(s)_+q28hd-FFVEr>Vu<4kA~ScAotn-1jh&Jf7%U{0mc{TE21ojzM|Fz$&w{g zx&ZvAUGN?HU&juUVEb1kKc7f=r1CvZ#%^-uTz@uMdnZ`;308g?tD`udM%1yxLs zaazV_85gVEAP-_{xm660@j1qN7-unj!mKK#jYuDiT%>+afWA+V^h3v3pvM8G90%C< z3Td@n@R_6kL+ApG1+*b)8_-syU6B53=mg|x+aohKQD)c|?f)4=B-~12jZ(hNe5F2tpT@b21IDYh$tlu_A{%C=?ZQVR7KC9!gjGO6r zURlQSoMHgxPQRl7`uoS4xuiymqH3P7CFX4#_b!h4yW-Nc*LTvse-#-qwTsN0Hx7Ni3Vpj- zHgDP{n>KD1#<_gguSdFGe0}{?-_y^hUAJ-5M&<8ue5V}H2c#`Xo6sr;5w#5%Khkob zZA0>(GC-KVVi4yQx#sMrpMJWNGG)pU=u^fHD?$!RW1G*naDFZk!1Wn%0nX#nM}TM` za1)OT3=v2`q*Ff?WWC;gUwsi zHv4j}Yzp9VnL({i5`Z<*&rk4XY7UMwlzv!DQ8{G8EXp4UZ zpDhE%=v3fuN{sdFTaNw7(irvt^#bLAafIvz+25Je{0-NKH0xUe_!i?hfbqL^U##64 z(pbjN>LarkOqS&<7s|2 z7s*{B33!{z5m(XusAF)9!x=DqZT6`K?XA$j@qqR@$8c@)aZJyaKRIHy8RbXJzf{Ls zfCgQQf!D=gpBGi@LfQ_jBwYvBm*JB;$?QdAWyPvR;I1FW?p?BN>rV8^E?_5Yx7}*Y z-V1%bci&#w1z(-9yX}bEP>*ljYGBLOEwUN?xtVeRj75xo*|KHIm!m(=ZPou64`>tk zA>9Z)!Q&|d1Y<$8|Jd(Z4kBV3(Eg_#$bM)46O;$)0_p(D0QG@6uNa6m22#6rZ7EQo zzgI(UVkGY1Y zYdLAr6>D$@G?oz)ddTeglhH^1il4i8?UOyQ*=V=z-Me4*?LQy~4jq((@Wl=sJgD~f z?A?cB_sCB8=j?mhcdGxl2g?9;0Bt;D9N3K5{u)`dXc1z0voOaqLzb^tuIvEzy)Oa# zfS`Tg4>?f!z?1{V0q6^`@2zqWUfY0jz&>Z3i2YAcCTI(=|0hnIsB8n|1tG?)?1FE< z{dNobx)S=jEYgC&S3nBjbM*WBlmTpWjmInISb)voztbnr$+Gp6C2PI}=%+-c50y~q zYU*nhgM$xEA4~aLu(cVF%anuuHI4_LIlj|wW6JnU_5vxTXxU6^-u0LIxxnj!=<8ze z!Ah#WR%`rvmXns=vM;%imN= z>-dLs?9o^T48?PK6GmemWsw?VcR+_9LSG*{h8P>TbQ0}&8Zoz1@V!o*fu98&KY3D) z9Y2A7N9=|De&{ebe+aT+@P033fIc0uQ|bL(7VaB;ulgN!-zH`IZ9+fe`4aG%yrzy1 z?rY6?*p2iNd<{Q=w&7ZUDWP=&{RNH0=C;eti*w>HT3ZM)>q!K3KsQ{c;4Id}eoT!24) z;nHQfco}gvq-T+L=IlAN<5@Xz67lyF!F_-Dh{5{<&^%kWn|;1+9iB~CyAFOM`W$h7+K2|$ zsJUQ{89r;)Aa9L2&KEMGd`IXG$^v79j2pB6wJzY85Z1T>^*#HSwjkwz(0YLV&-rNB zD}kJ2$dV;XH}v_}@cnb5uQLKEvCVfRd<>`<(R=T`_ZsX0HIIyP)&Dzp?Cg5>+!^UJ zwthh23dyk!CYMxeQe0{_FCq2Xm%y6qlG0{a8LYK0D{TjtldfYbNv{c2rOS{SGHgO8 z88xx5Oqn?v-0(4Mq-|Se@1Ff~aQ_iGdgKK9@r;~<-*oxPRXkgbI0|t6CgQ8Wm1{TT z67t#a=Psaq&YhRj=P>VrzCU^Dw2~7;-yfGl=zH>hKY71Dc)X|1C-%eUJFtHrbjdzB zdhmc8KYCbBA3q{zPac&EXHLk)vnLfUojWC$&SL-caXE+blZW@q(fzyS;O_0RXZse} zxpkv#+vG2sH~7jX^sB!we8RQxE!Oy8O}mfT|30#MwU4Y?y;@fLtTto;a>955#}4Wg zjt^Ej(7NFKdHhD`wy@4A&^DkP5ZvY%!2ZWvWB}JGVGeNx`adK3JPW#(en4XAd(Iz! zguHjr?(D|qEK88~m^U?S4 zxo86%fWAKnKm72)eRAyZ0XcQ#keoYlST3DDCfCoOl-rlj%Khu-<=HPuH_slGOGo#~sr~Tpc5RaVTm5A3#;C~SPmDa6WUqGK{f{(}d-z0_%#K-oh z(ET4^9^qZ&y@_R>$`{C1>dFb8Sx9t zIds+UckV(KOx(Hy-rtsMkdG_4_9gT`xqlvgfA$>pKGqy!TsVe)XP@s!yY1VvTlVjU zjj(qoc)C+g9NZ&kj_i~3#}3NnQ%B_5nWJ*!{0X^z<&50Da!&4DJummKU6cnmF3aCH zugJq&SCC$o2S^{>z9#o?U6%VdF3H`i7v$!}vvT#^2{{iLI(-;2wQr{!*tJ#m;n~x@ zTl{6`ruDMb-$yp7{$DQZS1gv*OXtb*`Lks4oar)u#uS+|eX`7&GC`(K8ZXnPOq3bZ zkvDsWEMBxw$%8M(6v_ha1NtfC{}qf2lmm_llmpt1-p(m--3j}C>eQ*K|CcOT62xm` z-r!&KH{X>I4_xQ7m>;9xKR}-1KIDPp|7(x|6%RnZ>U$g?3%V)`Wb``6+bdVE1>L@L zPwxNyPr!qR{{-B*_aNx@-FxWM2XgOk^gsId?|&XC;23%E@L#pfK6l_AWP@^I$_nLx z*Q6ZWfDBv%|1V#;ZgL-EK6L*H%)ii=+eMpw>n7R0d86#wvQhQ`2X}6jBk2F*hhSf! z@2R&hoH{NS&zyp8KPl&-+s~gpjrTU3k~3(_Q{dDI%-fS!^wYVP=kVb}usxtZFg7rj zN55eo#*4l18L6lD?%jiNYme-K{kUiMF4+y6p7TLF;p^`}9BJDY`2U*_2k=LKuEV&$ zY6Wz_0$DhBhLVA)6EKG}a)^u`iaDL317+l}Au?vl^Hu1gEzHK`LaWy-{u@H=?^_9OKFd+6(T(C`1>-j%@Bn7#kHg&D>= z7+Z=`X|?ZTnHk$y$1)g(vCF>ilrCha^Njac_|Zor!zlX5VT!}NTte(oN&u3@(sHmfZPMk>aJ9jSi`BmuW4AAW{=$n-zmtVPhP44HnOJd)dW1!f#X1W&u zwiT*#tQUl>c=SZ*|J#s%rak*}u`w8nh0hcVe=8niJ*S|5Q_m)Y-k5_0e`NqS4<5qD z0Nl@D-vVRr_t?+C_&fRx%!9XJPZ@XD!3(TkS*Kowy}bh8llg)5E8AJ_UtWMeA@l-| zCx9Q$p+Cv<`DdUT*uPNn0(67m1?C5(Uf|dt=7WS2%CRM(8=xPKGq8?8zXSL}-ydoZd3b`K=V=xqc&veWjro>&fPwiTzmNDP-+;%a zM1K@~#3jbMBwt@&>eQ)Iccv%ijElqW7sYyK!roV`SWydf7qLRn2TbQYTJ!b1#mC2K zqJ7#)Ny%dV734|tA%`GI+X#~@=M8-b8j7v~LRyL1V1MwXJ@3g`rfRl@ol~V>wLERT!MEc?gL=WvTjUE3kwTgqd~+8f)8ZKInY$=eB>hh ziS~R?{te^hDqct`5K9mgxVI|mYXw<|M87PDeK)2l>wVaTT$Bp65AY^F;J&~E=ztrz zkL`3i%jTtvbPMf%`t%86ud*pCE1RCbfX#WX-;D-k) zez<=h`~caxcb8)|U{mkF&xT&O31BT{G|TNeei+|^)G_{R{>tw7aXLIv5v`*hlu>V0Dq8ugk0DP!3*3s zQ1b%w#sl!n!-t^XBj|MK^CzHbPEHOW7jf5FpuY-UX3@)+FX;t%;l*?KoD9$lPr(mQ zzzcleV-+tveDp}@jRzUf4ZvFl_(45KtM;*2H?T}yXI>Ee0G|PNf^o}Z6vA&vQ`rfO zHRjogJpU1X1MHR14Z#0t@PgonM5PZY#v#B9LO)>anQ6}Q&vruSgk#5{GfraMFoHIt zALruYN}D#i2^-F1Mhs$}iunfjF%Pm%yyTn{sn=^B^Y|e89l}Ar>z?n|VOV4_v-{!Tj(Xx z0`mcYZH2HCf*07XD(CAtu2XF%m=}c4kl#+Q&%k!#3hN~$FR1a2F%sbXys%rMKOuMl zJ_Gc2GVBEN0?#|y#?+rlw6 zaP$b`5Cr`>7KP(ZFee3FzrtW!CXk#B8n zoks^HHU8P(*Li{8-lKba+2O;78lw%1zzZptE~QC4_RBWn#mj67@~vQ+=BK$_E+>Zk z=U(kAZA1?4QTvQaUU;eW8K4`UV=PkG3G_jgx1tlM3_buaa9@J^^XHit0BReN0)LKuh7|Bc3iLxF{Koir z#3EsCDi%JUn2UzIGap2Ojx7I5d!UR#<8!ew%9vCU&xCtnYb4Z1f?u4=zA@q!ZnbIs zBd^(@v0}O1KPvnD&bMvM3-FN(@Z%c0724t9VXeUnD`7V;VVqx#H)31?yukWEo&!2d zOi!k*TISWX=VRViC={Z^#o`)1FRsOXf)`K<|50Tp^7{-=;D6-V385SE^McZc0s5GAGJ_a*K)-^=e%Ti|20xJfe3t1r z(31Optn0Zim&Xg>f&BUa@kbJLfrNW<@r+#7C9Fd*j-_CKa@q3b)0qZq)~w~Zy)SM{ zNI0R1`paPN3h=_1u_KEloH+iy!)k{JKYxGtjW=KL*Z|KZOvIY2QD`$<1c~(k`v6Q| zraJ@ESg9j&QNo90U4cFX_ag)!uzg@q^MmM5pf8c%e^m7?xj&KDx6G#(9$=h-b%S!u zNzDtdd`Pwxd442(aJ4@v`V!CyJierkP2hMGw*L%DUl8Nm;03j>$GSl90NNZA6DuK3 zO%A@u0nHW1ah-@wiH;Iuhe1KX66Ss$I6H3$UAkn681wPpzT=CL`>HxRG8Jf|6!ofB zy?S2%5qztKzBnH%&mpJbyULXku?E3-^lj~-7jAa#-ktUa22*rwJjPy6N!dAa>19^7 z#C`hFSetu;vy1Q_S;m>hIp|9;-PL+RT?+l6))B&9sQVM@zNN})CmspELFqpVUO+#BbpqR8)(JeWa5)WqGtfLW^*qL7&cX-eu_Hhd`s(Zp0ysW} z;}n<&(8rS)Fs`h?SWzy{F-SbN#Qi_!g(HYhQ01EDV4U?T#`ygZ8#r^}qJ^z{_Uc_$ zE$B;aZU1rFGhG4N`RFWYsiwEOZd|I*sjlT%Gz}eH-4d2{>lVYBaY83lsaCCD*>Aty z$p88I`V==cGdt3yYu6V8|M=tHPwm=~=k^_f-Ye`^(tv@36lv+#6zcho2fj{zucz)%73I`Aoxnbj;f?P$AU; zuB!s51gHrp&8Jaz2Dk#;0EU3M0G_WD8}vhm>Uw%FP0Y+p`9!5ERSuRaQ)U|Pck0q* zTEoVTGcdMrW5_V9^X%v(cmd-|3iKs%F|H)3=NoyRiTz3*YkG-XP6b;K)yDhmXYd>r z^9jczDCeR;XUs=)zw`zAr94l?biZ~TvW>B#^sCC)lq(#Ugt@LXj!R1e51=ogicyl# z4`xtcTv-mt;c*a@5|1-;+#=6yvJPOK&psaJfD}Q&!4I&uNF3&JJrUC}WBs~yzs#OB z+n}yx9gg4s)8^;rE5mi#>(;H8t#VkU>9A_mXOVlZ7-&}!FagjLpa)n0&;rx~oB^B! zqyuyS-2efAMgR*yaeybFy}FUuUkeBZOyqOmhXde;*1TV_Ql-k^ha=<1jjd#6VX*`H zKlSFV+vgeg_wHw)FNr?ii!237!3#`Vo>%np_Mv(6t!eDo@ib!OC>l0=IQ>3w5OwR; zjgT`-W@cujTfI7AoRsk0A8OXTInA9npAKMrhUNO&4fL})KHDsj$66V1e=d0Vm1xs3b{Gk`yUd1E)A2!MHkV;Y$k+5n<> zAH1+0fDrik*(_K9ns+CB!+|g? zPNhqgrW!SBNKKkFl{$CnD)k>QKpH+`gkr>~QHn9+#^o+wVV4VEH3z<^{O-L66347@ z>>B%~Oly7@+j@>gJq4LYUq+6Y!iR?shb0E@+qcKp&)31rYsXl3_syN`>{b|eXxFX; z1p1A1<~AKT5F+#N*ji-s=FM8JF0Pu$3;Zm!=DNJTfd*=NvF;{7LjcSCB>=vgrSqE# z?xQRUXbd*1F*jE1snnl1SA6f(5qR~ z0DN!@kPdw?M_t#=o88J{9JL>OrtPq~85}cw=WYf)&q9Aesr%UqAfDx=9I|H# zZYWCtjsoHU^8oz;cL45yyMU2^7l1K<(twTt{*QU0CBT`ViIV+AH9xVQhy@G*tN;jG zfU*~WbqCvup8(dXV@=SV`xUG==JWHWPMcN?^RNYQzR}gSY-ngmU-X~d;Y(kEZzgeE zDaRXdj4=bp7+=18h5fc%(Dnsr`zSu{*m>l8#T+^u<_~#vM!b#<;w*;m4hZPt>AAK3 zyt#8Kv}neAcb1w(th_d#~%1SAY6n;92d{ zvrMM|Sl$x=^#RcUFTgec)0_WK2J`^14vz{sDy!4Kjb#z%O3LHk_lxdJ+N#j52c5Wmm}xxT%QL`DvQ&ovTjIQ0ZwI|c;o zY2&@a%ffN}TAg7-29;>lq8YER^j`Q+IeSiqd5$7M!9m)H!O;S(W!^izHNAK4e6Rc8 z)y^;JKj2v{tK+dB3aARW2QUFN0W1QrpU?hWMF7+EYXIACKBuM``~C+3{G5dV&QW2$ zC_pbhr(07;R=tLfW{q0aWi^eeYoXMxZK+#8#`}$~r8#`2q0BMROw+;7RHg(I@vex- zLz>aiQQ9XHP8PU_pZz}DwVQV}G2WmR7IwG@_(dDOn-+4yWUQyL=97T;dCq^~8Z~`T zvM;8#&#Bm-#qC2`U_9^jHd~rik+o}CQLRJR$FlF!k=XOW8ej{&NBZspe&#Ypa!50@ALCf7SixzAo?RdL%*1Y z?8j!+WX84iWR$>T=_@c6+m{)-zS=j@-U^>_haZN-QR zq7GX|>U}eBc&Wv+hL?1jJ-nnlVCS3>B?G4qE)lkJM&+o3o{c#tS;Kpc(oRoYX(FCC zd6jAX@pi_KL2Cj?s*?8!`k%(y)usiT%?b2<6DU;Yz0^&>@jrqS_4__|dFR$O&4(HH zK3ki2Ss4o-V8505=(QuO(DdOY6my1`B+y^L%%R`NJ?)JtaARFZ#?@|TOWCqDW}2YC zs544W06_=HRrF^bP^dsY)6q;m*Tq6^yUk3odY38FTMcp*?H{15!_P+fNo)>3yKwt6 z2KHDfX}Hx&|EoYN)04hdMg*D9few(*8Bt0;eMkv~-Ly*by>4|0bbkuqwTd)Wt~C=p z1G+Z?JY)Kgx2w%G7jn<#2+00~RaleL)q>_YThM$r3tH(@KnJMlzk;6$+W%|yKG*-> zxPkrx=P3IJSea0e6=ZZ|Wtuj;IL#SeiXi*sX>UY(TGY`yiG8goR{0kmfvek^B1K19z_5LO7^O{HhZ~VT0%H}gp-?gb_AEgWs z1t91E#m-TN&;g}s`jFzZe9Cte;97_2E&;gA_1j=6#(^fUG-(Z*=c?#0aXG=hcAnjz zw916$L-v{WYG7Tk(ns)sn*I~Gj{jx7|2XrZ=9fbA{QM9wGEeq9G3^18N(T_@fT=^i zmOSl@h;_e8_T?%b*v8KRz5P|R7qZX$lK^9u8%tKO|B!tJ=&bVdaR2T<-v02}O4}bW%Jcw$0P@`^1Fg(x`>4-<6ug&T+Ct90bHtJE=oW)UA7nEAmiTcPfq*TrN%<`W0x2=jI}kEM=vr2{q-aOmkL!m zoAJBL)7*0x=njwz`g>W>_&HdMeUKhmEi$IXo^{A(vn4HXx0C=}=HgiRht?Y{i$LDB zUI)m()>2Qi|F?ZTHLdgW@0-r$|Nmp|=h1(u@n-B3^Fa7qeL6TjkM>s%&Z!~#WT1aT z(Eg>LCuHBtLUM96rLH4uP}dPPsK@A%}YlHTgO#e9B+LB5K$W^jGlds*ktd@xL1^wMw_V;*M$VbmIpr427(JxjtsMAnA z8g6YwOFZjHDjkpsy7TwX3hB>C_>1lD(*DWgOwFfHGXE$05Vy=o=v~l#g^>NF#&R_e zgwLtTI^cTPtQr-$>U-B4i)+2Mm^BFWw#asJG-277x{s-fGx*=H=g|Hl2l%!e6&N!P#2FR#}i&ellj^Q|zfg8lpO{aE))0E$~?ERR}Pi|zkB zzAtQc4MF=gYm~mi?j7ddqo(Q8PXl%3ordVq&x7@d%XYu(N`qz@!sn}V!+MiNO}@8~ z{)~kW+a7*G-~ZGGWh_vlYgL;BhnjT4-aroEQsVNsox#oM#WncbL>lqS^aZah+h{KA z#j4F_P3Ab6<<4?6qv`8RrD>~8Y4S=_8o#`@0{wsV0qQyMebd$|ujl>3?fo(EzsmMs zy(wv96+utXzCzNb%2!W0R;L7eeJNq3J^|#a(wd)he1-TT-!G3kF=*d+|*;iM3&EEP#2doXK*L2<9`VxR%mG!^_Z4@s1+mg%vAAjR}K!5Qr z_5FqA=fyyhTU8;Cko&Jd`!h^`>?=;KXB}Xmmi^^iOYp!OX}4xyeesO-f%SI*2q0e{ zSdSconu6|aLI0mn{&Wl=a@VS_-cD4~8VkbarG0qCQ4;HlFSVfVvN$3E`zR&^p zKz9Qb{e`T*UUkr0@CC{?D*7`INY4A(F#VbKY91KK_u}}CeDwNr3y(i720(8ihly@g zi(>zTlKxc{NgJy|2UL-tTvLM*>}J__3T`G>(LO)@Q*e&I zVWr`5xPPGzP$Ta%mFISf?@DT<`h4Bv^!Cz}ysfO1>{*VIJ<3bTTg!t7Dm^`6uW!WF zJGJgre*c@Q>$q2`1046(`;m2k^S;&+6=|OHGzo?))cz~fRxrTHl->4bUf$_^X?}=Ny2C}~p zFc~le&<)ULZ@jJWH~#X4g%^A<20(KmdnorX{Q>f`-rq3&Q#!p1~x9|_T3w}Y_UPXUNtqV4W_9oA8 zE7}%5TJn#vR)7Z--~k3n$qS1KwqFjK6TqF{kFwB4Fd{zUmXH1(*cY}}y=<)A-<1Un#kM^0Ah{Uy)^wiI%5J>*`!M2)X~CsYw|&tL#F*8~&?R0h-mPjuWG zHtLU{V=HDKJmtI*^gRGL4!8n%22j)gJoZKYKgy5FpZ`qD|Np+ld4Cs8_d^4C%|C9Qa}^NBFaJ?@GoVj;A6`)51m>s3rlpC?T8pJgAM?U)e1be zOm-;I6v-3>0FZ5Cer6_`DeS z&=|GPTkFEN7h<3g1BDp)@-e{uw129v_CDAs)c5a$rNV3eix~LQWbxmC36k?zd1BDnU#K6B51BHFUe=FraPQ451|8ekG_>@8n6k?zd1OFxr zu{z=_b;IipR@h{^>;tG_wIF)3+eymaX{vyj6bbm`95R9yguUHTh|N3k7ho4 z@ImY0ba&*h_m@^b%tQSvw?_qQovBseSP~!8eswBBL&N&j5oLkay7`W6 za9sM;G5@WR?}7Zc21iaPH}QAA2a3NnG+Gt>JMV$2zcq>}|CjT_cvC$vT^#U_^8dU; zST;LcFEO3k(7d*Cp?YPxn9P7UJzixr{F$!%8yg-*CUOUcw?HHVtZ_}lM zH{duQfs`c5cex;0dcG65p7Iy~=lM8)m0R&~z8l1Gz8kFh|9ou_hm@#(gNlbU)W^!d zZ$F4oo@gbGQ!ghdZ%|&Hk$m{qX}HxxK}?t$Nj3EovP#?Ns`t6f(zR*DrFzTMjcBFb=Q6X^>&NK@ z{!ed}uFKb{w{+`FUG+Yf5!RV1GAqwUP*#Cs8_Fusz6D@7YvrZlR};tibQ@`rlpkNx zYsVDJ44UtL?7n_%Q{V+GBGv_ODA;2B7hdrH!lTcI0b@vhYk&(DDpiUZ8X6WWQ>F~Bb;0NVE4Wa% zR|}hV$&w|Dp{*rq)iNkk%g~@gHJ!?pzb;Ws2W@7k3S3nE=9_Q$8zUtE+Q8Aj4G&yj zLECS>DNzJ%{mRJ5s1(}!ZTSl2Drw3zs^Ne5JQ}>lp(&s-E^lw3Yu2ZJoyJ3p7A?{h z=Nf+X)mLUkiWK2>GQR=}zUZ8HrV;p6t5m5{MRav_i<_93lr}V~RlazMuPUMb++ICg z!ltN6QSEQK*0*dnX2_rss}?U_)D+*smi=I;Z}G=( zeFoW1pEhInvK5QZY}jP~$kTs~;75f959YH22Q5v_`@`1@-%AK zu5DzoV#S7|u|EI@bv`FAaC@=IAiLUV=T{aM79|b9&qay~{;Y!kbfLM;Wt!UU8rEw* zdi2N%j;mI!irl)x?WWgmmt3#F)#R~v0d3kl9qk-T>vs*8*7yuntnnExU+XhcvEFyI z#ICHw8a z)3U976w5q+l`r4cPhq$1cWLF0LFC{ygdDtw&}xRALs1STyX^zW#eXUtJamv89UT>` z99GekDO0F@`}RkQ7A?x_CKuoZ$lOQO3*cG7*KCXG)Tvw2*x0BXaKO5_3d|AftLBzw z^#_j{F>bBhij`4YJT_+R+`U=a8RSS?0v6Kh9b;&bYaeOW+Ai`Lt2@bOuk9wycj`$t z&b?`&%dfP^?N?g7u@5cY1b9Qa(5)vearuJ+1NYLhWy{FT%}v^{VS{4PqDA0^!4IHE zc`b6m3$PPvz3{PkL5AmlUAuPevLJhTptdsJRr{L~r8@QLJz(An+m%6{+qPc!3-DCz z+`EA``Ys^*&7)}c>K@YgC2i%SZGKRUwP`C&Slp2&+jgcY%ev5%<(+Bj@-8%O1;CD> zD^0imGl=u}Z>n70iN?>`Xq^gx&&c?Yc_2aky~ zeZ?=*$T@A~11C3=51iCO8a$;H4Vn4_4V|Wf>0GvBoJ@qcTYvbYz8g&!t6JA1T$87*0|gjTLxNzTsB5(;GfnNX}aw?ezs zyuh+r>_haz&>=(1L_|bh2#)lid8-E~225zK=seI|{&PPIsbinI)UkJ6YTv64we4X+ zKXfyr)}2kMRVNc_`EzY**%5$}kNJF?E~fNDS5x{C*DYF==0aZ#|2 z7(RUXBiLU@w7UQ=KyPW6FJJz>K2SYqF@i7wS?sz>!&)TH{~*Tl8@)UdSyHU6O% z?yp77elnyM?TqRB4#vO}a0EQHQQ?Wp)}737Y)(J?VnhkaN9ju1RXPD4ICA8Oz=M~U z7t@{AtXV@VR;&=9<^|{nY4+^d)VXu#xZ=f&j|LuEgC{JYBLpwt_`Phz<%?H>ckEw6 za~!)U7C85znX9@%uG@f)W>mXQRnjx80H{bcjlatSeUtB~mRV&ovZz9}>sBMvdOBoU zUx&;aRxf~)2Hyi8z+WTagn{=Pwgi6K)S~7c45>pOQ)=JOi0quEQ`XBYx_b30UA%aa z&YU?z$B!SU@bGZjvu6)^dU~=RAO{Br!4L2;gkE5oVE!06a%85dsp$r^nQcT9;3H2j z=<65!ZV|32u$?}aaL0DjA2eZcdujZljx>6HJF=SBPUtL_^QJ!GPwg}z8?Pqyl8v%WxfUT6~&YeqLx^y`P9uT|$8eQ^Q0k!|tjQWmlOk?m4n>B-IgQpGo2W|zAN6_(OC+WoTQxp*qLDA7s zl$e-E*REZo`}gnD?c290EiH}CojWJa$Hc_YfddEfbOX1Y@xb;GIzfWIP%uuctgIfJ zo143U$X#F~8$%xSuwMdvp^g6KpY%dl)L!WD2J};RbD`t7WIe~atQBOo1!T8HdzRta zkY^*R*Ssd=q8jNNSE3q*-+?zOp}kc=<7(8jZA~S8C$^x83%b%$Co6J7d$;d$qM-e| zC^9mV;$n}}vG@}d6B8@i9UdM=$BrEXK8^~xkByC`)2C0r zI(hP>xQ6`%)(!9v2sT0B0DdEF-n?0XbCR{SHFfLOjd_86$M3bZwYd*g22cbz(KI$T z&cnmr{X407`&vRaSuS76sy?y&a(nAEsX>Ul2Gq7!ZP>1cG;C^H znqm7Jt#qA2>?4JQ@1~fzqo{8pB`2Px25?_23kUHzo+5T+tai~ztM81 z$+X#PCGFYoO-G|6C@CqKE}T!JOBY#(U7^%e=&`eCH)J^B)G4(41loO!qGRJIDmsRa z9F3w#&^!XV{%}}0g-1jJB81Lky%!!HA^0UWE>_3@qxb3h>wpipc|kEgw14K zxpnJSIe^BGAAbq$?t*qVf`6b3D2aV-=u5!^=gude??37%s@t-%ylqc2`ekrE8Z@yL zO|a=g)((ToVbgT-@Uths;7xQWGMHlHV!)p%lz!y~-MX0pIekDkZ=qh-Z_wp5v>W>S z?737*K6925fs@3RW;`&wO*cRWgpOn!KxZm;?ASp~nlzaJ92k`-Q9>V0 zF9%&vOw9wS=PoQdnH)_aQQH(zC-*8&rbOgkxRRu}b~Bwa9z3K+kDdXZQ)cE1di(_N z^f^6x{FLtFzgu_i()F9SDE-=Xx_Bv#&ZeA0JCo>4(n(4^ok&+w&(N*3RLZ!KMvw1Y zqn8hFQ_kail=Ccua-QC&7a8E~s~0Hk>`6L(Jep3%gi}mJC`E<_Q)tj`3f$#G{ytvh zx6_*fcKcHZ@3+ep@rtRpU8zMQ8USZ-LJxXp|Ql=6^}5bi&4|EWyXs#U9??WLdt zilI*{WFT-~Kn@bHP^QreZ=+js9ukDffG%qPIZ<0tem z^D$*S%%r>bLHFBt>B7ZJ!e@z#K0*m`(Ug*uKxr3J==zmQbn|LD-MD&%uBBgrZ*y7H z`~3M-!Ov&Uo)vm7IXOw__fyafCleB251=2x^Rdtkk>Q6aWM3fd+KKkKI+Nqt)#T*3 z4(-}b+}0~st_Yc6JiJLafd2BshYz#=6(;$n$E)~ee&#u9CXhG4kRTWp3>cW8H8&oJ~oDuP9CSL>6aplXurm|apQ`y zF95rcr~jj(qBO5wyT&tzdFM7bt}T(2l+@+=jhmjg@7@Ec9}4cnl%d9MV{_HtDefoqRKYmP^j~)qpWB?cJ+uXTxN60SI3-1(u4$JXH z*f*vh<1;1YtkCi7`>@_P1>Je_WCCnQ0x^#y;`nG(R9^pp?M6KGD&vrCCBK9HC&nxM z$Xq@Td$69{zkU1mB4x{#<#y(^mCy4AxzbENeOl}8-TPwwYUNpcugcZAB!!vMCGg&(2boFJ8Q$=g%1zPwB~%C(s|6N?beu zF5urNaiNr9rW@CpadGLg5*Mk!#X0DcGti^#4}cy57YUFN_LEp2vaGXD0UE-lL<>KH z?^EkY@LUe#6}}Stgc^_oZFRfeRUSKbTodor0*wVOP(OjMonAZ2o=QyYd+E|;Kj0#h zagm*qBLN2tatT{bcDBU)kPCibV88z5%a`=x#dCW0>{&isJfa5=9ta4viQG$;JAHhMY}(>c#I#O*e3Scuzy)ko`STYp^n*Q* zymle;^e2Jgxh zQtq>7&*jfwypXbUas__g^uxGey?OWEJ?ZxCJJR(VHxyT|UXw$|=R!Z^rk+19KYKPs z;%6p9FEg&02Uzx*|HHz=AHt73zB?dbG_-&| zd($=QbEv<-6UudfZU7H}EnqBQ9^e>YHsD)8aRB3^sZRCk6M>6~)%En|RjaN$pu%_G z^{ZH^l6&8NecM6~2Say;-MW4E#Z|QHXjC+9 zq+bQCFJwUfoH=4qAnVqv6vas#N%WS8o&z>)Q z^7Prbo44-tMxU^S|89T7C5so8sZ~?=jcrsv@810kt(e$Y?ZCi5ZC_tsEw3G3@7-4Q zGxC>ci{KNKodGieQvkKl-fwH`>z3E4u2cS-Z*^p#b%koxbw=aA=6pZOzkDy`{V%V{ zUl;X0bcYNwpv^Qrboj8=-o1NepsgnO;Des0e(sw}bvsa229yJouUxHQ+s6K0Mb@KT z8SUSD8_IhBW+3P@)Y|ad5lf8fja+KfV(0>+pQo-h?!Cs}^mlu2)6ouorZWJx4t{1l zr=Ssa+`kC=4%)zn){CrcEjU)%@UgX_)3lGDNYH{@YeA36VAnMR1A{(#8{gFKH=R@C zqEp*)!e3ZBqRQOaBTAl`KBUAcyJ?lug54W7Qr|bh-o(#pnGub$HIf4dG}F=^XmRq#+eI7l%;7yisx>%H=?~8>+R;YOj>Eu zYSJnb8fRCVMl3Ouk6&3kd#;N`_M$E3S*v%M=AiA*0pfdVDBmg1Um9)#MwyEC`;RhN z5^QBoPQ$8YEuLIn9_U(E;qPQg!A_P9M%&f)o@j4EJurhw4~**hGJU+#9dl=f`2piR!^ z7bdSYeL8)e8BG&lnmX6j!UOd8Li=|tbT{{K3N)$8?OElk9BcU!+V(zmh*@GJELudIy_D9H@-g5%i@}|6Xq@c(3KCK zW0;Hflg(z!o&4W?H;W?Rf34XYEVPz-nrp2KP(F+Q`?qYdOKJ=H#o8K=h+S$-3=#A6 zleSK%B7Et+UKZ0v&orQRf9U0Q8Ky^5SDU_E=~u5Fw{L;F<-bbDy-t%Px2l5nX~#5* zoO0AnI$>`>Dj1@^cIgJQa*I7IuYupmW|KKB^=x>G=+M8q-RidCJMe<`DEsg?;ZHi? zJMi}UDG3g`g7#Z>*A;rfHKgIJ4f`9A^MOV=ZlU`5Bu+yNUnR&-=HPDV`+- z{n7U5q)nCSlw)-|VP{~)?KrVgU&|@Df%t#T?ndR;?X7#$DX0a$aW1}b9jk7u&(SHe zfY?P^!N*r>9ZuRPu2=u}C6}+h3IA2cGyFa1ZDr~7)^g`htS}V){3O@PqAeTtwGuRT z3T`$}+4i>CT;hA*LO(hNHOtfg{7sK9xy||Omg-kb)D>lj_$E5z!0Vf_e9h?{CG*;} zDYUP+4&S=2h;QB9=I>m(9_WH^n+|(`Z(B#<+tvpFUih||ZFusQ(tJO@Z}>&yfxiLB z^+eeWfbYV7P5Acr<;1Pua{Q&n8J`jb>W?-H9zbc$-*?><+6Uiw9HYRueZ_Y@@hxZh z{)9DjFwuD$-w!^>!yg}iX&Zn4j_ZW-TL6C>wQtJK60KC{3bdWi;hW~-oa=#Z-=Y0? zw;mqG-#5i~Ehq6e4ReEz+r7j$4f$J!*8m(l_^Qhwnyk7~eRKMcdXLr7mdH(NBo6CMBA8ZR7 zt+^v|VkwWqBMf#$&uMWe(fK#De>%Vo-~*_@_oMt1FTLrx|E6=UA>H2T`=HI@TTcI` zHhoB4cOIF--#C=*j->_GE1)fKTA@Uk0s?gL660!n+TigxnyI_M~EV_7R4w2;lS`ZfIk45 z8hZG}W}qwzfB)MUu(BE@n>KB#_T2e1i_Wu|UTn(LNkuKpU(MfrNv)qed9vo*d2_W! zjUHaKU8fdbm;0{xH>e+vuX5Z|Wq?>m0P)S0D^{#n8gbsAb-ZcP#EF{7<5NB?THgLTCC!q!6nq@0j+7)Th zy3tp7AA*`SOCtY|^J2~Pb#O?RJNFs3WRdMA*Nu+J?mO1JbltI- zR(njQg-!#J@7#qZEN!dc9O+569TmuhmS)&@Lw;d*n(3eh96Rv2ZZvCkcjQcWB2TYP zWV>`Z$LuROuWRw*#q{g1zn;dL3*%7f2B1Z?N|h@8ZCW&MW2yCZk+R=T8aD&+lJ2{9 z?eV(hwFfx`o^xoP!|ya2Ie*A)R`eg=L_T1AbH%`kEu}vux1qt4ThrhvuYhwSInQ}0 z=Q$&{nPK>hA4R_4uo-P=cc2%oU9+B+EM3C+nj(*#bJd`~ULgO#18rbh7=fS4A`btZ zW2gCvG;h}8%0a<F54t@{WBi6v(TUI`yrG9NW6op?95E z@M|6F_-kE}ciS0xx14j^_4fwIyKN|Pmqo5J=lczANJA#KrMP29kz?n}Idx=jZ%>?q z%(URVGT!gkuish3&~rXb1IR};Ugre+e<>HI6VEO1KfH!U%xjk0?pG6elb;L}oL|ep zd7J?b(=BNp!&$E<-9D;M{C0Qw8*7x-p)wm9E&_!&Nc4Bd3t8ZRkff7KU5>@ z6{8U|eM`hZb50rJ{dqkFkvEGxQISW^xz)&rd5N4LPZcc;!B0$!cgh8Fgc6r;8Ax;1 z{i2w{UaXlaCzjj9dBU7eCjk2mTi2lP zI~h>7L3L@^ln#`fa-1GLd@OQ9IRAlTxe?z<9v&Vdw~cdMA=e7daRYBr|Ni~Yl`B_{ zX;B}vsQNBigdW|QHQE|{3SMO%{$p}0w4s^E(Kbg;Gw1kLHz+UKQ_EDD*U5RU#un8? zj;AqlKg}9er3S5a>BnD;ac@(avglV@yLm1JhIrG-Qzz)m=`$i%k>mL}7lY%~Ie&w5 z6#V`DMQ%IiYa(w`0)Mf56Kvm0=$7qh!_Ux7hLCf%>3@=o?f&bf4t>l7FSqY)DeBER z=A5U@x#x}B7?N52>LMSL+oEq$fsE@`q`EDtQrn&;)X%B~O|CbO7GDS2chC$$6HXkHPKWd<4!V;T#;!HR0TJt~a*>a;-q@wSx0d2M!#V zinSD2N7X|+*am6C7Uju>TQWlkmMlAAR|-gM)tRKHbqYSz96{m|W* zx(#eV!>4qj`F118b=y+fALc``$0J1!2jDqtyAd>YNzPh2i`$wQR5~fS)Af5X)gpY0jKES;!5YkGj`~A5s}UR1xfp%_m^< zV*|@Fl5xF?ih8Z8QOnM?sB{0i^vC$0Xv%`Vw9Ii5xolldyZ3FU7}Pc8Tnh5Dt|KRj z^LTF{w)?Wk2|S716~wTM{BF+iK6Wf#)QNfh2>1kX?IP!o^R_tm?+DtV&WF8y`GgQf)w7NnrUEs*P13%0eiTCS5%pW5RaGQhx?mS%c=;5;~&z|Mb^A~dDl3hpL?<=0Z z$l}~I#Y5!hajw?Y8#l$f;*nRGoN$~jrJkkh$WOa<{VLrATti;o70xvhxiy?~m4ZAY z&M`v174oc3fG+XK!Ha@C917V_{=PeDvzrS!u3L+|;~nDJoMXhY!TClk8=S9+_-tw4 zzI~i?+MbyPa{U$RFJw9XSgeqR$p1Lmro?Bj=tXUrFd7 z=Ce@9h$DD~`Gs?3I1i88!8x_O<^beg;(Q|TkceeOzMP12;I=@PWT0E#F`v79>C)F1 zE?#VpoP|xd@7%ln;87;$hDx08#5q8m9EMyd9KRtKOqKhj&WRIwPtZA+k?(Qw!bO4C z6v*r8)5xJ^x(6do2X^cV8tB;*DuP`6yPMS*(096EGJ4X)qRsZ;-? zNAVm@EVPev+c?LM z^BwPJ+!wl%bGSHfN#yqdr^wwA_JHlcxm1ylhuoz^1@g;sk-Lx!nU{0!4$}g%A!j-O z|A)Em81~51oqYWIR@1;h{2#n;zh-P)yl5v%aSrzuUA216teDuiqsZNQkOIDd+)1ga z=Xo?mj@&GyrsYa}kbgt2mV}%!1=b%>fG%>zDRSR(FQ=u+IR}SxkC>lMAP0|g_K~jv zn{h;O_|W0&;QL_YCd`FS<$kEfyK)o|V=m)3a{%WVaK3>aa?Ls$)vjI7z|gQ$r7Be{ zixw+pq+PVg@XA%I_Wz}4FY6hzW+lhO#%FR4Cg-4n-;g_gRN>?63mfDvIXP`W4o#5A z8$vD#@++@HKctKNT+T~Ie!7HuKZuQsON5Q^3k?ai0U!0ky(XiqMsZ(6Y(as6Z^b+6 zDe#Qa9Iyc30N4na062oYkn#Kwv}K@yVXa>Jwe$z0Wn;@#DBJPdish%b?eIhY`x$q- zr=?#F0G~aIL=L>u24`u#qZ4iM*edz@?RtWo@oUI=I)3I%${z5_8sz^>Kwf-j=oYh; z_V#7*_&3%M@*{)Y(?-to8~^8ep^n1GL)jIu2`~wHEdv2RBf+Z$a^BivzZr6RbSi#V z4K}<8*2Ss`8)yz$sR2K?YMwoejEwjea^4F3(-zPeU<9ZXee_5%e%ISJT%&pY`VB4c zy*7A8+soTq1|QJA>!oZrn*@WOs8i?cYTS9^N)zP77|SO)n9y7oOT|)8(S~G{f0{cNae~~A zclMRuhPRJ(K6$hHYfz`*HKcj2=9$a9>ek?U z=DS&HFWG7?Tf6)7=MbG-rzdcEYJ*Ncj*UOQqSlj$B?iV^PumTqU1zRGKFn%U#Kzb2 z=5v!*nS54W;X1r&OWIWB=&5yjlwfDz%>VCSW+40_*O2;=t|5)dEu`%|r=YgHhN%W( zx{L0OU#5NFwym9zRw+tcGg=NM~wK|gJ-&ca@yGy+^feDK4hZDlODKBv8vYpJ+} z^b+lG3+dUDe`;~F3)w`)M$qH&1HT!A`=09L5#|Ji78&PQAGoNwuO@-XrX-uOT2&vB)1{O_N_ z`}@4dJWCu`nL?eUMjpO(6yfF;Iwsd>D9~`S7#qe2fWT z6JrB!DLJr-|Bt|Di%`lr$O>fy2TEyZ$k7%q(^0lUX@gQ1C2z%4r8?^CPtjhjl-G%` zC-APW@_sHw+!sm__k|Mg6aS02FKgvH`T38n(-D29q4AQNfl?GGm2q3IO65nDP~Sz$ z>#}T>Wp=Exe5@*;URNGpPgj<=Gh1N?&sCSCt31YU{`ZN)eD8nXWA0$-0a^p{;`fRYgorx6RU=C5S)Pg&ERwSk3Ysf=6v(sh4Jis&&Ssbw6uBr zvr5^LI(1t#Zr83<$+GO%e`9aw@IU#u7}FN-#JFN^=3?DgU z{+xvqcCL1tcWR^0;=A6#4svUoxtA-HuQ(BP&~4qib+NyLk0(!`0#Ib?GBr*5 z^!)wT*>k7c+pn_@$J)bp9Cu8U9DT-xqVPi< zS|Jvx6vnmR3m4g(Fk-X2Srt;rLw~z*m{hodw z-%_l1`Um1XhEDyF5dT5WTb7ga1~+NhGFt`54qGNe z=tp7?VlMP3)-81Bb)I=GTLrKCjd`_e_zuSu)I+CNuU@|x9{6IZWs%jY;gp>{pY={KrE4cb(vcD>AL$ixn`aob9))p%dbiSe8huQ7<& z4_sw3Do{23 zGNf0#44F3k4r|66Q~!}a(#*v}Xv3Bz6ddY@^>Je{FPtFegLuw}=jM3bJFNdC;s?Nk zOb-Q0nlx$B4FdxM!54aZdi?zYv5lWGNKvU~v0TGC0n*8#50)B;kA{IQb;J~ZZYp1hWRyKTaMq)^IE)KC$Gzn z`2_+V!Ce^JiJ6&tJT>&&pO@x{G%`!hCjCwuE&% zvlQ2F+{(rLu5|89GS*~G!}`6~=oZ%SyngK}*7N20;0u(3^%Z&D&68M%J`VH8VW`J0 ztTVc4qbt^=4-|0`yj~^dN)@U(-{W|{_OM~Yv|F}psTp}BT92(3xW@^KBNrmCu;BT_RiC}*)N{U?%&U7@!;X3bq^jq zyo*IV#T+fK*NJr*d5$)h=QnxE7W;CnOUZMoV(yRUR(VZTt_$X)1aC4Q;Jp&+rHGD- z9?b8@9C`u$h&eE=rp=p|Zr-9rrSB?zXO8vQc`cxF^%~ai+NWRN)hq1nB0~>`zIcwg z)Q7+UuM>?m&O{8y<+LjzCV}yB5$o%oIeS)twGQvb#>O4TyFG#TshDg05o^ASykdU8 zdc&NMs0Yd(07uMKSXb4l?x0_*Rxfi)^CsoXS8iFX=r;}U*{1r{Dw#FQenBlRr=@QV z2|bkP;_7y6%T~{jsOZ?OSl4$c*54a}In;Kc2M-#7-^IL)`aS9r>+Xa>4wUlE-qtY|o8t892_`S)7{WY7;aWAgV_bv4*SKv8( z?)43Gwwj1H&_+BF&z)%@R^qMqtRGfg;KAF$|Qx(&d{m%Z$@8FGCA9 zn=3GIATJD6WOr;RyNEzFn7u#Vze-}QPu)yLbG z>Jtt;^U9Csn@VccCXYSaf1$>SZVMpKiea;PHoqaCRnTE zM-gAZ=lo-4Xnv}(v=r|Wr%rDx!?8#jn?pN^b~^9tu+e3INAijsYZG*AW$!)li;ehy zjIaJ}-s1b-ww?DYR`#6lSAJ)_zv;r)9NJ?l<~CdobTiv@uwRZ>mLIwd@L zGv>8F&DsQsE>-f{ZRH4i_Z{>_DN`2TtX3F$ zD2*JvV#v1>xpWwL&}aqF1#p~gF&hBJP>Nyvq%s9n%#)y{F9vAdl^wc zwvqBtq(`^k498CXqsMZ`DT{1ur>?17QP-4TiMVMQ@;P3+UPEKfw7v<^VHA>tFP87p@$a>%S{NL_}Z(lD39oQv5o)9BlJb#WZoxeyiQTVnd)uSi5$+3RNn0DOc*NYG4+lj{PfjKYih77r$M5N9_*S)9=#dD=qPzl$t)ietGd} z>KALc;0|ow)AhpL)|q-wUSH?@3NQ0$r~ThD`)RE3(JR0+@S|m^=gw&(<~Z+s%#vEa z#V)GlF?WsWOmsbX#JMSL8M!h9%sSr%lwJWUJ z*K(r!!5%)b=R>RYTcNC%`kJ?un1d~q;`en6{@-bDtp zCsvqgCfJ*5+6Dh0>WBH|BCuz9ePMpiySB4FO8e**(iLmh41KE%zUvwJ|BE{7^+r79 pzec^!W1^BZ#)DhojL<|VQ3D%5CV>Ax3OEJW4|obtj-x8e{{x+0!{z`0 literal 0 HcmV?d00001 diff --git a/src/SetupDLL/Setup.manifest b/src/SetupDLL/Setup.manifest new file mode 100644 index 00000000..afd4c1c0 --- /dev/null +++ b/src/SetupDLL/Setup.manifest @@ -0,0 +1,33 @@ + + + + + + + + + + + + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/SetupDLL/Setup.rc b/src/SetupDLL/Setup.rc new file mode 100644 index 00000000..6e1a5312 --- /dev/null +++ b/src/SetupDLL/Setup.rc @@ -0,0 +1,367 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" +#include "..\\common\\resource.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,24,25,0 + PRODUCTVERSION 1,24,25,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "IDRIX" + VALUE "FileDescription", "VeraCryptSetup" + VALUE "FileVersion", "1.24-Update9" + VALUE "LegalTrademarks", "VeraCrypt" + VALUE "OriginalFilename", "VeraCryptSetup.dll" + VALUE "ProductName", "VeraCrypt" + VALUE "ProductVersion", "1.24-Update9" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// HEADER +// + +IDR_SETUP_RSRC_HEADER HEADER "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// REGISTRY +// + +IDR_COMREG REGISTRY "ComSetup.rgs" + +///////////////////////////////////////////////////////////////////////////// +// +// LANGUAGES +// + +IDR_LANG_AR LANGUAGES "..\\..\\Translations\\Language.ar.xml" +IDR_LANG_CS LANGUAGES "..\\..\\Translations\\Language.cs.xml" +IDR_LANG_DE LANGUAGES "..\\..\\Translations\\Language.de.xml" +IDR_LANG_ES LANGUAGES "..\\..\\Translations\\Language.es.xml" +IDR_LANG_FR LANGUAGES "..\\..\\Translations\\Language.fr.xml" +IDR_LANG_IT LANGUAGES "..\\..\\Translations\\Language.it.xml" +IDR_LANG_JA LANGUAGES "..\\..\\Translations\\Language.ja.xml" +IDR_LANG_NL LANGUAGES "..\\..\\Translations\\Language.nl.xml" +IDR_LANG_PL LANGUAGES "..\\..\\Translations\\Language.pl.xml" +IDR_LANG_RO LANGUAGES "..\\..\\Translations\\Language.ro.xml" +IDR_LANG_RU LANGUAGES "..\\..\\Translations\\Language.ru.xml" +IDR_LANG_VI LANGUAGES "..\\..\\Translations\\Language.vi.xml" +IDR_LANG_ZHCN LANGUAGES "..\\..\\Translations\\Language.zh-cn.xml" +IDR_LANG_ZHHK LANGUAGES "..\\..\\Translations\\Language.zh-hk.xml" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_UNINSTALL DIALOGEX 0, 0, 349, 234 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Uninstall VeraCrypt" +CLASS "VeraCryptCustomDlg" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "Click Uninstall to remove VeraCrypt from this system.",IDT_UNINSTALL_DIR,8,8,334,8 + LISTBOX IDC_LOG_WINDOW,7,21,335,179,LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL + DEFPUSHBUTTON "&Uninstall",IDC_UNINSTALL,236,213,50,14 + PUSHBUTTON "Cancel",IDCANCEL,292,213,50,14 + CONTROL "Create System &Restore point",IDC_SYSTEM_RESTORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,215,194,10 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,206,347,1,WS_EX_STATICEDGE + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,1,348,1,WS_EX_STATICEDGE +END + +IDD_INSTALL_OPTIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + EDITTEXT IDC_DESTINATION,11,41,260,13,ES_AUTOHSCROLL + PUSHBUTTON "Bro&wse...",IDC_BROWSE,278,40,59,14 + CONTROL "Install &for all users",IDC_ALL_USERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,77,168,11 + CONTROL "Associate the .hc file &extension with VeraCrypt",IDC_FILE_TYPE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,113,232,11 + CONTROL "Add VeraCrypt to &Start menu",IDC_PROG_GROUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,89,168,11 + CONTROL "Create System &Restore point",IDC_SYSTEM_RESTORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,125,194,11 + CONTROL "Add VeraCrypt icon to &desktop",IDC_DESKTOP_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,101,168,11 + LTEXT "Please select or type the location where you want to install the VeraCrypt program files. If the specified folder does not exist, it will be automatically created.",IDT_INSTALL_DESTINATION,11,14,319,25 +END + +IDD_INFO_PAGE_DLG DIALOGEX 0, 0, 217, 156 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "",IDC_BOX_HELP,0,10,217,146 +END + +IDD_INTRO_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_LICENSE_TEXT,"RichEdit20W",ES_MULTILINE | ES_READONLY | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,0,23,345,108 + CONTROL "",IDC_AGREE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,2,137,126,10 + LTEXT "",IDC_BOX_HELP,0,0,346,22 +END + +IDD_INSTL_DLG DIALOGEX 0, 0, 374, 231 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "VeraCrypt Setup Wizard" +CLASS "VeraCryptCustomDlg" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "&Help",IDHELP,150,211,50,14 + PUSHBUTTON "",IDC_PREV,209,211,50,14 + DEFPUSHBUTTON "",IDC_NEXT,259,211,50,14 + PUSHBUTTON "Cancel",IDCANCEL,317,211,50,14 + LTEXT "",IDC_BOX_TITLE,11,5,324,12,0,WS_EX_TRANSPARENT + CONTROL 107,IDC_BITMAP_SETUP_WIZARD,"Static",SS_BITMAP | SS_NOTIFY,139,3,228,30 + CONTROL 109,IDC_SETUP_WIZARD_BKG,"Static",SS_BITMAP,0,0,11,10 + CONTROL "",IDC_SETUP_WIZARD_GFX_AREA,"Static",SS_GRAYRECT | NOT WS_VISIBLE,0,0,378,36,WS_EX_TRANSPARENT | WS_EX_STATICEDGE + CONTROL "",IDC_HR_BOTTOM,"Static",SS_ETCHEDHORZ,67,204,306,1,WS_EX_STATICEDGE + CONTROL "",IDC_HR,"Static",SS_ETCHEDHORZ,0,35,399,1,WS_EX_STATICEDGE + LTEXT "VeraCrypt Installer",IDC_STATIC,4,200,62,8,WS_DISABLED + LTEXT "",IDC_BOX_INFO,18,18,317,13,0,WS_EX_TRANSPARENT + LTEXT "",IDC_MAIN_CONTENT_CANVAS,0,36,374,164 + LTEXT "",IDC_POS_BOX,14,42,346,155,0,WS_EX_TRANSPARENT +END + +IDD_EXTRACTION_OPTIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Bro&wse...",IDC_BROWSE,277,32,62,14 + EDITTEXT IDC_DESTINATION,6,33,264,12,ES_AUTOHSCROLL + LTEXT "Please select or type the location where you want to place the extracted files:",IDT_EXTRACT_DESTINATION,6,15,333,17 + CONTROL "&Open the destination location when finished",IDC_OPEN_CONTAINING_FOLDER, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,91,318,16 + LTEXT "",IDC_BOX_HELP,6,56,333,32 +END + +IDD_WIZARD_MODE_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "&Install",IDC_WIZARD_MODE_INSTALL,"Button",BS_AUTORADIOBUTTON,6,14,232,10 + CONTROL "&Extract",IDC_WIZARD_MODE_EXTRACT_ONLY,"Button",BS_AUTORADIOBUTTON,6,60,232,10 + LTEXT "",IDC_BOX_HELP,42,77,286,64 + LTEXT "",IDC_BOX_HELP2,42,30,286,29 +END + +IDD_PROGRESS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LISTBOX IDC_LOG_WINDOW,0,1,345,131,LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL + CONTROL "",IDC_PROGRESS_BAR,"msctls_progress32",PBS_SMOOTH | WS_BORDER,0,139,345,12 +END + +IDD_DONATIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +EXSTYLE WS_EX_TRANSPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Donate now...",IDC_DONATE,124,94,96,14 +END + +IDD_INSTALL_LANGUAGE DIALOGEX 0, 0, 214, 75 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "VeraCrypt Setup Wizard" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,102,54,50,14 + PUSHBUTTON "Cancel",IDCANCEL,157,54,50,14 + ICON IDI_SETUP,IDC_STATIC,10,10,32,32 + LTEXT "Select the language to use during the installation:",IDC_SELECT_LANGUAGE_LABEL,42,13,158,17 + COMBOBOX IDC_LANGUAGES_LIST,42,36,164,155,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SETUP ICON "Setup.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""..\\\\common\\\\resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""..\\\\common\\\\common.rc""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_UNINSTALL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 342 + TOPMARGIN, 7 + BOTTOMMARGIN, 229 + END + + IDD_INSTALL_OPTIONS_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 147 + END + + IDD_INFO_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 210 + TOPMARGIN, 7 + BOTTOMMARGIN, 149 + END + + IDD_INTRO_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 145 + END + + IDD_INSTL_DLG, DIALOG + BEGIN + RIGHTMARGIN, 367 + TOPMARGIN, 1 + BOTTOMMARGIN, 229 + HORZGUIDE, 196 + END + + IDD_EXTRACTION_OPTIONS_PAGE_DLG, DIALOG + BEGIN + RIGHTMARGIN, 343 + BOTTOMMARGIN, 147 + END + + IDD_WIZARD_MODE_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 145 + END + + IDD_PROGRESS_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 145 + END + + IDD_DONATIONS_PAGE_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 147 + END + + IDD_INSTALL_LANGUAGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 207 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_SETUP_WIZARD BITMAP "VeraCrypt_setup.bmp" +IDB_SETUP_WIZARD_BKG BITMAP "VeraCrypt_setup_background.bmp" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "..\\common\\common.rc" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/SetupDLL/Setup.vcxproj.filters b/src/SetupDLL/Setup.vcxproj.filters new file mode 100644 index 00000000..d747363f --- /dev/null +++ b/src/SetupDLL/Setup.vcxproj.filters @@ -0,0 +1,162 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {6073052c-2d95-47a0-95d8-5960d4c1d1c0} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + {a540fb0a-850b-4cb9-85f9-ade0112ebb50} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files + + + + + Source Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + Resource Files\Common + + + \ No newline at end of file diff --git a/src/SetupDLL/Setup.vcxproj.user b/src/SetupDLL/Setup.vcxproj.user new file mode 100644 index 00000000..ace9a86a --- /dev/null +++ b/src/SetupDLL/Setup.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/SetupDLL/SetupDLL.def b/src/SetupDLL/SetupDLL.def new file mode 100644 index 00000000..8a54fa06 --- /dev/null +++ b/src/SetupDLL/SetupDLL.def @@ -0,0 +1,7 @@ +LIBRARY VERACRYPTSETUP +EXPORTS + VC_CustomAction_PreInstall + VC_CustomAction_PostInstall + VC_CustomAction_PreUninstall + VC_CustomAction_PostUninstall + VC_CustomAction_DoChecks \ No newline at end of file diff --git a/src/SetupDLL/SetupDLL.vcproj b/src/SetupDLL/SetupDLL.vcproj new file mode 100644 index 00000000..a1a6a81f --- /dev/null +++ b/src/SetupDLL/SetupDLL.vcproj @@ -0,0 +1,484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/SetupDLL/SetupDLL.vcxproj b/src/SetupDLL/SetupDLL.vcxproj new file mode 100644 index 00000000..374ad866 --- /dev/null +++ b/src/SetupDLL/SetupDLL.vcxproj @@ -0,0 +1,279 @@ + + + + + Debug + Win32 + + + ReleaseCustomEFI + Win32 + + + Release + Win32 + + + + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49} + Setup + Win32Proj + SetupDLL + + + + DynamicLibrary + Unicode + Windows7.1SDK + + + DynamicLibrary + Unicode + Windows7.1SDK + + + DynamicLibrary + Unicode + Windows7.1SDK + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + Debug\ + Debug\ + true + true + true + Release\ + Release\ + Release\ + Release\ + false + false + true + true + VeraCryptSetup + VeraCryptSetup + VeraCryptSetup + + + + Disabled + ..\Common;..\Crypto;..\;..\PKCS11;..\Common\zlib;..\Common\libzip;%(AdditionalIncludeDirectories) + SETUP;SETUP_DLL;WIN32;HAVE_CONFIG_H;ZIP_STATIC;DEBUG;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;_ATL_NO_DEFAULT_LIBS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level4 + EditAndContinue + 4057;4100;4127;4201;4505;4701;4706;4131;%(DisableSpecificWarnings) + + + /NODEFAULTLIB:LIBCMTD %(AdditionalOptions) + msi.lib;libcmtd.lib;atlsd.lib;mpr.lib;..\Common\Debug\Zip.lib;..\Crypto\Debug\crypto.lib;%(AdditionalDependencies) + $(OutDir)VeraCryptSetup.dll + RequireAdministrator + user32.dll;gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;oleaut32.dll;mpr.dll;%(DelayLoadDLLs) + true + $(OutDir)Setup.pdb + Windows + false + true + MachineX86 + SetupDLL.def + + + Setup.manifest;%(AdditionalManifestFiles) + + + md "..\Debug\Setup Files" 2>NUL: +copy Debug\VeraCryptSetup.dll "..\Debug\Setup Files\VeraCryptSetup.dll" >NUL: + + + + + + /w34189 %(AdditionalOptions) + MaxSpeed + ..\Common;..\Crypto;..\;..\PKCS11;..\Common\zlib;..\Common\libzip;%(AdditionalIncludeDirectories) + SETUP;SETUP_DLL;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;_ATL_NO_DEFAULT_LIBS;%(PreprocessorDefinitions) + MultiThreaded + true + + + All + $(IntDir) + Level4 + ProgramDatabase + 4995;4057;4100;4127;4201;4505;4701;4706;4131;%(DisableSpecificWarnings) + + + /IGNORE:4089 %(AdditionalOptions) + msi.lib;mpr.lib;..\Common\Release\Zip.lib;..\Crypto\Release\crypto.lib;%(AdditionalDependencies) + $(OutDir)VeraCryptSetup.dll + RequireAdministrator + user32.dll;gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;oleaut32.dll;mpr.dll;%(DelayLoadDLLs) + true + true + Windows + true + true + true + true + MachineX86 + SetupDLL.def + + + Setup.manifest;%(AdditionalManifestFiles) + + + copy Release\VeraCryptSetup.dll "..\Release\Setup Files\VeraCryptSetup.dll" + + + + + /w34189 %(AdditionalOptions) + MaxSpeed + ..\Common;..\Crypto;..\;..\PKCS11;..\Common\zlib;..\Common\libzip;%(AdditionalIncludeDirectories) + SETUP;VC_EFI_CUSTOM_MODE;WIN32;HAVE_CONFIG_H;ZIP_STATIC;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS;_ATL_NO_DEFAULT_LIBS;%(PreprocessorDefinitions) + MultiThreaded + true + + + All + $(IntDir) + Level4 + ProgramDatabase + 4057;4100;4127;4201;4505;4701;4706;4131;%(DisableSpecificWarnings) + + + /IGNORE:4089 %(AdditionalOptions) + msi.lib;mpr.lib;..\Common\Release\Zip.lib;..\Crypto\Release\crypto.lib;%(AdditionalDependencies) + $(OutDir)VeraCryptSetup.exe + RequireAdministrator + user32.dll;gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;oleaut32.dll;mpr.dll;%(DelayLoadDLLs) + true + true + Windows + true + true + true + true + MachineX86 + + + Setup.manifest;%(AdditionalManifestFiles) + + + copy Release\VeraCryptSetup.dll "..\Release\Setup Files\VeraCryptSetup.dll" + + + VC_EFI_CUSTOM_MODE;%(PreprocessorDefinitions) + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + + + + + {8b7f059f-e4c7-4e11-88f5-ee8b8433072e} + false + + + {9715ff1d-599b-4bbc-ad96-bef6e08ff827} + false + + + {9dc1abe2-d18b-48fb-81d2-8c50adc57bcf} + false + + + {e4c40f94-e7f9-4981-86e4-186b46f993f3} + false + + + + + + \ No newline at end of file diff --git a/src/SetupDLL/SetupDLL.vcxproj.filters b/src/SetupDLL/SetupDLL.vcxproj.filters new file mode 100644 index 00000000..e0429539 --- /dev/null +++ b/src/SetupDLL/SetupDLL.vcxproj.filters @@ -0,0 +1,150 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + Source Files\Common + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files\Common + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Resource Files\Common + + + Source Files + + + Source Files + + + + + {abfa03d7-3de7-4832-b36d-5b45cd0fc304} + + + {d912b4b9-7f5e-4063-8af7-4d544dde2233} + + + {5a0efac0-b028-4388-a278-1fe6dc479d79} + + + {3cb669f1-3949-43f4-a1e5-3b5d0fd75f76} + + + {92f9499e-670d-464b-9edf-c1a2c56fb813} + + + + + Resource Files + + + \ No newline at end of file diff --git a/src/SetupDLL/SetupDLL.vcxproj.user b/src/SetupDLL/SetupDLL.vcxproj.user new file mode 100644 index 00000000..ace9a86a --- /dev/null +++ b/src/SetupDLL/SetupDLL.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/SetupDLL/VeraCrypt_setup.bmp b/src/SetupDLL/VeraCrypt_setup.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b99619e348af9cb456e86a6076e4a9fabc36c7fd GIT binary patch literal 49398 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 V0vabk8lZ8clpzs#s|e`m{1>W%H^cw{ literal 0 HcmV?d00001 diff --git a/src/SetupDLL/VeraCrypt_setup_background.bmp b/src/SetupDLL/VeraCrypt_setup_background.bmp new file mode 100644 index 0000000000000000000000000000000000000000..85397e8048a71dc6029fb7810ca3320ec3cceab6 GIT binary patch literal 822 pcmZ?rHDhJ~12Z700mK4O%*Y@C76%bW_#hZ2@P8DHhQJ680RW{g05Jdn literal 0 HcmV?d00001 diff --git a/src/Signing/sign-sha256.bat b/src/Signing/sign-sha256.bat index 99cad96d..7902e66c 100644 --- a/src/Signing/sign-sha256.bat +++ b/src/Signing/sign-sha256.bat @@ -1,6 +1,7 @@ PATH=%PATH%;%WSDK81%\bin\x86;C:\Program Files\7-Zip;C:\Program Files (x86)\7-Zip set VC_VERSION=1.24-Update9 +set VC_VERSION_NBRE=1.24.25 set SIGNINGPATH=%~dp0 cd %SIGNINGPATH% @@ -9,47 +10,51 @@ call "..\..\doc\chm\create_chm.bat" cd %SIGNINGPATH% rem sign using SHA-1 -signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_MS_Cross_Cert.crt /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" +signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_MS_Cross_Cert.crt /fd sha1 /t http://timestamp.digicert.com "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" timeout /t 10 rem sign using SHA-256 signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_R3Cross.cer /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_R3Cross.cer /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\veracrypt-arm64.sys" -signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt-arm64.exe" "..\Release\Setup Files\VeraCrypt Format-arm64.exe" "..\Release\Setup Files\VeraCryptExpander-arm64.exe" - +signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt-arm64.exe" "..\Release\Setup Files\VeraCrypt Format-arm64.exe" "..\Release\Setup Files\VeraCryptExpander-arm64.exe" "..\Release\Setup Files\VeraCrypt COMReg.exe" +rem create setup and MSI cd "..\Release\Setup Files\" - copy ..\..\LICENSE . copy ..\..\License.txt . copy ..\..\NOTICE . - +copy ..\..\Resources\Texts\License.rtf . +copy ..\..\Common\VeraCrypt.ico . +copy ..\..\Setup\VeraCrypt_setup_background.bmp . +copy ..\..\Setup\VeraCrypt_setup.bmp . +copy ..\..\Setup\Setup.ico . del *.xml rmdir /S /Q Languages mkdir Languages copy /V /Y ..\..\..\Translations\*.xml Languages\. del Languages.zip 7z a -y Languages.zip Languages - rmdir /S /Q docs mkdir docs\html\en mkdir docs\EFI-DCS copy /V /Y ..\..\..\doc\html\* docs\html\en\. copy "..\..\..\doc\chm\VeraCrypt User Guide.chm" docs\. copy "..\..\..\doc\EFI-DCS\*.pdf" docs\EFI-DCS\. - del docs.zip 7z a -y docs.zip docs - "VeraCrypt Setup.exe" /p "VeraCrypt Portable.exe" /p - +call build_msi_x64.bat %VC_VERSION_NBRE% del LICENSE del License.txt del NOTICE +del License.rtf +del VeraCrypt.ico +del VeraCrypt_setup_background.bmp +del VeraCrypt_setup.bmp +del Setup.ico del "VeraCrypt User Guide.chm" - del Languages.zip del docs.zip rmdir /S /Q Languages @@ -58,6 +63,6 @@ rmdir /S /Q docs cd %SIGNINGPATH% rem sign using SHA-256 -signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" +signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64.msi" "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64_en-us.msi" pause diff --git a/src/Signing/sign.bat b/src/Signing/sign.bat index f4efacdd..15dca15d 100644 --- a/src/Signing/sign.bat +++ b/src/Signing/sign.bat @@ -1,6 +1,7 @@ PATH=%PATH%;%WSDK81%\bin\x86;C:\Program Files\7-Zip;C:\Program Files (x86)\7-Zip set VC_VERSION=1.24-Update9 +set VC_VERSION_NBRE=1.24.25 set SIGNINGPATH=%~dp0 cd %SIGNINGPATH% @@ -9,47 +10,51 @@ call "..\..\doc\chm\create_chm.bat" cd %SIGNINGPATH% rem sign using SHA-1 -signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_MS_Cross_Cert.crt /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" -signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_Code_Signing_CA.cer /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" +signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_MS_Cross_Cert.crt /fd sha1 /t http://timestamp.digicert.com "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" +signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_Code_Signing_CA.cer /fd sha1 /t http://timestamp.digicert.com "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt COMReg.exe" timeout /t 10 rem sign using SHA-256 signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_R3Cross.cer /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" -signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" - +signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt COMReg.exe" +rem create setup and MSI cd "..\Release\Setup Files\" - copy ..\..\LICENSE . copy ..\..\License.txt . copy ..\..\NOTICE . - +copy ..\..\Resources\Texts\License.rtf . +copy ..\..\Common\VeraCrypt.ico . +copy ..\..\Setup\VeraCrypt_setup_background.bmp . +copy ..\..\Setup\VeraCrypt_setup.bmp . +copy ..\..\Setup\Setup.ico . del *.xml rmdir /S /Q Languages mkdir Languages copy /V /Y ..\..\..\Translations\*.xml Languages\. del Languages.zip 7z a -y Languages.zip Languages - rmdir /S /Q docs mkdir docs\html\en mkdir docs\EFI-DCS copy /V /Y ..\..\..\doc\html\* docs\html\en\. copy "..\..\..\doc\chm\VeraCrypt User Guide.chm" docs\. copy "..\..\..\doc\EFI-DCS\*.pdf" docs\EFI-DCS\. - del docs.zip 7z a -y docs.zip docs - "VeraCrypt Setup.exe" /p "VeraCrypt Portable.exe" /p - +call build_msi_x64.bat %VC_VERSION_NBRE% del LICENSE del License.txt del NOTICE +del License.rtf +del VeraCrypt.ico +del VeraCrypt_setup_background.bmp +del VeraCrypt_setup.bmp +del Setup.ico del "VeraCrypt User Guide.chm" - del Languages.zip del docs.zip rmdir /S /Q Languages @@ -57,13 +62,18 @@ rmdir /S /Q docs cd %SIGNINGPATH% +rem Can't dual-sign MSI files when using signtool (only jsign / osslsigncode can do that) + rem sign using SHA-1 -signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_Code_Signing_CA.cer /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" +signtool sign /v /sha1 85aa2e55cfb9c38fe474c58b38e9521450cd9306 /ac DigiCert_Assured_ID_Code_Signing_CA.cer /fd sha1 /t http://timestamp.digicert.com "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" timeout /t 10 -rem sign using SHA-256 -signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" +rem dual sign Setup using SHA-256 +signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64.msi" "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64_en-us.msi" + +rem single sign MSI using SHA-256 +signtool sign /v /sha1 04141E4EA6D9343CEC994F6C099DC09BDD8937C9 /ac GlobalSign_SHA256_EV_CodeSigning_CA.cer /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64.msi" "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64_en-us.msi" move "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Legacy Setup %VC_VERSION%.exe" move "..\Release\Setup Files\VeraCrypt Portable %VC_VERSION%.exe" "..\Release\Setup Files\VeraCrypt Legacy Portable %VC_VERSION%.exe" diff --git a/src/Signing/sign_test.bat b/src/Signing/sign_test.bat index 858e545f..9e4b2e87 100644 --- a/src/Signing/sign_test.bat +++ b/src/Signing/sign_test.bat @@ -1,5 +1,6 @@ PATH=%PATH%;%WSDK81%\bin\x86;C:\Program Files\7-Zip;C:\Program Files (x86)\7-Zip set VC_VERSION=1.24-Update9 +set VC_VERSION_NBRE=1.24.25 set PFXNAME=TestCertificate\idrix_codeSign.pfx set PFXPASSWORD=idrix set PFXCA=TestCertificate\idrix_TestRootCA.crt @@ -15,43 +16,48 @@ call "..\..\doc\chm\create_chm.bat" cd %SIGNINGPATH% rem sign using SHA-1 -signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" +signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.digicert.com "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt COMReg.exe" timeout /t 10 rem sign using SHA-256 -signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" "..\Release\Setup Files\veracrypt-arm64.sys" "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt-arm64.exe" "..\Release\Setup Files\VeraCrypt Format-arm64.exe" "..\Release\Setup Files\VeraCryptExpander-arm64.exe" +signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\veracrypt.sys" "..\Release\Setup Files\veracrypt-x64.sys" "..\Release\Setup Files\veracrypt-arm64.sys" "..\Release\Setup Files\VeraCrypt.exe" "..\Release\Setup Files\VeraCrypt Format.exe" "..\Release\Setup Files\VeraCryptExpander.exe" "..\Release\Setup Files\VeraCrypt-x64.exe" "..\Release\Setup Files\VeraCrypt Format-x64.exe" "..\Release\Setup Files\VeraCryptExpander-x64.exe" "..\Release\Setup Files\VeraCrypt-arm64.exe" "..\Release\Setup Files\VeraCrypt Format-arm64.exe" "..\Release\Setup Files\VeraCryptExpander-arm64.exe" "..\Release\Setup Files\VeraCrypt COMReg.exe" +rem create setup and MSI cd "..\Release\Setup Files\" - copy ..\..\LICENSE . copy ..\..\License.txt . copy ..\..\NOTICE . - +copy ..\..\Resources\Texts\License.rtf . +copy ..\..\Common\VeraCrypt.ico . +copy ..\..\Setup\VeraCrypt_setup_background.bmp . +copy ..\..\Setup\VeraCrypt_setup.bmp . +copy ..\..\Setup\Setup.ico . del *.xml rmdir /S /Q Languages mkdir Languages copy /V /Y ..\..\..\Translations\*.xml Languages\. del Languages.zip 7z a -y Languages.zip Languages - rmdir /S /Q docs mkdir docs\html\en mkdir docs\EFI-DCS copy /V /Y ..\..\..\doc\html\* docs\html\en\. copy "..\..\..\doc\chm\VeraCrypt User Guide.chm" docs\. copy "..\..\..\doc\EFI-DCS\*.pdf" docs\EFI-DCS\. - del docs.zip 7z a -y docs.zip docs - "VeraCrypt Setup.exe" /p - +call build_msi_x64.bat %VC_VERSION_NBRE% del LICENSE del License.txt del NOTICE +del License.rtf +del VeraCrypt.ico +del VeraCrypt_setup_background.bmp +del VeraCrypt_setup.bmp +del Setup.ico del "VeraCrypt User Guide.chm" - del Languages.zip del docs.zip rmdir /S /Q Languages @@ -59,12 +65,17 @@ rmdir /S /Q docs cd %SIGNINGPATH% +rem Can't dual-sign MSI files when using signtool (only jsign / osslsigncode can do that) + rem sign using SHA-1 -signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" +signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.digicert.com "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" timeout /t 10 -rem sign using SHA-256 +rem dual-sign Setup using SHA-256 signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" +rem single sign MSI using SHA-256 +signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64.msi" "..\Release\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64_en-us.msi" + pause \ No newline at end of file diff --git a/src/Signing/sign_test_debug.bat b/src/Signing/sign_test_debug.bat index 9cf8e562..4b5e33ac 100644 --- a/src/Signing/sign_test_debug.bat +++ b/src/Signing/sign_test_debug.bat @@ -1,5 +1,6 @@ PATH=%PATH%;%WSDK81%\bin\x86;C:\Program Files\7-Zip;C:\Program Files (x86)\7-Zip set VC_VERSION=1.24-Update9 +set VC_VERSION_NBRE=1.24.25 set PFXNAME=TestCertificate\idrix_codeSign.pfx set PFXPASSWORD=idrix set PFXCA=TestCertificate\idrix_TestRootCA.crt @@ -15,26 +16,29 @@ call "..\..\doc\chm\create_chm.bat" cd %SIGNINGPATH% rem sign using SHA-1 -signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Debug\Setup Files\veracrypt.sys" "..\Debug\Setup Files\veracrypt-x64.sys" "..\Debug\Setup Files\VeraCrypt.exe" "..\Debug\Setup Files\VeraCrypt Format.exe" "..\Debug\Setup Files\VeraCryptExpander.exe" "..\Debug\Setup Files\VeraCrypt-x64.exe" "..\Debug\Setup Files\VeraCrypt Format-x64.exe" "..\Debug\Setup Files\VeraCryptExpander-x64.exe" +signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.digicert.com "..\Debug\Setup Files\veracrypt.sys" "..\Debug\Setup Files\veracrypt-x64.sys" "..\Debug\Setup Files\VeraCrypt.exe" "..\Debug\Setup Files\VeraCrypt Format.exe" "..\Debug\Setup Files\VeraCryptExpander.exe" "..\Debug\Setup Files\VeraCrypt-x64.exe" "..\Debug\Setup Files\VeraCrypt Format-x64.exe" "..\Debug\Setup Files\VeraCryptExpander-x64.exe" "..\Debug\Setup Files\VeraCrypt COMReg.exe" timeout /t 10 rem sign using SHA-256 -signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Debug\Setup Files\veracrypt.sys" "..\Debug\Setup Files\veracrypt-x64.sys" "..\Debug\Setup Files\veracrypt-arm64.sys" "..\Debug\Setup Files\VeraCrypt.exe" "..\Debug\Setup Files\VeraCrypt Format.exe" "..\Debug\Setup Files\VeraCryptExpander.exe" "..\Debug\Setup Files\VeraCrypt-x64.exe" "..\Debug\Setup Files\VeraCrypt Format-x64.exe" "..\Debug\Setup Files\VeraCryptExpander-x64.exe" "..\Debug\Setup Files\VeraCrypt-arm64.exe" "..\Debug\Setup Files\VeraCrypt Format-arm64.exe" "..\Debug\Setup Files\VeraCryptExpander-arm64.exe" +signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Debug\Setup Files\veracrypt.sys" "..\Debug\Setup Files\veracrypt-x64.sys" "..\Debug\Setup Files\veracrypt-arm64.sys" "..\Debug\Setup Files\VeraCrypt.exe" "..\Debug\Setup Files\VeraCrypt Format.exe" "..\Debug\Setup Files\VeraCryptExpander.exe" "..\Debug\Setup Files\VeraCrypt-x64.exe" "..\Debug\Setup Files\VeraCrypt Format-x64.exe" "..\Debug\Setup Files\VeraCryptExpander-x64.exe" "..\Debug\Setup Files\VeraCrypt-arm64.exe" "..\Debug\Setup Files\VeraCrypt Format-arm64.exe" "..\Debug\Setup Files\VeraCryptExpander-arm64.exe" "..\Debug\Setup Files\VeraCrypt COMReg.exe" +rem create setup and MSI cd "..\Debug\Setup Files\" - copy ..\..\LICENSE . copy ..\..\License.txt . copy ..\..\NOTICE . - +copy ..\..\Resources\Texts\License.rtf . +copy ..\..\Common\VeraCrypt.ico . +copy ..\..\Setup\VeraCrypt_setup_background.bmp . +copy ..\..\Setup\VeraCrypt_setup.bmp . +copy ..\..\Setup\Setup.ico . del *.xml rmdir /S /Q Languages mkdir Languages copy /V /Y ..\..\..\Translations\*.xml Languages\. del Languages.zip 7z a -y Languages.zip Languages - rmdir /S /Q docs mkdir docs\html\en mkdir docs\EFI-DCS @@ -43,17 +47,19 @@ copy "..\..\..\doc\chm\VeraCrypt User Guide.chm" docs\. copy "..\..\..\doc\EFI-DCS\*.pdf" docs\EFI-DCS\. copy "..\..\Release\Setup Files\*.cat" . copy "..\..\Release\Setup Files\veracrypt.inf" . - del docs.zip 7z a -y docs.zip docs - "VeraCrypt Setup.exe" /p - +call build_msi_x64.bat %VC_VERSION_NBRE% del LICENSE del License.txt del NOTICE +del License.rtf +del VeraCrypt.ico +del VeraCrypt_setup_background.bmp +del VeraCrypt_setup.bmp +del Setup.ico del "VeraCrypt User Guide.chm" - del Languages.zip del docs.zip rmdir /S /Q Languages @@ -61,12 +67,17 @@ rmdir /S /Q docs cd %SIGNINGPATH% +rem Can't dual-sign MSI files when using signtool (only jsign / osslsigncode can do that) + rem sign using SHA-1 -signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.verisign.com/scripts/timestamp.dll "..\Debug\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" +signtool sign /v /a /f %PFXNAME% /p %PFXPASSWORD% /ac %PFXCA% /fd sha1 /t http://timestamp.digicert.com "..\Debug\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" timeout /t 10 -rem sign using SHA-256 +rem dual-sign Setup using SHA-256 signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /as /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Debug\Setup Files\VeraCrypt Setup %VC_VERSION%.exe" +rem single sign MSI using SHA-256 +signtool sign /v /a /f %SHA256PFXNAME% /p %SHA256PFXPASSWORD% /ac %SHA256PFXCA% /fd sha256 /tr http://rfc3161timestamp.globalsign.com/advanced /td SHA256 "..\Debug\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64.msi" "..\Debug\Setup Files\bin\VeraCrypt_%VC_VERSION_NBRE%_Setup_x64_en-us.msi" + pause \ No newline at end of file diff --git a/src/VeraCrypt.sln b/src/VeraCrypt.sln index 6f373bcd..c7a31445 100644 --- a/src/VeraCrypt.sln +++ b/src/VeraCrypt.sln @@ -33,6 +33,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Portable", "Setup\Portable. {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC} = {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SetupDLL", "SetupDLL\SetupDLL.vcxproj", "{ADD324E2-ADC8-402E-87EB-03E4E26B1B49}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All CustomEFI|Win32 = All CustomEFI|Win32 @@ -73,6 +75,8 @@ Global Portable|x64 = Portable|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 + ReleaseCustomEFI|Win32 = ReleaseCustomEFI|Win32 + ReleaseCustomEFI|x64 = ReleaseCustomEFI|x64 Setup Debug|Win32 = Setup Debug|Win32 Setup Debug|x64 = Setup Debug|x64 Setup|Win32 = Setup|Win32 @@ -145,6 +149,9 @@ Global {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.Release|Win32.Build.0 = Release|Win32 {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.Release|x64.ActiveCfg = Release|x64 {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.Release|x64.Build.0 = Release|x64 + {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.ReleaseCustomEFI|Win32.ActiveCfg = Release|x64 + {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.ReleaseCustomEFI|x64.ActiveCfg = Release|x64 + {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.ReleaseCustomEFI|x64.Build.0 = Release|x64 {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.Setup Debug|x64.ActiveCfg = Debug|x64 {993245CF-6B70-47EE-91BB-39F8FC6DC0E7}.Setup Debug|x64.Build.0 = Debug|x64 @@ -200,6 +207,9 @@ Global {EF5EF444-18D0-40D7-8DFA-775EC4448602}.Release|Win32.ActiveCfg = Release|Win32 {EF5EF444-18D0-40D7-8DFA-775EC4448602}.Release|Win32.Build.0 = Release|Win32 {EF5EF444-18D0-40D7-8DFA-775EC4448602}.Release|x64.ActiveCfg = Release|Win32 + {EF5EF444-18D0-40D7-8DFA-775EC4448602}.ReleaseCustomEFI|Win32.ActiveCfg = Release|Win32 + {EF5EF444-18D0-40D7-8DFA-775EC4448602}.ReleaseCustomEFI|Win32.Build.0 = Release|Win32 + {EF5EF444-18D0-40D7-8DFA-775EC4448602}.ReleaseCustomEFI|x64.ActiveCfg = Release|Win32 {EF5EF444-18D0-40D7-8DFA-775EC4448602}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {EF5EF444-18D0-40D7-8DFA-775EC4448602}.Setup Debug|x64.ActiveCfg = Debug|Win32 {EF5EF444-18D0-40D7-8DFA-775EC4448602}.Setup|Win32.ActiveCfg = Release|Win32 @@ -268,6 +278,10 @@ Global {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.Release|Win32.Build.0 = Release|Win32 {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.Release|x64.ActiveCfg = Release|x64 {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.Release|x64.Build.0 = Release|x64 + {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.ReleaseCustomEFI|Win32.ActiveCfg = ReleaseCustomEFI|Win32 + {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.ReleaseCustomEFI|Win32.Build.0 = ReleaseCustomEFI|Win32 + {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.ReleaseCustomEFI|x64.ActiveCfg = ReleaseCustomEFI|x64 + {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.ReleaseCustomEFI|x64.Build.0 = ReleaseCustomEFI|x64 {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.Setup Debug|x64.ActiveCfg = Debug|x64 {9DC1ABE2-D18B-48FB-81D2-8C50ADC57BCF}.Setup Debug|x64.Build.0 = Debug|x64 @@ -338,6 +352,10 @@ Global {E4C40F94-E7F9-4981-86E4-186B46F993F3}.Release|Win32.Build.0 = Release|Win32 {E4C40F94-E7F9-4981-86E4-186B46F993F3}.Release|x64.ActiveCfg = Release|x64 {E4C40F94-E7F9-4981-86E4-186B46F993F3}.Release|x64.Build.0 = Release|x64 + {E4C40F94-E7F9-4981-86E4-186B46F993F3}.ReleaseCustomEFI|Win32.ActiveCfg = ReleaseCustomEFI|Win32 + {E4C40F94-E7F9-4981-86E4-186B46F993F3}.ReleaseCustomEFI|Win32.Build.0 = ReleaseCustomEFI|Win32 + {E4C40F94-E7F9-4981-86E4-186B46F993F3}.ReleaseCustomEFI|x64.ActiveCfg = ReleaseCustomEFI|x64 + {E4C40F94-E7F9-4981-86E4-186B46F993F3}.ReleaseCustomEFI|x64.Build.0 = ReleaseCustomEFI|x64 {E4C40F94-E7F9-4981-86E4-186B46F993F3}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {E4C40F94-E7F9-4981-86E4-186B46F993F3}.Setup Debug|x64.ActiveCfg = Debug|x64 {E4C40F94-E7F9-4981-86E4-186B46F993F3}.Setup Debug|x64.Build.0 = Debug|x64 @@ -389,6 +407,9 @@ Global {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.Release|Win32.ActiveCfg = Release|Win32 {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.Release|Win32.Build.0 = Release|Win32 {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.Release|x64.ActiveCfg = Release|Win32 + {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.ReleaseCustomEFI|Win32.ActiveCfg = ReleaseCustomEFI|Win32 + {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.ReleaseCustomEFI|Win32.Build.0 = ReleaseCustomEFI|Win32 + {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.ReleaseCustomEFI|x64.ActiveCfg = ReleaseCustomEFI|Win32 {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.Setup Debug|Win32.Build.0 = Debug|Win32 {DF5F654D-BD44-4E31-B92E-B68074DC37A8}.Setup Debug|x64.ActiveCfg = Debug|Win32 @@ -440,6 +461,9 @@ Global {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.Release|Win32.ActiveCfg = Release|Win32 {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.Release|Win32.Build.0 = Release|Win32 {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.Release|x64.ActiveCfg = Release|Win32 + {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.ReleaseCustomEFI|Win32.ActiveCfg = Release|Win32 + {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.ReleaseCustomEFI|Win32.Build.0 = Release|Win32 + {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.ReleaseCustomEFI|x64.ActiveCfg = Release|Win32 {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.Setup Debug|Win32.ActiveCfg = Release|Win32 {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.Setup Debug|x64.ActiveCfg = Release Loader|Win32 {8B7F059F-E4C7-4E11-88F5-EE8B8433072E}.Setup|Win32.ActiveCfg = Release|Win32 @@ -518,6 +542,10 @@ Global {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.Release|Win32.Build.0 = Release|Win32 {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.Release|x64.ActiveCfg = Release|x64 {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.Release|x64.Build.0 = Release|x64 + {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.ReleaseCustomEFI|Win32.ActiveCfg = ReleaseCustomEFI|Win32 + {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.ReleaseCustomEFI|Win32.Build.0 = ReleaseCustomEFI|Win32 + {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.ReleaseCustomEFI|x64.ActiveCfg = ReleaseCustomEFI|x64 + {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.ReleaseCustomEFI|x64.Build.0 = ReleaseCustomEFI|x64 {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.Setup Debug|Win32.Build.0 = Debug|Win32 {9715FF1D-599B-4BBC-AD96-BEF6E08FF827}.Setup Debug|x64.ActiveCfg = Debug|x64 @@ -585,6 +613,9 @@ Global {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.Release|Win32.ActiveCfg = Release|Win32 {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.Release|Win32.Build.0 = Release|Win32 {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.Release|x64.ActiveCfg = Release|Win32 + {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.ReleaseCustomEFI|Win32.ActiveCfg = Release|x64 + {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.ReleaseCustomEFI|x64.ActiveCfg = Release|x64 + {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.ReleaseCustomEFI|x64.Build.0 = Release|x64 {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.Setup Debug|Win32.Build.0 = Debug|Win32 {6316EE71-0210-4CA4-BCC7-CFB7A3C090FC}.Setup Debug|x64.ActiveCfg = Debug|Win32 @@ -648,12 +679,81 @@ Global {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Release|Win32.ActiveCfg = Release|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Release|Win32.Build.0 = Release|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Release|x64.ActiveCfg = Release|Win32 + {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.ReleaseCustomEFI|Win32.ActiveCfg = ReleaseCustomEFI|Win32 + {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.ReleaseCustomEFI|Win32.Build.0 = ReleaseCustomEFI|Win32 + {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.ReleaseCustomEFI|x64.ActiveCfg = ReleaseCustomEFI|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Setup Debug|Win32.ActiveCfg = Debug|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Setup Debug|Win32.Build.0 = Debug|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Setup Debug|x64.ActiveCfg = Debug|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Setup|Win32.ActiveCfg = Release|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Setup|Win32.Build.0 = Release|Win32 {60698D56-DB83-4D19-9C87-9DFB6A6F8C87}.Setup|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All CustomEFI|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All CustomEFI|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All CustomEFI|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.All|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Boot Loader|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Boot Loader|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Boot Loader|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Boot|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Boot|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Boot|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x64 Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x64 Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x64 Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x64|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x64|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x64|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x86 Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x86 Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x86 Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x86|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x86|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver x86|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Driver|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Format Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Format Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Format Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Format|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Format|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Format|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Mount Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Mount Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Mount Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Mount|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Mount|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Mount|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Portable Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Portable Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Portable Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Portable|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Portable|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Portable|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Release|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Release|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Release|x64.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.ReleaseCustomEFI|Win32.ActiveCfg = ReleaseCustomEFI|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.ReleaseCustomEFI|Win32.Build.0 = ReleaseCustomEFI|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.ReleaseCustomEFI|x64.ActiveCfg = ReleaseCustomEFI|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Setup Debug|Win32.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Setup Debug|Win32.Build.0 = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Setup Debug|x64.ActiveCfg = Debug|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Setup|Win32.ActiveCfg = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Setup|Win32.Build.0 = Release|Win32 + {ADD324E2-ADC8-402E-87EB-03E4E26B1B49}.Setup|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE