VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Setup
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2013-06-22 16:16:13 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2014-11-08 23:18:07 +0100
commitc606f0866c3a2a5db3ef9bc41738ef33eb9612a9 (patch)
tree5847c644cdfff3c1dd55b88b565448087ae89f11 /src/Setup
downloadVeraCrypt-c606f0866c3a2a5db3ef9bc41738ef33eb9612a9.tar.gz
VeraCrypt-c606f0866c3a2a5db3ef9bc41738ef33eb9612a9.zip
Add original TrueCrypt 7.1a sources
Diffstat (limited to 'src/Setup')
-rw-r--r--src/Setup/ComSetup.cpp88
-rw-r--r--src/Setup/ComSetup.h18
-rw-r--r--src/Setup/ComSetup.rgs92
-rw-r--r--src/Setup/Dir.c104
-rw-r--r--src/Setup/Dir.h21
-rw-r--r--src/Setup/Resource.h64
-rw-r--r--src/Setup/SelfExtract.c734
-rw-r--r--src/Setup/SelfExtract.h39
-rw-r--r--src/Setup/Setup.c2160
-rw-r--r--src/Setup/Setup.h100
-rw-r--r--src/Setup/Setup.icobin0 -> 13382 bytes
-rw-r--r--src/Setup/Setup.manifest21
-rw-r--r--src/Setup/Setup.rc327
-rw-r--r--src/Setup/Setup.vcproj482
-rw-r--r--src/Setup/TrueCrypt_setup.bmpbin0 -> 49398 bytes
-rw-r--r--src/Setup/TrueCrypt_setup_background.bmpbin0 -> 822 bytes
-rw-r--r--src/Setup/Wizard.c1203
-rw-r--r--src/Setup/Wizard.h29
18 files changed, 5482 insertions, 0 deletions
diff --git a/src/Setup/ComSetup.cpp b/src/Setup/ComSetup.cpp
new file mode 100644
index 00000000..1608bcea
--- /dev/null
+++ b/src/Setup/ComSetup.cpp
@@ -0,0 +1,88 @@
+/*
+ Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved.
+
+ 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.
+*/
+
+#define TC_MAIN_COM_VERSION_MAJOR 2
+#define TC_MAIN_COM_VERSION_MINOR 4
+
+#define TC_FORMAT_COM_VERSION_MAJOR 2
+#define TC_FORMAT_COM_VERSION_MINOR 4
+
+#include <atlbase.h>
+#include <comdef.h>
+#include <statreg.h>
+#include <windows.h>
+#include "ComSetup.h"
+#include "Dlgcode.h"
+#include "Resource.h"
+#include "../Mount/MainCom_i.c"
+#include "../Format/FormatCom_i.c"
+
+
+extern "C" BOOL RegisterComServers (char *modulePath)
+{
+ BOOL ret = TRUE;
+ wchar_t mainModule[1024], formatModule[1024];
+ CComPtr<ITypeLib> tl, tl2;
+
+ wsprintfW (mainModule, L"%hsTrueCrypt.exe", modulePath);
+ wsprintfW (formatModule, L"%hsTrueCrypt Format.exe", modulePath);
+
+ UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR, 0, SYS_WIN32);
+ UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR, 0, SYS_WIN32);
+
+ wchar_t setupModule[MAX_PATH];
+ GetModuleFileNameW (NULL, setupModule, sizeof (setupModule) / sizeof (setupModule[0]));
+
+ CRegObject ro;
+ HRESULT r;
+
+ if (!SUCCEEDED (r = ro.FinalConstruct ())
+ || !SUCCEEDED (r = ro.AddReplacement (L"MAIN_MODULE", mainModule))
+ || !SUCCEEDED (r = ro.AddReplacement (L"FORMAT_MODULE", formatModule))
+ || !SUCCEEDED (r = ro.ResourceRegister (setupModule, IDR_COMREG, L"REGISTRY"))
+ || !SUCCEEDED (r = LoadTypeLib (mainModule, &tl))
+ || !SUCCEEDED (r = RegisterTypeLib (tl, mainModule, 0))
+ || !SUCCEEDED (r = LoadTypeLib (formatModule, &tl2))
+ || !SUCCEEDED (r = RegisterTypeLib (tl2, formatModule, 0)))
+ {
+ MessageBox (MainDlg, _com_error (r).ErrorMessage(), TC_APP_NAME, MB_ICONERROR);
+ ret = FALSE;
+ }
+
+ ro.FinalRelease ();
+ return ret;
+}
+
+
+extern "C" BOOL UnregisterComServers (char *modulePath)
+{
+ BOOL ret;
+
+ if (UnRegisterTypeLib (LIBID_TrueCryptMainCom, TC_MAIN_COM_VERSION_MAJOR, TC_MAIN_COM_VERSION_MINOR, 0, SYS_WIN32) != S_OK)
+ return FALSE;
+ if (UnRegisterTypeLib (LIBID_TrueCryptFormatCom, TC_FORMAT_COM_VERSION_MAJOR, TC_FORMAT_COM_VERSION_MINOR, 0, SYS_WIN32) != S_OK)
+ return FALSE;
+
+ wchar_t module[1024];
+ CRegObject ro;
+ ro.FinalConstruct ();
+
+ wsprintfW (module, L"%hsTrueCrypt.exe", modulePath);
+ ro.AddReplacement (L"MAIN_MODULE", module);
+
+ wsprintfW (module, L"%hsTrueCrypt Format.exe", modulePath);
+ ro.AddReplacement (L"FORMAT_MODULE", module);
+
+ wchar_t setupModule[MAX_PATH];
+ GetModuleFileNameW (NULL, setupModule, sizeof (setupModule) / sizeof (setupModule[0]));
+
+ ret = ro.ResourceUnregister (setupModule, IDR_COMREG, L"REGISTRY") == S_OK;
+
+ ro.FinalRelease ();
+ return ret;
+}
diff --git a/src/Setup/ComSetup.h b/src/Setup/ComSetup.h
new file mode 100644
index 00000000..7a9fad2d
--- /dev/null
+++ b/src/Setup/ComSetup.h
@@ -0,0 +1,18 @@
+/*
+ Copyright (c) 2007 TrueCrypt Developers Association. All rights reserved.
+
+ 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.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BOOL RegisterComServers (char *modulePath);
+BOOL UnregisterComServers (char *modulePath);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/Setup/ComSetup.rgs b/src/Setup/ComSetup.rgs
new file mode 100644
index 00000000..a1cf61f5
--- /dev/null
+++ b/src/Setup/ComSetup.rgs
@@ -0,0 +1,92 @@
+HKCR
+{
+ ForceRemove TrueCrypt.1 = s 'TrueCrypt class'
+ {
+ CLSID = s '{CECBC0EE-78D9-41E6-BCF1-BC222BB224BA}'
+ }
+
+ ForceRemove TrueCrypt = s 'TrueCrypt class'
+ {
+ CLSID = s '{CECBC0EE-78D9-41E6-BCF1-BC222BB224BA}'
+ CurVer = s 'TrueCrypt.1'
+ }
+
+ NoRemove CLSID
+ {
+ ForceRemove {CECBC0EE-78D9-41E6-BCF1-BC222BB224BA} = s 'TrueCrypt class'
+ {
+ ProgID = s 'TrueCrypt.1'
+ VersionIndependentProgID = s 'TrueCrypt'
+ LocalServer32 = s '"%MAIN_MODULE%"'
+
+ TypeLib = s '{1770F56C-7881-4591-A179-79B8001C7D42}'
+
+ Elevation
+ {
+ val Enabled = d 1
+ val IconReference = s '@%MAIN_MODULE%,-501'
+ }
+
+ val AppId = s '{CECBC0EE-78D9-41E6-BCF1-BC222BB224BA}'
+ val LocalizedString = s '@%MAIN_MODULE%,-110'
+ }
+ }
+
+ NoRemove AppId
+ {
+ ForceRemove {CECBC0EE-78D9-41E6-BCF1-BC222BB224BA} = s 'TrueCrypt class'
+ {
+ val AccessPermission = b 010004803000000040000000000000001400000002001c000100000000001400070000000101000000000005040000000102000000000005200000002002000001020000000000052000000020020000
+ }
+
+ ForceRemove TrueCrypt.exe
+ {
+ val AppId = s '{CECBC0EE-78D9-41E6-BCF1-BC222BB224BA}'
+ }
+ }
+
+ ForceRemove TrueCryptFormat.1 = s 'TrueCryptFormat class'
+ {
+ CLSID = s '{777DCDFD-C330-480B-B582-B02B57580CC9}'
+ }
+
+ ForceRemove TrueCryptFormat = s 'TrueCryptFormat class'
+ {
+ CLSID = s '{777DCDFD-C330-480B-B582-B02B57580CC9}'
+ CurVer = s 'TrueCryptFormat.1'
+ }
+
+ NoRemove CLSID
+ {
+ ForceRemove {777DCDFD-C330-480B-B582-B02B57580CC9} = s 'TrueCryptFormat class'
+ {
+ ProgID = s 'TrueCryptFormat.1'
+ VersionIndependentProgID = s 'TrueCryptFormat'
+ LocalServer32 = s '"%FORMAT_MODULE%"'
+
+ TypeLib = s '{A7DF958C-0716-49E9-8C3E-53A775797576}'
+
+ Elevation
+ {
+ val Enabled = d 1
+ val IconReference = s '@%FORMAT_MODULE%,-501'
+ }
+
+ val AppId = s '{777DCDFD-C330-480B-B582-B02B57580CC9}'
+ val LocalizedString = s '@%FORMAT_MODULE%,-112'
+ }
+ }
+
+ NoRemove AppId
+ {
+ ForceRemove {777DCDFD-C330-480B-B582-B02B57580CC9} = s 'TrueCryptFormat class'
+ {
+ val AccessPermission = b 010004803000000040000000000000001400000002001c000100000000001400070000000101000000000005040000000102000000000005200000002002000001020000000000052000000020020000
+ }
+
+ ForceRemove 'TrueCrypt Format.exe'
+ {
+ val AppId = s '{777DCDFD-C330-480B-B582-B02B57580CC9}'
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Setup/Dir.c b/src/Setup/Dir.c
new file mode 100644
index 00000000..7c418c74
--- /dev/null
+++ b/src/Setup/Dir.c
@@ -0,0 +1,104 @@
+/*
+ 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-2008 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 <sys/types.h>
+#include <sys/stat.h>
+#include <direct.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "Dir.h"
+
+/* create full directory tree. returns 0 for success, -1 if failure */
+int
+mkfulldir (char *oriPath, BOOL bCheckonly)
+{
+ struct _stat st;
+ char *uniq_file;
+ char path [TC_MAX_PATH];
+
+ strcpy (path, oriPath);
+
+ if (strlen (path) == 3 && path[1] == ':')
+ goto is_root; /* keep final slash in root if present */
+
+ /* strip final forward or backslash if we have one! */
+ uniq_file = strrchr (path, '\\');
+ if (uniq_file && uniq_file[1] == '\0')
+ uniq_file[0] = '\0';
+ else
+ {
+ uniq_file = strrchr (path, '/');
+ if (uniq_file && uniq_file[1] == '\0')
+ uniq_file[0] = '\0';
+ }
+
+ is_root:
+ if (bCheckonly)
+ return _stat (path, &st);
+
+ if (_stat (path, &st))
+ return mkfulldir_internal (path);
+ else
+ return 0;
+}
+
+
+int
+mkfulldir_internal (char *path)
+{
+ char *token;
+ struct _stat st;
+ static char tokpath[_MAX_PATH];
+ static char trail[_MAX_PATH];
+
+ strcpy (tokpath, path);
+ trail[0] = '\0';
+
+ token = strtok (tokpath, "\\/");
+
+ if (tokpath[0] == '\\' && tokpath[1] == '\\')
+ { /* unc */
+ trail[0] = tokpath[0];
+ trail[1] = tokpath[1];
+ trail[2] = '\0';
+ strcat (trail, token);
+ strcat (trail, "\\");
+ token = strtok (NULL, "\\/");
+ if (token)
+ { /* get share name */
+ strcat (trail, token);
+ strcat (trail, "\\");
+ }
+ token = strtok (NULL, "\\/");
+ }
+
+ if (tokpath[1] == ':')
+ { /* drive letter */
+ strcat (trail, tokpath);
+ strcat (trail, "\\");
+ token = strtok (NULL, "\\/");
+ }
+
+ while (token != NULL)
+ {
+ int x;
+ strcat (trail, token);
+ x = _mkdir (trail);
+ strcat (trail, "\\");
+ token = strtok (NULL, "\\/");
+ }
+
+ return _stat (path, &st);
+}
diff --git a/src/Setup/Dir.h b/src/Setup/Dir.h
new file mode 100644
index 00000000..506dff17
--- /dev/null
+++ b/src/Setup/Dir.h
@@ -0,0 +1,21 @@
+/*
+ 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-2008 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. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int mkfulldir ( char *path , BOOL bCheckonly );
+int mkfulldir_internal ( char *path );
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/Setup/Resource.h b/src/Setup/Resource.h
new file mode 100644
index 00000000..2baaefe0
--- /dev/null
+++ b/src/Setup/Resource.h
@@ -0,0 +1,64 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Setup.rc
+//
+#define IDR_COMREG 10
+#define IDD_INSTALL 101
+#define IDD_INSTALL_OPTIONS_PAGE_DLG 102
+#define IDD_UNINSTALL 103
+#define IDI_SETUP 104
+#define IDR_SETUP_RSRC_HEADER 105
+#define IDD_EXTRACTION_OPTIONS_PAGE_DLG 106
+#define IDB_SETUP_WIZARD 107
+#define IDD_INTRO_PAGE_DLG 108
+#define IDB_SETUP_WIZARD_BKG 109
+#define IDD_INFO_PAGE_DLG 110
+#define IDD_INSTL_DLG 111
+#define IDD_WIZARD_MODE_PAGE_DLG 112
+#define IDD_PROGRESS_PAGE_DLG 113
+#define IDD_DONATIONS_PAGE_DLG 114
+#define IDC_DESTINATION 1000
+#define IDC_BOX_TITLE 1001
+#define IDC_BROWSE 1002
+#define IDC_BOX_INFO 1003
+#define IDC_LICENSE 1004
+#define IDC_BOX_HELP 1005
+#define IDC_LICENSE_TEXT 1006
+#define IDC_BOX_HELP2 1007
+#define IDC_FILE_TYPE 1008
+#define IDT_UNINSTALL_DIR 1009
+#define IDC_PROG_GROUP 1010
+#define IDC_SYSTEM_RESTORE 1011
+#define IDC_DESKTOP_ICON 1012
+#define IDC_ALL_USERS 1013
+#define IDT_INSTALL_DESTINATION 1014
+#define IDC_UNINSTALL 1015
+#define IDC_PROGRESS_BAR 1016
+#define IDC_LOG_WINDOW 1017
+#define IDC_SETUP_WIZARD_BKG 1018
+#define IDC_SETUP_WIZARD_GFX_AREA 1019
+#define IDC_HR 1020
+#define IDC_OPEN_CONTAINING_FOLDER 1021
+#define IDC_AGREE 1022
+#define IDC_HR_BOTTOM 1023
+#define IDC_WIZARD_MODE_INSTALL 1024
+#define IDC_WIZARD_MODE_EXTRACT_ONLY 1025
+#define IDC_NEXT 1026
+#define IDC_PREV 1027
+#define IDT_EXTRACT_DESTINATION 1028
+#define IDC_POS_BOX 1029
+#define IDC_BITMAP_SETUP_WIZARD 1030
+#define IDC_MAIN_CONTENT_CANVAS 1031
+#define IDC_DONATE 1032
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 115
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1033
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/Setup/SelfExtract.c b/src/Setup/SelfExtract.c
new file mode 100644
index 00000000..7377da4a
--- /dev/null
+++ b/src/Setup/SelfExtract.c
@@ -0,0 +1,734 @@
+/*
+ Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
+
+ 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 "Inflate.h"
+#include "SelfExtract.h"
+#include "Wizard.h"
+#include "Setup.h"
+#include "Crc.h"
+#include "Endian.h"
+#include "Dlgcode.h"
+#include "Dir.h"
+#include "Language.h"
+#include "Resource.h"
+
+#define OutputPackageFile "TrueCrypt Setup " VERSION_STRING ".exe"
+
+#define MAG_START_MARKER "TCINSTRT"
+#define MAG_END_MARKER_OBFUSCATED "T/C/I/N/S/C/R/C"
+#define PIPE_BUFFER_LEN (4 * BYTES_PER_KB)
+
+unsigned char MagEndMarker [sizeof (MAG_END_MARKER_OBFUSCATED)];
+char DestExtractPath [TC_MAX_PATH];
+DECOMPRESSED_FILE Decompressed_Files [NBR_COMPRESSED_FILES];
+
+volatile char *PipeWriteBuf = NULL;
+volatile HANDLE hChildStdinWrite = INVALID_HANDLE_VALUE;
+unsigned char *DecompressedData = NULL;
+
+
+
+void SelfExtractStartupInit (void)
+{
+ DeobfuscateMagEndMarker ();
+}
+
+
+// The end marker must be included in the self-extracting exe only once, not twice (used e.g.
+// by IsSelfExtractingPackage()) and that's why MAG_END_MARKER_OBFUSCATED is obfuscated and
+// needs to be deobfuscated using this function at startup.
+static void DeobfuscateMagEndMarker (void)
+{
+ int i;
+
+ for (i = 0; i < sizeof (MAG_END_MARKER_OBFUSCATED); i += 2)
+ MagEndMarker [i/2] = MAG_END_MARKER_OBFUSCATED [i];
+
+ MagEndMarker [i/2] = 0;
+}
+
+
+static void PkgError (char *msg)
+{
+ MessageBox (NULL, msg, "TrueCrypt", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
+}
+
+
+static void PkgWarning (char *msg)
+{
+ MessageBox (NULL, msg, "TrueCrypt", MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+}
+
+
+static void PkgInfo (char *msg)
+{
+ MessageBox (NULL, msg, "TrueCrypt", MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST);
+}
+
+
+// Returns 0 if decompression fails or, if successful, returns the size of the decompressed data
+static int DecompressBuffer (char *out, char *in, int len)
+{
+ return (DecompressDeflatedData (out, in, len)); // Inflate
+}
+
+
+static void __cdecl PipeWriteThread (void *len)
+{
+ int sendBufSize = PIPE_BUFFER_LEN, bytesSent = 0;
+ int bytesToSend = *((int *) len), bytesSentTotal = 0;
+
+ if (PipeWriteBuf == NULL || (HANDLE) hChildStdinWrite == INVALID_HANDLE_VALUE)
+ {
+ PkgError ("Failed sending data to the STDIN pipe");
+ return;
+ }
+
+ while (bytesToSend > 0)
+ {
+ if (bytesToSend < PIPE_BUFFER_LEN)
+ sendBufSize = bytesToSend;
+
+ if (!WriteFile ((HANDLE) hChildStdinWrite, (char *) PipeWriteBuf + bytesSentTotal, sendBufSize, &bytesSent, NULL)
+ || bytesSent == 0
+ || bytesSent != sendBufSize)
+ {
+ PkgError ("Failed sending data to the STDIN pipe");
+ return;
+ }
+
+ bytesToSend -= bytesSent;
+ bytesSentTotal += bytesSent;
+ }
+
+ // Closing the pipe causes the child process to stop reading from it
+
+ if (!CloseHandle (hChildStdinWrite))
+ {
+ PkgError ("Cannot close pipe");
+ return;
+ }
+}
+
+
+// Returns 0 if compression fails or, if successful, the size of the compressed data
+static int CompressBuffer (char *out, char *in, int len)
+{
+ SECURITY_ATTRIBUTES securityAttrib;
+ DWORD bytesReceived = 0;
+ HANDLE hChildStdoutWrite = INVALID_HANDLE_VALUE;
+ HANDLE hChildStdoutRead = INVALID_HANDLE_VALUE;
+ HANDLE hChildStdinRead = INVALID_HANDLE_VALUE;
+ STARTUPINFO startupInfo;
+ PROCESS_INFORMATION procInfo;
+ char pipeBuffer [PIPE_BUFFER_LEN];
+ int res_len = 0;
+ BOOL bGzipHeaderRead = FALSE;
+
+ ZeroMemory (&startupInfo, sizeof (startupInfo));
+ ZeroMemory (&procInfo, sizeof (procInfo));
+
+ // Pipe handle inheritance
+ securityAttrib.bInheritHandle = TRUE;
+ securityAttrib.nLength = sizeof (securityAttrib);
+ securityAttrib.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe (&hChildStdoutRead, &hChildStdoutWrite, &securityAttrib, 0))
+ {
+ PkgError ("Cannot create STDOUT pipe.");
+ return 0;
+ }
+ SetHandleInformation (hChildStdoutRead, HANDLE_FLAG_INHERIT, 0);
+
+ if (!CreatePipe (&hChildStdinRead, &((HANDLE) hChildStdinWrite), &securityAttrib, 0))
+ {
+ PkgError ("Cannot create STDIN pipe.");
+ return 0;
+ }
+ SetHandleInformation (hChildStdinWrite, HANDLE_FLAG_INHERIT, 0);
+
+ // Create a child process that will compress the data
+
+ startupInfo.wShowWindow = SW_HIDE;
+ startupInfo.hStdInput = hChildStdinRead;
+ startupInfo.hStdOutput = hChildStdoutWrite;
+ startupInfo.cb = sizeof (startupInfo);
+ startupInfo.hStdError = hChildStdoutWrite;
+ startupInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+
+ if (!CreateProcess (NULL, "gzip --best", NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &procInfo))
+ {
+ PkgError ("Error: Cannot run gzip.\n\nBefore you can create a self-extracting TrueCrypt package, you need to have the open-source 'gzip' compression tool placed in any directory in the search path for executable files (for example, in 'C:\\Windows\\').\n\nNote: gzip can be freely downloaded e.g. from www.gzip.org");
+ return 0;
+ }
+
+ CloseHandle (procInfo.hProcess);
+ CloseHandle (procInfo.hThread);
+
+ // Start sending the uncompressed data to the pipe (STDIN)
+ PipeWriteBuf = in;
+ _beginthread (PipeWriteThread, PIPE_BUFFER_LEN * 2, (void *) &len);
+
+ if (!CloseHandle (hChildStdoutWrite))
+ {
+ PkgError ("Cannot close STDOUT write");
+ return 0;
+ }
+
+ bGzipHeaderRead = FALSE;
+
+ // Read the compressed data from the pipe (sent by the child process to STDOUT)
+ while (TRUE)
+ {
+ if (!ReadFile (hChildStdoutRead, pipeBuffer, bGzipHeaderRead ? PIPE_BUFFER_LEN : 10, &bytesReceived, NULL))
+ break;
+
+ if (bGzipHeaderRead)
+ {
+ memcpy (out + res_len, pipeBuffer, bytesReceived);
+ res_len += bytesReceived;
+ }
+ else
+ bGzipHeaderRead = TRUE; // Skip the 10-byte gzip header
+ }
+ return res_len - 8; // A gzip stream ends with a CRC-32 hash and a 32-bit size (those 8 bytes need to be chopped off)
+}
+
+
+// Clears all bytes that change when an exe file is digitally signed, except the data that are appended.
+// If those bytes weren't cleared, CRC-32 checks would fail after signing.
+static void WipeSignatureAreas (char *buffer)
+{
+ // Clear bytes 0x130-0x1ff
+ memset (buffer + 0x130, 0, 0x200 - 0x130);
+}
+
+
+BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir)
+{
+ int i, x;
+ unsigned char inputFile [TC_MAX_PATH];
+ unsigned char outputFile [TC_MAX_PATH];
+ unsigned char szTmpFilePath [TC_MAX_PATH];
+ unsigned char szTmp32bit [4] = {0};
+ unsigned char *szTmp32bitPtr = szTmp32bit;
+ unsigned char *buffer = NULL, *compressedBuffer = NULL;
+ unsigned char *bufIndex = NULL;
+ char tmpStr [2048];
+ int bufLen = 0, compressedDataLen = 0, uncompressedDataLen = 0;
+
+ x = strlen (szDestDir);
+ if (x < 2)
+ goto err;
+
+ if (szDestDir[x - 1] != '\\')
+ strcat (szDestDir, "\\");
+
+ GetModuleFileName (NULL, inputFile, sizeof (inputFile));
+
+ strcpy (outputFile, szDestDir);
+ strncat (outputFile, OutputPackageFile, sizeof (outputFile) - strlen (outputFile) - 1);
+
+ // Clone 'TrueCrypt Setup.exe' to create the base of the new self-extracting archive
+
+ if (!TCCopyFile (inputFile, outputFile))
+ {
+ handleWin32Error (hwndDlg);
+ PkgError ("Cannot copy 'TrueCrypt Setup.exe' to the package");
+ goto err;
+ }
+
+ // Determine the buffer size needed for all the files and meta data and check if all required files exist
+
+ bufLen = 0;
+
+ for (i = 0; i < sizeof (szCompressedFiles) / sizeof (szCompressedFiles[0]); i++)
+ {
+ _snprintf (szTmpFilePath, sizeof(szTmpFilePath), "%s%s", szDestDir, szCompressedFiles[i]);
+
+ if (!FileExists (szTmpFilePath))
+ {
+ char tmpstr [1000];
+
+ _snprintf (tmpstr, sizeof(tmpstr), "File not found:\n\n'%s'", szTmpFilePath);
+ remove (outputFile);
+ PkgError (tmpstr);
+ goto err;
+ }
+
+ bufLen += (int) GetFileSize64 (szTmpFilePath);
+
+ bufLen += 2; // 16-bit filename length
+ bufLen += strlen(szCompressedFiles[i]); // Filename
+ bufLen += 4; // CRC-32
+ bufLen += 4; // 32-bit file length
+ }
+
+ buffer = malloc (bufLen + 524288); // + 512K reserve
+ if (buffer == NULL)
+ {
+ PkgError ("Cannot allocate memory for uncompressed data");
+ remove (outputFile);
+ goto err;
+ }
+
+
+ // Write the start marker
+ if (!SaveBufferToFile (MAG_START_MARKER, outputFile, strlen (MAG_START_MARKER), TRUE))
+ {
+ PkgError ("Cannot write the start marker");
+ remove (outputFile);
+ goto err;
+ }
+
+
+ bufIndex = buffer;
+
+ // Copy all required files and their meta data to the buffer
+ for (i = 0; i < sizeof (szCompressedFiles) / sizeof (szCompressedFiles[0]); i++)
+ {
+ DWORD tmpFileSize;
+ unsigned char *tmpBuffer;
+
+ _snprintf (szTmpFilePath, sizeof(szTmpFilePath), "%s%s", szDestDir, szCompressedFiles[i]);
+
+ tmpBuffer = LoadFile (szTmpFilePath, &tmpFileSize);
+
+ if (tmpBuffer == NULL)
+ {
+ char tmpstr [1000];
+
+ free (tmpBuffer);
+ _snprintf (tmpstr, sizeof(tmpstr), "Cannot load file \n'%s'", szTmpFilePath);
+ remove (outputFile);
+ PkgError (tmpstr);
+ goto err;
+ }
+
+ // Copy the filename length to the main buffer
+ mputWord (bufIndex, (WORD) strlen(szCompressedFiles[i]));
+
+ // Copy the filename to the main buffer
+ memcpy (bufIndex, szCompressedFiles[i], strlen(szCompressedFiles[i]));
+ bufIndex += strlen(szCompressedFiles[i]);
+
+ // Compute CRC-32 hash of the uncompressed file and copy it to the main buffer
+ mputLong (bufIndex, GetCrc32 (tmpBuffer, tmpFileSize));
+
+ // Copy the file length to the main buffer
+ mputLong (bufIndex, (unsigned __int32) tmpFileSize);
+
+ // Copy the file contents to the main buffer
+ memcpy (bufIndex, tmpBuffer, tmpFileSize);
+ bufIndex += tmpFileSize;
+
+ free (tmpBuffer);
+ }
+
+ // Calculate the total size of the uncompressed data
+ uncompressedDataLen = (int) (bufIndex - buffer);
+
+ // Write total size of the uncompressed data
+ szTmp32bitPtr = szTmp32bit;
+ mputLong (szTmp32bitPtr, (unsigned __int32) uncompressedDataLen);
+ if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE))
+ {
+ remove (outputFile);
+ PkgError ("Cannot write the total size of the uncompressed data");
+ goto err;
+ }
+
+ // Compress all the files and meta data in the buffer to create a solid archive
+
+ compressedBuffer = malloc (uncompressedDataLen + 524288); // + 512K reserve
+ if (compressedBuffer == NULL)
+ {
+ remove (outputFile);
+ PkgError ("Cannot allocate memory for compressed data");
+ goto err;
+ }
+
+ compressedDataLen = CompressBuffer (compressedBuffer, buffer, uncompressedDataLen);
+ if (compressedDataLen <= 0)
+ {
+ remove (outputFile);
+ PkgError ("Failed to compress the data");
+ goto err;
+ }
+
+ free (buffer);
+ buffer = NULL;
+
+ // Write the total size of the compressed data
+ szTmp32bitPtr = szTmp32bit;
+ mputLong (szTmp32bitPtr, (unsigned __int32) compressedDataLen);
+ if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE))
+ {
+ remove (outputFile);
+ PkgError ("Cannot write the total size of the compressed data");
+ goto err;
+ }
+
+ // Write the compressed data
+ if (!SaveBufferToFile (compressedBuffer, outputFile, compressedDataLen, TRUE))
+ {
+ remove (outputFile);
+ PkgError ("Cannot write compressed data to the package");
+ goto err;
+ }
+
+ // Write the end marker
+ if (!SaveBufferToFile (MagEndMarker, outputFile, strlen (MagEndMarker), TRUE))
+ {
+ remove (outputFile);
+ PkgError ("Cannot write the end marker");
+ goto err;
+ }
+
+ free (compressedBuffer);
+ compressedBuffer = NULL;
+
+ // Compute and write CRC-32 hash of the entire package
+ {
+ DWORD tmpFileSize;
+ char *tmpBuffer;
+
+ tmpBuffer = LoadFile (outputFile, &tmpFileSize);
+
+ if (tmpBuffer == NULL)
+ {
+ handleWin32Error (hwndDlg);
+ remove (outputFile);
+ PkgError ("Cannot load the package to compute CRC");
+ goto err;
+ }
+
+ // Zero all bytes that change when the exe is digitally signed (except appended blocks).
+ WipeSignatureAreas (tmpBuffer);
+
+ szTmp32bitPtr = szTmp32bit;
+ mputLong (szTmp32bitPtr, GetCrc32 (tmpBuffer, tmpFileSize));
+ free (tmpBuffer);
+
+ if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE))
+ {
+ remove (outputFile);
+ PkgError ("Cannot write the total size of the compressed data");
+ goto err;
+ }
+ }
+
+ sprintf (tmpStr, "Self-extracting package successfully created (%s)", outputFile);
+ PkgInfo (tmpStr);
+ return TRUE;
+
+err:
+ if (buffer)
+ free (buffer);
+ if (compressedBuffer)
+ free (compressedBuffer);
+
+ return FALSE;
+}
+
+
+// Verifies the CRC-32 of the whole self-extracting package (except the digital signature areas, if present)
+BOOL VerifyPackageIntegrity (void)
+{
+ int fileDataEndPos = 0;
+ int fileDataStartPos = 0;
+ unsigned __int32 crc = 0;
+ unsigned char *tmpBuffer;
+ int tmpFileSize;
+ char path [TC_MAX_PATH];
+
+ GetModuleFileName (NULL, path, sizeof (path));
+
+ fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker));
+ if (fileDataEndPos < 0)
+ {
+ Error ("DIST_PACKAGE_CORRUPTED");
+ return FALSE;
+ }
+ fileDataEndPos--;
+
+ fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER));
+ if (fileDataStartPos < 0)
+ {
+ Error ("DIST_PACKAGE_CORRUPTED");
+ return FALSE;
+ }
+ fileDataStartPos += strlen (MAG_START_MARKER);
+
+
+ if (!LoadInt32 (path, &crc, fileDataEndPos + strlen (MagEndMarker) + 1))
+ {
+ Error ("CANT_VERIFY_PACKAGE_INTEGRITY");
+ return FALSE;
+ }
+
+ // Compute the CRC-32 hash of the whole file (except the digital signature area, if present)
+ tmpBuffer = LoadFile (path, &tmpFileSize);
+
+ if (tmpBuffer == NULL)
+ {
+ Error ("CANT_VERIFY_PACKAGE_INTEGRITY");
+ return FALSE;
+ }
+
+ // Zero all bytes that change when an exe is digitally signed (except appended blocks).
+ WipeSignatureAreas (tmpBuffer);
+
+ if (crc != GetCrc32 (tmpBuffer, fileDataEndPos + 1 + strlen (MagEndMarker)))
+ {
+ free (tmpBuffer);
+ Error ("DIST_PACKAGE_CORRUPTED");
+ return FALSE;
+ }
+
+ free (tmpBuffer);
+
+ return TRUE;
+}
+
+
+// Determines whether we are a self-extracting package
+BOOL IsSelfExtractingPackage (void)
+{
+ char path [TC_MAX_PATH];
+
+ GetModuleFileName (NULL, path, sizeof (path));
+
+ return (FindStringInFile (path, MagEndMarker, strlen (MagEndMarker)) != -1);
+}
+
+
+static void FreeAllFileBuffers (void)
+{
+ int fileNo;
+
+ if (DecompressedData != NULL)
+ {
+ free (DecompressedData);
+ DecompressedData = NULL;
+ }
+
+ for (fileNo = 0; fileNo < NBR_COMPRESSED_FILES; fileNo++)
+ {
+ Decompressed_Files[fileNo].fileName = NULL;
+ Decompressed_Files[fileNo].fileContent = NULL;
+ Decompressed_Files[fileNo].fileNameLength = 0;
+ Decompressed_Files[fileNo].fileLength = 0;
+ Decompressed_Files[fileNo].crc = 0;
+ }
+}
+
+
+// Assumes that VerifyPackageIntegrity() has been used. Returns TRUE, if successful (otherwise FALSE).
+// Creates a table of pointers to buffers containing the following objects for each file:
+// filename size, filename (not null-terminated!), file size, file CRC-32, uncompressed file contents.
+// For details, see the definition of the DECOMPRESSED_FILE structure.
+BOOL SelfExtractInMemory (char *path)
+{
+ int filePos = 0, fileNo = 0;
+ int fileDataEndPos = 0;
+ int fileDataStartPos = 0;
+ int uncompressedLen = 0;
+ int compressedLen = 0;
+ unsigned char *compressedData = NULL;
+ unsigned char *bufPos = NULL, *bufEndPos = NULL;
+
+ FreeAllFileBuffers();
+
+ fileDataEndPos = (int) FindStringInFile (path, MagEndMarker, strlen (MagEndMarker));
+ if (fileDataEndPos < 0)
+ {
+ Error ("CANNOT_READ_FROM_PACKAGE");
+ return FALSE;
+ }
+
+ fileDataEndPos--;
+
+ fileDataStartPos = (int) FindStringInFile (path, MAG_START_MARKER, strlen (MAG_START_MARKER));
+ if (fileDataStartPos < 0)
+ {
+ Error ("CANNOT_READ_FROM_PACKAGE");
+ return FALSE;
+ }
+
+ fileDataStartPos += strlen (MAG_START_MARKER);
+
+ filePos = fileDataStartPos;
+
+ // Read the stored total size of the uncompressed data
+ if (!LoadInt32 (path, &uncompressedLen, filePos))
+ {
+ Error ("CANNOT_READ_FROM_PACKAGE");
+ return FALSE;
+ }
+
+ filePos += 4;
+
+ // Read the stored total size of the compressed data
+ if (!LoadInt32 (path, &compressedLen, filePos))
+ {
+ Error ("CANNOT_READ_FROM_PACKAGE");
+ return FALSE;
+ }
+
+ filePos += 4;
+
+ if (compressedLen != fileDataEndPos - fileDataStartPos - 8 + 1)
+ {
+ Error ("DIST_PACKAGE_CORRUPTED");
+ }
+
+ DecompressedData = malloc (uncompressedLen + 524288); // + 512K reserve
+ if (DecompressedData == NULL)
+ {
+ Error ("ERR_MEM_ALLOC");
+ return FALSE;
+ }
+
+ bufPos = DecompressedData;
+ bufEndPos = bufPos + uncompressedLen - 1;
+
+ compressedData = LoadFileBlock (path, filePos, compressedLen);
+
+ if (compressedData == NULL)
+ {
+ free (DecompressedData);
+ DecompressedData = NULL;
+
+ Error ("CANNOT_READ_FROM_PACKAGE");
+ return FALSE;
+ }
+
+ // Decompress the data
+ if (DecompressBuffer (DecompressedData, compressedData, compressedLen) != uncompressedLen)
+ {
+ Error ("DIST_PACKAGE_CORRUPTED");
+ goto sem_end;
+ }
+
+ while (bufPos <= bufEndPos && fileNo < NBR_COMPRESSED_FILES)
+ {
+ // Filename length
+ Decompressed_Files[fileNo].fileNameLength = mgetWord (bufPos);
+
+ // Filename
+ Decompressed_Files[fileNo].fileName = bufPos;
+ bufPos += Decompressed_Files[fileNo].fileNameLength;
+
+ // CRC-32 of the file
+ Decompressed_Files[fileNo].crc = mgetLong (bufPos);
+
+ // File length
+ Decompressed_Files[fileNo].fileLength = mgetLong (bufPos);
+
+ // File content
+ Decompressed_Files[fileNo].fileContent = bufPos;
+ bufPos += Decompressed_Files[fileNo].fileLength;
+
+ // Verify CRC-32 of the file (to verify that it didn't get corrupted while creating the solid archive).
+ if (Decompressed_Files[fileNo].crc
+ != GetCrc32 (Decompressed_Files[fileNo].fileContent, Decompressed_Files[fileNo].fileLength))
+ {
+ Error ("DIST_PACKAGE_CORRUPTED");
+ goto sem_end;
+ }
+
+ fileNo++;
+ }
+
+ if (fileNo < NBR_COMPRESSED_FILES)
+ {
+ Error ("DIST_PACKAGE_CORRUPTED");
+ goto sem_end;
+ }
+
+ free (compressedData);
+ return TRUE;
+
+sem_end:
+ FreeAllFileBuffers();
+ free (compressedData);
+ return FALSE;
+}
+
+
+void __cdecl ExtractAllFilesThread (void *hwndDlg)
+{
+ int fileNo;
+ BOOL bSuccess = FALSE;
+ char packageFile [TC_MAX_PATH];
+
+ InvalidateRect (GetDlgItem (GetParent (hwndDlg), IDD_INSTL_DLG), NULL, TRUE);
+
+ ClearLogWindow (hwndDlg);
+
+ GetModuleFileName (NULL, packageFile, sizeof (packageFile));
+
+ if (!(bSuccess = SelfExtractInMemory (packageFile)))
+ goto eaf_end;
+
+ if (mkfulldir (DestExtractPath, TRUE) != 0)
+ {
+ if (mkfulldir (DestExtractPath, FALSE) != 0)
+ {
+ wchar_t szTmp[TC_MAX_PATH];
+
+ handleWin32Error (hwndDlg);
+ wsprintfW (szTmp, GetString ("CANT_CREATE_FOLDER"), DestExtractPath);
+ MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONHAND);
+ bSuccess = FALSE;
+ goto eaf_end;
+ }
+ }
+
+ for (fileNo = 0; fileNo < NBR_COMPRESSED_FILES; fileNo++)
+ {
+ char fileName [TC_MAX_PATH] = {0};
+ char filePath [TC_MAX_PATH] = {0};
+
+ // Filename
+ strncpy (fileName, Decompressed_Files[fileNo].fileName, Decompressed_Files[fileNo].fileNameLength);
+ fileName [Decompressed_Files[fileNo].fileNameLength] = 0;
+ strcpy (filePath, DestExtractPath);
+ strcat (filePath, fileName);
+
+ StatusMessageParam (hwndDlg, "EXTRACTING_VERB", filePath);
+
+ // Write the file
+ if (!SaveBufferToFile (
+ Decompressed_Files[fileNo].fileContent,
+ filePath,
+ Decompressed_Files[fileNo].fileLength,
+ FALSE))
+ {
+ wchar_t szTmp[512];
+
+ _snwprintf (szTmp, sizeof (szTmp) / 2, GetString ("CANNOT_WRITE_FILE_X"), filePath);
+ MessageBoxW (hwndDlg, szTmp, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
+ bSuccess = FALSE;
+ goto eaf_end;
+ }
+ UpdateProgressBarProc ((int) (100 * ((float) fileNo / NBR_COMPRESSED_FILES)));
+ }
+
+eaf_end:
+ FreeAllFileBuffers();
+
+ if (bSuccess)
+ PostMessage (MainDlg, TC_APPMSG_EXTRACTION_SUCCESS, 0, 0);
+ else
+ PostMessage (MainDlg, TC_APPMSG_EXTRACTION_FAILURE, 0, 0);
+}
+
diff --git a/src/Setup/SelfExtract.h b/src/Setup/SelfExtract.h
new file mode 100644
index 00000000..f1e62990
--- /dev/null
+++ b/src/Setup/SelfExtract.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
+
+ 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 "Setup.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ // WARNING: file name is NOT null-terminated (use fileNameLength).
+ unsigned char *fileName;
+ int fileNameLength;
+ uint32 crc;
+ __int32 fileLength;
+ unsigned char *fileContent;
+} DECOMPRESSED_FILE;
+
+extern DECOMPRESSED_FILE Decompressed_Files [NBR_COMPRESSED_FILES];
+
+void SelfExtractStartupInit (void);
+BOOL SelfExtractInMemory (char *path);
+void __cdecl ExtractAllFilesThread (void *hwndDlg);
+BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir);
+BOOL VerifyPackageIntegrity (void);
+BOOL IsSelfExtractingPackage (void);
+static void DeobfuscateMagEndMarker (void);
+
+extern char DestExtractPath [TC_MAX_PATH];
+
+#ifdef __cplusplus
+}
+#endif
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 <SrRestorePtApi.h>
+#include <io.h>
+#include <propkey.h>
+#include <propvarutil.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "Apidrvr.h"
+#include "BootEncryption.h"
+#include "Boot/Windows/BootCommon.h"
+#include "Combo.h"
+#include "ComSetup.h"
+#include "Dlgcode.h"
+#include "Language.h"
+#include "Registry.h"
+#include "Resource.h"
+
+#include "Dir.h"
+#include "Setup.h"
+#include "SelfExtract.h"
+#include "Wizard.h"
+
+#include "../Common/Resource.h"
+
+using namespace TrueCrypt;
+
+#pragma warning( disable : 4201 )
+#pragma warning( disable : 4115 )
+
+#include <shlobj.h>
+
+#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 ("<volume ");
+ while (p != string::npos)
+ {
+ if (bMountFavoritesOnLogon)
+ favorites.insert (p + 8, "mountOnLogOn=\"1\" ");
+
+ if (bOpenExplorerWindowAfterMount)
+ favorites.insert (p + 8, "openExplorerWindow=\"1\" ");
+
+ p = favorites.find ("<volume ", p + 1);
+ }
+
+ SaveBufferToFile (favorites.c_str(), favoritesFilename, favorites.size(), FALSE);
+
+ if (bMountFavoritesOnLogon)
+ {
+ char regk[64];
+ char regVal[MAX_PATH * 2];
+
+ GetStartupRegKeyName (regk);
+
+ ReadRegistryString (regk, "TrueCrypt", "", regVal, sizeof (regVal));
+
+ if (strstr (regVal, "favorites"))
+ {
+ strcat_s (regVal, sizeof (regVal), " /a logon");
+ WriteRegistryString (regk, "TrueCrypt", regVal);
+ }
+ }
+ }
+
+ if (favoritesXml)
+ free (favoritesXml);
+ }
+ }
+
+ GetWindowsDirectory (path, sizeof (path));
+ strcat_s (path, sizeof (path), "\\TrueCrypt Setup.exe");
+ DeleteFile (path);
+
+ if (UpdateProgressBarProc(63) && UnloadDriver && DoServiceUninstall (hwndDlg, "truecrypt") == 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 (SystemEncryptionUpdate && InstalledVersion == 0x630)
+ {
+ string sysFavorites = GetServiceConfigPath (TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES);
+ string legacySysFavorites = GetProgramConfigPath ("System Favorite Volumes.xml");
+
+ if (FileExists (legacySysFavorites.c_str()) && !FileExists (sysFavorites.c_str()))
+ MoveFile (legacySysFavorites.c_str(), sysFavorites.c_str());
+ }
+
+ 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");
+ }
+ }
+
+outcome:
+ 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;
+ char path[MAX_PATH+20];
+ ITEMIDLIST *itemList;
+
+ memset (InstallationPath, 0, sizeof (InstallationPath));
+
+ // Determine if TrueCrypt is already installed and try to determine its "Program Files" location
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\TrueCrypt", 0, KEY_READ, &hkey) == ERROR_SUCCESS)
+ {
+ /* Default 'UninstallString' registry strings written by past versions of TrueCrypt:
+ ------------------------------------------------------------------------------------
+ 1.0 C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 1.0a C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 2.0 C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 2.1 C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 2.1a C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 3.0 C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 3.0a C:\WINDOWS\TrueCrypt Setup.exe /u [optional]
+ 3.1 The UninstallString was NEVER written (fortunately, 3.1a replaced 3.1 after 2 weeks)
+ 3.1a C:\WINDOWS\TrueCrypt Setup.exe /u
+ 4.0 C:\WINDOWS\TrueCrypt Setup.exe /u C:\Program Files\TrueCrypt
+ 4.1 C:\WINDOWS\TrueCrypt Setup.exe /u C:\Program Files\TrueCrypt
+ 4.2 C:\WINDOWS\TrueCrypt Setup.exe /u C:\Program Files\TrueCrypt
+ 4.2a C:\WINDOWS\TrueCrypt Setup.exe /u C:\Program Files\TrueCrypt
+ 4.3 "C:\Program Files\TrueCrypt\TrueCrypt Setup.exe" /u C:\Program Files\TrueCrypt\
+ 4.3a "C:\Program Files\TrueCrypt\TrueCrypt Setup.exe" /u C:\Program Files\TrueCrypt\
+ 5.0+ "C:\Program Files\TrueCrypt\TrueCrypt Setup.exe" /u
+
+ Note: In versions 1.0-3.0a the user was able to choose whether to install the uninstaller.
+ The default was to install it. If it wasn't installed, there was no UninstallString.
+ */
+
+ char rv[MAX_PATH*4];
+ DWORD size = sizeof (rv);
+ if (RegQueryValueEx (hkey, "UninstallString", 0, 0, (LPBYTE) &rv, &size) == ERROR_SUCCESS && strrchr (rv, '/'))
+ {
+ size_t len = 0;
+
+ // Cut and paste the location (path) where TrueCrypt is installed to InstallationPath
+ if (rv[0] == '"')
+ {
+ // 4.3 or later
+
+ len = strrchr (rv, '/') - rv - 2;
+ strncpy (InstallationPath, rv + 1, len);
+ InstallationPath [len] = 0;
+ bInstallPathDetermined = TRUE;
+
+ if (InstallationPath [strlen (InstallationPath) - 1] != '\\')
+ {
+ len = strrchr (InstallationPath, '\\') - InstallationPath;
+ InstallationPath [len] = 0;
+ }
+ }
+ else
+ {
+ // 1.0-4.2a (except 3.1)
+
+ len = strrchr (rv, '/') - rv;
+ if (rv[len+2] == ' ')
+ {
+ // 4.0-4.2a
+
+ strncpy (InstallationPath, rv + len + 3, strlen (rv) - len - 3);
+ InstallationPath [strlen (rv) - len - 3] = 0;
+ bInstallPathDetermined = TRUE;
+ }
+ else
+ {
+ // 1.0-3.1a (except 3.1)
+
+ // We know that TrueCrypt is installed but don't know where. It's not safe to continue installing
+ // over the old version.
+
+ Error ("UNINSTALL_OLD_VERSION_FIRST");
+
+ len = strrchr (rv, '/') - rv - 1;
+ strncpy (InstallationPath, rv, len); // Path and filename of the uninstaller
+ InstallationPath [len] = 0;
+ bInstallPathDetermined = FALSE;
+
+ ShellExecute (NULL, "open", InstallationPath, "/u", NULL, SW_SHOWNORMAL);
+ RegCloseKey (hkey);
+ exit (1);
+ }
+ }
+
+ }
+ RegCloseKey (hkey);
+ }
+
+ if (bInstallPathDetermined)
+ {
+ char mp[MAX_PATH];
+
+ // Determine whether we were launched from the folder where TrueCrypt is installed
+ GetModuleFileName (NULL, mp, sizeof (mp));
+ if (strncmp (InstallationPath, mp, min (strlen(InstallationPath), strlen(mp))) == 0)
+ {
+ // We were launched from the folder where TrueCrypt is installed
+
+ if (!IsNonInstallMode() && !bDevm)
+ bChangeMode = TRUE;
+ }
+ }
+ else
+ {
+ /* TrueCypt 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)
+ string s = path;
+ size_t p = s.find (" (x86)");
+ if (p != string::npos)
+ {
+ s = s.substr (0, p);
+ if (_access (s.c_str(), 0) != -1)
+ strcpy_s (path, sizeof (path), s.c_str());
+ }
+ }
+
+ strncat (path, "\\TrueCrypt\\", min (strlen("\\TrueCrypt\\"), sizeof(path)-strlen(path)-1));
+ strncpy (InstallationPath, path, sizeof(InstallationPath)-1);
+ }
+
+ // Make sure the path ends with a backslash
+ if (InstallationPath [strlen (InstallationPath) - 1] != '\\')
+ {
+ strcat (InstallationPath, "\\");
+ }
+}
+
+
+// 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") == IDNO)
+ {
+ return 1;
+ }
+ WaitCursor ();
+ }
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, char *lpszCommandLine, int nCmdShow)
+{
+ atexit (localcleanup);
+
+ SelfExtractStartupInit();
+
+ lpszTitle = L"TrueCrypt 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)
+ {
+ exit (1);
+ }
+
+ /* Setup directory */
+ {
+ char *s;
+ GetModuleFileName (NULL, SetupFilesDir, sizeof (SetupFilesDir));
+ s = strrchr (SetupFilesDir, '\\');
+ if (s)
+ s[1] = 0;
+ }
+
+ /* Parse command line arguments */
+
+ if (lpszCommandLine[0] == '/')
+ {
+ if (lpszCommandLine[1] == 'u')
+ {
+ // Uninstall: /u
+
+ bUninstall = TRUE;
+ }
+ else if (lpszCommandLine[1] == 'c')
+ {
+ // Change: /c
+
+ bChangeMode = TRUE;
+ }
+ else if (lpszCommandLine[1] == 'p')
+ {
+ // Create self-extracting package: /p
+
+ bMakePackage = TRUE;
+ }
+ else if (lpszCommandLine[1] == '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, "Error: This installer file does not contain any compressed files.\n\nTo create a self-extracting installation package (with embedded compressed files), run:\n\"TrueCrypt Setup.exe\" /p", "TrueCrypt", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
+ exit (1);
+ }
+
+ if (bChangeMode)
+ {
+ /* TrueCrypt 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))
+ {
+ case 1:
+ bRepairMode = TRUE;
+ break;
+ case 2:
+ bUninstall = TRUE;
+ break;
+ default:
+ exit (1);
+ }
+ }
+ }
+
+ // System Restore
+ SystemRestoreDll = LoadLibrary ("srclient.dll");
+
+ 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);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/Setup/Setup.h b/src/Setup/Setup.h
new file mode 100644
index 00000000..fc1feb55
--- /dev/null
+++ b/src/Setup/Setup.h
@@ -0,0 +1,100 @@
+/*
+ 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-2009 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. */
+
+#ifndef SETUP_H
+#define SETUP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Specifies what files to install, where (determined by the prefix), and in what order
+static char *szFiles[]=
+{
+ "ATrueCrypt User Guide.pdf",
+ "ALicense.txt",
+ "ATrueCrypt.exe",
+ "ATrueCrypt Format.exe",
+ "Atruecrypt.sys",
+ "Atruecrypt-x64.sys",
+ "Dtruecrypt.sys",
+ "ATrueCrypt Setup.exe"
+};
+
+// Specifies what files are included in self-extracting packages (no other files will be packaged or extracted).
+static char *szCompressedFiles[]=
+{
+ "TrueCrypt User Guide.pdf",
+ "License.txt",
+ "TrueCrypt.exe",
+ "TrueCrypt Format.exe",
+ "truecrypt.sys",
+ "truecrypt-x64.sys"
+};
+
+#define FILENAME_64BIT_DRIVER "truecrypt-x64.sys"
+#define NBR_COMPRESSED_FILES (sizeof(szCompressedFiles) / sizeof(szCompressedFiles[0]))
+
+void localcleanup (void);
+BOOL StatDeleteFile ( char *lpszFile );
+BOOL StatRemoveDirectory ( char *lpszDir );
+HRESULT CreateLink ( char *lpszPathObj , char *lpszArguments , char *lpszPathLink );
+void GetProgramPath ( HWND hwndDlg , char *path );
+void StatusMessage (HWND hwndDlg, char *stringId);
+void StatusMessageParam (HWND hwndDlg, char *stringId, char *param);
+void ClearLogWindow (HWND hwndDlg);
+void StatusMessage ( HWND hwndDlg , char *stringId );
+void StatusMessageParam ( HWND hwndDlg , char *stringId , char *param );
+void RegMessage ( HWND hwndDlg , char *txt );
+void RegRemoveMessage (HWND hwndDlg, char *txt);
+void CopyMessage ( HWND hwndDlg , char *txt );
+void RemoveMessage ( HWND hwndDlg , char *txt );
+void IconMessage ( HWND hwndDlg , char *txt );
+static int CALLBACK BrowseCallbackProc ( HWND hwnd , UINT uMsg , LPARAM lp , LPARAM pData );
+void LoadLicense ( HWND hwndDlg );
+void DetermineUpgradeDowngradeStatus (BOOL bCloseDriverHandle, LONG *driverVersionPtr);
+BOOL DoFilesInstall ( HWND hwndDlg , char *szDestDir );
+BOOL DoRegInstall ( HWND hwndDlg , char *szDestDir , BOOL bInstallType );
+BOOL DoRegUninstall (HWND hwndDlg, BOOL bRemoveDeprecated);
+BOOL DoServiceUninstall ( HWND hwndDlg , char *lpszService );
+BOOL DoDriverUnload ( HWND hwndDlg );
+BOOL DoShortcutsInstall ( HWND hwndDlg , char *szDestDir , BOOL bProgGroup, BOOL bDesktopIcon );
+BOOL DoShortcutsUninstall (HWND hwndDlg, char *szDestDir);
+void OutcomePrompt ( HWND hwndDlg , BOOL bOK );
+void DoUninstall ( void *hwndDlg );
+void DoInstall ( void *hwndDlg );
+void SetInstallationPath (HWND hwndDlg);
+BOOL UpgradeBootLoader (HWND hwndDlg);
+BOOL CALLBACK InstallDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
+
+extern BOOL bDevm;
+extern BOOL Rollback;
+extern BOOL bUpgrade;
+extern BOOL bPossiblyFirstTimeInstall;
+extern BOOL bRepairMode;
+extern BOOL bSystemRestore;
+extern BOOL bDisableSwapFiles;
+extern BOOL bForAllUsers;
+extern BOOL bRegisterFileExt;
+extern BOOL bAddToStartMenu;
+extern BOOL bDesktopIcon;
+extern BOOL bDesktopIconStatusDetermined;
+extern BOOL SystemEncryptionUpdate;
+extern BOOL bRestartRequired;
+extern HMODULE volatile SystemRestoreDll;
+extern char InstallationPath[TC_MAX_PATH];
+extern char SetupFilesDir[TC_MAX_PATH];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef SETUP_H
diff --git a/src/Setup/Setup.ico b/src/Setup/Setup.ico
new file mode 100644
index 00000000..01a35e1f
--- /dev/null
+++ b/src/Setup/Setup.ico
Binary files differ
diff --git a/src/Setup/Setup.manifest b/src/Setup/Setup.manifest
new file mode 100644
index 00000000..64572284
--- /dev/null
+++ b/src/Setup/Setup.manifest
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <asmv3:application>
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ </application>
+ </compatibility>
+</assembly> \ No newline at end of file
diff --git a/src/Setup/Setup.rc b/src/Setup/Setup.rc
new file mode 100644
index 00000000..c53be64f
--- /dev/null
+++ b/src/Setup/Setup.rc
@@ -0,0 +1,327 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "..\\common\\resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 7,1,1,0
+ PRODUCTVERSION 7,1,1,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "TrueCrypt Foundation"
+ VALUE "FileDescription", "TrueCrypt Setup"
+ VALUE "FileVersion", "7.1a"
+ VALUE "LegalTrademarks", "TrueCrypt"
+ VALUE "OriginalFilename", "TrueCrypt Setup.exe"
+ VALUE "ProductName", "TrueCrypt"
+ VALUE "ProductVersion", "7.1a"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// HEADER
+//
+
+IDR_SETUP_RSRC_HEADER HEADER "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// REGISTRY
+//
+
+IDR_COMREG REGISTRY "ComSetup.rgs"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_UNINSTALL DIALOGEX 0, 0, 349, 234
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Uninstall TrueCrypt"
+CLASS "CustomDlg"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "Click Uninstall to remove TrueCrypt from this system.",IDT_UNINSTALL_DIR,8,8,334,8
+ LISTBOX IDC_LOG_WINDOW,7,21,335,179,LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL
+ DEFPUSHBUTTON "&Uninstall",IDC_UNINSTALL,236,213,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,292,213,50,14
+ CONTROL "Create System &Restore point",IDC_SYSTEM_RESTORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,215,194,10
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,206,347,1,WS_EX_STATICEDGE
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,1,348,1,WS_EX_STATICEDGE
+END
+
+IDD_INSTALL_OPTIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ EDITTEXT IDC_DESTINATION,11,41,260,13,ES_AUTOHSCROLL
+ PUSHBUTTON "Bro&wse...",IDC_BROWSE,278,40,59,14
+ CONTROL "Install &for all users",IDC_ALL_USERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,77,168,11
+ CONTROL "Associate the .tc file &extension with TrueCrypt",IDC_FILE_TYPE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,113,232,11
+ CONTROL "Add TrueCrypt to &Start menu",IDC_PROG_GROUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,89,168,11
+ CONTROL "Create System &Restore point",IDC_SYSTEM_RESTORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,125,194,11
+ CONTROL "Add TrueCrypt icon to &desktop",IDC_DESKTOP_ICON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,101,168,11
+ LTEXT "Please select or type the location where you want to install the TrueCrypt program files. If the specified folder does not exist, it will be automatically created.",IDT_INSTALL_DESTINATION,11,14,319,25
+END
+
+IDD_INFO_PAGE_DLG DIALOGEX 0, 0, 217, 156
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "",IDC_BOX_HELP,0,10,217,146
+END
+
+IDD_INTRO_PAGE_DLG DIALOGEX 0, 0, 346, 152
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_LICENSE_TEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,0,23,345,108
+ CONTROL "",IDC_AGREE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,2,137,126,10
+ LTEXT "",IDC_BOX_HELP,0,0,346,22
+END
+
+IDD_INSTL_DLG DIALOGEX 0, 0, 374, 231
+STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "TrueCrypt Setup Wizard"
+CLASS "CustomDlg"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ PUSHBUTTON "&Help",IDHELP,150,211,50,14
+ PUSHBUTTON "",IDC_PREV,209,211,50,14
+ DEFPUSHBUTTON "",IDC_NEXT,259,211,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,317,211,50,14
+ LTEXT "",IDC_BOX_TITLE,11,5,324,12,0,WS_EX_TRANSPARENT
+ CONTROL 107,IDC_BITMAP_SETUP_WIZARD,"Static",SS_BITMAP | SS_NOTIFY,139,3,228,30
+ CONTROL 109,IDC_SETUP_WIZARD_BKG,"Static",SS_BITMAP,0,0,11,10
+ CONTROL "",IDC_SETUP_WIZARD_GFX_AREA,"Static",SS_GRAYRECT | NOT WS_VISIBLE,0,0,378,36,WS_EX_TRANSPARENT | WS_EX_STATICEDGE
+ CONTROL "",IDC_HR_BOTTOM,"Static",SS_ETCHEDHORZ,67,204,306,1,WS_EX_STATICEDGE
+ CONTROL "",IDC_HR,"Static",SS_ETCHEDHORZ,0,35,399,1,WS_EX_STATICEDGE
+ LTEXT "TrueCrypt Installer",IDC_STATIC,4,200,62,8,WS_DISABLED
+ LTEXT "",IDC_BOX_INFO,18,18,317,13,0,WS_EX_TRANSPARENT
+ LTEXT "",IDC_MAIN_CONTENT_CANVAS,0,36,374,164
+ LTEXT "",IDC_POS_BOX,14,42,346,155,0,WS_EX_TRANSPARENT
+END
+
+IDD_EXTRACTION_OPTIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ PUSHBUTTON "Bro&wse...",IDC_BROWSE,277,32,62,14
+ EDITTEXT IDC_DESTINATION,6,33,264,12,ES_AUTOHSCROLL
+ LTEXT "Please select or type the location where you want to place the extracted files:",IDT_EXTRACT_DESTINATION,6,15,333,17
+ CONTROL "&Open the destination location when finished",IDC_OPEN_CONTAINING_FOLDER,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,91,318,16
+ LTEXT "",IDC_BOX_HELP,6,56,333,32
+END
+
+IDD_WIZARD_MODE_PAGE_DLG DIALOGEX 0, 0, 346, 152
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "&Install",IDC_WIZARD_MODE_INSTALL,"Button",BS_AUTORADIOBUTTON,6,14,232,10
+ CONTROL "&Extract",IDC_WIZARD_MODE_EXTRACT_ONLY,"Button",BS_AUTORADIOBUTTON,6,60,232,10
+ LTEXT "",IDC_BOX_HELP,42,77,286,64
+ LTEXT "",IDC_BOX_HELP2,42,30,286,29
+END
+
+IDD_PROGRESS_PAGE_DLG DIALOGEX 0, 0, 346, 152
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LISTBOX IDC_LOG_WINDOW,0,1,345,131,LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL
+ CONTROL "",IDC_PROGRESS_BAR,"msctls_progress32",PBS_SMOOTH | WS_BORDER,0,139,345,12
+END
+
+IDD_DONATIONS_PAGE_DLG DIALOGEX 0, 0, 346, 152
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+EXSTYLE WS_EX_TRANSPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ PUSHBUTTON "Donate now...",IDC_DONATE,124,94,96,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_SETUP ICON "Setup.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""..\\\\common\\\\resource.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""..\\\\common\\\\common.rc""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_UNINSTALL, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 342
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 229
+ END
+
+ IDD_INSTALL_OPTIONS_PAGE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 339
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+
+ IDD_INFO_PAGE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 210
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 149
+ END
+
+ IDD_INTRO_PAGE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 339
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 145
+ END
+
+ IDD_INSTL_DLG, DIALOG
+ BEGIN
+ RIGHTMARGIN, 367
+ TOPMARGIN, 1
+ BOTTOMMARGIN, 229
+ HORZGUIDE, 196
+ END
+
+ IDD_EXTRACTION_OPTIONS_PAGE_DLG, DIALOG
+ BEGIN
+ RIGHTMARGIN, 343
+ BOTTOMMARGIN, 147
+ END
+
+ IDD_WIZARD_MODE_PAGE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 339
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 145
+ END
+
+ IDD_PROGRESS_PAGE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 339
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 145
+ END
+
+ IDD_DONATIONS_PAGE_DLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 339
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_SETUP_WIZARD BITMAP "TrueCrypt_setup.bmp"
+IDB_SETUP_WIZARD_BKG BITMAP "TrueCrypt_setup_background.bmp"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "..\\common\\common.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/src/Setup/Setup.vcproj b/src/Setup/Setup.vcproj
new file mode 100644
index 00000000..bb1d6f57
--- /dev/null
+++ b/src/Setup/Setup.vcproj
@@ -0,0 +1,482 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="Setup"
+ ProjectGUID="{DF5F654D-BD44-4E31-B92E-B68074DC37A8}"
+ RootNamespace="Setup"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\Common;..\Crypto;..\;$(PKCS11_INC)"
+ PreprocessorDefinitions="SETUP;WIN32;DEBUG;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4057;4100;4127;4201;4505;4701;4706"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/NODEFAULTLIB:LIBCMTD"
+ AdditionalDependencies="libcmtd.lib comctl32.lib setupapi.lib"
+ OutputFile="$(OutDir)/TrueCryptSetup.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ UACExecutionLevel="2"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/Setup.pdb"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AdditionalManifestFiles="Setup.manifest"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="md &quot;..\Debug\Setup Files&quot; 2&gt;NUL:&#x0D;&#x0A;copy Debug\TrueCryptSetup.exe &quot;..\Debug\Setup Files\TrueCrypt Setup.exe&quot; &gt;NUL:&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/w34189"
+ Optimization="2"
+ AdditionalIncludeDirectories="..\Common;..\Crypto;..\;$(PKCS11_INC)"
+ PreprocessorDefinitions="SETUP;WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NON_CONFORMING_SWPRINTFS"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)/"
+ WarningLevel="4"
+ DebugInformationFormat="0"
+ DisableSpecificWarnings="4057;4100;4127;4201;4505;4701;4706"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/IGNORE:4089"
+ AdditionalDependencies="comctl32.lib setupapi.lib"
+ OutputFile="$(OutDir)/TrueCryptSetup.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ UACExecutionLevel="2"
+ GenerateDebugInformation="false"
+ GenerateMapFile="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AdditionalManifestFiles="Setup.manifest"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine="copy Release\TrueCryptSetup.exe &quot;..\Release\Setup Files\TrueCrypt Setup.exe&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\ComSetup.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\ComSetup.rgs"
+ >
+ </File>
+ <File
+ RelativePath=".\Dir.c"
+ >
+ </File>
+ <File
+ RelativePath=".\SelfExtract.c"
+ >
+ </File>
+ <File
+ RelativePath=".\Setup.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\Wizard.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\Xml.c"
+ >
+ </File>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\Common\BootEncryption.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Crc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Dictionary.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\Dlgcode.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\Endian.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Inflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Language.c"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Registry.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\Common\Apidrvr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Combo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\ComSetup.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Crc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Dir.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Dlgcode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Exception.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Inflate.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Language.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Registry.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Resource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\SelfExtract.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Setup.h"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Tcdefs.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Wizard.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\Setup.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\Setup.manifest"
+ >
+ </File>
+ <File
+ RelativePath=".\Setup.rc"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\TrueCrypt.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\TrueCrypt_setup.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\TrueCrypt_setup_background.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\TrueCrypt_Volume.ico"
+ >
+ </File>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\Common\Common.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\Common\Language.xml"
+ >
+ </File>
+ <File
+ RelativePath="..\Resources\Texts\License.rtf"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Textual_logo_288dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Textual_logo_96dpi.bmp"
+ >
+ </File>
+ <File
+ RelativePath="..\Common\Textual_logo_background.bmp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/Setup/TrueCrypt_setup.bmp b/src/Setup/TrueCrypt_setup.bmp
new file mode 100644
index 00000000..ab663195
--- /dev/null
+++ b/src/Setup/TrueCrypt_setup.bmp
Binary files differ
diff --git a/src/Setup/TrueCrypt_setup_background.bmp b/src/Setup/TrueCrypt_setup_background.bmp
new file mode 100644
index 00000000..ed469a16
--- /dev/null
+++ b/src/Setup/TrueCrypt_setup_background.bmp
Binary files differ
diff --git a/src/Setup/Wizard.c b/src/Setup/Wizard.c
new file mode 100644
index 00000000..3e9de719
--- /dev/null
+++ b/src/Setup/Wizard.c
@@ -0,0 +1,1203 @@
+/*
+ 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 <Shlobj.h>
+#include <io.h>
+#include <stdio.h>
+#include <time.h>
+#include "SelfExtract.h"
+#include "Wizard.h"
+#include "Dlgcode.h"
+#include "Language.h"
+#include "Common/Resource.h"
+#include "Resource.h"
+#include "Setup.h"
+
+using namespace std;
+
+enum wizard_pages
+{
+ INTRO_PAGE,
+ WIZARD_MODE_PAGE,
+ INSTALL_OPTIONS_PAGE,
+ INSTALL_PROGRESS_PAGE,
+ EXTRACTION_OPTIONS_PAGE,
+ EXTRACTION_PROGRESS_PAGE,
+ DONATIONS_PAGE
+};
+
+HWND hCurPage = NULL; /* Handle to current wizard page */
+int nCurPageNo = -1; /* The current wizard page */
+char WizardDestInstallPath [TC_MAX_PATH];
+char WizardDestExtractPath [TC_MAX_PATH];
+char SelfFile [TC_MAX_PATH];
+
+HBITMAP hbmWizardBitmapRescaled = NULL;
+
+BOOL bExtractOnly = FALSE;
+BOOL bLicenseAccepted = FALSE;
+BOOL bOpenContainingFolder = TRUE;
+BOOL bExtractionSuccessful = FALSE;
+BOOL bStartInstall = FALSE;
+BOOL bStartExtraction = FALSE;
+BOOL bInProgress = FALSE;
+BOOL bPromptTutorial = FALSE;
+BOOL bPromptReleaseNotes = FALSE;
+
+int nPbar = 0; /* Control ID of progress bar */
+
+static HFONT hDonTextFont;
+static BOOL OsPrngAvailable;
+static HCRYPTPROV hCryptProv;
+static int DonColorSchemeId;
+static COLORREF DonTextColor;
+static COLORREF DonBkgColor;
+
+wstring DonText = L"";
+
+void localcleanupwiz (void)
+{
+ /* Delete buffered bitmaps (if any) */
+ if (hbmWizardBitmapRescaled != NULL)
+ {
+ DeleteObject ((HGDIOBJ) hbmWizardBitmapRescaled);
+ hbmWizardBitmapRescaled = NULL;
+ }
+
+ if (hCryptProv != 0)
+ {
+ OsPrngAvailable = FALSE;
+ CryptReleaseContext (hCryptProv, 0);
+ hCryptProv = 0;
+ }
+
+ if (hDonTextFont != NULL)
+ {
+ DeleteObject (hDonTextFont);
+ hDonTextFont = NULL;
+ }
+}
+
+static void InitWizardDestInstallPath (void)
+{
+ if (strlen (WizardDestInstallPath) < 2)
+ {
+ strcpy (WizardDestInstallPath, InstallationPath);
+ if (WizardDestInstallPath [strlen (WizardDestInstallPath) - 1] != '\\')
+ {
+ strcat (WizardDestInstallPath, "\\");
+ }
+ }
+}
+
+void LoadPage (HWND hwndDlg, int nPageNo)
+{
+ RECT rD, rW;
+
+ if (hCurPage != NULL)
+ {
+ DestroyWindow (hCurPage);
+ }
+
+ InvalidateRect (GetDlgItem (MainDlg, IDC_MAIN_CONTENT_CANVAS), NULL, TRUE);
+
+ GetWindowRect (GetDlgItem (hwndDlg, IDC_POS_BOX), &rW);
+
+ nCurPageNo = nPageNo;
+
+ switch (nPageNo)
+ {
+ case INTRO_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INTRO_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
+ case WIZARD_MODE_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_WIZARD_MODE_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
+ case INSTALL_OPTIONS_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_INSTALL_OPTIONS_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
+ case INSTALL_PROGRESS_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_PROGRESS_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
+ case EXTRACTION_OPTIONS_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_EXTRACTION_OPTIONS_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
+ case EXTRACTION_PROGRESS_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_PROGRESS_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+
+ case DONATIONS_PAGE:
+ hCurPage = CreateDialogW (hInst, MAKEINTRESOURCEW (IDD_DONATIONS_PAGE_DLG), hwndDlg,
+ (DLGPROC) PageDialogProc);
+ break;
+ }
+
+ rD.left = 15;
+ rD.top = 45;
+ rD.right = 0;
+ rD.bottom = 0;
+ MapDialogRect (hwndDlg, &rD);
+
+ if (hCurPage != NULL)
+ {
+ MoveWindow (hCurPage, rD.left, rD.top, rW.right - rW.left, rW.bottom - rW.top, TRUE);
+ ShowWindow (hCurPage, SW_SHOWNORMAL);
+ }
+
+ /* Refresh the graphics (white background of some texts, etc.) */
+ RefreshUIGFX ();
+}
+
+
+static int GetDonVal (int minVal, int maxVal)
+{
+ static BOOL prngInitialized = FALSE;
+ static unsigned __int8 buffer [2];
+
+ if (!prngInitialized)
+ {
+ if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)
+ && !CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ OsPrngAvailable = FALSE;
+ else
+ OsPrngAvailable = TRUE;
+
+ srand ((unsigned int) time (NULL));
+ rand(); // Generate and discard the inital value, as it always appears to be somewhat non-random.
+
+ prngInitialized = TRUE;
+ }
+
+ if (OsPrngAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer) != 0)
+ {
+ return ((int) ((double) *((uint16 *) buffer) / (0xFFFF+1) * (maxVal + 1 - minVal)) + minVal);
+ }
+ else
+ return ((int) ((double) rand() / (RAND_MAX+1) * (maxVal + 1 - minVal)) + minVal);
+}
+
+
+/* Except in response to the WM_INITDIALOG message, the dialog box procedure
+ should return nonzero if it processes the message, and zero if it does
+ not. - see DialogProc */
+BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static char PageDebugId[128];
+ WORD lw = LOWORD (wParam);
+ WORD hw = HIWORD (wParam);
+
+ hCurPage = hwndDlg;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ LocalizeDialog (hwndDlg, "IDD_INSTL_DLG");
+
+ sprintf (PageDebugId, "SETUP_WIZARD_PAGE_%d", nCurPageNo);
+ LastDialogId = PageDebugId;
+
+ switch (nCurPageNo)
+ {
+ case INTRO_PAGE:
+ {
+ char *licenseText = NULL;
+
+ licenseText = GetLegalNotices ();
+ if (licenseText != NULL)
+ {
+ SetWindowText (GetDlgItem (hwndDlg, IDC_LICENSE_TEXT), licenseText);
+ free (licenseText);
+ }
+ else
+ {
+ Error("CANNOT_DISPLAY_LICENSE");
+ exit (1);
+ }
+
+ /* For legal reasons, some of the following texts cannot be localized by third parties. */
+
+ SetCheckBox (hwndDlg, IDC_AGREE, bLicenseAccepted);
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), L"Please read the license terms");
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), L"You must accept these license terms before you can use, extract, or install TrueCrypt.");
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), L"IMPORTANT: By checking the checkbox below, you accept these license terms and signify that you understand and agree to them. Please click the 'arrow down' icon to see the rest of the license."); // Cannot be localized by third parties (for legal reasons).
+ //SendMessage (GetDlgItem (hwndDlg, IDC_BOX_HELP), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_AGREE), L"I &accept the license terms"); // Cannot be localized by third parties (for legal reasons).
+ //SetWindowTextW (GetDlgItem (hwndDlg, IDC_DISAGREE), L"I &do not accept the license terms");
+
+ //SendMessage (GetDlgItem (hwndDlg, IDC_AGREE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
+ //SendMessage (GetDlgItem (hwndDlg, IDC_DISAGREE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_AGREE), TRUE);
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), bLicenseAccepted);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), bLicenseAccepted);
+
+ // Left margin for license text
+ SendMessage (GetDlgItem (hwndDlg, IDC_LICENSE_TEXT), EM_SETMARGINS, (WPARAM) EC_LEFTMARGIN, (LPARAM) CompensateXDPI (4));
+ }
+ return 1;
+
+ case WIZARD_MODE_PAGE:
+ {
+ LONG driverVersion;
+
+ DetermineUpgradeDowngradeStatus (TRUE, &driverVersion);
+
+ if (bRepairMode)
+ {
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_WIZARD_MODE_INSTALL), GetString ("REPAIR_REINSTALL"));
+ bExtractOnly = FALSE;
+ }
+ else if (bUpgrade)
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_WIZARD_MODE_INSTALL), GetString ("UPGRADE"));
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SETUP_MODE_TITLE"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), GetString ("SETUP_MODE_INFO"));
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_WIZARD_MODE_INSTALL), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
+ SendMessage (GetDlgItem (hwndDlg, IDC_WIZARD_MODE_EXTRACT_ONLY), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
+
+ CheckButton (GetDlgItem (hwndDlg, bExtractOnly ? IDC_WIZARD_MODE_EXTRACT_ONLY : IDC_WIZARD_MODE_INSTALL));
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("SETUP_MODE_HELP_EXTRACT"));
+
+ if (!bRepairMode)
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP2), GetString (bUpgrade ? "SETUP_MODE_HELP_UPGRADE" : "SETUP_MODE_HELP_INSTALL"));
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_WIZARD_MODE_EXTRACT_ONLY), !bRepairMode);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_BOX_HELP), !bRepairMode);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_WIZARD_MODE_INSTALL), TRUE);
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDCANCEL), GetString ("CANCEL"));
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
+ }
+ return 1;
+
+ case EXTRACTION_OPTIONS_PAGE:
+
+ if (strlen(WizardDestExtractPath) < 2)
+ {
+ strcpy (WizardDestExtractPath, SetupFilesDir);
+ strncat (WizardDestExtractPath, "TrueCrypt\\", sizeof (WizardDestExtractPath) - strlen (WizardDestExtractPath) - 1);
+ }
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_DESTINATION), EM_LIMITTEXT, TC_MAX_PATH - 1, 0);
+
+ SetDlgItemText (hwndDlg, IDC_DESTINATION, WizardDestExtractPath);
+
+ SetCheckBox (hwndDlg, IDC_OPEN_CONTAINING_FOLDER, bOpenContainingFolder);
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("EXTRACTION_OPTIONS_TITLE"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), GetString ("EXTRACTION_OPTIONS_INFO"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("AUTO_FOLDER_CREATION"));
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("EXTRACT"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
+
+ return 1;
+
+ case EXTRACTION_PROGRESS_PAGE:
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("EXTRACTING_VERB"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), GetString ("EXTRACTION_PROGRESS_INFO"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
+
+ if (bStartExtraction)
+ {
+ /* Start extraction */
+
+ LastDialogId = "EXTRACTION_IN_PROGRESS";
+
+ WaitCursor ();
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), FALSE);
+
+ if (WizardDestExtractPath [strlen(WizardDestExtractPath)-1] != '\\')
+ strcat (WizardDestExtractPath, "\\");
+
+ strcpy (DestExtractPath, WizardDestExtractPath);
+
+ InitProgressBar ();
+
+ bInProgress = TRUE;
+ bStartExtraction = FALSE;
+
+ _beginthread (ExtractAllFilesThread, 0, (void *) hwndDlg);
+ }
+ else
+ {
+ NormalCursor ();
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
+ }
+
+ return 1;
+
+ case INSTALL_OPTIONS_PAGE:
+ {
+ LONG driverVersion;
+
+ DetermineUpgradeDowngradeStatus (TRUE, &driverVersion);
+
+ if (!bDesktopIconStatusDetermined)
+ {
+ bDesktopIcon = !bUpgrade;
+ bDesktopIconStatusDetermined = TRUE;
+ }
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SETUP_OPTIONS_TITLE"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), GetString ("SETUP_OPTIONS_INFO"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_HELP), GetString ("AUTO_FOLDER_CREATION"));
+
+ InitWizardDestInstallPath ();
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_DESTINATION), EM_LIMITTEXT, TC_MAX_PATH - 1, 0);
+
+ SetDlgItemText (hwndDlg, IDC_DESTINATION, WizardDestInstallPath);
+
+ if (bUpgrade)
+ {
+ SetWindowTextW (GetDlgItem (hwndDlg, IDT_INSTALL_DESTINATION), GetString ("SETUP_UPGRADE_DESTINATION"));
+ EnableWindow (GetDlgItem (hwndDlg, IDC_DESTINATION), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_BROWSE), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_ALL_USERS), FALSE);
+
+ char path[MAX_PATH];
+ SHGetSpecialFolderPath (hwndDlg, path, CSIDL_COMMON_PROGRAMS, 0);
+ bForAllUsers = (_access ((string (path) + "\\" TC_APP_NAME).c_str(), 0) == 0);
+ }
+
+ // System Restore
+ SetCheckBox (hwndDlg, IDC_SYSTEM_RESTORE, bSystemRestore);
+ if (SystemRestoreDll == 0)
+ {
+ SetCheckBox (hwndDlg, IDC_SYSTEM_RESTORE, FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_SYSTEM_RESTORE), FALSE);
+ }
+
+ SetCheckBox (hwndDlg, IDC_ALL_USERS, bForAllUsers);
+ SetCheckBox (hwndDlg, IDC_FILE_TYPE, bRegisterFileExt);
+ SetCheckBox (hwndDlg, IDC_PROG_GROUP, bAddToStartMenu);
+ SetCheckBox (hwndDlg, IDC_DESKTOP_ICON, bDesktopIcon);
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString (bUpgrade ? "UPGRADE" : "INSTALL"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
+ }
+ return 1;
+
+ case INSTALL_PROGRESS_PAGE:
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString ("SETUP_PROGRESS_TITLE"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), GetString ("SETUP_PROGRESS_INFO"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_PREV), GetString ("PREV"));
+
+ if (bStartInstall)
+ {
+ /* Start install */
+
+ LastDialogId = "INSTALL_IN_PROGRESS";
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), GetString ("NEXT"));
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), FALSE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), FALSE);
+
+ InitProgressBar ();
+
+ if (WizardDestInstallPath [strlen(WizardDestInstallPath)-1] != '\\')
+ strcat (WizardDestInstallPath, "\\");
+
+ strcpy (InstallationPath, WizardDestInstallPath);
+
+ WaitCursor ();
+
+ bInProgress = TRUE;
+ bStartInstall = FALSE;
+
+ _beginthread (DoInstall, 0, (void *) hwndDlg);
+ }
+ else
+ {
+ NormalCursor ();
+
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_PREV), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDHELP), TRUE);
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDCANCEL), TRUE);
+
+ }
+
+ return 1;
+
+ case DONATIONS_PAGE:
+
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_TITLE), GetString (bExtractOnly ? "EXTRACTION_FINISHED_TITLE_DON" : (bUpgrade ? "SETUP_FINISHED_UPGRADE_TITLE_DON" : "SETUP_FINISHED_TITLE_DON")));
+ SetWindowTextW (GetDlgItem (GetParent (hwndDlg), IDC_BOX_INFO), GetString ("SETUP_FINISHED_INFO_DON"));
+
+ DonText = L"Please consider making a donation.";
+
+
+ // Colors
+
+ switch (DonColorSchemeId)
+ {
+ case 2:
+ // NOP - Default OS colors (foreground and background)
+ break;
+
+ case 3:
+ // Red
+ DonTextColor = RGB (255, 255, 255);
+ DonBkgColor = RGB (255, 0, 0);
+ break;
+
+ case 4:
+ // Yellow
+ DonTextColor = RGB (255, 15, 49);
+ DonBkgColor = RGB (255, 255, 0);
+ break;
+
+ case 5:
+ // Light red
+ DonTextColor = RGB (255, 255, 255);
+ DonBkgColor = RGB (255, 141, 144);
+ break;
+
+ case 6:
+ // Pink
+ DonTextColor = RGB (255, 255, 255);
+ DonBkgColor = RGB (248, 148, 207);
+ break;
+
+ case 7:
+ // White + red text
+ DonTextColor = RGB (255, 15, 49);
+ DonBkgColor = RGB (255, 255, 255);
+ break;
+
+ case 8:
+ // Blue
+ DonTextColor = RGB (255, 255, 255);
+ DonBkgColor = RGB (54, 140, 255);
+ break;
+
+ case 9:
+ // Green
+ DonTextColor = RGB (255, 255, 255);
+ DonBkgColor = RGB (70, 180, 80);
+ break;
+ }
+
+ {
+ // Font
+
+ LOGFONTW lf;
+ memset (&lf, 0, sizeof(lf));
+
+ // Main font
+ wcsncpy (lf.lfFaceName, L"Times New Roman", sizeof (lf.lfFaceName)/2);
+ lf.lfHeight = CompensateDPIFont (-21);
+ lf.lfWeight = FW_NORMAL;
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = 0;
+ lf.lfItalic = FALSE;
+ lf.lfUnderline = FALSE;
+ lf.lfStrikeOut = FALSE;
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfQuality = PROOF_QUALITY;
+ lf.lfPitchAndFamily = FF_DONTCARE;
+ hDonTextFont = CreateFontIndirectW (&lf);
+
+ if (hDonTextFont == NULL)
+ AbortProcessSilent ();
+ }
+
+ return 1;
+ }
+
+ return 0;
+
+ case WM_HELP:
+ if (bLicenseAccepted)
+ OpenPageHelp (GetParent (hwndDlg), nCurPageNo);
+
+ return 1;
+
+ case WM_ENDSESSION:
+
+ bPromptTutorial = FALSE;
+ bPromptReleaseNotes = FALSE;
+
+ EndDialog (MainDlg, 0);
+ localcleanup ();
+ return 0;
+
+
+ case WM_COMMAND:
+
+ if (lw == IDC_AGREE && nCurPageNo == INTRO_PAGE)
+ {
+ EnableWindow (GetDlgItem (GetParent (hwndDlg), IDC_NEXT), IsButtonChecked (GetDlgItem (hwndDlg, IDC_AGREE)));
+ return 1;
+ }
+
+ if (lw == IDC_WIZARD_MODE_EXTRACT_ONLY && nCurPageNo == WIZARD_MODE_PAGE)
+ {
+ bExtractOnly = TRUE;
+ return 1;
+ }
+
+ if (lw == IDC_WIZARD_MODE_INSTALL && nCurPageNo == WIZARD_MODE_PAGE)
+ {
+ bExtractOnly = FALSE;
+ return 1;
+ }
+
+ if ( nCurPageNo == EXTRACTION_OPTIONS_PAGE && hw == EN_CHANGE )
+ {
+ EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), (GetWindowTextLength (GetDlgItem (hCurPage, IDC_DESTINATION)) > 1));
+ return 1;
+ }
+
+ if ( nCurPageNo == INSTALL_OPTIONS_PAGE && hw == EN_CHANGE )
+ {
+ EnableWindow (GetDlgItem (MainDlg, IDC_NEXT), (GetWindowTextLength (GetDlgItem (hCurPage, IDC_DESTINATION)) > 1));
+ return 1;
+ }
+
+ if ( nCurPageNo == EXTRACTION_OPTIONS_PAGE )
+ {
+ switch (lw)
+ {
+ case IDC_BROWSE:
+ if (BrowseDirectories (hwndDlg, "SELECT_DEST_DIR", WizardDestExtractPath))
+ {
+ if (WizardDestExtractPath [strlen(WizardDestExtractPath)-1] != '\\')
+ {
+ strcat (WizardDestExtractPath, "\\");
+ }
+ SetDlgItemText (hwndDlg, IDC_DESTINATION, WizardDestExtractPath);
+ }
+ return 1;
+
+ case IDC_OPEN_CONTAINING_FOLDER:
+ bOpenContainingFolder = IsButtonChecked (GetDlgItem (hCurPage, IDC_OPEN_CONTAINING_FOLDER));
+ return 1;
+ }
+ }
+
+ if ( nCurPageNo == INSTALL_OPTIONS_PAGE )
+ {
+ switch (lw)
+ {
+ case IDC_BROWSE:
+ if (BrowseDirectories (hwndDlg, "SELECT_DEST_DIR", WizardDestInstallPath))
+ {
+ if (WizardDestInstallPath [strlen(WizardDestInstallPath)-1] != '\\')
+ {
+ strcat (WizardDestInstallPath, "\\");
+ }
+ SetDlgItemText (hwndDlg, IDC_DESTINATION, WizardDestInstallPath);
+ }
+ return 1;
+
+ case IDC_SYSTEM_RESTORE:
+ bSystemRestore = IsButtonChecked (GetDlgItem (hCurPage, IDC_SYSTEM_RESTORE));
+ return 1;
+
+ case IDC_ALL_USERS:
+ bForAllUsers = IsButtonChecked (GetDlgItem (hCurPage, IDC_ALL_USERS));
+ return 1;
+
+ case IDC_FILE_TYPE:
+ bRegisterFileExt = IsButtonChecked (GetDlgItem (hCurPage, IDC_FILE_TYPE));
+ return 1;
+
+ case IDC_PROG_GROUP:
+ bAddToStartMenu = IsButtonChecked (GetDlgItem (hCurPage, IDC_PROG_GROUP));
+ return 1;
+
+ case IDC_DESKTOP_ICON:
+ bDesktopIcon = IsButtonChecked (GetDlgItem (hCurPage, IDC_DESKTOP_ICON));
+ return 1;
+
+ }
+ }
+
+ if (nCurPageNo == DONATIONS_PAGE)
+ {
+ switch (lw)
+ {
+ case IDC_DONATE:
+ {
+ char tmpstr [200];
+
+ sprintf (tmpstr, "&ref=%d", DonColorSchemeId);
+
+ Applink ("donate", FALSE, tmpstr);
+ }
+ return 1;
+ }
+ }
+
+ return 0;
+
+
+ case WM_PAINT:
+
+ if (nCurPageNo == DONATIONS_PAGE)
+ {
+ PAINTSTRUCT tmpPaintStruct;
+ HDC hdc = BeginPaint (hCurPage, &tmpPaintStruct);
+
+ if (hdc == NULL)
+ AbortProcessSilent ();
+
+ SelectObject (hdc, hDonTextFont);
+
+ if (DonColorSchemeId != 2)
+ {
+ HBRUSH tmpBrush = CreateSolidBrush (DonBkgColor);
+
+ if (tmpBrush == NULL)
+ AbortProcessSilent ();
+
+ RECT trect;
+
+ trect.left = 0;
+ trect.right = CompensateXDPI (526);
+ trect.top = 0;
+ trect.bottom = CompensateYDPI (246);
+
+ FillRect (hdc, &trect, tmpBrush);
+
+ SetTextColor (hdc, DonTextColor);
+ SetBkColor (hdc, DonBkgColor);
+ }
+
+ SetTextAlign(hdc, TA_CENTER);
+
+ TextOutW (hdc,
+ CompensateXDPI (258),
+ CompensateYDPI (70),
+ DonText.c_str(),
+ DonText.length());
+
+ EndPaint (hCurPage, &tmpPaintStruct);
+ ReleaseDC (hCurPage, hdc);
+ }
+ return 0;
+
+
+ case WM_CTLCOLORSTATIC:
+
+ /* This maintains the background under the transparent-backround texts */
+
+ SetBkMode ((HDC) wParam, TRANSPARENT);
+ return ((LONG) (HBRUSH) (GetStockObject (NULL_BRUSH)));
+
+
+ case WM_ERASEBKGND:
+
+ return 0;
+ }
+
+ return 0;
+}
+
+void InitProgressBar (void)
+{
+ HWND hProgressBar = GetDlgItem (hCurPage, nPbar);
+ SendMessage (hProgressBar, PBM_SETRANGE32, 0, 100);
+ SendMessage (hProgressBar, PBM_SETSTEP, 1, 0);
+ InvalidateRect (hProgressBar, NULL, TRUE);
+}
+
+// Must always return TRUE
+BOOL UpdateProgressBarProc (int nPercent)
+{
+ HWND hProgressBar = GetDlgItem (hCurPage, nPbar);
+ SendMessage (hProgressBar, PBM_SETPOS, (int) (100.0 * nPercent / 100), 0);
+ InvalidateRect (hProgressBar, NULL, TRUE);
+ ShowWindow(hProgressBar, SW_HIDE);
+ ShowWindow(hProgressBar, SW_SHOW);
+ // Prevent the IDC_LOG_WINDOW item from partially disappearing at higher DPIs
+ ShowWindow(GetDlgItem (hCurPage, IDC_LOG_WINDOW), SW_HIDE);
+ ShowWindow(GetDlgItem (hCurPage, IDC_LOG_WINDOW), SW_SHOW);
+ RefreshUIGFX();
+ return TRUE;
+}
+
+void RefreshUIGFX (void)
+{
+ InvalidateRect (GetDlgItem (MainDlg, IDC_SETUP_WIZARD_BKG), NULL, TRUE);
+ InvalidateRect (GetDlgItem (MainDlg, IDC_BOX_TITLE), NULL, TRUE);
+ InvalidateRect (GetDlgItem (MainDlg, IDC_BOX_INFO), NULL, TRUE);
+ InvalidateRect (GetDlgItem (MainDlg, IDC_BITMAP_SETUP_WIZARD), NULL, TRUE);
+ InvalidateRect (GetDlgItem (MainDlg, IDC_HR), NULL, TRUE);
+ // Prevent these items from disappearing at higher DPIs
+ ShowWindow(GetDlgItem(MainDlg, IDC_HR), SW_HIDE);
+ ShowWindow(GetDlgItem(MainDlg, IDC_HR), SW_SHOW);
+ ShowWindow(GetDlgItem(MainDlg, IDC_HR_BOTTOM), SW_HIDE);
+ ShowWindow(GetDlgItem(MainDlg, IDC_HR_BOTTOM), SW_SHOW);
+ ShowWindow(GetDlgItem(MainDlg, IDC_BOX_INFO), SW_HIDE);
+ ShowWindow(GetDlgItem(MainDlg, IDC_BOX_INFO), SW_SHOW);
+ ShowWindow(GetDlgItem(MainDlg, IDC_BOX_TITLE), SW_HIDE);
+ ShowWindow(GetDlgItem(MainDlg, IDC_BOX_TITLE), SW_SHOW);
+}
+
+
+/* Except in response to the WM_INITDIALOG message, the dialog box procedure
+ should return nonzero if it processes the message, and zero if it does
+ not. - see DialogProc */
+BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ WORD lw = LOWORD (wParam);
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ RECT rec;
+
+ GetModuleFileName (NULL, SelfFile, sizeof (SelfFile));
+
+ MainDlg = hwndDlg;
+
+ if (!CreateAppSetupMutex ())
+ AbortProcess ("TC_INSTALLER_IS_RUNNING");
+
+ InitDialog (hwndDlg);
+ LocalizeDialog (hwndDlg, "IDD_INSTL_DLG");
+
+ // Resize the bitmap if the user has a non-default DPI
+ if (ScreenDPI != USER_DEFAULT_SCREEN_DPI)
+ {
+ hbmWizardBitmapRescaled = RenderBitmap (MAKEINTRESOURCE (IDB_SETUP_WIZARD),
+ GetDlgItem (hwndDlg, IDC_BITMAP_SETUP_WIZARD),
+ 0, 0, 0, 0, FALSE, TRUE);
+ }
+
+ // Gfx area background (must not keep aspect ratio; must retain Windows-imposed distortion)
+ GetClientRect (GetDlgItem (hwndDlg, IDC_SETUP_WIZARD_GFX_AREA), &rec);
+ SetWindowPos (GetDlgItem (hwndDlg, IDC_SETUP_WIZARD_BKG), HWND_TOP, 0, 0, rec.right, rec.bottom, SWP_NOMOVE);
+
+ nPbar = IDC_PROGRESS_BAR;
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_BOX_TITLE), WM_SETFONT, (WPARAM) hUserBoldFont, (LPARAM) TRUE);
+
+ SetWindowText (hwndDlg, "TrueCrypt Setup " VERSION_STRING);
+
+ DonColorSchemeId = GetDonVal (2, 9);
+
+ if (bDevm)
+ {
+ InitWizardDestInstallPath ();
+ bSystemRestore = FALSE;
+ bRegisterFileExt = FALSE;
+ bAddToStartMenu = FALSE;
+ bDesktopIcon = TRUE;
+ bLicenseAccepted = TRUE;
+ bStartInstall = TRUE;
+ LoadPage (hwndDlg, INSTALL_PROGRESS_PAGE);
+ }
+ else
+ LoadPage (hwndDlg, INTRO_PAGE);
+
+ }
+ return 0;
+
+ case WM_SYSCOMMAND:
+ if (lw == IDC_ABOUT)
+ {
+ if (bLicenseAccepted)
+ DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc);
+
+ return 1;
+ }
+ return 0;
+
+ case WM_HELP:
+ if (bLicenseAccepted)
+ OpenPageHelp (hwndDlg, nCurPageNo);
+
+ return 1;
+
+
+ case WM_COMMAND:
+ if (lw == IDHELP)
+ {
+ if (bLicenseAccepted)
+ OpenPageHelp (hwndDlg, nCurPageNo);
+
+ return 1;
+ }
+ if (lw == IDCANCEL)
+ {
+ PostMessage (hwndDlg, WM_CLOSE, 0, 0);
+ return 1;
+ }
+ if (lw == IDC_NEXT)
+ {
+ if (nCurPageNo == INTRO_PAGE)
+ {
+ if (!IsButtonChecked (GetDlgItem (hCurPage, IDC_AGREE)))
+ {
+ bLicenseAccepted = FALSE;
+ return 1;
+ }
+ bLicenseAccepted = TRUE;
+ EnableWindow (GetDlgItem (hwndDlg, IDHELP), TRUE);
+
+ if (nCurrentOS == WIN_2000)
+ {
+ WarningDirect (L"Warning: Please note that this may be the last version of TrueCrypt that supports Windows 2000. If you want to be able to upgrade to future versions of TrueCrypt (which is highly recommended), you will need to upgrade to Windows XP or a later version of Windows.\n\nNote: Microsoft stopped issuing security updates for Windows 2000 to the general public on 7/13/2010 (the last non-security update for Windows 2000 was issued to the general public in 2005).");
+
+
+ HKEY hkey;
+
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Updates\\Windows 2000\\SP5\\Update Rollup 1", 0, KEY_READ, &hkey) != ERROR_SUCCESS)
+ {
+ ErrorDirect (L"TrueCrypt requires Update Rollup 1 for Windows 2000 SP4 to be installed.\n\nFor more information, see http://support.microsoft.com/kb/891861");
+ AbortProcessSilent ();
+ }
+
+ RegCloseKey (hkey);
+ }
+ }
+
+ else if (nCurPageNo == WIZARD_MODE_PAGE)
+ {
+ if (IsButtonChecked (GetDlgItem (hCurPage, IDC_WIZARD_MODE_EXTRACT_ONLY)))
+ {
+ Info ("TRAVELER_LIMITATIONS_NOTE");
+
+ if (IsUacSupported()
+ && AskWarnYesNo ("TRAVELER_UAC_NOTE") == IDNO)
+ {
+ return 1;
+ }
+
+ bExtractOnly = TRUE;
+ nCurPageNo = EXTRACTION_OPTIONS_PAGE - 1;
+ }
+ }
+
+ else if (nCurPageNo == EXTRACTION_OPTIONS_PAGE)
+ {
+ GetWindowText (GetDlgItem (hCurPage, IDC_DESTINATION), WizardDestExtractPath, sizeof (WizardDestExtractPath));
+
+ bStartExtraction = TRUE;
+ }
+
+ else if (nCurPageNo == INSTALL_OPTIONS_PAGE)
+ {
+ GetWindowText (GetDlgItem (hCurPage, IDC_DESTINATION), WizardDestInstallPath, sizeof (WizardDestInstallPath));
+
+ bStartInstall = TRUE;
+ }
+
+ else if (nCurPageNo == INSTALL_PROGRESS_PAGE)
+ {
+ PostMessage (hwndDlg, WM_CLOSE, 0, 0);
+ return 1;
+ }
+
+ else if (nCurPageNo == EXTRACTION_PROGRESS_PAGE)
+ {
+ PostMessage (hwndDlg, WM_CLOSE, 0, 0);
+ return 1;
+ }
+
+ else if (nCurPageNo == DONATIONS_PAGE)
+ {
+ // 'Finish' button clicked
+
+ PostMessage (hwndDlg, WM_CLOSE, 0, 0);
+
+ return 1;
+ }
+
+ LoadPage (hwndDlg, ++nCurPageNo);
+
+ return 1;
+ }
+
+ if (lw == IDC_PREV)
+ {
+ if (nCurPageNo == WIZARD_MODE_PAGE)
+ {
+ bExtractOnly = IsButtonChecked (GetDlgItem (hCurPage, IDC_WIZARD_MODE_EXTRACT_ONLY));
+ }
+
+ else if (nCurPageNo == EXTRACTION_OPTIONS_PAGE)
+ {
+ GetWindowText (GetDlgItem (hCurPage, IDC_DESTINATION), WizardDestExtractPath, sizeof (WizardDestExtractPath));
+ nCurPageNo = WIZARD_MODE_PAGE + 1;
+ }
+
+ else if (nCurPageNo == INSTALL_OPTIONS_PAGE)
+ {
+ GetWindowText (GetDlgItem (hCurPage, IDC_DESTINATION), WizardDestInstallPath, sizeof (WizardDestInstallPath));
+ }
+
+ LoadPage (hwndDlg, --nCurPageNo);
+
+ return 1;
+ }
+
+ return 0;
+
+
+
+ case WM_PAINT:
+
+ if (nCurPageNo == DONATIONS_PAGE && DonColorSchemeId != 2)
+ {
+ HWND hwndItem = GetDlgItem (MainDlg, IDC_MAIN_CONTENT_CANVAS);
+
+ PAINTSTRUCT tmpPaintStruct;
+ HDC hdc = BeginPaint (hwndItem, &tmpPaintStruct);
+
+ if (DonColorSchemeId != 2)
+ {
+ HBRUSH tmpBrush = CreateSolidBrush (DonBkgColor);
+
+ RECT trect;
+
+ trect.left = CompensateXDPI (1);
+ trect.right = CompensateXDPI (560);
+ trect.top = CompensateYDPI (DonColorSchemeId == 7 ? 11 : 0);
+ trect.bottom = CompensateYDPI (260);
+
+ FillRect (hdc, &trect, tmpBrush);
+ }
+
+ EndPaint(hwndItem, &tmpPaintStruct);
+ ReleaseDC (hwndItem, hdc);
+ }
+ return 0;
+
+
+
+ case WM_CTLCOLORSTATIC:
+
+ if ((HWND) lParam != GetDlgItem (MainDlg, IDC_MAIN_CONTENT_CANVAS))
+ {
+ /* This maintains the background under the transparent-backround texts. The above 'if' statement allows
+ colored background to be erased automatically when leaving a page that uses it. */
+
+ SetBkMode ((HDC) wParam, TRANSPARENT);
+ return ((LONG) (HBRUSH) (GetStockObject (NULL_BRUSH)));
+ }
+
+
+ case WM_ERASEBKGND:
+
+ return 0;
+
+
+
+ case TC_APPMSG_INSTALL_SUCCESS:
+
+ /* Installation completed successfully */
+
+ bInProgress = FALSE;
+
+ nCurPageNo = DONATIONS_PAGE;
+ LoadPage (hwndDlg, DONATIONS_PAGE);
+
+ NormalCursor ();
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_NEXT), GetString ("FINALIZE"));
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (hwndDlg, IDHELP), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDCANCEL), FALSE);
+
+
+ RefreshUIGFX ();
+ return 1;
+
+ case TC_APPMSG_INSTALL_FAILURE:
+
+ /* Installation failed */
+
+ bInProgress = FALSE;
+
+ NormalCursor ();
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_TITLE), GetString ("INSTALL_FAILED"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_INFO), L"");
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDCANCEL), GetString ("IDCLOSE"));
+ EnableWindow (GetDlgItem (hwndDlg, IDHELP), TRUE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NEXT), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDCANCEL), TRUE);
+
+ RefreshUIGFX();
+
+ return 1;
+
+ case TC_APPMSG_EXTRACTION_SUCCESS:
+
+ /* Extraction completed successfully */
+
+ UpdateProgressBarProc(100);
+
+ bInProgress = FALSE;
+ bExtractionSuccessful = TRUE;
+
+ NormalCursor ();
+
+ StatusMessage (hCurPage, "EXTRACTION_FINISHED_INFO");
+
+ EnableWindow (GetDlgItem (hwndDlg, IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NEXT), TRUE);
+ EnableWindow (GetDlgItem (hwndDlg, IDHELP), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDCANCEL), FALSE);
+
+ RefreshUIGFX ();
+
+ Info ("EXTRACTION_FINISHED_INFO");
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_NEXT), GetString ("FINALIZE"));
+
+ nCurPageNo = DONATIONS_PAGE;
+ LoadPage (hwndDlg, DONATIONS_PAGE);
+
+ return 1;
+
+ case TC_APPMSG_EXTRACTION_FAILURE:
+
+ /* Extraction failed */
+
+ bInProgress = FALSE;
+
+ NormalCursor ();
+
+ StatusMessage (hCurPage, "EXTRACTION_FAILED");
+
+ UpdateProgressBarProc(0);
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_TITLE), GetString ("EXTRACTION_FAILED"));
+ SetWindowTextW (GetDlgItem (hwndDlg, IDC_BOX_INFO), L"");
+
+ SetWindowTextW (GetDlgItem (hwndDlg, IDCANCEL), GetString ("IDCLOSE"));
+ EnableWindow (GetDlgItem (hwndDlg, IDHELP), TRUE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_PREV), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NEXT), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDCANCEL), TRUE);
+
+ RefreshUIGFX();
+
+ Error ("EXTRACTION_FAILED");
+
+ return 1;
+
+ case WM_CLOSE:
+
+ if (!bDevm)
+ {
+ if (bInProgress)
+ {
+ NormalCursor();
+ if (AskNoYes("CONFIRM_EXIT_UNIVERSAL") == IDNO)
+ {
+ return 1;
+ }
+ WaitCursor ();
+ }
+
+ if (bOpenContainingFolder && bExtractOnly && bExtractionSuccessful)
+ {
+ ShellExecute (NULL, "open", WizardDestExtractPath, NULL, NULL, SW_SHOWNORMAL);
+ }
+ else
+ {
+ if (bPromptReleaseNotes
+ && AskYesNo ("AFTER_UPGRADE_RELEASE_NOTES") == IDYES)
+ {
+ Applink ("releasenotes", TRUE, "");
+ }
+
+ bPromptReleaseNotes = FALSE;
+
+ if (bPromptTutorial
+ && AskYesNo ("AFTER_INSTALL_TUTORIAL") == IDYES)
+ {
+ Applink ("beginnerstutorial", TRUE, "");
+ }
+
+ bPromptTutorial = FALSE;
+ }
+
+ if (bRestartRequired
+ && AskYesNo (bUpgrade ? "UPGRADE_OK_REBOOT_REQUIRED" : "CONFIRM_RESTART") == IDYES)
+ {
+ RestartComputer();
+ }
+ }
+
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+
+ return 0;
+}
+
+
diff --git a/src/Setup/Wizard.h b/src/Setup/Wizard.h
new file mode 100644
index 00000000..dc8845ea
--- /dev/null
+++ b/src/Setup/Wizard.h
@@ -0,0 +1,29 @@
+/*
+ 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-2008 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. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void InitProgressBar (void);
+BOOL UpdateProgressBarProc (int nPercent);
+void RefreshUIGFX (void);
+void localcleanupwiz (void);
+
+BOOL CALLBACK PageDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam );
+BOOL CALLBACK MainDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam );
+
+extern BOOL bPromptTutorial;
+extern BOOL bPromptReleaseNotes;
+
+#ifdef __cplusplus
+}
+#endif