From fc37cc4a02ed13d1a73b941a9f80975600fd1b99 Mon Sep 17 00:00:00 2001 From: David Foerster Date: Tue, 10 May 2016 20:20:14 +0200 Subject: Normalize all line terminators --- src/Setup/Setup.c | 5264 ++++++++++++++++++++++++++--------------------------- 1 file changed, 2632 insertions(+), 2632 deletions(-) (limited to 'src/Setup/Setup.c') diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c index 7c382986..899c1583 100644 --- a/src/Setup/Setup.c +++ b/src/Setup/Setup.c @@ -1,2632 +1,2632 @@ -/* - 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-2016 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 "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 "SelfExtract.h" -#include "Wizard.h" - -#include "../Common/Resource.h" - -using namespace VeraCrypt; - -#pragma warning( disable : 4201 ) -#pragma warning( disable : 4115 ) - -#include - -#pragma warning( default : 4201 ) -#pragma warning( default : 4115 ) - -#include - -wchar_t InstallationPath[TC_MAX_PATH]; -wchar_t SetupFilesDir[TC_MAX_PATH]; -wchar_t UninstallBatch[MAX_PATH]; - -BOOL bUninstall = FALSE; -BOOL bRestartRequired = FALSE; -BOOL bMakePackage = FALSE; -BOOL bDone = FALSE; -BOOL Rollback = FALSE; -BOOL bUpgrade = FALSE; -BOOL bDowngrade = FALSE; -BOOL SystemEncryptionUpdate = FALSE; -BOOL PortableMode = FALSE; -BOOL bRepairMode = FALSE; -BOOL bReinstallMode = FALSE; -BOOL bChangeMode = FALSE; -BOOL bDevm = FALSE; -BOOL bPossiblyFirstTimeInstall = FALSE; -BOOL bUninstallInProgress = FALSE; -BOOL UnloadDriver = TRUE; - -BOOL bSystemRestore = TRUE; -BOOL bDisableSwapFiles = FALSE; -BOOL bForAllUsers = TRUE; -BOOL bRegisterFileExt = TRUE; -BOOL bAddToStartMenu = TRUE; -BOOL bDesktopIcon = TRUE; - -BOOL bDesktopIconStatusDetermined = FALSE; - -HMODULE volatile SystemRestoreDll = 0; - -void localcleanup (void) -{ - localcleanupwiz (); - cleanup (); - - CloseAppSetupMutex (); -} - -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; -} - -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; -} - -BOOL StatRemoveDirectory (wchar_t *lpszDir) -{ - struct __stat64 st; - - if (_wstat64 (lpszDir, &st) == 0) - { - BOOL bStatus = RemoveDirectory (lpszDir); - if (!bStatus) - { - /* force removal of the non empty directory */ - wchar_t szOpPath[TC_MAX_PATH + 1] = {0}; - SHFILEOPSTRUCTW op; - - StringCchCopyW(szOpPath, ARRAYSIZE(szOpPath)-1, lpszDir); - ZeroMemory(&op, sizeof(op)); - op.wFunc = FO_DELETE; - op.pFrom = szOpPath; - op.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR; - - if ((0 == SHFileOperation(&op)) && (!op.fAnyOperationsAborted)) - bStatus = TRUE; - } - return bStatus; - } - else - return TRUE; -} - - -/* Recursively set the given OWNER security descriptor to the key and its subkeys */ -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); -} - -/* Recursively set the given DACL security descriptor to the key and its subkeys */ -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; - } - } -} - -/* Correct the key permissions to allow its deletion */ -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); -} - -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); - } - } - } -} - -/* Set the given privilege of the current process */ -BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable) -{ - TOKEN_PRIVILEGES tp; - LUID luid; - HANDLE hProcessToken; - BOOL bStatus = FALSE; - - if ( OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - &hProcessToken) ) - { - if ( LookupPrivilegeValue( - NULL, - szPrivilegeName, - &luid ) ) - { - - tp.PrivilegeCount = 1; - tp.Privileges[0].Luid = luid; - tp.Privileges[0].Attributes = bEnable? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED; - - // Enable the privilege - bStatus = AdjustTokenPrivileges( - hProcessToken, - FALSE, - &tp, - sizeof(TOKEN_PRIVILEGES), - (PTOKEN_PRIVILEGES) NULL, - (PDWORD) NULL); - } - - CloseHandle(hProcessToken); - } - - return bStatus; -} - -/* - * Creates a VT_LPWSTR propvariant. - * we use our own implementation to use SHStrDupW function pointer - * that we retreive ourselves to avoid dll hijacking attacks - */ -inline HRESULT VCInitPropVariantFromString(__in PCWSTR psz, __out PROPVARIANT *ppropvar) -{ - ppropvar->vt = VT_LPWSTR; - HRESULT hr = VCStrDupW(psz, &ppropvar->pwszVal); - if (FAILED(hr)) - { - PropVariantInit(ppropvar); - } - return hr; -} - -HRESULT CreateLink (wchar_t *lpszPathObj, wchar_t *lpszArguments, - wchar_t *lpszPathLink, const wchar_t* iconFile, int iconIndex) -{ - HRESULT hres; - IShellLink *psl; - - /* Get a pointer to the IShellLink interface. */ - hres = CoCreateInstance (CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); - if (SUCCEEDED (hres)) - { - IPersistFile *ppf; - - /* Set the path to the shortcut target, and add the - description. */ - psl->SetPath (lpszPathObj); - psl->SetArguments (lpszArguments); - if (iconFile) - { - psl->SetIconLocation (iconFile, iconIndex); - } - - // Application ID - if (_tcsstr (lpszPathObj, _T(TC_APP_NAME) _T(".exe"))) - { - IPropertyStore *propStore; - - if (SUCCEEDED (psl->QueryInterface (IID_PPV_ARGS (&propStore)))) - { - PROPVARIANT propVariant; - if (SUCCEEDED (VCInitPropVariantFromString (TC_APPLICATION_ID, &propVariant))) - { - if (SUCCEEDED (propStore->SetValue (PKEY_AppUserModel_ID, propVariant))) - propStore->Commit(); - - PropVariantClear (&propVariant); - } - - propStore->Release(); - } - } - - /* Query IShellLink for the IPersistFile interface for saving - the shortcut in persistent storage. */ - hres = psl->QueryInterface (IID_IPersistFile, - (void **) &ppf); - - if (SUCCEEDED (hres)) - { - /* Save the link by calling IPersistFile::Save. */ - hres = ppf->Save (lpszPathLink, TRUE); - ppf->Release (); - } - psl->Release (); - } - return hres; -} - -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; -} - -void GetProgramPath (HWND hwndDlg, wchar_t *path) -{ - ITEMIDLIST *i; - HRESULT res; - - if (bForAllUsers) - res = SHGetSpecialFolderLocation (hwndDlg, CSIDL_COMMON_PROGRAMS, &i); - else - res = SHGetSpecialFolderLocation (hwndDlg, CSIDL_PROGRAMS, &i); - - SHGetPathFromIDList (i, path); -} - -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); -} - -void StatusMessageParam (HWND hwndDlg, char *stringId, wchar_t *param) -{ - wchar_t szTmp[1024]; - - if (Rollback) - return; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s %s", GetString (stringId), param); - SendMessageW (GetDlgItem (hwndDlg, IDC_LOG_WINDOW), LB_ADDSTRING, 0, (LPARAM) szTmp); - - SendDlgItemMessage (hwndDlg, IDC_LOG_WINDOW, LB_SETTOPINDEX, - SendDlgItemMessage (hwndDlg, IDC_LOG_WINDOW, LB_GETCOUNT, 0, 0) - 1, 0); -} - -void ClearLogWindow (HWND hwndDlg) -{ - SendMessage (GetDlgItem (hwndDlg, IDC_LOG_WINDOW), LB_RESETCONTENT, 0, 0); -} - -void RegMessage (HWND hwndDlg, wchar_t *txt) -{ - StatusMessageParam (hwndDlg, "ADDING_REG", txt); -} - -void CopyMessage (HWND hwndDlg, wchar_t *txt) -{ - StatusMessageParam (hwndDlg, "INSTALLING", txt); -} - -void RemoveMessage (HWND hwndDlg, wchar_t *txt) -{ - if (!Rollback) - StatusMessageParam (hwndDlg, "REMOVING", txt); -} - -void IconMessage (HWND hwndDlg, wchar_t *txt) -{ - StatusMessageParam (hwndDlg, "ADDING_ICON", txt); -} - -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; -} - - -static BOOL IsFileInUse (const wstring &filePath) -{ - HANDLE useTestHandle = CreateFile (filePath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - - if (useTestHandle != INVALID_HANDLE_VALUE) - CloseHandle (useTestHandle); - else if (GetLastError() == ERROR_SHARING_VIOLATION) - return TRUE; - - return FALSE; -} - - -BOOL DoFilesInstall (HWND hwndDlg, wchar_t *szDestDir) -{ - /* WARNING: Note that, despite its name, this function is used during UNinstallation as well. */ - - wchar_t szTmp[TC_MAX_PATH]; - BOOL bOK = TRUE; - int i, x, fileNo; - wchar_t curFileName [TC_MAX_PATH] = {0}; - - if (!bUninstall && !bDevm) - { - // Self-extract all files to memory - - GetModuleFileName (NULL, szTmp, ARRAYSIZE (szTmp)); - - if (!SelfExtractInMemory (szTmp)) - return FALSE; - } - - x = wcslen (szDestDir); - if (x < 2) - return FALSE; - - if (szDestDir[x - 1] != L'\\') - StringCbCatW (szDestDir, MAX_PATH, L"\\"); - - for (i = 0; i < sizeof (szFiles) / sizeof (szFiles[0]); i++) - { - BOOL bResult, driver64 = FALSE; - wchar_t szDir[TC_MAX_PATH]; - - if (wcsstr (szFiles[i], L"VeraCrypt Setup") != 0) - { - if (bUninstall) - continue; // Prevent 'access denied' error - - if (bRepairMode) - continue; // Destination = target - } - - // skip files that don't apply to the current architecture - if ( (Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt-x64.exe") == 0)) - || (Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCryptExpander-x64.exe") == 0)) - || (Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt Format-x64.exe") == 0)) - || (!Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt-x86.exe") == 0)) - || (!Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCryptExpander-x86.exe") == 0)) - || (!Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt Format-x86.exe") == 0)) - ) - { - continue; - } - - if (*szFiles[i] == L'A') - StringCbCopyW (szDir, sizeof(szDir), szDestDir); - else if (*szFiles[i] == L'D') - { - if (Is64BitOs ()) - driver64 = TRUE; - - GetSystemDirectory (szDir, ARRAYSIZE (szDir)); - - x = wcslen (szDir); - if (szDir[x - 1] != L'\\') - StringCbCatW (szDir, sizeof(szDir), L"\\"); - - StringCbCatW (szDir, sizeof(szDir), L"Drivers\\"); - } - else if (*szFiles[i] == L'W') - GetWindowsDirectory (szDir, ARRAYSIZE (szDir)); - - if (*szFiles[i] == L'I') - continue; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, szFiles[i] + 1); - - if (bUninstall == FALSE) - CopyMessage (hwndDlg, szTmp); - else - RemoveMessage (hwndDlg, szTmp); - - if (bUninstall == FALSE) - { - SetCurrentDirectory (SetupFilesDir); - - if (wcsstr (szFiles[i], L"VeraCrypt Setup") != 0) - { - // Copy ourselves (the distribution package) to the destination location as 'VeraCrypt Setup.exe' - - wchar_t mp[MAX_PATH]; - - GetModuleFileName (NULL, mp, ARRAYSIZE (mp)); - bResult = TCCopyFile (mp, szTmp); - } - else - { - StringCchCopyNW (curFileName, ARRAYSIZE(curFileName), szFiles[i] + 1, wcslen (szFiles[i]) - 1); - curFileName [wcslen (szFiles[i]) - 1] = 0; - - if (Is64BitOs () - && wcscmp (szFiles[i], L"Dveracrypt.sys") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), FILENAME_64BIT_DRIVER, sizeof (FILENAME_64BIT_DRIVER)); - } - - if (Is64BitOs () - && wcscmp (szFiles[i], L"AVeraCrypt.exe") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt-x64.exe", sizeof (L"VeraCrypt-x64.exe")); - } - - if (Is64BitOs () - && wcscmp (szFiles[i], L"AVeraCrypt-x86.exe") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt.exe", sizeof (L"VeraCrypt.exe")); - } - - if (Is64BitOs () - && wcscmp (szFiles[i], L"AVeraCryptExpander.exe") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCryptExpander-x64.exe", sizeof (L"VeraCryptExpander-x64.exe")); - } - - if (Is64BitOs () - && wcscmp (szFiles[i], L"AVeraCryptExpander-x86.exe") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCryptExpander.exe", sizeof (L"VeraCryptExpander.exe")); - } - - if (Is64BitOs () - && wcscmp (szFiles[i], L"AVeraCrypt Format.exe") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt Format-x64.exe", sizeof (L"VeraCrypt Format-x64.exe")); - } - - if (Is64BitOs () - && wcscmp (szFiles[i], L"AVeraCrypt Format-x86.exe") == 0) - { - StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt Format.exe", sizeof (L"VeraCrypt Format.exe")); - } - - if (!bDevm) - { - bResult = FALSE; - - // Find the correct decompressed file in memory - for (fileNo = 0; fileNo < NBR_COMPRESSED_FILES; fileNo++) - { - // Write the file (stored in memory) directly to the destination location - // (there will be no temporary files). - if (wmemcmp ( - curFileName, - Decompressed_Files[fileNo].fileName, - min (wcslen (curFileName), (size_t) Decompressed_Files[fileNo].fileNameLength)) == 0) - { - // Dump filter driver cannot be installed to SysWOW64 directory - if (driver64 && !EnableWow64FsRedirection (FALSE)) - { - handleWin32Error (hwndDlg, SRC_POS); - bResult = FALSE; - goto err; - } - - bResult = SaveBufferToFile ( - (char *) Decompressed_Files[fileNo].fileContent, - szTmp, - Decompressed_Files[fileNo].fileLength, - FALSE, - TRUE); - - if (driver64) - { - if (!EnableWow64FsRedirection (TRUE)) - { - handleWin32Error (hwndDlg, SRC_POS); - bResult = FALSE; - goto err; - } - - if (!bResult) - goto err; - - } - - break; - } - } - } - else - { - if (driver64) - EnableWow64FsRedirection (FALSE); - - bResult = TCCopyFile (curFileName, szTmp); - - if (driver64) - EnableWow64FsRedirection (TRUE); - } - - if (bResult && wcscmp (szFiles[i], L"AVeraCrypt.exe") == 0) - { - 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 ( FileExists (servicePath.c_str()) - || (Is64BitOs () && FileExists (serviceLegacyPath.c_str())) - ) - { - CopyMessage (hwndDlg, (wchar_t *) servicePath.c_str()); - bResult = CopyFile (szTmp, servicePath.c_str(), FALSE); - } - - if (bResult && 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); - } - - if (bResult && Is64BitOs () && FileExists (favoritesFile.c_str()) && FileExists (servicePath.c_str())) - { - // Update the path of the service - BootEncryption BootEncObj (hwndDlg); - - try - { - if (BootEncObj.GetDriverServiceStartType() == SERVICE_BOOT_START) - { - BootEncObj.UpdateSystemFavoritesService (); - } - } - catch (...) {} - } - - if (Is64BitOs ()) - { - // delete files from legacy path - if (FileExists (favoritesLegacyFile.c_str())) - { - RemoveMessage (hwndDlg, (wchar_t *) favoritesLegacyFile.c_str()); - ForceDeleteFile (favoritesLegacyFile.c_str()); - } - - if (FileExists (serviceLegacyPath.c_str())) - { - RemoveMessage (hwndDlg, (wchar_t *) serviceLegacyPath.c_str()); - ForceDeleteFile (serviceLegacyPath.c_str()); - } - - EnableWow64FsRedirection (TRUE); - } - } - } - } - else - { - if (driver64) - EnableWow64FsRedirection (FALSE); - bResult = StatDeleteFile (szTmp, TRUE); - if (driver64) - EnableWow64FsRedirection (TRUE); - - if (bResult && wcscmp (szFiles[i], L"AVeraCrypt.exe") == 0) - { - 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())) - { - RemoveMessage (hwndDlg, (wchar_t *) favoritesFile.c_str()); - ForceDeleteFile (favoritesFile.c_str()); - } - - if (FileExists (servicePath.c_str())) - { - RemoveMessage (hwndDlg, (wchar_t *) servicePath.c_str()); - ForceDeleteFile (servicePath.c_str()); - } - - if (Is64BitOs ()) - { - if (FileExists (favoritesLegacyFile.c_str())) - { - RemoveMessage (hwndDlg, (wchar_t *) favoritesLegacyFile.c_str()); - ForceDeleteFile (favoritesLegacyFile.c_str()); - } - - if (FileExists (serviceLegacyPath.c_str())) - { - RemoveMessage (hwndDlg, (wchar_t *) serviceLegacyPath.c_str()); - ForceDeleteFile (serviceLegacyPath.c_str()); - } - - EnableWow64FsRedirection (TRUE); - } - } - } - -err: - 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) - return FALSE; - } - } - - // Language pack - if (bUninstall == FALSE) - { - WIN32_FIND_DATA f; - HANDLE h; - - SetCurrentDirectory (SetupFilesDir); - h = FindFirstFile (L"Language.*.xml", &f); - - if (h != INVALID_HANDLE_VALUE) - { - wchar_t d[MAX_PATH*2]; - StringCbPrintfW (d, sizeof(d), L"%s%s", szDestDir, f.cFileName); - CopyMessage (hwndDlg, d); - TCCopyFile (f.cFileName, d); - FindClose (h); - } - - SetCurrentDirectory (SetupFilesDir); - SetCurrentDirectory (L"Setup files"); - h = FindFirstFile (L"VeraCrypt User Guide.*.pdf", &f); - if (h != INVALID_HANDLE_VALUE) - { - wchar_t d[MAX_PATH*2]; - StringCbPrintfW (d, sizeof(d), L"%s%s", szDestDir, f.cFileName); - CopyMessage (hwndDlg, d); - TCCopyFile (f.cFileName, d); - FindClose (h); - } - SetCurrentDirectory (SetupFilesDir); - } - - return bOK; -} - -BOOL DoRegInstall (HWND hwndDlg, wchar_t *szDestDir, BOOL bInstallType) -{ - wchar_t szDir[TC_MAX_PATH], *key; - wchar_t szTmp[TC_MAX_PATH*4]; - HKEY hkey = 0; - BOOL bSlash, bOK = FALSE; - DWORD dw; - int x; - - if (SystemEncryptionUpdate) - { - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", - 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_32KEY, NULL, &hkey, &dw) == ERROR_SUCCESS) - { - StringCbCopyW (szTmp, sizeof(szTmp), _T(VERSION_STRING)); - RegSetValueEx (hkey, L"DisplayVersion", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)); - - StringCbCopyW (szTmp, sizeof(szTmp), _T(TC_HOMEPAGE)); - RegSetValueEx (hkey, L"URLInfoAbout", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)); - - RegCloseKey (hkey); - } - - return TRUE; - } - - StringCbCopyW (szDir, sizeof(szDir), szDestDir); - x = wcslen (szDestDir); - if (szDestDir[x - 1] == L'\\') - bSlash = TRUE; - else - bSlash = FALSE; - - if (bSlash == FALSE) - StringCbCatW (szDir, sizeof(szDir), L"\\"); - - if (bInstallType) - { - - key = L"Software\\Classes\\VeraCryptVolume"; - RegMessage (hwndDlg, key); - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - key, - 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) - goto error; - - StringCbCopyW (szTmp, sizeof(szTmp), L"VeraCrypt Volume"); - if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%ws", TC_APPLICATION_ID); - if (RegSetValueEx (hkey, L"AppUserModelID", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - RegCloseKey (hkey); - hkey = 0; - - key = L"Software\\Classes\\VeraCryptVolume\\DefaultIcon"; - RegMessage (hwndDlg, key); - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - key, - 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%sVeraCrypt.exe,1", szDir); - if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - RegCloseKey (hkey); - hkey = 0; - - key = L"Software\\Classes\\VeraCryptVolume\\Shell\\open\\command"; - RegMessage (hwndDlg, key); - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - key, - 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt.exe\" /v \"%%1\"", szDir ); - if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - RegCloseKey (hkey); - hkey = 0; - - key = L"Software\\Classes\\.hc"; - BOOL typeClassChanged = TRUE; - wchar_t typeClass[256]; - DWORD typeClassSize = sizeof (typeClass); - - if (ReadLocalMachineRegistryString (key, L"", typeClass, &typeClassSize) && typeClassSize > 0 && wcscmp (typeClass, L"VeraCryptVolume") == 0) - typeClassChanged = FALSE; - - RegMessage (hwndDlg, key); - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - key, - 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) - goto error; - - StringCbCopyW (szTmp, sizeof(szTmp), L"VeraCryptVolume"); - if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - RegCloseKey (hkey); - hkey = 0; - - if (typeClassChanged) - SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); - } - - key = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt"; - RegMessage (hwndDlg, key); - if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, - key, - 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_32KEY, NULL, &hkey, &dw) != ERROR_SUCCESS) - goto error; - - /* IMPORTANT: IF YOU CHANGE THIS IN ANY WAY, REVISE AND UPDATE SetInstallationPath() ACCORDINGLY! */ - StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt Setup.exe\" /u", szDir); - if (RegSetValueEx (hkey, L"UninstallString", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt Setup.exe\" /c", szDir); - if (RegSetValueEx (hkey, L"ModifyPath", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt Setup.exe\"", szDir); - if (RegSetValueEx (hkey, L"DisplayIcon", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbCopyW (szTmp, sizeof(szTmp), _T(VERSION_STRING)); - if (RegSetValueEx (hkey, L"DisplayVersion", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbCopyW (szTmp, sizeof(szTmp), L"VeraCrypt"); - if (RegSetValueEx (hkey, L"DisplayName", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbCopyW (szTmp, sizeof(szTmp), L"IDRIX"); - if (RegSetValueEx (hkey, L"Publisher", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - StringCbCopyW (szTmp, sizeof(szTmp), _T(TC_HOMEPAGE)); - if (RegSetValueEx (hkey, L"URLInfoAbout", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) - goto error; - - bOK = TRUE; - -error: - if (hkey != 0) - RegCloseKey (hkey); - - if (bOK == FALSE) - { - handleWin32Error (hwndDlg, SRC_POS); - Error ("REG_INSTALL_FAILED", hwndDlg); - } - - // Register COM servers for UAC - if (IsOSAtLeast (WIN_VISTA)) - { - if (!RegisterComServers (szDir)) - { - Error ("COM_REG_FAILED", hwndDlg); - return FALSE; - } - } - - return bOK; -} - -BOOL DoApplicationDataUninstall (HWND hwndDlg) -{ - wchar_t path[MAX_PATH]; - wchar_t path2[MAX_PATH]; - BOOL bOK = TRUE; - - StatusMessage (hwndDlg, "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); - RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2, FALSE); - - // Delete keyfile defaults - StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_DEFAULT_KEYFILES); - RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2, FALSE); - - // Delete history file - StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_HISTORY); - RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2, FALSE); - - // Delete configuration file - StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_CONFIGURATION); - RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2, FALSE); - - // Delete system encryption configuration file - StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION); - RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2, FALSE); - - SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); - StringCbCatW (path, sizeof(path), L"\\VeraCrypt"); - RemoveMessage (hwndDlg, path); - if (!StatRemoveDirectory (path)) - { - handleWin32Error (hwndDlg, 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); - RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2, FALSE); - - // remove VeraCrypt folder - RemoveMessage (hwndDlg, path); - StatRemoveDirectory (path); - } - - - return bOK; -} - -BOOL DoRegUninstall (HWND hwndDlg, BOOL bRemoveDeprecated) -{ - 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)) - StatusMessage (hwndDlg, "COM_DEREG_FAILED"); - } - - if (!bRemoveDeprecated) - StatusMessage (hwndDlg, "REMOVING_REG"); - - 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"); - - 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); - - SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); - } - - if (hAdvapiDll) - FreeLibrary (hAdvapiDll); - - return TRUE; -} - - -BOOL DoServiceUninstall (HWND hwndDlg, wchar_t *lpszService) -{ - SC_HANDLE hManager, hService = NULL; - BOOL bOK = FALSE, bRet; - SERVICE_STATUS status; - BOOL firstTry = TRUE; - int x; - - 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 (...) { } - - StatusMessage (hwndDlg, "STOPPING_DRIVER"); - } - else - StatusMessageParam (hwndDlg, "STOPPING", lpszService); - -#define WAIT_PERIOD 3 - - 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) - StatusMessage (hwndDlg, "REMOVING_DRIVER"); - else - StatusMessageParam (hwndDlg, "REMOVING", 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 (hwndDlg, SRC_POS); - MessageBoxW (hwndDlg, GetString ("DRIVER_UINSTALL_FAILED"), lpszTitle, MB_ICONHAND); - } - else - bOK = TRUE; - - if (hService != NULL) - CloseServiceHandle (hService); - - if (hManager != NULL) - CloseServiceHandle (hManager); - - return bOK; -} - - -BOOL DoDriverUnload (HWND hwndDlg) -{ - BOOL bOK = TRUE; - int status; - - status = DriverAttach (); - if (status != 0) - { - if (status == ERR_OS_ERROR && GetLastError () != ERROR_FILE_NOT_FOUND) - { - handleWin32Error (hwndDlg, SRC_POS); - AbortProcess ("NODRIVER"); - } - - if (status != ERR_OS_ERROR) - { - handleError (NULL, status, SRC_POS); - AbortProcess ("NODRIVER"); - } - } - - 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 (hwndDlg); - 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", hwndDlg) == IDNO) - AbortProcessSilent (); - } - } - } - 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) - { - Error (bDowngrade ? "SETUP_FAILED_BOOT_DRIVE_ENCRYPTED_DOWNGRADE" : "SETUP_FAILED_BOOT_DRIVE_ENCRYPTED", hwndDlg); - return FALSE; - } - else - { - if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1) - AbortProcess ("SYS_ENCRYPTION_UPGRADE_UNSUPPORTED_ON_VISTA_SP0"); - - 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; - MessageBoxW (hwndDlg, GetString ("DISMOUNT_ALL_FIRST"), lpszTitle, MB_ICONHAND); - } - } - else - { - bOK = FALSE; - handleWin32Error (hwndDlg, 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) - { - MessageBoxW (hwndDlg, GetString ("CLOSE_TC_FIRST"), lpszTitle, MB_ICONSTOP); - 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; - } - - return bOK; -} - - -BOOL UpgradeBootLoader (HWND hwndDlg) -{ - if (!SystemEncryptionUpdate) - return TRUE; - - try - { - BootEncryption bootEnc (hwndDlg); - uint64 bootLoaderVersion = bootEnc.GetInstalledBootLoaderVersion(); - if ((bootLoaderVersion < VERSION_NUM) || (bReinstallMode && (bootLoaderVersion == VERSION_NUM))) - { - StatusMessage (hwndDlg, "INSTALLER_UPDATING_BOOT_LOADER"); - - bootEnc.InstallBootLoader (true); - - if (bootEnc.GetInstalledBootLoaderVersion() <= TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION) - Info (IsHiddenOSRunning() ? "BOOT_LOADER_UPGRADE_OK_HIDDEN_OS" : "BOOT_LOADER_UPGRADE_OK", hwndDlg); - } - return TRUE; - } - catch (Exception &e) - { - e.Show (hwndDlg); - } - catch (...) { } - - Error ("BOOT_LOADER_UPGRADE_FAILED", hwndDlg); - return FALSE; -} - - -BOOL DoShortcutsUninstall (HWND hwndDlg, wchar_t *szDestDir) -{ - wchar_t szLinkDir[TC_MAX_PATH]; - wchar_t szTmp2[TC_MAX_PATH]; - BOOL bSlash, bOK = FALSE; - HRESULT hOle; - int x; - BOOL allUsers = FALSE; - - hOle = OleInitialize (NULL); - - // User start menu - SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_PROGRAMS, 0); - x = wcslen (szLinkDir); - if (szLinkDir[x - 1] == L'\\') - bSlash = TRUE; - else - bSlash = FALSE; - - if (bSlash == FALSE) - StringCbCatW (szLinkDir, sizeof(szLinkDir), L"\\"); - - StringCbCatW (szLinkDir, sizeof(szLinkDir), L"VeraCrypt"); - - // Global start menu - { - struct _stat st; - wchar_t path[TC_MAX_PATH]; - - SHGetSpecialFolderPath (hwndDlg, path, CSIDL_COMMON_PROGRAMS, 0); - StringCbCatW (path, sizeof(path), L"\\VeraCrypt"); - - if (_wstat (path, &st) == 0) - { - StringCbCopyW (szLinkDir, sizeof(szLinkDir), path); - allUsers = TRUE; - } - } - - // Start menu entries - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); - RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2, FALSE) == FALSE) - goto error; - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCryptExpander.lnk"); - RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2, FALSE) == FALSE) - goto error; - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt Website.url"); - RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2, FALSE) == FALSE) - goto error; - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\Uninstall VeraCrypt.lnk"); - RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2, FALSE) == FALSE) - goto error; - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt User's Guide.lnk"); - StatDeleteFile (szTmp2, FALSE); - - // Start menu group - RemoveMessage ((HWND) hwndDlg, szLinkDir); - if (StatRemoveDirectory (szLinkDir) == FALSE) - handleWin32Error ((HWND) hwndDlg, SRC_POS); - - // Desktop icon - - if (allUsers) - SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_COMMON_DESKTOPDIRECTORY, 0); - else - SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_DESKTOPDIRECTORY, 0); - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); - - RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2, FALSE) == FALSE) - goto error; - - bOK = TRUE; - -error: - OleUninitialize (); - - return bOK; -} - -BOOL DoShortcutsInstall (HWND hwndDlg, wchar_t *szDestDir, BOOL bProgGroup, BOOL bDesktopIcon) -{ - wchar_t szLinkDir[TC_MAX_PATH], szDir[TC_MAX_PATH]; - wchar_t szTmp[TC_MAX_PATH], szTmp2[TC_MAX_PATH], szTmp3[TC_MAX_PATH]; - BOOL bSlash, bOK = FALSE; - HRESULT hOle; - int x; - - if (bProgGroup == FALSE && bDesktopIcon == FALSE) - return TRUE; - - hOle = OleInitialize (NULL); - - GetProgramPath (hwndDlg, szLinkDir); - - x = wcslen (szLinkDir); - if (szLinkDir[x - 1] == L'\\') - bSlash = TRUE; - else - bSlash = FALSE; - - if (bSlash == FALSE) - StringCbCatW (szLinkDir, sizeof(szLinkDir), L"\\"); - - StringCbCatW (szLinkDir, sizeof(szLinkDir), L"VeraCrypt"); - - StringCbCopyW (szDir, sizeof(szDir), szDestDir); - x = wcslen (szDestDir); - if (szDestDir[x - 1] == L'\\') - bSlash = TRUE; - else - bSlash = FALSE; - - if (bSlash == FALSE) - StringCbCatW (szDir, sizeof(szDir), L"\\"); - - if (bProgGroup) - { - FILE *f; - - if (mkfulldir (szLinkDir, TRUE) != 0) - { - if (mkfulldir (szLinkDir, FALSE) != 0) - { - wchar_t szTmpW[TC_MAX_PATH]; - - handleWin32Error (hwndDlg, SRC_POS); - StringCbPrintfW (szTmpW, sizeof(szTmpW), GetString ("CANT_CREATE_FOLDER"), szLinkDir); - MessageBoxW (hwndDlg, szTmpW, lpszTitle, MB_ICONHAND); - goto error; - } - } - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCrypt.exe"); - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); - - IconMessage (hwndDlg, szTmp2); - if (CreateLink (szTmp, L"", szTmp2, NULL, -1) != S_OK) - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCryptExpander.exe"); - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCryptExpander.lnk"); - - IconMessage (hwndDlg, szTmp2); - if (CreateLink (szTmp, L"", szTmp2, NULL, -1) != S_OK) - goto error; - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt Website.url"); - IconMessage (hwndDlg, szTmp2); - f = _wfopen (szTmp2, L"w"); - if (f) - { - fprintf (f, "[InternetShortcut]\nURL=%s\n", TC_APPLINK); - - CheckFileStreamWriteErrors (hwndDlg, f, szTmp2); - fclose (f); - } - else - goto error; - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCrypt Setup.exe"); - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\Uninstall VeraCrypt.lnk"); - if (GetSystemDirectory (szTmp3, ARRAYSIZE(szTmp3))) - { - StringCbCatW (szTmp3, sizeof(szTmp3), L"\\control.exe"); - } - else - StringCbCopyW(szTmp3, sizeof(szTmp3), L"C:\\Windows\\System32\\control.exe"); - - IconMessage (hwndDlg, szTmp2); - if (CreateLink (szTmp3, L"appwiz.cpl", szTmp2, szTmp, 0) != S_OK) - goto error; - - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt User's Guide.lnk"); - StatDeleteFile (szTmp2, FALSE); - } - - if (bDesktopIcon) - { - StringCbCopyW (szDir, sizeof(szDir), szDestDir); - x = wcslen (szDestDir); - if (szDestDir[x - 1] == L'\\') - bSlash = TRUE; - else - bSlash = FALSE; - - if (bSlash == FALSE) - StringCbCatW (szDir, sizeof(szDir), L"\\"); - - if (bForAllUsers) - SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_COMMON_DESKTOPDIRECTORY, 0); - else - SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_DESKTOPDIRECTORY, 0); - - StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCrypt.exe"); - StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); - - IconMessage (hwndDlg, szTmp2); - - if (CreateLink (szTmp, L"", szTmp2, NULL, -1) != S_OK) - goto error; - } - - bOK = TRUE; - -error: - OleUninitialize (); - - return bOK; -} - - -void OutcomePrompt (HWND hwndDlg, BOOL bOK) -{ - if (bOK) - { - EnableWindow (GetDlgItem ((HWND) hwndDlg, IDCANCEL), FALSE); - - bDone = TRUE; - - if (bUninstall == FALSE) - { - if (bDevm) - PostMessage (MainDlg, WM_CLOSE, 0, 0); - else if (bPossiblyFirstTimeInstall || bRepairMode || (!bUpgrade && !bDowngrade)) - Info ("INSTALL_OK", hwndDlg); - else - Info ("SETUP_UPDATE_OK", hwndDlg); - } - else - { - wchar_t str[4096]; - - StringCbPrintfW (str, sizeof(str), GetString ("UNINSTALL_OK"), InstallationPath); - MessageBoxW (hwndDlg, str, lpszTitle, MB_ICONASTERISK); - } - } - else - { - if (bUninstall == FALSE) - Error ("INSTALL_FAILED", hwndDlg); - else - Error ("UNINSTALL_FAILED", hwndDlg); - } -} - -static void SetSystemRestorePoint (HWND hwndDlg, BOOL finalize) -{ - static RESTOREPOINTINFO RestPtInfo; - static STATEMGRSTATUS SMgrStatus; - static BOOL failed = FALSE; - static BOOL (__stdcall *_SRSetRestorePoint)(PRESTOREPOINTINFO, PSTATEMGRSTATUS); - - if (!SystemRestoreDll) return; - - _SRSetRestorePoint = (BOOL (__stdcall *)(PRESTOREPOINTINFO, PSTATEMGRSTATUS))GetProcAddress (SystemRestoreDll,"SRSetRestorePointW"); - if (_SRSetRestorePoint == 0) - { - FreeLibrary (SystemRestoreDll); - SystemRestoreDll = 0; - return; - } - - if (!finalize) - { - StatusMessage (hwndDlg, "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)) - { - StatusMessage (hwndDlg, "FAILED_SYS_RESTORE"); - failed = TRUE; - } - } - else if (!failed) - { - RestPtInfo.dwEventType = END_SYSTEM_CHANGE; - RestPtInfo.llSequenceNumber = SMgrStatus.llSequenceNumber; - - if(!_SRSetRestorePoint(&RestPtInfo, &SMgrStatus)) - { - StatusMessage (hwndDlg, "FAILED_SYS_RESTORE"); - } - } -} - -void DoUninstall (void *arg) -{ - HWND hwndDlg = (HWND) arg; - BOOL bOK = TRUE; - BOOL bTempSkipSysRestore = FALSE; - - if (!Rollback) - EnableWindow (GetDlgItem ((HWND) hwndDlg, IDC_UNINSTALL), FALSE); - - WaitCursor (); - - if (!Rollback) - { - ClearLogWindow (hwndDlg); - } - - if (DoDriverUnload (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 (hwndDlg, FALSE); - - if (DoServiceUninstall (hwndDlg, L"veracrypt") == FALSE) - { - bOK = FALSE; - } - else if (DoRegUninstall ((HWND) hwndDlg, FALSE) == FALSE) - { - bOK = FALSE; - } - else if (DoFilesInstall ((HWND) hwndDlg, InstallationPath) == FALSE) - { - bOK = FALSE; - } - else if (DoShortcutsUninstall (hwndDlg, InstallationPath) == FALSE) - { - bOK = FALSE; - } - else if (!DoApplicationDataUninstall (hwndDlg)) - { - bOK = FALSE; - } - else - { - wchar_t temp[MAX_PATH]; - FILE *f; - - // Deprecated service - DoServiceUninstall (hwndDlg, L"VeraCryptService"); - - GetTempPath (ARRAYSIZE (temp), temp); - StringCbPrintfW (UninstallBatch, sizeof (UninstallBatch), L"%sVeraCrypt-Uninstall.bat", temp); - - UninstallBatch [ARRAYSIZE(UninstallBatch)-1] = 0; - - // Create uninstall batch - f = _wfopen (UninstallBatch, L"w"); - if (!f) - bOK = FALSE; - else - { - fwprintf (f,L":loop\n" - L"del \"%s%s\"\n" - L"if exist \"%s%s\" goto loop\n" - L"rmdir \"%s\"\n" - L"del \"%s\"", - InstallationPath, L"VeraCrypt Setup.exe", - InstallationPath, L"VeraCrypt Setup.exe", - InstallationPath, - UninstallBatch - ); - - CheckFileStreamWriteErrors (hwndDlg, f, UninstallBatch); - fclose (f); - } - } - } - - NormalCursor (); - - if (Rollback) - return; - - if (bSystemRestore && !bTempSkipSysRestore) - SetSystemRestorePoint (hwndDlg, TRUE); - - if (bOK) - PostMessage (hwndDlg, TC_APPMSG_UNINSTALL_SUCCESS, 0, 0); - else - bUninstallInProgress = FALSE; - - EnableWindow (GetDlgItem ((HWND) hwndDlg, IDC_UNINSTALL), TRUE); - OutcomePrompt (hwndDlg, bOK); -} - -void DoInstall (void *arg) -{ - HWND hwndDlg = (HWND) arg; - BOOL bOK = TRUE; - wchar_t path[MAX_PATH]; - - BootEncryption bootEnc (hwndDlg); - - // Refresh the main GUI (wizard thread) - InvalidateRect (MainDlg, NULL, TRUE); - - ClearLogWindow (hwndDlg); - - if (mkfulldir (InstallationPath, TRUE) != 0) - { - if (mkfulldir (InstallationPath, FALSE) != 0) - { - wchar_t szTmp[TC_MAX_PATH]; - - handleWin32Error (hwndDlg, SRC_POS); - StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CANT_CREATE_FOLDER"), InstallationPath); - MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONHAND); - Error ("INSTALL_FAILED", hwndDlg); - PostMessage (MainDlg, TC_APPMSG_INSTALL_FAILURE, 0, 0); - return; - } - } - - UpdateProgressBarProc(2); - - if (DoDriverUnload (hwndDlg) == FALSE) - { - NormalCursor (); - PostMessage (MainDlg, TC_APPMSG_INSTALL_FAILURE, 0, 0); - return; - } - - if (bUpgrade - && (IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L".exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"-x86.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"-x64.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Format.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Format-x86.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Format-x64.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"Expander.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"Expander-x86.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"Expander-x64.exe") - || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Setup.exe") - ) - ) - { - NormalCursor (); - Error ("CLOSE_TC_FIRST", hwndDlg); - PostMessage (MainDlg, TC_APPMSG_INSTALL_FAILURE, 0, 0); - return; - } - - UpdateProgressBarProc(12); - - if (bSystemRestore) - SetSystemRestorePoint (hwndDlg, FALSE); - - UpdateProgressBarProc(48); - - if (bDisableSwapFiles - && IsPagingFileActive (FALSE)) - { - if (!DisablePagingFile()) - { - handleWin32Error (hwndDlg, SRC_POS); - Error ("FAILED_TO_DISABLE_PAGING_FILES", hwndDlg); - } - else - bRestartRequired = TRUE; - } - - UpdateProgressBarProc(50); - - // Remove deprecated - DoServiceUninstall (hwndDlg, L"VeraCryptService"); - - UpdateProgressBarProc(55); - - if (!SystemEncryptionUpdate) - DoRegUninstall ((HWND) hwndDlg, TRUE); - - UpdateProgressBarProc(61); - - GetWindowsDirectory (path, ARRAYSIZE (path)); - StringCbCatW (path, sizeof (path), L"\\VeraCrypt Setup.exe"); - StatDeleteFile (path, FALSE); - - if (UpdateProgressBarProc(63) && UnloadDriver && DoServiceUninstall (hwndDlg, L"veracrypt") == FALSE) - { - bOK = FALSE; - } - else if (UpdateProgressBarProc(72) && DoFilesInstall ((HWND) hwndDlg, InstallationPath) == FALSE) - { - bOK = FALSE; - } - else if (UpdateProgressBarProc(80) && DoRegInstall ((HWND) hwndDlg, InstallationPath, bRegisterFileExt) == FALSE) - { - bOK = FALSE; - } - else if (UpdateProgressBarProc(85) && UnloadDriver && DoDriverInstall (hwndDlg) == FALSE) - { - bOK = FALSE; - } - else if (UpdateProgressBarProc(90) && SystemEncryptionUpdate && UpgradeBootLoader (hwndDlg) == FALSE) - { - bOK = FALSE; - } - else if (UpdateProgressBarProc(93) && DoShortcutsInstall (hwndDlg, InstallationPath, bAddToStartMenu, bDesktopIcon) == FALSE) - { - bOK = FALSE; - } - - if (!UnloadDriver) - bRestartRequired = TRUE; - - try - { - bootEnc.RenameDeprecatedSystemLoaderBackup(); - } - catch (...) { } - - if (bOK) - UpdateProgressBarProc(97); - - if (bSystemRestore) - SetSystemRestorePoint (hwndDlg, TRUE); - - if (bOK) - { - UpdateProgressBarProc(100); - UninstallBatch[0] = 0; - StatusMessage (hwndDlg, "INSTALL_COMPLETED"); - } - else - { - UpdateProgressBarProc(0); - - if (!SystemEncryptionUpdate) - { - bUninstall = TRUE; - Rollback = TRUE; - Silent = TRUE; - - DoUninstall (hwndDlg); - - bUninstall = FALSE; - Rollback = FALSE; - Silent = FALSE; - - StatusMessage (hwndDlg, "ROLLBACK"); - } - else - { - Warning ("SYS_ENC_UPGRADE_FAILED", hwndDlg); - } - } - - OutcomePrompt (hwndDlg, bOK); - - if (bOK && !bUninstall && !bDowngrade && !bRepairMode && !bDevm) - { - 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); - } - else if (bPossiblyFirstTimeInstall) - { - SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_TUTORIAL); - } - } - else - { - // No restart will be required - - if (bUpgrade) - { - bPromptReleaseNotes = TRUE; - } - else if (bPossiblyFirstTimeInstall) - { - bPromptTutorial = TRUE; - } - } - } - } - - PostMessage (MainDlg, bOK ? TC_APPMSG_INSTALL_SUCCESS : TC_APPMSG_INSTALL_FAILURE, 0, 0); -} - - -void SetInstallationPath (HWND hwndDlg) -{ - HKEY hkey; - BOOL bInstallPathDetermined = FALSE; - wchar_t path[MAX_PATH+20]; - ITEMIDLIST *itemList; - - memset (InstallationPath, 0, sizeof (InstallationPath)); - - // Determine if VeraCrypt is already installed and try to determine its "Program Files" location - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", 0, KEY_READ | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS) - { - /* Default 'UninstallString' registry strings written by VeraCrypt: - ------------------------------------------------------------------------------------ - 5.0+ "C:\Program Files\VeraCrypt\VeraCrypt Setup.exe" /u - */ - - wchar_t rv[MAX_PATH*4]; - DWORD size = sizeof (rv); - if (RegQueryValueEx (hkey, L"UninstallString", 0, 0, (LPBYTE) &rv, &size) == ERROR_SUCCESS && wcsrchr (rv, L'/')) - { - size_t len = 0; - - // Cut and paste the location (path) where VeraCrypt is installed to InstallationPath - if (rv[0] == L'"') - { - len = wcsrchr (rv, L'/') - rv - 2; - StringCchCopyNW (InstallationPath, ARRAYSIZE(InstallationPath), rv + 1, len); - InstallationPath [len] = 0; - bInstallPathDetermined = TRUE; - - if (InstallationPath [wcslen (InstallationPath) - 1] != L'\\') - { - len = wcsrchr (InstallationPath, L'\\') - InstallationPath; - InstallationPath [len] = 0; - } - } - - } - RegCloseKey (hkey); - } - - if (bInstallPathDetermined) - { - wchar_t mp[MAX_PATH]; - - // Determine whether we were launched from the folder where VeraCrypt is installed - GetModuleFileName (NULL, mp, ARRAYSIZE (mp)); - if (wcsncmp (InstallationPath, mp, min (wcslen(InstallationPath), wcslen(mp))) == 0) - { - // We were launched from the folder where VeraCrypt is installed - - if (!IsNonInstallMode() && !bDevm) - bChangeMode = TRUE; - } - } - else - { - /* VeraCrypt is not installed or it wasn't possible to determine where it is installed. */ - - // Default "Program Files" path. - SHGetSpecialFolderLocation (hwndDlg, CSIDL_PROGRAM_FILES, &itemList); - SHGetPathFromIDList (itemList, path); - - if (Is64BitOs()) - { - // Use a unified default installation path (registry redirection of %ProgramFiles% does not work if the installation path is user-selectable) - wstring s = path; - size_t p = s.find (L" (x86)"); - if (p != wstring::npos) - { - s = s.substr (0, p); - if (_waccess (s.c_str(), 0) != -1) - StringCbCopyW (path, sizeof (path), s.c_str()); - } - } - - StringCbCatW (path, sizeof(path), L"\\VeraCrypt\\"); - StringCbCopyW (InstallationPath, sizeof(InstallationPath), path); - } - - // Make sure the path ends with a backslash - if (InstallationPath [wcslen (InstallationPath) - 1] != L'\\') - { - StringCbCatW (InstallationPath, sizeof(InstallationPath), L"\\"); - } -} - - -// Handler for uninstall only (install is handled by the wizard) -BOOL CALLBACK UninstallDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WORD lw = LOWORD (wParam); - - switch (msg) - { - case WM_INITDIALOG: - - MainDlg = hwndDlg; - - if (!CreateAppSetupMutex ()) - AbortProcess ("TC_INSTALLER_IS_RUNNING"); - - InitDialog (hwndDlg); - LocalizeDialog (hwndDlg, NULL); - - SetWindowTextW (hwndDlg, lpszTitle); - - // System Restore - SetCheckBox (hwndDlg, IDC_SYSTEM_RESTORE, bSystemRestore); - if (SystemRestoreDll == 0) - { - SetCheckBox (hwndDlg, IDC_SYSTEM_RESTORE, FALSE); - EnableWindow (GetDlgItem (hwndDlg, IDC_SYSTEM_RESTORE), FALSE); - } - - SetFocus (GetDlgItem (hwndDlg, IDC_UNINSTALL)); - - return 1; - - case WM_SYSCOMMAND: - if (lw == IDC_ABOUT) - { - DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc); - return 1; - } - return 0; - - case WM_COMMAND: - if (lw == IDC_UNINSTALL) - { - if (bDone) - { - bUninstallInProgress = FALSE; - PostMessage (hwndDlg, WM_CLOSE, 0, 0); - return 1; - } - - bUninstallInProgress = TRUE; - - WaitCursor (); - - if (bUninstall) - _beginthread (DoUninstall, 0, (void *) hwndDlg); - - return 1; - } - - if (lw == IDC_SYSTEM_RESTORE) - { - bSystemRestore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_SYSTEM_RESTORE)); - return 1; - } - - if (lw == IDCANCEL) - { - PostMessage (hwndDlg, WM_CLOSE, 0, 0); - return 1; - } - - return 0; - - case TC_APPMSG_UNINSTALL_SUCCESS: - SetWindowTextW (GetDlgItem ((HWND) hwndDlg, IDC_UNINSTALL), GetString ("FINALIZE")); - NormalCursor (); - return 1; - - case WM_CLOSE: - if (bUninstallInProgress) - { - NormalCursor(); - if (AskNoYes("CONFIRM_EXIT_UNIVERSAL", hwndDlg) == IDNO) - { - return 1; - } - WaitCursor (); - } - EndDialog (hwndDlg, IDCANCEL); - return 1; - } - - return 0; -} - - -int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpszCommandLine, int nCmdShow) -{ - atexit (localcleanup); - - SelfExtractStartupInit(); - - lpszTitle = L"VeraCrypt Setup"; - - /* Call InitApp to initialize the common code */ - InitApp (hInstance, NULL); - - if (IsAdmin () != TRUE) - if (MessageBoxW (NULL, GetString ("SETUP_ADMIN"), lpszTitle, MB_YESNO | MB_ICONQUESTION) != IDYES) - { - FinalizeApp (); - exit (1); - } - - /* Setup directory */ - { - wchar_t *s; - GetModuleFileName (NULL, SetupFilesDir, ARRAYSIZE (SetupFilesDir)); - s = wcsrchr (SetupFilesDir, L'\\'); - if (s) - s[1] = 0; - } - - /* Parse command line arguments */ - - if (lpszCommandLine[0] == L'/') - { - if (lpszCommandLine[1] == L'u') - { - // Uninstall: /u - - bUninstall = TRUE; - } - else if (lpszCommandLine[1] == L'c') - { - // Change: /c - - bChangeMode = TRUE; - } - else if (lpszCommandLine[1] == L'p') - { - // Create self-extracting package: /p - - bMakePackage = TRUE; - } - else if (lpszCommandLine[1] == L'd') - { - // Dev mode: /d - bDevm = TRUE; - } - } - - if (bMakePackage) - { - /* Create self-extracting package */ - - MakeSelfExtractingPackage (NULL, SetupFilesDir); - } - else - { - SetInstallationPath (NULL); - - if (!bUninstall) - { - if (IsSelfExtractingPackage()) - { - if (!VerifyPackageIntegrity()) - { - // Package corrupted - exit (1); - } - bDevm = FALSE; - } - else if (!bDevm) - { - MessageBox (NULL, L"Error: This installer file does not contain any compressed files.\n\nTo create a self-extracting installation package (with embedded compressed files), run:\n\"VeraCrypt Setup.exe\" /p", L"VeraCrypt", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); - FinalizeApp (); - exit (1); - } - - if (bChangeMode) - { - /* VeraCrypt is already installed on this system and we were launched from the Program Files folder */ - - char *tmpStr[] = {0, "SELECT_AN_ACTION", "REPAIR_REINSTALL", "UNINSTALL", "EXIT", 0}; - - // Ask the user to select either Repair or Unistallation - switch (AskMultiChoice ((void **) tmpStr, FALSE, NULL)) - { - case 1: - bRepairMode = TRUE; - break; - case 2: - bUninstall = TRUE; - break; - default: - FinalizeApp (); - exit (1); - } - } - } - - // System Restore - if (IsSystemRestoreEnabled ()) - { - 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 - SystemRestoreDll = 0; - - if (!bUninstall) - { - /* Create the main dialog for install */ - - DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_INSTL_DLG), NULL, (DLGPROC) MainDialogProc, - (LPARAM)lpszCommandLine); - } - else - { - /* Create the main dialog for uninstall */ - - DialogBoxW (hInstance, MAKEINTRESOURCEW (IDD_UNINSTALL), NULL, (DLGPROC) UninstallDlgProc); - - if (UninstallBatch[0]) - { - STARTUPINFO si; - PROCESS_INFORMATION pi; - - ZeroMemory (&si, sizeof (si)); - si.cb = sizeof (si); - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; - - if (!CreateProcess (UninstallBatch, NULL, NULL, NULL, FALSE, IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) - DeleteFile (UninstallBatch); - else - { - CloseHandle (pi.hProcess); - CloseHandle (pi.hThread); - } - } - } - } - FinalizeApp (); - return 0; -} +/* + 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-2016 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 "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 "SelfExtract.h" +#include "Wizard.h" + +#include "../Common/Resource.h" + +using namespace VeraCrypt; + +#pragma warning( disable : 4201 ) +#pragma warning( disable : 4115 ) + +#include + +#pragma warning( default : 4201 ) +#pragma warning( default : 4115 ) + +#include + +wchar_t InstallationPath[TC_MAX_PATH]; +wchar_t SetupFilesDir[TC_MAX_PATH]; +wchar_t UninstallBatch[MAX_PATH]; + +BOOL bUninstall = FALSE; +BOOL bRestartRequired = FALSE; +BOOL bMakePackage = FALSE; +BOOL bDone = FALSE; +BOOL Rollback = FALSE; +BOOL bUpgrade = FALSE; +BOOL bDowngrade = FALSE; +BOOL SystemEncryptionUpdate = FALSE; +BOOL PortableMode = FALSE; +BOOL bRepairMode = FALSE; +BOOL bReinstallMode = FALSE; +BOOL bChangeMode = FALSE; +BOOL bDevm = FALSE; +BOOL bPossiblyFirstTimeInstall = FALSE; +BOOL bUninstallInProgress = FALSE; +BOOL UnloadDriver = TRUE; + +BOOL bSystemRestore = TRUE; +BOOL bDisableSwapFiles = FALSE; +BOOL bForAllUsers = TRUE; +BOOL bRegisterFileExt = TRUE; +BOOL bAddToStartMenu = TRUE; +BOOL bDesktopIcon = TRUE; + +BOOL bDesktopIconStatusDetermined = FALSE; + +HMODULE volatile SystemRestoreDll = 0; + +void localcleanup (void) +{ + localcleanupwiz (); + cleanup (); + + CloseAppSetupMutex (); +} + +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; +} + +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; +} + +BOOL StatRemoveDirectory (wchar_t *lpszDir) +{ + struct __stat64 st; + + if (_wstat64 (lpszDir, &st) == 0) + { + BOOL bStatus = RemoveDirectory (lpszDir); + if (!bStatus) + { + /* force removal of the non empty directory */ + wchar_t szOpPath[TC_MAX_PATH + 1] = {0}; + SHFILEOPSTRUCTW op; + + StringCchCopyW(szOpPath, ARRAYSIZE(szOpPath)-1, lpszDir); + ZeroMemory(&op, sizeof(op)); + op.wFunc = FO_DELETE; + op.pFrom = szOpPath; + op.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR; + + if ((0 == SHFileOperation(&op)) && (!op.fAnyOperationsAborted)) + bStatus = TRUE; + } + return bStatus; + } + else + return TRUE; +} + + +/* Recursively set the given OWNER security descriptor to the key and its subkeys */ +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); +} + +/* Recursively set the given DACL security descriptor to the key and its subkeys */ +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; + } + } +} + +/* Correct the key permissions to allow its deletion */ +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); +} + +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); + } + } + } +} + +/* Set the given privilege of the current process */ +BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable) +{ + TOKEN_PRIVILEGES tp; + LUID luid; + HANDLE hProcessToken; + BOOL bStatus = FALSE; + + if ( OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &hProcessToken) ) + { + if ( LookupPrivilegeValue( + NULL, + szPrivilegeName, + &luid ) ) + { + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = bEnable? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED; + + // Enable the privilege + bStatus = AdjustTokenPrivileges( + hProcessToken, + FALSE, + &tp, + sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES) NULL, + (PDWORD) NULL); + } + + CloseHandle(hProcessToken); + } + + return bStatus; +} + +/* + * Creates a VT_LPWSTR propvariant. + * we use our own implementation to use SHStrDupW function pointer + * that we retreive ourselves to avoid dll hijacking attacks + */ +inline HRESULT VCInitPropVariantFromString(__in PCWSTR psz, __out PROPVARIANT *ppropvar) +{ + ppropvar->vt = VT_LPWSTR; + HRESULT hr = VCStrDupW(psz, &ppropvar->pwszVal); + if (FAILED(hr)) + { + PropVariantInit(ppropvar); + } + return hr; +} + +HRESULT CreateLink (wchar_t *lpszPathObj, wchar_t *lpszArguments, + wchar_t *lpszPathLink, const wchar_t* iconFile, int iconIndex) +{ + HRESULT hres; + IShellLink *psl; + + /* Get a pointer to the IShellLink interface. */ + hres = CoCreateInstance (CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); + if (SUCCEEDED (hres)) + { + IPersistFile *ppf; + + /* Set the path to the shortcut target, and add the + description. */ + psl->SetPath (lpszPathObj); + psl->SetArguments (lpszArguments); + if (iconFile) + { + psl->SetIconLocation (iconFile, iconIndex); + } + + // Application ID + if (_tcsstr (lpszPathObj, _T(TC_APP_NAME) _T(".exe"))) + { + IPropertyStore *propStore; + + if (SUCCEEDED (psl->QueryInterface (IID_PPV_ARGS (&propStore)))) + { + PROPVARIANT propVariant; + if (SUCCEEDED (VCInitPropVariantFromString (TC_APPLICATION_ID, &propVariant))) + { + if (SUCCEEDED (propStore->SetValue (PKEY_AppUserModel_ID, propVariant))) + propStore->Commit(); + + PropVariantClear (&propVariant); + } + + propStore->Release(); + } + } + + /* Query IShellLink for the IPersistFile interface for saving + the shortcut in persistent storage. */ + hres = psl->QueryInterface (IID_IPersistFile, + (void **) &ppf); + + if (SUCCEEDED (hres)) + { + /* Save the link by calling IPersistFile::Save. */ + hres = ppf->Save (lpszPathLink, TRUE); + ppf->Release (); + } + psl->Release (); + } + return hres; +} + +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; +} + +void GetProgramPath (HWND hwndDlg, wchar_t *path) +{ + ITEMIDLIST *i; + HRESULT res; + + if (bForAllUsers) + res = SHGetSpecialFolderLocation (hwndDlg, CSIDL_COMMON_PROGRAMS, &i); + else + res = SHGetSpecialFolderLocation (hwndDlg, CSIDL_PROGRAMS, &i); + + SHGetPathFromIDList (i, path); +} + +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); +} + +void StatusMessageParam (HWND hwndDlg, char *stringId, wchar_t *param) +{ + wchar_t szTmp[1024]; + + if (Rollback) + return; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s %s", GetString (stringId), param); + SendMessageW (GetDlgItem (hwndDlg, IDC_LOG_WINDOW), LB_ADDSTRING, 0, (LPARAM) szTmp); + + SendDlgItemMessage (hwndDlg, IDC_LOG_WINDOW, LB_SETTOPINDEX, + SendDlgItemMessage (hwndDlg, IDC_LOG_WINDOW, LB_GETCOUNT, 0, 0) - 1, 0); +} + +void ClearLogWindow (HWND hwndDlg) +{ + SendMessage (GetDlgItem (hwndDlg, IDC_LOG_WINDOW), LB_RESETCONTENT, 0, 0); +} + +void RegMessage (HWND hwndDlg, wchar_t *txt) +{ + StatusMessageParam (hwndDlg, "ADDING_REG", txt); +} + +void CopyMessage (HWND hwndDlg, wchar_t *txt) +{ + StatusMessageParam (hwndDlg, "INSTALLING", txt); +} + +void RemoveMessage (HWND hwndDlg, wchar_t *txt) +{ + if (!Rollback) + StatusMessageParam (hwndDlg, "REMOVING", txt); +} + +void IconMessage (HWND hwndDlg, wchar_t *txt) +{ + StatusMessageParam (hwndDlg, "ADDING_ICON", txt); +} + +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; +} + + +static BOOL IsFileInUse (const wstring &filePath) +{ + HANDLE useTestHandle = CreateFile (filePath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (useTestHandle != INVALID_HANDLE_VALUE) + CloseHandle (useTestHandle); + else if (GetLastError() == ERROR_SHARING_VIOLATION) + return TRUE; + + return FALSE; +} + + +BOOL DoFilesInstall (HWND hwndDlg, wchar_t *szDestDir) +{ + /* WARNING: Note that, despite its name, this function is used during UNinstallation as well. */ + + wchar_t szTmp[TC_MAX_PATH]; + BOOL bOK = TRUE; + int i, x, fileNo; + wchar_t curFileName [TC_MAX_PATH] = {0}; + + if (!bUninstall && !bDevm) + { + // Self-extract all files to memory + + GetModuleFileName (NULL, szTmp, ARRAYSIZE (szTmp)); + + if (!SelfExtractInMemory (szTmp)) + return FALSE; + } + + x = wcslen (szDestDir); + if (x < 2) + return FALSE; + + if (szDestDir[x - 1] != L'\\') + StringCbCatW (szDestDir, MAX_PATH, L"\\"); + + for (i = 0; i < sizeof (szFiles) / sizeof (szFiles[0]); i++) + { + BOOL bResult, driver64 = FALSE; + wchar_t szDir[TC_MAX_PATH]; + + if (wcsstr (szFiles[i], L"VeraCrypt Setup") != 0) + { + if (bUninstall) + continue; // Prevent 'access denied' error + + if (bRepairMode) + continue; // Destination = target + } + + // skip files that don't apply to the current architecture + if ( (Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt-x64.exe") == 0)) + || (Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCryptExpander-x64.exe") == 0)) + || (Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt Format-x64.exe") == 0)) + || (!Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt-x86.exe") == 0)) + || (!Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCryptExpander-x86.exe") == 0)) + || (!Is64BitOs () && (wcscmp (szFiles[i], L"AVeraCrypt Format-x86.exe") == 0)) + ) + { + continue; + } + + if (*szFiles[i] == L'A') + StringCbCopyW (szDir, sizeof(szDir), szDestDir); + else if (*szFiles[i] == L'D') + { + if (Is64BitOs ()) + driver64 = TRUE; + + GetSystemDirectory (szDir, ARRAYSIZE (szDir)); + + x = wcslen (szDir); + if (szDir[x - 1] != L'\\') + StringCbCatW (szDir, sizeof(szDir), L"\\"); + + StringCbCatW (szDir, sizeof(szDir), L"Drivers\\"); + } + else if (*szFiles[i] == L'W') + GetWindowsDirectory (szDir, ARRAYSIZE (szDir)); + + if (*szFiles[i] == L'I') + continue; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, szFiles[i] + 1); + + if (bUninstall == FALSE) + CopyMessage (hwndDlg, szTmp); + else + RemoveMessage (hwndDlg, szTmp); + + if (bUninstall == FALSE) + { + SetCurrentDirectory (SetupFilesDir); + + if (wcsstr (szFiles[i], L"VeraCrypt Setup") != 0) + { + // Copy ourselves (the distribution package) to the destination location as 'VeraCrypt Setup.exe' + + wchar_t mp[MAX_PATH]; + + GetModuleFileName (NULL, mp, ARRAYSIZE (mp)); + bResult = TCCopyFile (mp, szTmp); + } + else + { + StringCchCopyNW (curFileName, ARRAYSIZE(curFileName), szFiles[i] + 1, wcslen (szFiles[i]) - 1); + curFileName [wcslen (szFiles[i]) - 1] = 0; + + if (Is64BitOs () + && wcscmp (szFiles[i], L"Dveracrypt.sys") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), FILENAME_64BIT_DRIVER, sizeof (FILENAME_64BIT_DRIVER)); + } + + if (Is64BitOs () + && wcscmp (szFiles[i], L"AVeraCrypt.exe") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt-x64.exe", sizeof (L"VeraCrypt-x64.exe")); + } + + if (Is64BitOs () + && wcscmp (szFiles[i], L"AVeraCrypt-x86.exe") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt.exe", sizeof (L"VeraCrypt.exe")); + } + + if (Is64BitOs () + && wcscmp (szFiles[i], L"AVeraCryptExpander.exe") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCryptExpander-x64.exe", sizeof (L"VeraCryptExpander-x64.exe")); + } + + if (Is64BitOs () + && wcscmp (szFiles[i], L"AVeraCryptExpander-x86.exe") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCryptExpander.exe", sizeof (L"VeraCryptExpander.exe")); + } + + if (Is64BitOs () + && wcscmp (szFiles[i], L"AVeraCrypt Format.exe") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt Format-x64.exe", sizeof (L"VeraCrypt Format-x64.exe")); + } + + if (Is64BitOs () + && wcscmp (szFiles[i], L"AVeraCrypt Format-x86.exe") == 0) + { + StringCbCopyNW (curFileName, sizeof(curFileName), L"VeraCrypt Format.exe", sizeof (L"VeraCrypt Format.exe")); + } + + if (!bDevm) + { + bResult = FALSE; + + // Find the correct decompressed file in memory + for (fileNo = 0; fileNo < NBR_COMPRESSED_FILES; fileNo++) + { + // Write the file (stored in memory) directly to the destination location + // (there will be no temporary files). + if (wmemcmp ( + curFileName, + Decompressed_Files[fileNo].fileName, + min (wcslen (curFileName), (size_t) Decompressed_Files[fileNo].fileNameLength)) == 0) + { + // Dump filter driver cannot be installed to SysWOW64 directory + if (driver64 && !EnableWow64FsRedirection (FALSE)) + { + handleWin32Error (hwndDlg, SRC_POS); + bResult = FALSE; + goto err; + } + + bResult = SaveBufferToFile ( + (char *) Decompressed_Files[fileNo].fileContent, + szTmp, + Decompressed_Files[fileNo].fileLength, + FALSE, + TRUE); + + if (driver64) + { + if (!EnableWow64FsRedirection (TRUE)) + { + handleWin32Error (hwndDlg, SRC_POS); + bResult = FALSE; + goto err; + } + + if (!bResult) + goto err; + + } + + break; + } + } + } + else + { + if (driver64) + EnableWow64FsRedirection (FALSE); + + bResult = TCCopyFile (curFileName, szTmp); + + if (driver64) + EnableWow64FsRedirection (TRUE); + } + + if (bResult && wcscmp (szFiles[i], L"AVeraCrypt.exe") == 0) + { + 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 ( FileExists (servicePath.c_str()) + || (Is64BitOs () && FileExists (serviceLegacyPath.c_str())) + ) + { + CopyMessage (hwndDlg, (wchar_t *) servicePath.c_str()); + bResult = CopyFile (szTmp, servicePath.c_str(), FALSE); + } + + if (bResult && 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); + } + + if (bResult && Is64BitOs () && FileExists (favoritesFile.c_str()) && FileExists (servicePath.c_str())) + { + // Update the path of the service + BootEncryption BootEncObj (hwndDlg); + + try + { + if (BootEncObj.GetDriverServiceStartType() == SERVICE_BOOT_START) + { + BootEncObj.UpdateSystemFavoritesService (); + } + } + catch (...) {} + } + + if (Is64BitOs ()) + { + // delete files from legacy path + if (FileExists (favoritesLegacyFile.c_str())) + { + RemoveMessage (hwndDlg, (wchar_t *) favoritesLegacyFile.c_str()); + ForceDeleteFile (favoritesLegacyFile.c_str()); + } + + if (FileExists (serviceLegacyPath.c_str())) + { + RemoveMessage (hwndDlg, (wchar_t *) serviceLegacyPath.c_str()); + ForceDeleteFile (serviceLegacyPath.c_str()); + } + + EnableWow64FsRedirection (TRUE); + } + } + } + } + else + { + if (driver64) + EnableWow64FsRedirection (FALSE); + bResult = StatDeleteFile (szTmp, TRUE); + if (driver64) + EnableWow64FsRedirection (TRUE); + + if (bResult && wcscmp (szFiles[i], L"AVeraCrypt.exe") == 0) + { + 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())) + { + RemoveMessage (hwndDlg, (wchar_t *) favoritesFile.c_str()); + ForceDeleteFile (favoritesFile.c_str()); + } + + if (FileExists (servicePath.c_str())) + { + RemoveMessage (hwndDlg, (wchar_t *) servicePath.c_str()); + ForceDeleteFile (servicePath.c_str()); + } + + if (Is64BitOs ()) + { + if (FileExists (favoritesLegacyFile.c_str())) + { + RemoveMessage (hwndDlg, (wchar_t *) favoritesLegacyFile.c_str()); + ForceDeleteFile (favoritesLegacyFile.c_str()); + } + + if (FileExists (serviceLegacyPath.c_str())) + { + RemoveMessage (hwndDlg, (wchar_t *) serviceLegacyPath.c_str()); + ForceDeleteFile (serviceLegacyPath.c_str()); + } + + EnableWow64FsRedirection (TRUE); + } + } + } + +err: + 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) + return FALSE; + } + } + + // Language pack + if (bUninstall == FALSE) + { + WIN32_FIND_DATA f; + HANDLE h; + + SetCurrentDirectory (SetupFilesDir); + h = FindFirstFile (L"Language.*.xml", &f); + + if (h != INVALID_HANDLE_VALUE) + { + wchar_t d[MAX_PATH*2]; + StringCbPrintfW (d, sizeof(d), L"%s%s", szDestDir, f.cFileName); + CopyMessage (hwndDlg, d); + TCCopyFile (f.cFileName, d); + FindClose (h); + } + + SetCurrentDirectory (SetupFilesDir); + SetCurrentDirectory (L"Setup files"); + h = FindFirstFile (L"VeraCrypt User Guide.*.pdf", &f); + if (h != INVALID_HANDLE_VALUE) + { + wchar_t d[MAX_PATH*2]; + StringCbPrintfW (d, sizeof(d), L"%s%s", szDestDir, f.cFileName); + CopyMessage (hwndDlg, d); + TCCopyFile (f.cFileName, d); + FindClose (h); + } + SetCurrentDirectory (SetupFilesDir); + } + + return bOK; +} + +BOOL DoRegInstall (HWND hwndDlg, wchar_t *szDestDir, BOOL bInstallType) +{ + wchar_t szDir[TC_MAX_PATH], *key; + wchar_t szTmp[TC_MAX_PATH*4]; + HKEY hkey = 0; + BOOL bSlash, bOK = FALSE; + DWORD dw; + int x; + + if (SystemEncryptionUpdate) + { + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_32KEY, NULL, &hkey, &dw) == ERROR_SUCCESS) + { + StringCbCopyW (szTmp, sizeof(szTmp), _T(VERSION_STRING)); + RegSetValueEx (hkey, L"DisplayVersion", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)); + + StringCbCopyW (szTmp, sizeof(szTmp), _T(TC_HOMEPAGE)); + RegSetValueEx (hkey, L"URLInfoAbout", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)); + + RegCloseKey (hkey); + } + + return TRUE; + } + + StringCbCopyW (szDir, sizeof(szDir), szDestDir); + x = wcslen (szDestDir); + if (szDestDir[x - 1] == L'\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + StringCbCatW (szDir, sizeof(szDir), L"\\"); + + if (bInstallType) + { + + key = L"Software\\Classes\\VeraCryptVolume"; + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + StringCbCopyW (szTmp, sizeof(szTmp), L"VeraCrypt Volume"); + if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%ws", TC_APPLICATION_ID); + if (RegSetValueEx (hkey, L"AppUserModelID", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + key = L"Software\\Classes\\VeraCryptVolume\\DefaultIcon"; + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%sVeraCrypt.exe,1", szDir); + if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + key = L"Software\\Classes\\VeraCryptVolume\\Shell\\open\\command"; + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt.exe\" /v \"%%1\"", szDir ); + if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + key = L"Software\\Classes\\.hc"; + BOOL typeClassChanged = TRUE; + wchar_t typeClass[256]; + DWORD typeClassSize = sizeof (typeClass); + + if (ReadLocalMachineRegistryString (key, L"", typeClass, &typeClassSize) && typeClassSize > 0 && wcscmp (typeClass, L"VeraCryptVolume") == 0) + typeClassChanged = FALSE; + + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + StringCbCopyW (szTmp, sizeof(szTmp), L"VeraCryptVolume"); + if (RegSetValueEx (hkey, L"", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + if (typeClassChanged) + SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + key = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt"; + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_32KEY, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + /* IMPORTANT: IF YOU CHANGE THIS IN ANY WAY, REVISE AND UPDATE SetInstallationPath() ACCORDINGLY! */ + StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt Setup.exe\" /u", szDir); + if (RegSetValueEx (hkey, L"UninstallString", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt Setup.exe\" /c", szDir); + if (RegSetValueEx (hkey, L"ModifyPath", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"\"%sVeraCrypt Setup.exe\"", szDir); + if (RegSetValueEx (hkey, L"DisplayIcon", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbCopyW (szTmp, sizeof(szTmp), _T(VERSION_STRING)); + if (RegSetValueEx (hkey, L"DisplayVersion", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbCopyW (szTmp, sizeof(szTmp), L"VeraCrypt"); + if (RegSetValueEx (hkey, L"DisplayName", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbCopyW (szTmp, sizeof(szTmp), L"IDRIX"); + if (RegSetValueEx (hkey, L"Publisher", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + StringCbCopyW (szTmp, sizeof(szTmp), _T(TC_HOMEPAGE)); + if (RegSetValueEx (hkey, L"URLInfoAbout", 0, REG_SZ, (BYTE *) szTmp, (wcslen (szTmp) + 1) * sizeof (wchar_t)) != ERROR_SUCCESS) + goto error; + + bOK = TRUE; + +error: + if (hkey != 0) + RegCloseKey (hkey); + + if (bOK == FALSE) + { + handleWin32Error (hwndDlg, SRC_POS); + Error ("REG_INSTALL_FAILED", hwndDlg); + } + + // Register COM servers for UAC + if (IsOSAtLeast (WIN_VISTA)) + { + if (!RegisterComServers (szDir)) + { + Error ("COM_REG_FAILED", hwndDlg); + return FALSE; + } + } + + return bOK; +} + +BOOL DoApplicationDataUninstall (HWND hwndDlg) +{ + wchar_t path[MAX_PATH]; + wchar_t path2[MAX_PATH]; + BOOL bOK = TRUE; + + StatusMessage (hwndDlg, "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); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2, FALSE); + + // Delete keyfile defaults + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_DEFAULT_KEYFILES); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2, FALSE); + + // Delete history file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_HISTORY); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2, FALSE); + + // Delete configuration file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_CONFIGURATION); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2, FALSE); + + // Delete system encryption configuration file + StringCbPrintfW (path2, sizeof(path2), L"%s%s", path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2, FALSE); + + SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); + StringCbCatW (path, sizeof(path), L"\\VeraCrypt"); + RemoveMessage (hwndDlg, path); + if (!StatRemoveDirectory (path)) + { + handleWin32Error (hwndDlg, 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); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2, FALSE); + + // remove VeraCrypt folder + RemoveMessage (hwndDlg, path); + StatRemoveDirectory (path); + } + + + return bOK; +} + +BOOL DoRegUninstall (HWND hwndDlg, BOOL bRemoveDeprecated) +{ + 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)) + StatusMessage (hwndDlg, "COM_DEREG_FAILED"); + } + + if (!bRemoveDeprecated) + StatusMessage (hwndDlg, "REMOVING_REG"); + + 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"); + + 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); + + SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + if (hAdvapiDll) + FreeLibrary (hAdvapiDll); + + return TRUE; +} + + +BOOL DoServiceUninstall (HWND hwndDlg, wchar_t *lpszService) +{ + SC_HANDLE hManager, hService = NULL; + BOOL bOK = FALSE, bRet; + SERVICE_STATUS status; + BOOL firstTry = TRUE; + int x; + + 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 (...) { } + + StatusMessage (hwndDlg, "STOPPING_DRIVER"); + } + else + StatusMessageParam (hwndDlg, "STOPPING", lpszService); + +#define WAIT_PERIOD 3 + + 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) + StatusMessage (hwndDlg, "REMOVING_DRIVER"); + else + StatusMessageParam (hwndDlg, "REMOVING", 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 (hwndDlg, SRC_POS); + MessageBoxW (hwndDlg, GetString ("DRIVER_UINSTALL_FAILED"), lpszTitle, MB_ICONHAND); + } + else + bOK = TRUE; + + if (hService != NULL) + CloseServiceHandle (hService); + + if (hManager != NULL) + CloseServiceHandle (hManager); + + return bOK; +} + + +BOOL DoDriverUnload (HWND hwndDlg) +{ + BOOL bOK = TRUE; + int status; + + status = DriverAttach (); + if (status != 0) + { + if (status == ERR_OS_ERROR && GetLastError () != ERROR_FILE_NOT_FOUND) + { + handleWin32Error (hwndDlg, SRC_POS); + AbortProcess ("NODRIVER"); + } + + if (status != ERR_OS_ERROR) + { + handleError (NULL, status, SRC_POS); + AbortProcess ("NODRIVER"); + } + } + + 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 (hwndDlg); + 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", hwndDlg) == IDNO) + AbortProcessSilent (); + } + } + } + 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) + { + Error (bDowngrade ? "SETUP_FAILED_BOOT_DRIVE_ENCRYPTED_DOWNGRADE" : "SETUP_FAILED_BOOT_DRIVE_ENCRYPTED", hwndDlg); + return FALSE; + } + else + { + if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1) + AbortProcess ("SYS_ENCRYPTION_UPGRADE_UNSUPPORTED_ON_VISTA_SP0"); + + 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; + MessageBoxW (hwndDlg, GetString ("DISMOUNT_ALL_FIRST"), lpszTitle, MB_ICONHAND); + } + } + else + { + bOK = FALSE; + handleWin32Error (hwndDlg, 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) + { + MessageBoxW (hwndDlg, GetString ("CLOSE_TC_FIRST"), lpszTitle, MB_ICONSTOP); + 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; + } + + return bOK; +} + + +BOOL UpgradeBootLoader (HWND hwndDlg) +{ + if (!SystemEncryptionUpdate) + return TRUE; + + try + { + BootEncryption bootEnc (hwndDlg); + uint64 bootLoaderVersion = bootEnc.GetInstalledBootLoaderVersion(); + if ((bootLoaderVersion < VERSION_NUM) || (bReinstallMode && (bootLoaderVersion == VERSION_NUM))) + { + StatusMessage (hwndDlg, "INSTALLER_UPDATING_BOOT_LOADER"); + + bootEnc.InstallBootLoader (true); + + if (bootEnc.GetInstalledBootLoaderVersion() <= TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION) + Info (IsHiddenOSRunning() ? "BOOT_LOADER_UPGRADE_OK_HIDDEN_OS" : "BOOT_LOADER_UPGRADE_OK", hwndDlg); + } + return TRUE; + } + catch (Exception &e) + { + e.Show (hwndDlg); + } + catch (...) { } + + Error ("BOOT_LOADER_UPGRADE_FAILED", hwndDlg); + return FALSE; +} + + +BOOL DoShortcutsUninstall (HWND hwndDlg, wchar_t *szDestDir) +{ + wchar_t szLinkDir[TC_MAX_PATH]; + wchar_t szTmp2[TC_MAX_PATH]; + BOOL bSlash, bOK = FALSE; + HRESULT hOle; + int x; + BOOL allUsers = FALSE; + + hOle = OleInitialize (NULL); + + // User start menu + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_PROGRAMS, 0); + x = wcslen (szLinkDir); + if (szLinkDir[x - 1] == L'\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + StringCbCatW (szLinkDir, sizeof(szLinkDir), L"\\"); + + StringCbCatW (szLinkDir, sizeof(szLinkDir), L"VeraCrypt"); + + // Global start menu + { + struct _stat st; + wchar_t path[TC_MAX_PATH]; + + SHGetSpecialFolderPath (hwndDlg, path, CSIDL_COMMON_PROGRAMS, 0); + StringCbCatW (path, sizeof(path), L"\\VeraCrypt"); + + if (_wstat (path, &st) == 0) + { + StringCbCopyW (szLinkDir, sizeof(szLinkDir), path); + allUsers = TRUE; + } + } + + // Start menu entries + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2, FALSE) == FALSE) + goto error; + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCryptExpander.lnk"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2, FALSE) == FALSE) + goto error; + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt Website.url"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2, FALSE) == FALSE) + goto error; + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\Uninstall VeraCrypt.lnk"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2, FALSE) == FALSE) + goto error; + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt User's Guide.lnk"); + StatDeleteFile (szTmp2, FALSE); + + // Start menu group + RemoveMessage ((HWND) hwndDlg, szLinkDir); + if (StatRemoveDirectory (szLinkDir) == FALSE) + handleWin32Error ((HWND) hwndDlg, SRC_POS); + + // Desktop icon + + if (allUsers) + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_COMMON_DESKTOPDIRECTORY, 0); + else + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_DESKTOPDIRECTORY, 0); + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); + + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2, FALSE) == FALSE) + goto error; + + bOK = TRUE; + +error: + OleUninitialize (); + + return bOK; +} + +BOOL DoShortcutsInstall (HWND hwndDlg, wchar_t *szDestDir, BOOL bProgGroup, BOOL bDesktopIcon) +{ + wchar_t szLinkDir[TC_MAX_PATH], szDir[TC_MAX_PATH]; + wchar_t szTmp[TC_MAX_PATH], szTmp2[TC_MAX_PATH], szTmp3[TC_MAX_PATH]; + BOOL bSlash, bOK = FALSE; + HRESULT hOle; + int x; + + if (bProgGroup == FALSE && bDesktopIcon == FALSE) + return TRUE; + + hOle = OleInitialize (NULL); + + GetProgramPath (hwndDlg, szLinkDir); + + x = wcslen (szLinkDir); + if (szLinkDir[x - 1] == L'\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + StringCbCatW (szLinkDir, sizeof(szLinkDir), L"\\"); + + StringCbCatW (szLinkDir, sizeof(szLinkDir), L"VeraCrypt"); + + StringCbCopyW (szDir, sizeof(szDir), szDestDir); + x = wcslen (szDestDir); + if (szDestDir[x - 1] == L'\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + StringCbCatW (szDir, sizeof(szDir), L"\\"); + + if (bProgGroup) + { + FILE *f; + + if (mkfulldir (szLinkDir, TRUE) != 0) + { + if (mkfulldir (szLinkDir, FALSE) != 0) + { + wchar_t szTmpW[TC_MAX_PATH]; + + handleWin32Error (hwndDlg, SRC_POS); + StringCbPrintfW (szTmpW, sizeof(szTmpW), GetString ("CANT_CREATE_FOLDER"), szLinkDir); + MessageBoxW (hwndDlg, szTmpW, lpszTitle, MB_ICONHAND); + goto error; + } + } + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCrypt.exe"); + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); + + IconMessage (hwndDlg, szTmp2); + if (CreateLink (szTmp, L"", szTmp2, NULL, -1) != S_OK) + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCryptExpander.exe"); + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCryptExpander.lnk"); + + IconMessage (hwndDlg, szTmp2); + if (CreateLink (szTmp, L"", szTmp2, NULL, -1) != S_OK) + goto error; + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt Website.url"); + IconMessage (hwndDlg, szTmp2); + f = _wfopen (szTmp2, L"w"); + if (f) + { + fprintf (f, "[InternetShortcut]\nURL=%s\n", TC_APPLINK); + + CheckFileStreamWriteErrors (hwndDlg, f, szTmp2); + fclose (f); + } + else + goto error; + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCrypt Setup.exe"); + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\Uninstall VeraCrypt.lnk"); + if (GetSystemDirectory (szTmp3, ARRAYSIZE(szTmp3))) + { + StringCbCatW (szTmp3, sizeof(szTmp3), L"\\control.exe"); + } + else + StringCbCopyW(szTmp3, sizeof(szTmp3), L"C:\\Windows\\System32\\control.exe"); + + IconMessage (hwndDlg, szTmp2); + if (CreateLink (szTmp3, L"appwiz.cpl", szTmp2, szTmp, 0) != S_OK) + goto error; + + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt User's Guide.lnk"); + StatDeleteFile (szTmp2, FALSE); + } + + if (bDesktopIcon) + { + StringCbCopyW (szDir, sizeof(szDir), szDestDir); + x = wcslen (szDestDir); + if (szDestDir[x - 1] == L'\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + StringCbCatW (szDir, sizeof(szDir), L"\\"); + + if (bForAllUsers) + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_COMMON_DESKTOPDIRECTORY, 0); + else + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_DESKTOPDIRECTORY, 0); + + StringCbPrintfW (szTmp, sizeof(szTmp), L"%s%s", szDir, L"VeraCrypt.exe"); + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s%s", szLinkDir, L"\\VeraCrypt.lnk"); + + IconMessage (hwndDlg, szTmp2); + + if (CreateLink (szTmp, L"", szTmp2, NULL, -1) != S_OK) + goto error; + } + + bOK = TRUE; + +error: + OleUninitialize (); + + return bOK; +} + + +void OutcomePrompt (HWND hwndDlg, BOOL bOK) +{ + if (bOK) + { + EnableWindow (GetDlgItem ((HWND) hwndDlg, IDCANCEL), FALSE); + + bDone = TRUE; + + if (bUninstall == FALSE) + { + if (bDevm) + PostMessage (MainDlg, WM_CLOSE, 0, 0); + else if (bPossiblyFirstTimeInstall || bRepairMode || (!bUpgrade && !bDowngrade)) + Info ("INSTALL_OK", hwndDlg); + else + Info ("SETUP_UPDATE_OK", hwndDlg); + } + else + { + wchar_t str[4096]; + + StringCbPrintfW (str, sizeof(str), GetString ("UNINSTALL_OK"), InstallationPath); + MessageBoxW (hwndDlg, str, lpszTitle, MB_ICONASTERISK); + } + } + else + { + if (bUninstall == FALSE) + Error ("INSTALL_FAILED", hwndDlg); + else + Error ("UNINSTALL_FAILED", hwndDlg); + } +} + +static void SetSystemRestorePoint (HWND hwndDlg, BOOL finalize) +{ + static RESTOREPOINTINFO RestPtInfo; + static STATEMGRSTATUS SMgrStatus; + static BOOL failed = FALSE; + static BOOL (__stdcall *_SRSetRestorePoint)(PRESTOREPOINTINFO, PSTATEMGRSTATUS); + + if (!SystemRestoreDll) return; + + _SRSetRestorePoint = (BOOL (__stdcall *)(PRESTOREPOINTINFO, PSTATEMGRSTATUS))GetProcAddress (SystemRestoreDll,"SRSetRestorePointW"); + if (_SRSetRestorePoint == 0) + { + FreeLibrary (SystemRestoreDll); + SystemRestoreDll = 0; + return; + } + + if (!finalize) + { + StatusMessage (hwndDlg, "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)) + { + StatusMessage (hwndDlg, "FAILED_SYS_RESTORE"); + failed = TRUE; + } + } + else if (!failed) + { + RestPtInfo.dwEventType = END_SYSTEM_CHANGE; + RestPtInfo.llSequenceNumber = SMgrStatus.llSequenceNumber; + + if(!_SRSetRestorePoint(&RestPtInfo, &SMgrStatus)) + { + StatusMessage (hwndDlg, "FAILED_SYS_RESTORE"); + } + } +} + +void DoUninstall (void *arg) +{ + HWND hwndDlg = (HWND) arg; + BOOL bOK = TRUE; + BOOL bTempSkipSysRestore = FALSE; + + if (!Rollback) + EnableWindow (GetDlgItem ((HWND) hwndDlg, IDC_UNINSTALL), FALSE); + + WaitCursor (); + + if (!Rollback) + { + ClearLogWindow (hwndDlg); + } + + if (DoDriverUnload (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 (hwndDlg, FALSE); + + if (DoServiceUninstall (hwndDlg, L"veracrypt") == FALSE) + { + bOK = FALSE; + } + else if (DoRegUninstall ((HWND) hwndDlg, FALSE) == FALSE) + { + bOK = FALSE; + } + else if (DoFilesInstall ((HWND) hwndDlg, InstallationPath) == FALSE) + { + bOK = FALSE; + } + else if (DoShortcutsUninstall (hwndDlg, InstallationPath) == FALSE) + { + bOK = FALSE; + } + else if (!DoApplicationDataUninstall (hwndDlg)) + { + bOK = FALSE; + } + else + { + wchar_t temp[MAX_PATH]; + FILE *f; + + // Deprecated service + DoServiceUninstall (hwndDlg, L"VeraCryptService"); + + GetTempPath (ARRAYSIZE (temp), temp); + StringCbPrintfW (UninstallBatch, sizeof (UninstallBatch), L"%sVeraCrypt-Uninstall.bat", temp); + + UninstallBatch [ARRAYSIZE(UninstallBatch)-1] = 0; + + // Create uninstall batch + f = _wfopen (UninstallBatch, L"w"); + if (!f) + bOK = FALSE; + else + { + fwprintf (f,L":loop\n" + L"del \"%s%s\"\n" + L"if exist \"%s%s\" goto loop\n" + L"rmdir \"%s\"\n" + L"del \"%s\"", + InstallationPath, L"VeraCrypt Setup.exe", + InstallationPath, L"VeraCrypt Setup.exe", + InstallationPath, + UninstallBatch + ); + + CheckFileStreamWriteErrors (hwndDlg, f, UninstallBatch); + fclose (f); + } + } + } + + NormalCursor (); + + if (Rollback) + return; + + if (bSystemRestore && !bTempSkipSysRestore) + SetSystemRestorePoint (hwndDlg, TRUE); + + if (bOK) + PostMessage (hwndDlg, TC_APPMSG_UNINSTALL_SUCCESS, 0, 0); + else + bUninstallInProgress = FALSE; + + EnableWindow (GetDlgItem ((HWND) hwndDlg, IDC_UNINSTALL), TRUE); + OutcomePrompt (hwndDlg, bOK); +} + +void DoInstall (void *arg) +{ + HWND hwndDlg = (HWND) arg; + BOOL bOK = TRUE; + wchar_t path[MAX_PATH]; + + BootEncryption bootEnc (hwndDlg); + + // Refresh the main GUI (wizard thread) + InvalidateRect (MainDlg, NULL, TRUE); + + ClearLogWindow (hwndDlg); + + if (mkfulldir (InstallationPath, TRUE) != 0) + { + if (mkfulldir (InstallationPath, FALSE) != 0) + { + wchar_t szTmp[TC_MAX_PATH]; + + handleWin32Error (hwndDlg, SRC_POS); + StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CANT_CREATE_FOLDER"), InstallationPath); + MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONHAND); + Error ("INSTALL_FAILED", hwndDlg); + PostMessage (MainDlg, TC_APPMSG_INSTALL_FAILURE, 0, 0); + return; + } + } + + UpdateProgressBarProc(2); + + if (DoDriverUnload (hwndDlg) == FALSE) + { + NormalCursor (); + PostMessage (MainDlg, TC_APPMSG_INSTALL_FAILURE, 0, 0); + return; + } + + if (bUpgrade + && (IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L".exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"-x86.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"-x64.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Format.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Format-x86.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Format-x64.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"Expander.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"Expander-x86.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L"Expander-x64.exe") + || IsFileInUse (wstring (InstallationPath) + L'\\' + _T(TC_APP_NAME) L" Setup.exe") + ) + ) + { + NormalCursor (); + Error ("CLOSE_TC_FIRST", hwndDlg); + PostMessage (MainDlg, TC_APPMSG_INSTALL_FAILURE, 0, 0); + return; + } + + UpdateProgressBarProc(12); + + if (bSystemRestore) + SetSystemRestorePoint (hwndDlg, FALSE); + + UpdateProgressBarProc(48); + + if (bDisableSwapFiles + && IsPagingFileActive (FALSE)) + { + if (!DisablePagingFile()) + { + handleWin32Error (hwndDlg, SRC_POS); + Error ("FAILED_TO_DISABLE_PAGING_FILES", hwndDlg); + } + else + bRestartRequired = TRUE; + } + + UpdateProgressBarProc(50); + + // Remove deprecated + DoServiceUninstall (hwndDlg, L"VeraCryptService"); + + UpdateProgressBarProc(55); + + if (!SystemEncryptionUpdate) + DoRegUninstall ((HWND) hwndDlg, TRUE); + + UpdateProgressBarProc(61); + + GetWindowsDirectory (path, ARRAYSIZE (path)); + StringCbCatW (path, sizeof (path), L"\\VeraCrypt Setup.exe"); + StatDeleteFile (path, FALSE); + + if (UpdateProgressBarProc(63) && UnloadDriver && DoServiceUninstall (hwndDlg, L"veracrypt") == FALSE) + { + bOK = FALSE; + } + else if (UpdateProgressBarProc(72) && DoFilesInstall ((HWND) hwndDlg, InstallationPath) == FALSE) + { + bOK = FALSE; + } + else if (UpdateProgressBarProc(80) && DoRegInstall ((HWND) hwndDlg, InstallationPath, bRegisterFileExt) == FALSE) + { + bOK = FALSE; + } + else if (UpdateProgressBarProc(85) && UnloadDriver && DoDriverInstall (hwndDlg) == FALSE) + { + bOK = FALSE; + } + else if (UpdateProgressBarProc(90) && SystemEncryptionUpdate && UpgradeBootLoader (hwndDlg) == FALSE) + { + bOK = FALSE; + } + else if (UpdateProgressBarProc(93) && DoShortcutsInstall (hwndDlg, InstallationPath, bAddToStartMenu, bDesktopIcon) == FALSE) + { + bOK = FALSE; + } + + if (!UnloadDriver) + bRestartRequired = TRUE; + + try + { + bootEnc.RenameDeprecatedSystemLoaderBackup(); + } + catch (...) { } + + if (bOK) + UpdateProgressBarProc(97); + + if (bSystemRestore) + SetSystemRestorePoint (hwndDlg, TRUE); + + if (bOK) + { + UpdateProgressBarProc(100); + UninstallBatch[0] = 0; + StatusMessage (hwndDlg, "INSTALL_COMPLETED"); + } + else + { + UpdateProgressBarProc(0); + + if (!SystemEncryptionUpdate) + { + bUninstall = TRUE; + Rollback = TRUE; + Silent = TRUE; + + DoUninstall (hwndDlg); + + bUninstall = FALSE; + Rollback = FALSE; + Silent = FALSE; + + StatusMessage (hwndDlg, "ROLLBACK"); + } + else + { + Warning ("SYS_ENC_UPGRADE_FAILED", hwndDlg); + } + } + + OutcomePrompt (hwndDlg, bOK); + + if (bOK && !bUninstall && !bDowngrade && !bRepairMode && !bDevm) + { + 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); + } + else if (bPossiblyFirstTimeInstall) + { + SavePostInstallTasksSettings (TC_POST_INSTALL_CFG_TUTORIAL); + } + } + else + { + // No restart will be required + + if (bUpgrade) + { + bPromptReleaseNotes = TRUE; + } + else if (bPossiblyFirstTimeInstall) + { + bPromptTutorial = TRUE; + } + } + } + } + + PostMessage (MainDlg, bOK ? TC_APPMSG_INSTALL_SUCCESS : TC_APPMSG_INSTALL_FAILURE, 0, 0); +} + + +void SetInstallationPath (HWND hwndDlg) +{ + HKEY hkey; + BOOL bInstallPathDetermined = FALSE; + wchar_t path[MAX_PATH+20]; + ITEMIDLIST *itemList; + + memset (InstallationPath, 0, sizeof (InstallationPath)); + + // Determine if VeraCrypt is already installed and try to determine its "Program Files" location + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VeraCrypt", 0, KEY_READ | KEY_WOW64_32KEY, &hkey) == ERROR_SUCCESS) + { + /* Default 'UninstallString' registry strings written by VeraCrypt: + ------------------------------------------------------------------------------------ + 5.0+ "C:\Program Files\VeraCrypt\VeraCrypt Setup.exe" /u + */ + + wchar_t rv[MAX_PATH*4]; + DWORD size = sizeof (rv); + if (RegQueryValueEx (hkey, L"UninstallString", 0, 0, (LPBYTE) &rv, &size) == ERROR_SUCCESS && wcsrchr (rv, L'/')) + { + size_t len = 0; + + // Cut and paste the location (path) where VeraCrypt is installed to InstallationPath + if (rv[0] == L'"') + { + len = wcsrchr (rv, L'/') - rv - 2; + StringCchCopyNW (InstallationPath, ARRAYSIZE(InstallationPath), rv + 1, len); + InstallationPath [len] = 0; + bInstallPathDetermined = TRUE; + + if (InstallationPath [wcslen (InstallationPath) - 1] != L'\\') + { + len = wcsrchr (InstallationPath, L'\\') - InstallationPath; + InstallationPath [len] = 0; + } + } + + } + RegCloseKey (hkey); + } + + if (bInstallPathDetermined) + { + wchar_t mp[MAX_PATH]; + + // Determine whether we were launched from the folder where VeraCrypt is installed + GetModuleFileName (NULL, mp, ARRAYSIZE (mp)); + if (wcsncmp (InstallationPath, mp, min (wcslen(InstallationPath), wcslen(mp))) == 0) + { + // We were launched from the folder where VeraCrypt is installed + + if (!IsNonInstallMode() && !bDevm) + bChangeMode = TRUE; + } + } + else + { + /* VeraCrypt is not installed or it wasn't possible to determine where it is installed. */ + + // Default "Program Files" path. + SHGetSpecialFolderLocation (hwndDlg, CSIDL_PROGRAM_FILES, &itemList); + SHGetPathFromIDList (itemList, path); + + if (Is64BitOs()) + { + // Use a unified default installation path (registry redirection of %ProgramFiles% does not work if the installation path is user-selectable) + wstring s = path; + size_t p = s.find (L" (x86)"); + if (p != wstring::npos) + { + s = s.substr (0, p); + if (_waccess (s.c_str(), 0) != -1) + StringCbCopyW (path, sizeof (path), s.c_str()); + } + } + + StringCbCatW (path, sizeof(path), L"\\VeraCrypt\\"); + StringCbCopyW (InstallationPath, sizeof(InstallationPath), path); + } + + // Make sure the path ends with a backslash + if (InstallationPath [wcslen (InstallationPath) - 1] != L'\\') + { + StringCbCatW (InstallationPath, sizeof(InstallationPath), L"\\"); + } +} + + +// Handler for uninstall only (install is handled by the wizard) +BOOL CALLBACK UninstallDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + + MainDlg = hwndDlg; + + if (!CreateAppSetupMutex ()) + AbortProcess ("TC_INSTALLER_IS_RUNNING"); + + InitDialog (hwndDlg); + LocalizeDialog (hwndDlg, NULL); + + SetWindowTextW (hwndDlg, lpszTitle); + + // System Restore + SetCheckBox (hwndDlg, IDC_SYSTEM_RESTORE, bSystemRestore); + if (SystemRestoreDll == 0) + { + SetCheckBox (hwndDlg, IDC_SYSTEM_RESTORE, FALSE); + EnableWindow (GetDlgItem (hwndDlg, IDC_SYSTEM_RESTORE), FALSE); + } + + SetFocus (GetDlgItem (hwndDlg, IDC_UNINSTALL)); + + return 1; + + case WM_SYSCOMMAND: + if (lw == IDC_ABOUT) + { + DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc); + return 1; + } + return 0; + + case WM_COMMAND: + if (lw == IDC_UNINSTALL) + { + if (bDone) + { + bUninstallInProgress = FALSE; + PostMessage (hwndDlg, WM_CLOSE, 0, 0); + return 1; + } + + bUninstallInProgress = TRUE; + + WaitCursor (); + + if (bUninstall) + _beginthread (DoUninstall, 0, (void *) hwndDlg); + + return 1; + } + + if (lw == IDC_SYSTEM_RESTORE) + { + bSystemRestore = IsButtonChecked (GetDlgItem (hwndDlg, IDC_SYSTEM_RESTORE)); + return 1; + } + + if (lw == IDCANCEL) + { + PostMessage (hwndDlg, WM_CLOSE, 0, 0); + return 1; + } + + return 0; + + case TC_APPMSG_UNINSTALL_SUCCESS: + SetWindowTextW (GetDlgItem ((HWND) hwndDlg, IDC_UNINSTALL), GetString ("FINALIZE")); + NormalCursor (); + return 1; + + case WM_CLOSE: + if (bUninstallInProgress) + { + NormalCursor(); + if (AskNoYes("CONFIRM_EXIT_UNIVERSAL", hwndDlg) == IDNO) + { + return 1; + } + WaitCursor (); + } + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + + return 0; +} + + +int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpszCommandLine, int nCmdShow) +{ + atexit (localcleanup); + + SelfExtractStartupInit(); + + lpszTitle = L"VeraCrypt Setup"; + + /* Call InitApp to initialize the common code */ + InitApp (hInstance, NULL); + + if (IsAdmin () != TRUE) + if (MessageBoxW (NULL, GetString ("SETUP_ADMIN"), lpszTitle, MB_YESNO | MB_ICONQUESTION) != IDYES) + { + FinalizeApp (); + exit (1); + } + + /* Setup directory */ + { + wchar_t *s; + GetModuleFileName (NULL, SetupFilesDir, ARRAYSIZE (SetupFilesDir)); + s = wcsrchr (SetupFilesDir, L'\\'); + if (s) + s[1] = 0; + } + + /* Parse command line arguments */ + + if (lpszCommandLine[0] == L'/') + { + if (lpszCommandLine[1] == L'u') + { + // Uninstall: /u + + bUninstall = TRUE; + } + else if (lpszCommandLine[1] == L'c') + { + // Change: /c + + bChangeMode = TRUE; + } + else if (lpszCommandLine[1] == L'p') + { + // Create self-extracting package: /p + + bMakePackage = TRUE; + } + else if (lpszCommandLine[1] == L'd') + { + // Dev mode: /d + bDevm = TRUE; + } + } + + if (bMakePackage) + { + /* Create self-extracting package */ + + MakeSelfExtractingPackage (NULL, SetupFilesDir); + } + else + { + SetInstallationPath (NULL); + + if (!bUninstall) + { + if (IsSelfExtractingPackage()) + { + if (!VerifyPackageIntegrity()) + { + // Package corrupted + exit (1); + } + bDevm = FALSE; + } + else if (!bDevm) + { + MessageBox (NULL, L"Error: This installer file does not contain any compressed files.\n\nTo create a self-extracting installation package (with embedded compressed files), run:\n\"VeraCrypt Setup.exe\" /p", L"VeraCrypt", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); + FinalizeApp (); + exit (1); + } + + if (bChangeMode) + { + /* VeraCrypt is already installed on this system and we were launched from the Program Files folder */ + + char *tmpStr[] = {0, "SELECT_AN_ACTION", "REPAIR_REINSTALL", "UNINSTALL", "EXIT", 0}; + + // Ask the user to select either Repair or Unistallation + switch (AskMultiChoice ((void **) tmpStr, FALSE, NULL)) + { + case 1: + bRepairMode = TRUE; + break; + case 2: + bUninstall = TRUE; + break; + default: + FinalizeApp (); + exit (1); + } + } + } + + // System Restore + if (IsSystemRestoreEnabled ()) + { + 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 + SystemRestoreDll = 0; + + if (!bUninstall) + { + /* Create the main dialog for install */ + + DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_INSTL_DLG), NULL, (DLGPROC) MainDialogProc, + (LPARAM)lpszCommandLine); + } + else + { + /* Create the main dialog for uninstall */ + + DialogBoxW (hInstance, MAKEINTRESOURCEW (IDD_UNINSTALL), NULL, (DLGPROC) UninstallDlgProc); + + if (UninstallBatch[0]) + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory (&si, sizeof (si)); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + + if (!CreateProcess (UninstallBatch, NULL, NULL, NULL, FALSE, IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) + DeleteFile (UninstallBatch); + else + { + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); + } + } + } + } + FinalizeApp (); + return 0; +} -- cgit v1.2.3