/* 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-2015 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "Tcdefs.h" #include #include #include #include #include #include #include #include "Apidrvr.h" #include "BootEncryption.h" #include "Boot/Windows/BootCommon.h" #include "Combo.h" #include "ComSetup.h" #include "Dlgcode.h" #include "Language.h" #include "Registry.h" #include "Resource.h" #include "Dir.h" #include "Setup.h" #include "SelfExtract.h" #include "Wizard.h" #include "../Common/Resource.h" using namespace VeraCrypt; #pragma warning( disable : 4201 ) #pragma warning( disable : 4115 ) #include #pragma warning( default : 4201 ) #pragma warning( default : 4115 ) #include wchar_t InstallationPath[TC_MAX_PATH]; wchar_t SetupFilesDir[TC_MAX_PATH]; wchar_t UninstallBatch[MAX_PATH]; BOOL bUninstall = FALSE; BOOL bRestartRequired = FALSE; BOOL bMakePackage = FALSE; BOOL bDone = FALSE; BOOL Rollback = FALSE; BOOL bUpgrade = FALSE; BOOL bDowngrade = FALSE; BOOL SystemEncryptionUpdate = FALSE; BOOL PortableMode = FALSE; BOOL bRepairMode = FALSE; BOOL bReinstallMode = FALSE; BOOL bChangeMode = FALSE; BOOL bDevm = FALSE; BOOL bPossiblyFirstTimeInstall = FALSE; BOOL bUninstallInProgress = FALSE; BOOL UnloadDriver = TRUE; BOOL bSystemRestore = TRUE; BOOL bDisableSwapFiles = FALSE; BOOL bForAllUsers = TRUE; BOOL bRegisterFileExt = TRUE; BOOL bAddToStartMenu = TRUE; BOOL bDesktopIcon = TRUE; BOOL bDesktopIconStatusDetermined = FALSE; HMODULE volatile SystemRestoreDll = 0; void localcleanup (void) { localcleanupwiz (); cleanup (); CloseAppSetupMutex (); } BOOL 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) DeleteFile (szOldPath); } if (_wstat64 (lpszFile, &st) == 0) return DeleteFile (lpszFile); else return TRUE; } BOOL StatRemoveDirectory (wchar_t *lpszDir) { struct __stat64 st; if (_wstat64 (lpszDir, &st) == 0) { BOOL bStatus = RemoveDirectory (lpszDir); if (!bStatus) { /* force removal of the non empty directory */ wchar_t szOpPath[TC_MAX_PATH + 1] = {0}; SHFILEOPSTRUCTW op; StringCchCopyW(szOpPath, ARRAYSIZE(szOpPath)-1, lpszDir); ZeroMemory(&op, sizeof(op)); op.wFunc = FO_DELETE; op.pFrom = szOpPath; op.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR; if ((0 == SHFileOperation(&op)) && (!op.fAnyOperationsAborted)) bStatus = TRUE; } return bStatus; } else return TRUE; } /* Recursively set the given OWNER security descriptor to the key and its subkeys */ static void RecursiveSetOwner (HKEY hKey, PSECURITY_DESCRIPTOR pSD) { LSTATUS status = 0; DWORD dwIndex = 0, dwMaxNameLen = 0, dwNameLen = 0, numberSubKeys = 0; HKEY hSubKey; if ( (ERROR_SUCCESS == status) && (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, NULL, &numberSubKeys, &dwMaxNameLen, NULL, NULL, NULL, NULL, NULL, NULL)) && (numberSubKeys >= 1) ) { dwMaxNameLen++; wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; while (true) { dwNameLen = dwMaxNameLen; status = RegEnumKeyExW (hKey, dwIndex++, szNameValue, &dwNameLen, NULL, NULL, NULL, NULL); if (status == ERROR_SUCCESS) { status = RegOpenKeyExW (hKey, szNameValue, 0, WRITE_OWNER | KEY_READ , &hSubKey); if (ERROR_SUCCESS == status) { RecursiveSetOwner (hSubKey, pSD); RegCloseKey(hSubKey); } } else break; } delete [] szNameValue; } RegSetKeySecurity (hKey, OWNER_SECURITY_INFORMATION, pSD); } /* Recursively set the given DACL security descriptor to the key and its subkeys */ static void RecursiveSetDACL (HKEY hKey, const wchar_t* SubKeyName, PSECURITY_DESCRIPTOR pSD) { HKEY hSubKey; DWORD dwIndex = 0, dwMaxNameLen = 0, dwNameLen = 0, numberSubKeys = 0; LSTATUS status = RegOpenKeyExW(hKey, SubKeyName, 0, WRITE_DAC | KEY_READ /*| ACCESS_SYSTEM_SECURITY*/, &hSubKey); if (status == ERROR_SUCCESS) { status = RegSetKeySecurity (hSubKey, DACL_SECURITY_INFORMATION, pSD); if (status == ERROR_SUCCESS) { RegCloseKey(hSubKey); status = RegOpenKeyExW(hKey, SubKeyName, 0, WRITE_DAC | KEY_READ , &hSubKey); } if ( (ERROR_SUCCESS == status) && (ERROR_SUCCESS == RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &numberSubKeys, &dwMaxNameLen, NULL, NULL, NULL, NULL, NULL, NULL)) && (numberSubKeys >= 1) ) { dwMaxNameLen++; wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; while (true) { dwNameLen = dwMaxNameLen; status = RegEnumKeyExW (hSubKey, dwIndex++, szNameValue, &dwNameLen, NULL, NULL, NULL, NULL); if (status == ERROR_SUCCESS) { RecursiveSetDACL (hSubKey, szNameValue, pSD); } else break; } delete [] szNameValue; } } } /* Correct the key permissions to allow its deletion */ static void AllowKeyAccess(HKEY Key,const wchar_t* SubKeyName) { LSTATUS RegResult; HKEY SvcKey = NULL; DWORD dwLength = 0; HANDLE Token = NULL; PTOKEN_USER pTokenUser = NULL; std::string sNewSD; RegResult = RegOpenKeyExW(Key, SubKeyName, 0, WRITE_OWNER | KEY_READ, &SvcKey); if (RegResult==ERROR_SUCCESS) { if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token)) { if (!GetTokenInformation(Token, TokenUser, pTokenUser, 0, &dwLength)) { if (GetLastError() ==ERROR_INSUFFICIENT_BUFFER) { pTokenUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if (pTokenUser) { if (GetTokenInformation(Token, TokenUser, pTokenUser, dwLength, &dwLength)) { SECURITY_DESCRIPTOR SecDesc; if ( InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION) && SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, FALSE) // NULL DACL: full access to everyone && SetSecurityDescriptorOwner(&SecDesc, pTokenUser->User.Sid, FALSE) ) { RecursiveSetOwner(SvcKey, &SecDesc); } } } } } } RegCloseKey(SvcKey); } if (pTokenUser) { PSID pSid = pTokenUser->User.Sid; DWORD dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + ::GetLengthSid(pSid) - sizeof(DWORD); PACL pDacl = (PACL) new BYTE[dwAclSize]; if (pDacl) { if (TRUE == ::InitializeAcl(pDacl, dwAclSize, ACL_REVISION)) { if (TRUE == AddAccessAllowedAceEx(pDacl, ACL_REVISION, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, WRITE_DAC | KEY_ALL_ACCESS, pSid)) { SECURITY_DESCRIPTOR SecDesc; if (TRUE == ::InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION)) { if (TRUE == ::SetSecurityDescriptorDacl(&SecDesc, TRUE, pDacl, FALSE)) { RecursiveSetDACL (Key, SubKeyName, &SecDesc); } } } } delete [] pDacl; } } if (pTokenUser) HeapFree(GetProcessHeap(), 0, pTokenUser); if (Token) CloseHandle(Token); } void SearchAndDeleteRegistrySubString (HKEY hKey, const wchar_t *subKey, const wchar_t *str, BOOL bEnumSubKeys, const wchar_t* enumMatchSubStr) { HKEY hSubKey = 0; LSTATUS status = 0; DWORD dwIndex = 0, dwType, dwValueNameLen, dwDataLen; std::list subKeysList; size_t subStringLength = str? wcslen(str) : 0; if (bEnumSubKeys) { DWORD dwMaxNameLen = 0; if (ERROR_SUCCESS == RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwMaxNameLen, NULL, NULL, NULL, NULL, NULL, NULL)) { dwMaxNameLen++; wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; dwIndex = 0; while (true) { dwValueNameLen = dwMaxNameLen; status = RegEnumKeyExW (hKey, dwIndex++, szNameValue, &dwValueNameLen, NULL, NULL, NULL, NULL); if (status == ERROR_SUCCESS) { if (enumMatchSubStr && !wcsstr(szNameValue, enumMatchSubStr)) continue; std::wstring entryName = szNameValue; entryName += L"\\"; entryName += subKey; entryName += L"\\"; subKeysList.push_back(entryName); } else break; } delete [] szNameValue; } } else { subKeysList.push_back(subKey); } for (std::list::iterator ItSubKey = subKeysList.begin(); ItSubKey != subKeysList.end(); ItSubKey++) { // if the string to search for is empty, delete the sub key, otherwise, look for matching value and delete them if (subStringLength == 0) { if (ERROR_ACCESS_DENIED == SHDeleteKeyW (hKey, ItSubKey->c_str())) { // grant permission to delete AllowKeyAccess (hKey, ItSubKey->c_str()); // try again SHDeleteKeyW (hKey, ItSubKey->c_str()); } } else { if (RegOpenKeyExW (hKey, ItSubKey->c_str(), 0, KEY_ALL_ACCESS, &hSubKey) == ERROR_SUCCESS) { DWORD dwMaxNameLen = 0, dwMaxDataLen = 0; if (ERROR_SUCCESS == RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwMaxNameLen, &dwMaxDataLen, NULL, NULL)) { dwMaxNameLen++; wchar_t* szNameValue = new wchar_t[dwMaxNameLen]; LPBYTE pbData = new BYTE[dwMaxDataLen]; std::list foundEntries; dwIndex = 0; do { dwValueNameLen = dwMaxNameLen; dwDataLen = dwMaxDataLen; status = RegEnumValueW(hSubKey, dwIndex++, szNameValue, &dwValueNameLen, NULL, &dwType, pbData, &dwDataLen); if (status == ERROR_SUCCESS) { if ( (wcslen(szNameValue) >= subStringLength && wcsstr(szNameValue, str)) || (dwType == REG_SZ && wcslen((wchar_t*) pbData) >= subStringLength && wcsstr((wchar_t*) pbData, str)) ) { foundEntries.push_back(szNameValue); } } } while ((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)); // we ignore ERROR_MORE_DATA errors since // we are sure to use the correct sizes // delete the entries if (!foundEntries.empty()) { for (std::list::iterator It = foundEntries.begin(); It != foundEntries.end(); It++) { RegDeleteValueW (hSubKey, It->c_str()); } } delete [] szNameValue; delete [] pbData; } RegCloseKey (hSubKey); } } } } /* Set the given privilege of the current process */ BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable) { TOKEN_PRIVILEGES tp; LUID luid; HANDLE hProcessToken; BOOL bStatus = FALSE; if ( OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hProcessToken) ) { if ( LookupPrivilegeValue( NULL, szPrivilegeName, &luid ) ) { tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = bEnable? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED; // Enable the privilege bStatus = AdjustTokenPrivileges( hProcessToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL); } CloseHandle(hProcessToken); } return bStatus; } 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 (InitPropVariantFromString (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; 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') { 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, sizeof (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 { BOOL driver64 = FALSE; 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) { driver64 = TRUE; 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()); DeleteFile (favoritesLegacyFile.c_str()); } if (FileExists (serviceLegacyPath.c_str())) { RemoveMessage (hwndDlg, (wchar_t *) serviceLegacyPath.c_str()); DeleteFile (serviceLegacyPath.c_str()); } EnableWow64FsRedirection (TRUE); } } } } else { bResult = StatDeleteFile (szTmp, 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()); DeleteFile (favoritesFile.c_str()); } if (FileExists (servicePath.c_str())) { RemoveMessage (hwndDlg, (wchar_t *) servicePath.c_str()); DeleteFile (servicePath.c_str()); } if (Is64BitOs ()) { if (FileExists (favoritesLegacyFile.c_str())) { RemoveMessage (hwndDlg, (wchar_t *) favoritesLegacyFile.c_str()); DeleteFile (favoritesLegacyFile.c_str()); } if (FileExists (serviceLegacyPath.c_str())) { RemoveMessage (hwndDlg, (wchar_t *) serviceLegacyPath.c_str()); DeleteFile (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"); SHDeleteKey (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"); DeleteFile (szTmp2); // 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"); DeleteFile (szTmp2); } 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"); DeleteFile (path); 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"; InitCommonControls (); /* 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; }