VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Setup/Setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Setup/Setup.c')
-rw-r--r--src/Setup/Setup.c5264
1 files changed, 2632 insertions, 2632 deletions
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 <SrRestorePtApi.h>
-#include <io.h>
-#include <propkey.h>
-#include <propvarutil.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <tchar.h>
-
-#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 <shlobj.h>
-
-#pragma warning( default : 4201 )
-#pragma warning( default : 4115 )
-
-#include <Strsafe.h>
-
-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<std::wstring> 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<std::wstring>::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<std::wstring> 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<std::wstring>::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 <SrRestorePtApi.h>
+#include <io.h>
+#include <propkey.h>
+#include <propvarutil.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <tchar.h>
+
+#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 <shlobj.h>
+
+#pragma warning( default : 4201 )
+#pragma warning( default : 4115 )
+
+#include <Strsafe.h>
+
+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<std::wstring> 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<std::wstring>::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<std::wstring> 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<std::wstring>::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;
+}