From c606f0866c3a2a5db3ef9bc41738ef33eb9612a9 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sat, 22 Jun 2013 16:16:13 +0200 Subject: Add original TrueCrypt 7.1a sources --- src/Setup/Setup.c | 2160 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2160 insertions(+) create mode 100644 src/Setup/Setup.c (limited to 'src/Setup/Setup.c') diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c new file mode 100644 index 00000000..f607ab00 --- /dev/null +++ b/src/Setup/Setup.c @@ -0,0 +1,2160 @@ +/* + Legal Notice: Some portions of the source code contained in this file were + derived 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) 2003-2012 TrueCrypt Developers Association + and are governed by the TrueCrypt License 3.0 the full text of which is + contained in the file License.txt included in TrueCrypt binary and source + code distribution packages. */ + +#include "Tcdefs.h" +#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 TrueCrypt; + +#pragma warning( disable : 4201 ) +#pragma warning( disable : 4115 ) + +#include + +#pragma warning( default : 4201 ) +#pragma warning( default : 4115 ) + +char InstallationPath[TC_MAX_PATH]; +char SetupFilesDir[TC_MAX_PATH]; +char UninstallBatch[MAX_PATH]; + +LONG InstalledVersion = 0; +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 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 (char *lpszFile) +{ + struct __stat64 st; + + if (_stat64 (lpszFile, &st) == 0) + return DeleteFile (lpszFile); + else + return TRUE; +} + +BOOL StatRemoveDirectory (char *lpszDir) +{ + struct __stat64 st; + + if (_stat64 (lpszDir, &st) == 0) + return RemoveDirectory (lpszDir); + else + return TRUE; +} + +HRESULT CreateLink (char *lpszPathObj, char *lpszArguments, + char *lpszPathLink) +{ + 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); + + // Application ID + if (strstr (lpszPathObj, TC_APP_NAME ".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)) + { + wchar_t wsz[TC_MAX_PATH]; + + /* Ensure that the string is ANSI. */ + MultiByteToWideChar (CP_ACP, 0, lpszPathLink, -1, + wsz, sizeof(wsz) / sizeof(wsz[0])); + + /* Save the link by calling IPersistFile::Save. */ + hres = ppf->Save (wsz, TRUE); + ppf->Release (); + } + psl->Release (); + } + return hres; +} + +void GetProgramPath (HWND hwndDlg, char *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, char *param) +{ + wchar_t szTmp[1024]; + + if (Rollback) + return; + + wsprintfW (szTmp, L"%s %hs", 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, char *txt) +{ + StatusMessageParam (hwndDlg, "ADDING_REG", txt); +} + +void CopyMessage (HWND hwndDlg, char *txt) +{ + StatusMessageParam (hwndDlg, "INSTALLING", txt); +} + +void RemoveMessage (HWND hwndDlg, char *txt) +{ + if (!Rollback) + StatusMessageParam (hwndDlg, "REMOVING", txt); +} + +void IconMessage (HWND hwndDlg, char *txt) +{ + StatusMessageParam (hwndDlg, "ADDING_ICON", txt); +} + +void DetermineUpgradeDowngradeStatus (BOOL bCloseDriverHandle, LONG *driverVersionPtr) +{ + LONG driverVersion = VERSION_NUM; + + if (hDriver == INVALID_HANDLE_VALUE) + DriverAttach(); + + if (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); + + if (bResult) + InstalledVersion = driverVersion; + + bUpgrade = (bResult && driverVersion < VERSION_NUM); + bDowngrade = (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 string &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, char *szDestDir) +{ + /* WARNING: Note that, despite its name, this function is used during UNinstallation as well. */ + + char szTmp[TC_MAX_PATH]; + BOOL bOK = TRUE; + int i, x, fileNo; + char curFileName [TC_MAX_PATH] = {0}; + + if (!bUninstall && !bDevm) + { + // Self-extract all files to memory + + GetModuleFileName (NULL, szTmp, sizeof (szTmp)); + + if (!SelfExtractInMemory (szTmp)) + return FALSE; + } + + x = strlen (szDestDir); + if (x < 2) + return FALSE; + + if (szDestDir[x - 1] != '\\') + strcat (szDestDir, "\\"); + + for (i = 0; i < sizeof (szFiles) / sizeof (szFiles[0]); i++) + { + BOOL bResult; + char szDir[TC_MAX_PATH]; + + if (strstr (szFiles[i], "TrueCrypt Setup") != 0) + { + if (bUninstall) + continue; // Prevent 'access denied' error + + if (bRepairMode) + continue; // Destination = target + } + + if (*szFiles[i] == 'A') + strcpy (szDir, szDestDir); + else if (*szFiles[i] == 'D') + { + GetSystemDirectory (szDir, sizeof (szDir)); + + x = strlen (szDir); + if (szDir[x - 1] != '\\') + strcat (szDir, "\\"); + + strcat (szDir, "Drivers\\"); + } + else if (*szFiles[i] == 'W') + GetWindowsDirectory (szDir, sizeof (szDir)); + + if (*szFiles[i] == 'I') + continue; + + sprintf (szTmp, "%s%s", szDir, szFiles[i] + 1); + + if (bUninstall == FALSE) + CopyMessage (hwndDlg, szTmp); + else + RemoveMessage (hwndDlg, szTmp); + + if (bUninstall == FALSE) + { + SetCurrentDirectory (SetupFilesDir); + + if (strstr (szFiles[i], "TrueCrypt Setup") != 0) + { + // Copy ourselves (the distribution package) to the destination location as 'TrueCrypt Setup.exe' + + char mp[MAX_PATH]; + + GetModuleFileName (NULL, mp, sizeof (mp)); + bResult = TCCopyFile (mp, szTmp); + } + else + { + BOOL driver64 = FALSE; + + strncpy (curFileName, szFiles[i] + 1, strlen (szFiles[i]) - 1); + curFileName [strlen (szFiles[i]) - 1] = 0; + + if (Is64BitOs () + && strcmp (szFiles[i], "Dtruecrypt.sys") == 0) + { + driver64 = TRUE; + strncpy (curFileName, FILENAME_64BIT_DRIVER, sizeof (FILENAME_64BIT_DRIVER)); + } + + 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 (memcmp ( + curFileName, + Decompressed_Files[fileNo].fileName, + min (strlen (curFileName), (size_t) Decompressed_Files[fileNo].fileNameLength)) == 0) + { + // Dump filter driver cannot be installed to SysWOW64 directory + if (driver64 && !EnableWow64FsRedirection (FALSE)) + { + handleWin32Error (hwndDlg); + bResult = FALSE; + goto err; + } + + bResult = SaveBufferToFile ( + (char *) Decompressed_Files[fileNo].fileContent, + szTmp, + Decompressed_Files[fileNo].fileLength, + FALSE); + + if (driver64) + { + if (!EnableWow64FsRedirection (TRUE)) + { + handleWin32Error (hwndDlg); + bResult = FALSE; + goto err; + } + + if (!bResult) + goto err; + + if (bUpgrade && InstalledVersion < 0x700) + { + bResult = WriteLocalMachineRegistryString ("SYSTEM\\CurrentControlSet\\Services\\truecrypt", "ImagePath", "System32\\drivers\\truecrypt.sys", TRUE); + if (!bResult) + { + handleWin32Error (hwndDlg); + goto err; + } + + DeleteFile (szTmp); + } + } + + break; + } + } + } + else + { + if (driver64) + EnableWow64FsRedirection (FALSE); + + bResult = TCCopyFile (curFileName, szTmp); + + if (driver64) + EnableWow64FsRedirection (TRUE); + } + + if (bResult && strcmp (szFiles[i], "ATrueCrypt.exe") == 0) + { + string servicePath = GetServiceConfigPath (TC_APP_NAME ".exe"); + if (FileExists (servicePath.c_str())) + { + CopyMessage (hwndDlg, (char *) servicePath.c_str()); + bResult = CopyFile (szTmp, servicePath.c_str(), FALSE); + } + } + } + } + else + { + bResult = StatDeleteFile (szTmp); + } + +err: + if (bResult == FALSE) + { + LPVOID lpMsgBuf; + DWORD dwError = GetLastError (); + wchar_t szTmp2[700]; + + FormatMessage ( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwError, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (char *) &lpMsgBuf, + 0, + NULL + ); + + + if (bUninstall == FALSE) + wsprintfW (szTmp2, GetString ("INSTALL_OF_FAILED"), szTmp, lpMsgBuf); + else + wsprintfW (szTmp2, GetString ("UNINSTALL_OF_FAILED"), szTmp, 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 ("Language.*.xml", &f); + + if (h != INVALID_HANDLE_VALUE) + { + char d[MAX_PATH*2]; + sprintf (d, "%s%s", szDestDir, f.cFileName); + CopyMessage (hwndDlg, d); + TCCopyFile (f.cFileName, d); + FindClose (h); + } + + SetCurrentDirectory (SetupFilesDir); + SetCurrentDirectory ("Setup files"); + h = FindFirstFile ("TrueCrypt User Guide.*.pdf", &f); + if (h != INVALID_HANDLE_VALUE) + { + char d[MAX_PATH*2]; + sprintf (d, "%s%s", szDestDir, f.cFileName); + CopyMessage (hwndDlg, d); + TCCopyFile (f.cFileName, d); + FindClose (h); + } + SetCurrentDirectory (SetupFilesDir); + } + + return bOK; +} + +BOOL DoRegInstall (HWND hwndDlg, char *szDestDir, BOOL bInstallType) +{ + char szDir[TC_MAX_PATH], *key; + char szTmp[TC_MAX_PATH*4]; + HKEY hkey = 0; + BOOL bSlash, bOK = FALSE; + DWORD dw; + int x; + + if (SystemEncryptionUpdate) + { + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\TrueCrypt", + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) + { + strcpy (szTmp, VERSION_STRING); + RegSetValueEx (hkey, "DisplayVersion", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1); + + strcpy (szTmp, TC_HOMEPAGE); + RegSetValueEx (hkey, "URLInfoAbout", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1); + + RegCloseKey (hkey); + } + + return TRUE; + } + + strcpy (szDir, szDestDir); + x = strlen (szDestDir); + if (szDestDir[x - 1] == '\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + strcat (szDir, "\\"); + + if (bInstallType) + { + + key = "Software\\Classes\\TrueCryptVolume"; + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + strcpy (szTmp, "TrueCrypt Volume"); + if (RegSetValueEx (hkey, "", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + sprintf (szTmp, "%ws", TC_APPLICATION_ID); + if (RegSetValueEx (hkey, "AppUserModelID", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + key = "Software\\Classes\\TrueCryptVolume\\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; + + sprintf (szTmp, "%sTrueCrypt.exe,1", szDir); + if (RegSetValueEx (hkey, "", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + key = "Software\\Classes\\TrueCryptVolume\\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; + + sprintf (szTmp, "\"%sTrueCrypt.exe\" /v \"%%1\"", szDir ); + if (RegSetValueEx (hkey, "", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + key = "Software\\Classes\\.tc"; + BOOL typeClassChanged = TRUE; + char typeClass[256]; + DWORD typeClassSize = sizeof (typeClass); + + if (ReadLocalMachineRegistryString (key, "", typeClass, &typeClassSize) && typeClassSize > 0 && strcmp (typeClass, "TrueCryptVolume") == 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; + + strcpy (szTmp, "TrueCryptVolume"); + if (RegSetValueEx (hkey, "", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + RegCloseKey (hkey); + hkey = 0; + + if (typeClassChanged) + SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + key = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\TrueCrypt"; + RegMessage (hwndDlg, key); + if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, + key, + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &dw) != ERROR_SUCCESS) + goto error; + + /* IMPORTANT: IF YOU CHANGE THIS IN ANY WAY, REVISE AND UPDATE SetInstallationPath() ACCORDINGLY! */ + sprintf (szTmp, "\"%sTrueCrypt Setup.exe\" /u", szDir); + if (RegSetValueEx (hkey, "UninstallString", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + sprintf (szTmp, "\"%sTrueCrypt Setup.exe\" /c", szDir); + if (RegSetValueEx (hkey, "ModifyPath", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + sprintf (szTmp, "\"%sTrueCrypt Setup.exe\"", szDir); + if (RegSetValueEx (hkey, "DisplayIcon", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + strcpy (szTmp, VERSION_STRING); + if (RegSetValueEx (hkey, "DisplayVersion", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + strcpy (szTmp, "TrueCrypt"); + if (RegSetValueEx (hkey, "DisplayName", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + strcpy (szTmp, "TrueCrypt Foundation"); + if (RegSetValueEx (hkey, "Publisher", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + strcpy (szTmp, TC_HOMEPAGE); + if (RegSetValueEx (hkey, "URLInfoAbout", 0, REG_SZ, (BYTE *) szTmp, strlen (szTmp) + 1) != ERROR_SUCCESS) + goto error; + + bOK = TRUE; + +error: + if (hkey != 0) + RegCloseKey (hkey); + + if (bOK == FALSE) + { + handleWin32Error (hwndDlg); + Error ("REG_INSTALL_FAILED"); + } + + // Register COM servers for UAC + if (IsOSAtLeast (WIN_VISTA)) + { + if (!RegisterComServers (szDir)) + { + Error ("COM_REG_FAILED"); + return FALSE; + } + } + + return bOK; +} + +BOOL DoApplicationDataUninstall (HWND hwndDlg) +{ + char path[MAX_PATH]; + char path2[MAX_PATH]; + BOOL bOK = TRUE; + + StatusMessage (hwndDlg, "REMOVING_APPDATA"); + + SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); + strcat (path, "\\TrueCrypt\\"); + + // Delete favorite volumes file + sprintf (path2, "%s%s", path, TC_APPD_FILENAME_FAVORITE_VOLUMES); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2); + + // Delete keyfile defaults + sprintf (path2, "%s%s", path, TC_APPD_FILENAME_DEFAULT_KEYFILES); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2); + + // Delete history file + sprintf (path2, "%s%s", path, TC_APPD_FILENAME_HISTORY); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2); + + // Delete configuration file + sprintf (path2, "%s%s", path, TC_APPD_FILENAME_CONFIGURATION); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2); + + // Delete system encryption configuration file + sprintf (path2, "%s%s", path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION); + RemoveMessage (hwndDlg, path2); + StatDeleteFile (path2); + + SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); + strcat (path, "\\TrueCrypt"); + RemoveMessage (hwndDlg, path); + if (!StatRemoveDirectory (path)) + { + handleWin32Error (hwndDlg); + bOK = FALSE; + } + + return bOK; +} + +BOOL DoRegUninstall (HWND hwndDlg, BOOL bRemoveDeprecated) +{ + BOOL bOK = FALSE; + char regk [64]; + + // Unregister COM servers + if (!bRemoveDeprecated && IsOSAtLeast (WIN_VISTA)) + { + if (!UnregisterComServers (InstallationPath)) + StatusMessage (hwndDlg, "COM_DEREG_FAILED"); + } + + if (!bRemoveDeprecated) + StatusMessage (hwndDlg, "REMOVING_REG"); + + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\TrueCrypt"); + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Classes\\TrueCryptVolume\\Shell\\open\\command"); + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Classes\\TrueCryptVolume\\Shell\\open"); + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Classes\\TrueCryptVolume\\Shell"); + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Classes\\TrueCryptVolume\\DefaultIcon"); + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Classes\\TrueCryptVolume"); + RegDeleteKey (HKEY_CURRENT_USER, "Software\\TrueCrypt"); + + if (!bRemoveDeprecated) + { + GetStartupRegKeyName (regk); + DeleteRegistryValue (regk, "TrueCrypt"); + + RegDeleteKey (HKEY_LOCAL_MACHINE, "Software\\Classes\\.tc"); + SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + } + + bOK = TRUE; + + if (bOK == FALSE && GetLastError ()!= ERROR_NO_TOKEN && GetLastError ()!= ERROR_FILE_NOT_FOUND + && GetLastError ()!= ERROR_PATH_NOT_FOUND) + { + handleWin32Error (hwndDlg); + } + else + bOK = TRUE; + + return bOK; +} + + +BOOL DoServiceUninstall (HWND hwndDlg, char *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 (strcmp ("truecrypt", 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 (strcmp ("truecrypt", lpszService) == 0) + StatusMessage (hwndDlg, "REMOVING_DRIVER"); + else + StatusMessageParam (hwndDlg, "REMOVING", lpszService); + + if (hService != NULL) + CloseServiceHandle (hService); + + if (hManager != NULL) + CloseServiceHandle (hManager); + + 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); + + Sleep(1000); + firstTry = FALSE; + goto retry; + } + + goto error; + } + + bOK = TRUE; + +error: + + if (bOK == FALSE && GetLastError ()!= ERROR_SERVICE_DOES_NOT_EXIST) + { + handleWin32Error (hwndDlg); + 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); + AbortProcess ("NODRIVER"); + } + + if (status != ERR_OS_ERROR) + { + handleError (NULL, status); + 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") == IDNO) + AbortProcessSilent (); + } + } + } + catch (...) { } + + if (bUninstallInProgress && driverVersion >= 0x500 && !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"); + 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); + } + } + + // 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 TrueCrypt for the first time now (we also cannot know if the user has already + // installed and used TrueCrypt on another system before). + bPossiblyFirstTimeInstall = TRUE; + } + + return bOK; +} + + +BOOL UpgradeBootLoader (HWND hwndDlg) +{ + if (!SystemEncryptionUpdate) + return TRUE; + + try + { + BootEncryption bootEnc (hwndDlg); + if (bootEnc.GetInstalledBootLoaderVersion() < 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"); + } + return TRUE; + } + catch (Exception &e) + { + e.Show (hwndDlg); + } + catch (...) { } + + Error ("BOOT_LOADER_UPGRADE_FAILED"); + return FALSE; +} + + +BOOL DoShortcutsUninstall (HWND hwndDlg, char *szDestDir) +{ + char szLinkDir[TC_MAX_PATH]; + char 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 = strlen (szLinkDir); + if (szLinkDir[x - 1] == '\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + strcat (szLinkDir, "\\"); + + strcat (szLinkDir, "TrueCrypt"); + + // Global start menu + { + struct _stat st; + char path[TC_MAX_PATH]; + + SHGetSpecialFolderPath (hwndDlg, path, CSIDL_COMMON_PROGRAMS, 0); + strcat (path, "\\TrueCrypt"); + + if (_stat (path, &st) == 0) + { + strcpy (szLinkDir, path); + allUsers = TRUE; + } + } + + // Start menu entries + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt.lnk"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2) == FALSE) + goto error; + + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt Website.url"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2) == FALSE) + goto error; + + sprintf (szTmp2, "%s%s", szLinkDir, "\\Uninstall TrueCrypt.lnk"); + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2) == FALSE) + goto error; + + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt User's Guide.lnk"); + DeleteFile (szTmp2); + + // Start menu group + RemoveMessage ((HWND) hwndDlg, szLinkDir); + if (StatRemoveDirectory (szLinkDir) == FALSE) + handleWin32Error ((HWND) hwndDlg); + + // Desktop icon + + if (allUsers) + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_COMMON_DESKTOPDIRECTORY, 0); + else + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_DESKTOPDIRECTORY, 0); + + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt.lnk"); + + RemoveMessage (hwndDlg, szTmp2); + if (StatDeleteFile (szTmp2) == FALSE) + goto error; + + bOK = TRUE; + +error: + OleUninitialize (); + + return bOK; +} + +BOOL DoShortcutsInstall (HWND hwndDlg, char *szDestDir, BOOL bProgGroup, BOOL bDesktopIcon) +{ + char szLinkDir[TC_MAX_PATH], szDir[TC_MAX_PATH]; + char 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 = strlen (szLinkDir); + if (szLinkDir[x - 1] == '\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + strcat (szLinkDir, "\\"); + + strcat (szLinkDir, "TrueCrypt"); + + strcpy (szDir, szDestDir); + x = strlen (szDestDir); + if (szDestDir[x - 1] == '\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + strcat (szDir, "\\"); + + if (bProgGroup) + { + FILE *f; + + if (mkfulldir (szLinkDir, TRUE) != 0) + { + if (mkfulldir (szLinkDir, FALSE) != 0) + { + wchar_t szTmp[TC_MAX_PATH]; + + handleWin32Error (hwndDlg); + wsprintfW (szTmp, GetString ("CANT_CREATE_FOLDER"), szLinkDir); + MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONHAND); + goto error; + } + } + + sprintf (szTmp, "%s%s", szDir, "TrueCrypt.exe"); + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt.lnk"); + + IconMessage (hwndDlg, szTmp2); + if (CreateLink (szTmp, "", szTmp2) != S_OK) + goto error; + + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt Website.url"); + IconMessage (hwndDlg, szTmp2); + f = fopen (szTmp2, "w"); + if (f) + { + fprintf (f, "[InternetShortcut]\nURL=%s\n", TC_HOMEPAGE); + + CheckFileStreamWriteErrors (f, szTmp2); + fclose (f); + } + else + goto error; + + sprintf (szTmp, "%s%s", szDir, "TrueCrypt Setup.exe"); + sprintf (szTmp2, "%s%s", szLinkDir, "\\Uninstall TrueCrypt.lnk"); + strcpy (szTmp3, "/u"); + + IconMessage (hwndDlg, szTmp2); + if (CreateLink (szTmp, szTmp3, szTmp2) != S_OK) + goto error; + + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt User's Guide.lnk"); + DeleteFile (szTmp2); + } + + if (bDesktopIcon) + { + strcpy (szDir, szDestDir); + x = strlen (szDestDir); + if (szDestDir[x - 1] == '\\') + bSlash = TRUE; + else + bSlash = FALSE; + + if (bSlash == FALSE) + strcat (szDir, "\\"); + + if (bForAllUsers) + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_COMMON_DESKTOPDIRECTORY, 0); + else + SHGetSpecialFolderPath (hwndDlg, szLinkDir, CSIDL_DESKTOPDIRECTORY, 0); + + sprintf (szTmp, "%s%s", szDir, "TrueCrypt.exe"); + sprintf (szTmp2, "%s%s", szLinkDir, "\\TrueCrypt.lnk"); + + IconMessage (hwndDlg, szTmp2); + + if (CreateLink (szTmp, "", szTmp2) != 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"); + else + Info ("SETUP_UPDATE_OK"); + } + else + { + wchar_t str[4096]; + + swprintf (str, GetString ("UNINSTALL_OK"), InstallationPath); + MessageBoxW (hwndDlg, str, lpszTitle, MB_ICONASTERISK); + } + } + else + { + if (bUninstall == FALSE) + Error ("INSTALL_FAILED"); + else + Error ("UNINSTALL_FAILED"); + } +} + +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,"SRSetRestorePointA"); + 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; + strcpy (RestPtInfo.szDescription, bUninstall ? "TrueCrypt uninstallation" : "TrueCrypt 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, "truecrypt") == 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 + { + char temp[MAX_PATH]; + FILE *f; + + // Deprecated service + DoServiceUninstall (hwndDlg, "TrueCryptService"); + + GetTempPath (sizeof (temp), temp); + _snprintf (UninstallBatch, sizeof (UninstallBatch), "%s\\TrueCrypt-Uninstall.bat", temp); + + UninstallBatch [sizeof(UninstallBatch)-1] = 0; + + // Create uninstall batch + f = fopen (UninstallBatch, "w"); + if (!f) + bOK = FALSE; + else + { + fprintf (f, ":loop\n" + "del \"%s%s\"\n" + "if exist \"%s%s\" goto loop\n" + "rmdir \"%s\"\n" + "del \"%s\"", + InstallationPath, "TrueCrypt Setup.exe", + InstallationPath, "TrueCrypt Setup.exe", + InstallationPath, + UninstallBatch + ); + + CheckFileStreamWriteErrors (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; + char 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); + wsprintfW (szTmp, GetString ("CANT_CREATE_FOLDER"), InstallationPath); + MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONHAND); + Error ("INSTALL_FAILED"); + 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 (string (InstallationPath) + '\\' + TC_APP_NAME ".exe") + || IsFileInUse (string (InstallationPath) + '\\' + TC_APP_NAME " Format.exe") + || IsFileInUse (string (InstallationPath) + '\\' + TC_APP_NAME " Setup.exe") + ) + ) + { + NormalCursor (); + Error ("CLOSE_TC_FIRST"); + 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); + Error ("FAILED_TO_DISABLE_PAGING_FILES"); + } + else + bRestartRequired = TRUE; + } + + UpdateProgressBarProc(50); + + // Remove deprecated + DoServiceUninstall (hwndDlg, "TrueCryptService"); + + UpdateProgressBarProc(55); + + if (!SystemEncryptionUpdate) + DoRegUninstall ((HWND) hwndDlg, TRUE); + + if (SystemEncryptionUpdate && InstalledVersion < 0x700) + { + try + { + bootEnc.RegisterFilterDriver (false, BootEncryption::DumpFilter); + } + catch (...) { } + + try + { + bootEnc.RegisterFilterDriver (true, BootEncryption::DumpFilter); + } + catch (Exception &e) + { + try + { + bootEnc.RegisterFilterDriver (false, BootEncryption::DumpFilter); + } + catch (...) { } + + e.Show (hwndDlg); + + bOK = FALSE; + goto outcome; + } + + if (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES) + { + WriteLocalMachineRegistryString ("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, "Service", FALSE); + WriteLocalMachineRegistryString ("SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, "Service", FALSE); + } + } + + UpdateProgressBarProc(61); + + if (bUpgrade && InstalledVersion < 0x700) + { + bool bMountFavoritesOnLogon = ConfigReadInt ("MountFavoritesOnLogon", FALSE) != 0; + bool bOpenExplorerWindowAfterMount = ConfigReadInt ("OpenExplorerWindowAfterMount", FALSE) != 0; + + if (bMountFavoritesOnLogon || bOpenExplorerWindowAfterMount) + { + char *favoritesFilename = GetConfigPath (TC_APPD_FILENAME_FAVORITE_VOLUMES); + DWORD size; + char *favoritesXml = LoadFile (favoritesFilename, &size); + + if (favoritesXml && size != 0) + { + string favorites; + favorites.insert (0, favoritesXml, size); + + size_t p = favorites.find ("