summaryrefslogtreecommitdiffstats
path: root/chrome/installer/setup
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/installer/setup
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer/setup')
-rw-r--r--chrome/installer/setup/SConscript153
-rw-r--r--chrome/installer/setup/install.cc269
-rw-r--r--chrome/installer/setup/main.cc389
-rw-r--r--chrome/installer/setup/setup.cc290
-rw-r--r--chrome/installer/setup/setup.exe.manifest11
-rw-r--r--chrome/installer/setup/setup.h104
-rw-r--r--chrome/installer/setup/setup.icobin0 -> 766 bytes
-rw-r--r--chrome/installer/setup/setup.rc82
-rw-r--r--chrome/installer/setup/setup.vcproj130
-rw-r--r--chrome/installer/setup/setup.vsprops30
-rw-r--r--chrome/installer/setup/setup_constants.cc49
-rw-r--r--chrome/installer/setup/setup_constants.h53
-rw-r--r--chrome/installer/setup/setup_debug.vsprops8
-rw-r--r--chrome/installer/setup/setup_exe_version.rc.version40
-rw-r--r--chrome/installer/setup/setup_release.vsprops8
-rw-r--r--chrome/installer/setup/setup_resource.h17
-rw-r--r--chrome/installer/setup/uninstall.cc303
-rw-r--r--chrome/installer/setup/uninstall.h56
18 files changed, 1992 insertions, 0 deletions
diff --git a/chrome/installer/setup/SConscript b/chrome/installer/setup/SConscript
new file mode 100644
index 0000000..b26790f
--- /dev/null
+++ b/chrome/installer/setup/SConscript
@@ -0,0 +1,153 @@
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Import('env', 'env_res')
+
+env = env.Clone()
+env_res = env_res.Clone()
+
+
+env_res.Append(
+ CPPPATH = [
+ "$TARGET_ROOT",
+ ".",
+ "#/..",
+ ],
+ RCFLAGS = [
+ ["/l", "0x409"],
+ ],
+)
+
+
+resources = [
+ env_res.RES('setup.rc'),
+ env_res.RES('../util/setup_strings.rc'),
+]
+
+
+env.Prepend(
+ CPPPATH = [
+ '../util',
+ '$TARGET_ROOT',
+ '.',
+ '#/..',
+ ],
+ LINKFLAGS = [
+ '/INCREMENTAL',
+ '/DEBUG',
+
+ '/DELAYLOAD:"dwmapi.dll"',
+ '/DELAYLOAD:"uxtheme.dll"',
+
+ '/OPT:NOWIN98',
+ '/SUBSYSTEM:WINDOWS',
+ '/MACHINE:X86',
+ '/FIXED:No',
+
+ '/safeseh',
+ '/dynamicbase',
+ '/ignore:4199',
+ '/nxcompat',
+
+ '/PDB:${TARGETS[1]}',
+ '/MAP:${TARGETS[2]}',
+ ],
+ LIBS = [
+ 'shlwapi.lib',
+
+ 'msi.lib',
+
+ 'wininet.lib',
+ 'version.lib',
+ 'msimg32.lib',
+ 'ws2_32.lib',
+ 'usp10.lib',
+ 'psapi.lib',
+ 'kernel32.lib',
+ 'user32.lib',
+ 'gdi32.lib',
+ 'winspool.lib',
+ 'comdlg32.lib',
+ 'advapi32.lib',
+ 'shell32.lib',
+ 'ole32.lib',
+ 'oleaut32.lib',
+ 'uuid.lib',
+ 'odbc32.lib',
+ 'odbccp32.lib',
+
+ 'DelayImp.lib',
+ ],
+)
+
+input_files = [
+ 'install.cc',
+ 'main.cc',
+ 'setup.cc',
+ 'setup_constants.cc',
+ 'uninstall.cc',
+]
+
+libs = [
+ '../util/util.lib',
+ '$BSPATCH_DIR/bspatch.lib',
+ '$LZMA_SDK_DIR/lzma_sdk.lib',
+ '$ICU38_DIR/icuuc.lib',
+ '$CHROME_DIR/common/common.lib',
+ '$BASE_DIR/base.lib',
+]
+
+exe = env.Program(['setup',
+ 'setup.pdb',
+ 'setup.map'],
+ resources + input_files + libs)
+i = env.Install('$TARGET_ROOT', exe)
+
+env.Alias('chrome', i)
+
+
+
+env_version = env.Clone(
+ VERSION_BAT = File('#/../chrome/tools/build/win/version.bat'),
+ CHROMEDIR = Dir('#/../chrome'),
+ PWD = Dir('.'),
+)
+
+import os
+env_version['ENV']['PROGRAMFILES'] = os.environ['PROGRAMFILES']
+env_version['ENV']['SystemDrive'] = os.environ['SystemDrive']
+env_version['ENV']['USERPROFILE'] = os.environ['USERPROFILE']
+env_version['ENV']['PATH'] = os.environ['PATH']
+
+setup_exe_version_rc = env_version.Command(
+ 'setup_exe_version.rc',
+ ['setup_exe_version.rc.version',
+ '$CHROMEDIR/VERSION',
+ '$CHROMEDIR/BRANDING'],
+ '$VERSION_BAT $SOURCE $CHROMEDIR $PWD $TARGET')
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
new file mode 100644
index 0000000..5cd0f22
--- /dev/null
+++ b/chrome/installer/setup/install.cc
@@ -0,0 +1,269 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <time.h>
+
+#include "base/file_util.h"
+#include "base/scoped_ptr.h"
+#include "base/string_util.h"
+#include "chrome/installer/setup/setup.h"
+#include "chrome/installer/setup/setup_constants.h"
+#include "chrome/installer/util/copy_tree_work_item.h"
+#include "chrome/installer/util/create_dir_work_item.h"
+#include "chrome/installer/util/create_reg_key_work_item.h"
+#include "chrome/installer/util/delete_tree_work_item.h"
+#include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/logging_installer.h"
+#include "chrome/installer/util/google_update_constants.h"
+#include "chrome/installer/util/set_reg_value_work_item.h"
+#include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/util_constants.h"
+#include "chrome/installer/util/version.h"
+#include "chrome/installer/util/work_item_list.h"
+
+namespace {
+std::wstring AppendPath(const std::wstring parent_path,
+ const std::wstring path) {
+ std::wstring new_path(parent_path);
+ file_util::AppendToPath(&new_path, path);
+ return new_path;
+}
+
+
+// This method adds work items to create (or update) Chrome uninstall entry in
+// Control Panel->Add/Remove Programs list.
+void AddUninstallShortcutWorkItems(HKEY reg_root,
+ const std::wstring& exe_path,
+ const std::wstring& install_path,
+ const std::wstring& new_version,
+ WorkItemList* install_list) {
+ std::wstring uninstall_cmd(L"\"");
+ uninstall_cmd.append(installer::GetInstallerPathUnderChrome(install_path,
+ new_version));
+ file_util::AppendToPath(&uninstall_cmd,
+ file_util::GetFilenameFromPath(exe_path));
+ uninstall_cmd.append(L"\" --");
+ uninstall_cmd.append(installer_util::switches::kUninstall);
+
+ // Create DisplayName, UninstallString and InstallLocation keys
+ install_list->AddCreateRegKeyWorkItem(reg_root,
+ installer_util::kUninstallRegPath);
+ install_list->AddSetRegValueWorkItem(
+ reg_root,
+ installer_util::kUninstallRegPath,
+ installer_util::kUninstallDisplayNameField,
+ installer_util::kChrome, true);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ installer_util::kUninstallStringField,
+ uninstall_cmd, true);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"InstallLocation", install_path, true);
+
+ // DisplayIcon, NoModify and NoRepair
+ std::wstring chrome_icon = AppendPath(install_path,
+ installer_util::kChromeExe);
+ ShellUtil::GetChromeIcon(chrome_icon);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"DisplayIcon", chrome_icon, true);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"NoModify", 1, true);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"NoRepair", 1, true);
+
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"Publisher",
+ installer_util::kPublisherName, true);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"Version", new_version.c_str(), true);
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"DisplayVersion",
+ new_version.c_str(), true);
+ time_t rawtime = time(NULL);
+ struct tm timeinfo = {0};
+ localtime_s(&timeinfo, &rawtime);
+ wchar_t buffer[9];
+ if (wcsftime(buffer, 9, L"%Y%m%d", &timeinfo) == 8) {
+ install_list->AddSetRegValueWorkItem(reg_root,
+ installer_util::kUninstallRegPath,
+ L"InstallDate",
+ buffer, false);
+ }
+}
+
+void AddInstallerCopyTasks(const std::wstring& exe_path,
+ const std::wstring& archive_path,
+ const std::wstring& temp_path,
+ const std::wstring& install_path,
+ const std::wstring& new_version,
+ WorkItemList* install_list) {
+ std::wstring installer_dir(installer::GetInstallerPathUnderChrome(
+ install_path, new_version));
+ install_list->AddCreateDirWorkItem(installer_dir);
+
+ std::wstring exe_dst(installer_dir);
+ std::wstring archive_dst(installer_dir);
+ file_util::AppendToPath(&exe_dst,
+ file_util::GetFilenameFromPath(exe_path));
+ file_util::AppendToPath(&archive_dst,
+ file_util::GetFilenameFromPath(archive_path));
+
+ install_list->AddCopyTreeWorkItem(exe_path, exe_dst, temp_path,
+ WorkItem::ALWAYS);
+ install_list->AddCopyTreeWorkItem(archive_path, archive_dst, temp_path,
+ WorkItem::ALWAYS);
+}
+
+
+// This method tells if we are running on 64 bit platform so that we can copy
+// one extra exe. If the API call to determine 64 bit fails, we play it safe
+// and return true anyway so that the executable can be copied.
+bool Is64bit() {
+ typedef BOOL (WINAPI *WOW_FUNC)(HANDLE, PBOOL);
+ BOOL is64 = FALSE;
+
+ HANDLE handle = GetCurrentProcess();
+ HMODULE module = GetModuleHandle(L"kernel32.dll");
+ WOW_FUNC p = reinterpret_cast<WOW_FUNC>(GetProcAddress(module,
+ "IsWow64Process"));
+ if ((p != NULL) && (!(p)(handle, &is64) || (is64 != FALSE))) {
+ return true;
+ }
+
+ return false;
+}
+
+}
+
+bool installer::InstallNewVersion(const std::wstring& exe_path,
+ const std::wstring& archive_path,
+ const std::wstring& src_path,
+ const std::wstring& install_path,
+ const std::wstring& temp_dir,
+ const HKEY reg_root,
+ const Version& new_version) {
+
+ if (reg_root != HKEY_LOCAL_MACHINE && reg_root != HKEY_CURRENT_USER)
+ return false;
+
+ scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList());
+ // A temp directory that work items need and the actual install directory.
+ install_list->AddCreateDirWorkItem(temp_dir);
+ install_list->AddCreateDirWorkItem(install_path);
+
+ // Browse for all the files in archive, add work items to copy them while
+ // handling special cases of executables.
+ LOG(INFO) << "Looking for Chrome installation files under " << src_path;
+ std::wstring root_path(src_path);
+ file_util::AppendToPath(&root_path, L"*");
+ WIN32_FIND_DATA find_file_data;
+ HANDLE file_handle = FindFirstFile(root_path.c_str(), &find_file_data);
+ BOOL ret = TRUE;
+ while (ret) {
+ LOG(INFO) << "directory found: " << find_file_data.cFileName;
+ // We do not want any directories starting with '.'
+ if ((wcslen(find_file_data.cFileName) <= 0) ||
+ (find_file_data.cFileName[0] == '.')) {
+ LOG(INFO) << "Ignoring directory found: " << find_file_data.cFileName;
+ } else if (_wcsicmp(find_file_data.cFileName,
+ installer_util::kChromeExe) == 0) {
+ // Special case of chrome.exe. Delete any new_chrome.exe if present
+ // (we will create a new one if chrome.exe is in use) and then
+ // copy chrome.exe.
+ install_list->AddDeleteTreeWorkItem(
+ AppendPath(install_path, installer::kChromeNewExe), std::wstring());
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, installer_util::kChromeExe),
+ AppendPath(install_path, installer_util::kChromeExe),
+ temp_dir, WorkItem::RENAME_IF_IN_USE,
+ AppendPath(install_path, installer::kChromeNewExe));
+ } else if (_wcsicmp(find_file_data.cFileName,
+ installer::kWowHelperExe) == 0) {
+ // Special case of wow_helper.exe which is required only on 64 bit
+ // systems. This exe runs only for a short time when Chrome starts so
+ // it should not be locked most of the times and can be overwritten
+ // directly.
+ if (Is64bit()) {
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, installer::kWowHelperExe),
+ AppendPath(install_path, installer::kWowHelperExe),
+ temp_dir, WorkItem::ALWAYS);
+ }
+ } else {
+ // In all other cases just copy the file/directory to install location.
+ install_list->AddCopyTreeWorkItem(
+ AppendPath(src_path, find_file_data.cFileName),
+ AppendPath(install_path, find_file_data.cFileName),
+ temp_dir, WorkItem::ALWAYS); // Always overwrite.
+ }
+ ret = FindNextFile(file_handle, &find_file_data);
+ }
+ FindClose(file_handle);
+
+ // Copy installer in install directory and
+ // add shortcut in Control Panel->Add/Remove Programs.
+ AddInstallerCopyTasks(exe_path, archive_path, temp_dir, install_path,
+ new_version.GetString(), install_list.get());
+ AddUninstallShortcutWorkItems(reg_root, exe_path, install_path,
+ new_version.GetString(), install_list.get());
+
+ // Delete any old_chrome.exe if present.
+ install_list->AddDeleteTreeWorkItem(
+ AppendPath(install_path, installer::kChromeOldExe), std::wstring());
+
+ // Create Google Update key (if not already present) and set the new Chrome
+ // version as last step.
+ std::wstring chrome_google_update_key =
+ InstallUtil::GetChromeGoogleUpdateKey();
+ install_list->AddCreateRegKeyWorkItem(reg_root, chrome_google_update_key);
+ install_list->AddSetRegValueWorkItem(reg_root, chrome_google_update_key,
+ google_update::kRegNameField,
+ installer_util::kChrome,
+ false); // Don't overwrite.
+ install_list->AddSetRegValueWorkItem(reg_root, chrome_google_update_key,
+ google_update::kRegVersionField,
+ new_version.GetString(),
+ true); // overwrite version
+
+ // Perform install operations.
+ if (!install_list->Do()) {
+ LOG(ERROR) << "install failed, roll back... ";
+ install_list->Rollback();
+ return false;
+ }
+
+ return true;
+}
diff --git a/chrome/installer/setup/main.cc b/chrome/installer/setup/main.cc
new file mode 100644
index 0000000..233408b
--- /dev/null
+++ b/chrome/installer/setup/main.cc
@@ -0,0 +1,389 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/registry.h"
+#include "base/string_util.h"
+#include "chrome/installer/setup/setup.h"
+#include "chrome/installer/setup/setup_constants.h"
+#include "chrome/installer/setup/uninstall.h"
+#include "chrome/installer/util/delete_tree_work_item.h"
+#include "chrome/installer/util/helper.h"
+#include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/logging_installer.h"
+#include "chrome/installer/util/lzma_util.h"
+#include "chrome/installer/util/google_update_constants.h"
+#include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/util_constants.h"
+#include "chrome/installer/util/work_item.h"
+#include "third_party/bspatch/mbspatch.h"
+
+namespace {
+
+// Checks if the current system is running Windows XP or later. We are not
+// supporting Windows 2K for beta release.
+bool IsWindowsXPorLater() {
+ OSVERSIONINFOEX osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ GetVersionEx((OSVERSIONINFO *) &osvi);
+
+ // Windows versioning scheme doesn't seem very clear but here is what
+ // the code is checking as the minimum version required for Chrome:
+ // * Major > 5 is Vista or later so no further checks for Service Pack
+ // * Major = 5 && Minor > 1 is Windows Server 2003 so again no SP checks
+ // * Major = 5 && Minor = 1 is WinXP so check for SP1 or later
+ LOG(INFO) << "Windows Version: Major - " << osvi.dwMajorVersion
+ << " Minor - " << osvi.dwMinorVersion
+ << " Service Pack Major - " << osvi.wServicePackMajor
+ << " Service Pack Minor - " << osvi.wServicePackMinor;
+ if ((osvi.dwMajorVersion > 5) || // Vista or later
+ ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion > 1)) || // Win 2003
+ ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1) &&
+ (osvi.wServicePackMajor >= 1))) { // WinXP with SP1
+ return true;
+ }
+ return false;
+}
+
+// Applies a binary patch to existing Chrome installer archive on the system.
+// Uses bspatch library.
+int PatchArchiveFile(bool system_install, const std::wstring& archive_path,
+ const std::wstring& uncompressed_archive,
+ const installer::Version* installed_version) {
+ std::wstring existing_archive =
+ installer::GetChromeInstallPath(system_install);
+ file_util::AppendToPath(&existing_archive,
+ installed_version->GetString());
+ file_util::AppendToPath(&existing_archive, installer::kInstallerDir);
+ file_util::AppendToPath(&existing_archive, installer::kChromeArchive);
+
+ std::wstring patch_archive(archive_path);
+ file_util::AppendToPath(&patch_archive, installer::kChromePatchArchive);
+
+ LOG(INFO) << "Applying patch " << patch_archive
+ << " to file " << existing_archive
+ << " and generating file " << uncompressed_archive;
+ return ApplyBinaryPatch(WideToUTF8(existing_archive).c_str(),
+ WideToUTF8(patch_archive).c_str(),
+ WideToUTF8(uncompressed_archive).c_str());
+}
+
+
+// This method unpacks and uncompresses the given archive file. For Chrome
+// install we are creating a uncompressed archive that contains all the files
+// needed for the installer. This uncompressed archive is later compressed.
+//
+// This method first uncompresses archive specified by parameter "archive"
+// and assumes that it will result in an uncompressed full archive file
+// (chrome.7z) or uncompressed patch archive file (patch.7z). If it is patch
+// archive file, the patch is applied to the old archive file that should be
+// present on the system already. As the final step the new archive file
+// is unpacked in the path specified by parameter "path".
+DWORD UnPackArchive(const std::wstring& archive, bool system_install,
+ const installer::Version* installed_version,
+ const std::wstring& temp_path, const std::wstring& path,
+ bool& incremental_install) {
+ DWORD ret = NO_ERROR;
+ installer::LzmaUtil util;
+ // First uncompress the payload. This could be a differential
+ // update (patch.7z) or full archive (chrome.7z). If this uncompress fails
+ // return with error.
+ LOG(INFO) << "Opening archive " << archive;
+ if ((ret = util.OpenArchive(archive)) != NO_ERROR) {
+ LOG(ERROR) << "unable to open install archive: " << archive;
+ } else {
+ LOG(INFO) << "Uncompressing archive to path " << temp_path;
+ if ((ret = util.UnPack(temp_path)) != NO_ERROR) {
+ LOG(ERROR) << "error during uncompression: " << ret;
+ }
+ util.CloseArchive();
+ }
+ if (ret != NO_ERROR)
+ return ret;
+
+ std::wstring archive_name = file_util::GetFilenameFromPath(archive);
+ std::wstring uncompressed_archive(temp_path);
+ file_util::AppendToPath(&uncompressed_archive, installer::kChromeArchive);
+ // Check if this is differential update and if it is, patch it to the
+ // installer archive that should already be on the machine.
+ std::wstring prefix = installer::kChromeCompressedPatchArchivePrefix;
+ if ((archive_name.size() >= prefix.size()) &&
+ (std::equal(prefix.begin(), prefix.end(), archive_name.begin(),
+ CaseInsensitiveCompare<wchar_t>()))) {
+ LOG(INFO) << "Differential patch found. Applying to existing archive.";
+ incremental_install = true;
+ if (!installed_version) {
+ LOG(ERROR) << "Can not use differential update when Chrome is not "
+ << "installed on the system.";
+ return 1;
+ }
+ if (PatchArchiveFile(system_install, temp_path, uncompressed_archive,
+ installed_version)) {
+ LOG(ERROR) << "Binary patching failed.";
+ return 1;
+ }
+ }
+
+ // If we got the uncompressed archive, lets unpack it
+ LOG(INFO) << "Opening archive " << uncompressed_archive;
+ if ((ret = util.OpenArchive(uncompressed_archive)) != NO_ERROR) {
+ LOG(ERROR) << "unable to open install archive: " <<
+ uncompressed_archive;
+ } else {
+ LOG(INFO) << "Unpacking archive to path " << path;
+ if ((ret = util.UnPack(path)) != NO_ERROR) {
+ LOG(ERROR) << "error during uncompression: " << ret;
+ }
+ util.CloseArchive();
+ }
+
+ return ret;
+}
+
+
+// Find the version of Chrome from an install source directory.
+// Chrome_path should contain a complete and unpacked install package (i.e.
+// a Chrome directory under which there is a version folder).
+// Returns the version or NULL if no version is found.
+installer::Version* GetVersionFromDir(const std::wstring& chrome_path) {
+ LOG(INFO) << "Looking for Chrome version folder under " << chrome_path;
+ std::wstring root_path(chrome_path);
+ file_util::AppendToPath(&root_path, L"*");
+
+ WIN32_FIND_DATA find_file_data;
+ HANDLE file_handle = FindFirstFile(root_path.c_str(), &find_file_data);
+ BOOL ret = TRUE;
+ installer::Version *version = NULL;
+ // Here we are assuming that the installer we have is really valid so there
+ // can not be two version directories. We exit as soon as we find a valid
+ // version directory.
+ while (ret) {
+ if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ LOG(INFO) << "directory found: " << find_file_data.cFileName;
+ version =
+ installer::Version::GetVersionFromString(find_file_data.cFileName);
+ if (version) break;
+ }
+ ret = FindNextFile(file_handle, &find_file_data);
+ }
+ FindClose(file_handle);
+
+ return version;
+}
+
+// This method checks if we need to change "ap" key in Google Update to try
+// full installer as fall back method in case incremental installer fails.
+// - If incremental installer fails we append a magic string ("-full"), if
+// it is not present already, so that Google Update server next time will send
+// full installer to update Chrome on the local machine
+// - If we are currently running full installer, we remove this magic
+// string (if it is present) regardless of whether installer failed or not.
+// There is no fall-back for full installer :)
+void ResetGoogleUpdateApKey(bool system_install, bool incremental_install,
+ installer_util::InstallStatus install_status) {
+ HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+
+ RegKey key;
+ std::wstring ap_key_value;
+ std::wstring chrome_google_update_state_key(
+ google_update::kRegPathClientState);
+ chrome_google_update_state_key.append(L"\\");
+ chrome_google_update_state_key.append(google_update::kChromeGuid);
+ if (!key.Open(reg_root, chrome_google_update_state_key.c_str(),
+ KEY_ALL_ACCESS) || !key.ReadValue(google_update::kRegApFieldName,
+ &ap_key_value)) {
+ LOG(INFO) << "Application key not found. Returning without changing it.";
+ key.Close();
+ return;
+ }
+
+ std::wstring new_value = InstallUtil::GetNewGoogleUpdateApKey(
+ incremental_install, install_status, ap_key_value);
+ if ((new_value.compare(ap_key_value) != 0) &&
+ !key.WriteValue(google_update::kRegApFieldName, new_value.c_str())) {
+ LOG(ERROR) << "Failed to write value " << new_value
+ << " to the registry field " << google_update::kRegApFieldName;
+ }
+ key.Close();
+}
+} // namespace
+
+
+int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance,
+ wchar_t* command_line, int show_command) {
+ CommandLine parsed_command_line;
+ installer::InitInstallerLogging(parsed_command_line);
+
+ // Check to make sure current system is WinXP or later. If not, log
+ // error message and get out.
+ if (!IsWindowsXPorLater()) {
+ LOG(ERROR) << "Chrome only supports Windows XP or later";
+ return installer_util::OS_NOT_SUPPORTED;
+ }
+
+ // Initialize COM for use later.
+ if (CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) != S_OK) {
+ LOG(ERROR) << "COM initialization failed.";
+ return installer_util::OS_ERROR;
+ }
+
+ bool system_install =
+ parsed_command_line.HasSwitch(installer_util::switches::kSystemInstall);
+ LOG(INFO) << "system install is " << system_install;
+
+ // Check the existing version installed.
+ scoped_ptr<installer::Version>
+ installed_version(InstallUtil::GetChromeVersion(system_install));
+ if (installed_version.get()) {
+ LOG(INFO) << "version on the system: " << installed_version->GetString();
+ }
+
+ // If --register-chrome-browser option is specified, register all
+ // Chrome protocol/file associations as well as register it as a valid
+ // browser for StarMenu->Internet shortcut. This option should only
+ // be used when setup.exe is launched with admin rights. We do not
+ // make any user specific changes in this option.
+ if (parsed_command_line.HasSwitch(
+ installer_util::switches::kRegisterChromeBrowser)) {
+ std::wstring chrome_exe(parsed_command_line.GetSwitchValue(
+ installer_util::switches::kRegisterChromeBrowser));
+ return ShellUtil::AddChromeToSetAccessDefaults(chrome_exe, true);
+ }
+
+ installer_util::InstallStatus install_status = installer_util::UNKNOWN_STATUS;
+ if (parsed_command_line.HasSwitch(installer_util::switches::kUninstall)) {
+ bool remove_all = true;
+ if (parsed_command_line.HasSwitch(
+ installer_util::switches::kDoNotRemoveSharedItems))
+ remove_all = false;
+ // If --uninstall option is given, uninstall chrome
+ LOG(INFO) << "Uninstalling Chome";
+ if (!installed_version.get()) {
+ LOG(ERROR) << "No Chrome installation found for uninstall";
+ install_status = installer_util::CHROME_NOT_INSTALLED;
+ } else {
+ install_status = installer_setup::UninstallChrome(
+ parsed_command_line.program(), system_install,
+ *installed_version, remove_all);
+ }
+ } else {
+ // If --uninstall option is not specified, we assume it is install case.
+ // For install the default location for chrome.packed.7z is in current
+ // folder, so get that value first.
+ std::wstring archive_path =
+ file_util::GetDirectoryFromPath(parsed_command_line.program());
+ file_util::AppendToPath(&archive_path,
+ std::wstring(installer::kChromeCompressedArchive));
+ // If --install-archive is given, get the user specified value
+ if (parsed_command_line.HasSwitch(
+ installer_util::switches::kInstallArchive)) {
+ archive_path = parsed_command_line.GetSwitchValue(
+ installer_util::switches::kInstallArchive);
+ }
+ LOG(INFO) << "Archive found to install Chrome " << archive_path;
+
+ // Create a temp folder where we will unpack Chrome archive. If it fails,
+ // then we are doomed so return immediately and no cleanup is required.
+ std::wstring install_temp_path;
+ if (!file_util::CreateNewTempDirectory(std::wstring(L"chrome_"),
+ &install_temp_path)) {
+ LOG(ERROR) << "can not create temporary path";
+ return installer_util::TEMP_DIR_FAILED;
+ }
+ LOG(INFO) << "created path " << install_temp_path;
+ std::wstring unpack_path(install_temp_path);
+ file_util::AppendToPath(&unpack_path,
+ std::wstring(installer::kInstallSourceDir));
+
+ bool incremental_install = false;
+ if (UnPackArchive(archive_path, system_install, installed_version.get(),
+ install_temp_path, unpack_path, incremental_install)) {
+ install_status = installer_util::UNCOMPRESSION_FAILED;
+ } else {
+ LOG(INFO) << "unpacked to " << unpack_path;
+ std::wstring src_path(unpack_path);
+ file_util::AppendToPath(&src_path,
+ std::wstring(installer::kInstallSourceChromeDir));
+ scoped_ptr<installer::Version>
+ installer_version(GetVersionFromDir(src_path));
+ if (!installer_version.get()) {
+ LOG(ERROR) << "didn't find any valid version in installer";
+ install_status = installer_util::INVALID_ARCHIVE;
+ } else {
+ LOG(INFO) << "version to be installed: " <<
+ installer_version->GetString();
+ if (installed_version.get() &&
+ installed_version->IsHigherThan(installer_version.get())) {
+ LOG(ERROR) << "Higher version is already installed.";
+ install_status = installer_util::HIGHER_VERSION_EXISTS;
+ } else {
+ // We want to keep uncompressed archive (chrome.7z) that we get after
+ // uncompressing and binary patching. Get the location for this file.
+ std::wstring archive_to_copy(install_temp_path);
+ file_util::AppendToPath(&archive_to_copy,
+ std::wstring(installer::kChromeArchive));
+ install_status = installer::InstallOrUpdateChrome(
+ parsed_command_line.program(), archive_to_copy,
+ install_temp_path, system_install,
+ *installer_version, installed_version.get());
+ if (install_status == installer_util::FIRST_INSTALL_SUCCESS) {
+ LOG(INFO) << "First install successful. Launching Chrome.";
+ installer::LaunchChrome(system_install);
+ }
+ }
+ }
+ }
+
+ // Delete install temporary directory.
+ LOG(INFO) << "Deleting temporary directory " << install_temp_path;
+ scoped_ptr<DeleteTreeWorkItem> delete_tree(
+ WorkItem::CreateDeleteTreeWorkItem(install_temp_path,
+ std::wstring()));
+ delete_tree->Do();
+
+ ResetGoogleUpdateApKey(system_install, incremental_install, install_status);
+
+ // TBD: The previous installs/updates may leave some temporary files
+ // that were not deleted when the installs/updates exited, probably due
+ // to a crash. Try delete those temporary files again?
+ }
+
+ CoUninitialize();
+ if (InstallUtil::InstallSuccessful(install_status))
+ return 0; // For Google Update's benefit we need to return 0 for success
+ // cases.
+ else
+ return install_status;
+}
diff --git a/chrome/installer/setup/setup.cc b/chrome/installer/setup/setup.cc
new file mode 100644
index 0000000..7452f10
--- /dev/null
+++ b/chrome/installer/setup/setup.cc
@@ -0,0 +1,290 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <shlobj.h>
+
+#include "chrome/installer/setup/setup.h"
+
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/registry.h"
+#include "base/string_util.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/installer/setup/setup_constants.h"
+#include "chrome/installer/util/create_reg_key_work_item.h"
+#include "chrome/installer/util/l10n_string_util.h"
+#include "chrome/installer/util/logging_installer.h"
+#include "chrome/installer/util/helper.h"
+#include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/util_constants.h"
+#include "chrome/installer/util/version.h"
+#include "chrome/installer/util/work_item_list.h"
+
+#include "setup_strings.h"
+
+namespace {
+
+void AddChromeToMediaPlayerList() {
+ std::wstring reg_path(installer::kMediaPlayerRegPath);
+ // registry paths can also be appended like file system path
+ file_util::AppendToPath(&reg_path, installer_util::kChromeExe);
+ LOG(INFO) << "Adding Chrome to Media player list at " << reg_path;
+ scoped_ptr<WorkItem> work_item(WorkItem::CreateCreateRegKeyWorkItem(
+ HKEY_LOCAL_MACHINE, reg_path));
+
+ // if the operation fails we log the error but still continue
+ if (!work_item.get()->Do())
+ LOG(ERROR) << "Couldn't add Chrome to media player inclusion list.";
+
+}
+
+// If we ever rename Chrome shortcuts under Windows Start menu, this
+// function deletes any of the old Chrome shortcuts if they exist. This
+// function will probably contain hard coded names of old shortcuts as they
+// will not longer be used anywhere else.
+// Method returns true if it finds and deletes successfully any old shortcut,
+// in all other cases it returns false.
+bool DeleteOldShortcuts(const std::wstring shortcut_path) {
+ // Check for the existence of shortcuts when they were still created under
+ // Start->Programs->Chrome (as opposed to Start->Programs->Google Chrome).
+ std::wstring shortcut_folder(shortcut_path);
+ file_util::AppendToPath(&shortcut_folder, L"Chrome");
+ if (file_util::PathExists(shortcut_folder)) {
+ LOG(INFO) << "Old shortcut path " << shortcut_folder << " exists.";
+ return file_util::Delete(shortcut_folder, true);
+ }
+ return false;
+}
+
+// Update shortcuts that are created by chrome.exe during first run, but
+// we take care of updating them in case the location of chrome.exe changes.
+void UpdateChromeExeShortcuts(const std::wstring& chrome_exe) {
+ std::wstring desktop_shortcut, ql_shortcut, shortcut_name;
+ if (!ShellUtil::GetQuickLaunchPath(&ql_shortcut) ||
+ !ShellUtil::GetDesktopPath(&desktop_shortcut) ||
+ !ShellUtil::GetChromeShortcutName(&shortcut_name))
+ return;
+ // Migrate the old shortcuts from Chrome.lnk to the localized name.
+ std::wstring old_ql_shortcut = ql_shortcut;
+ file_util::AppendToPath(&old_ql_shortcut, L"Chrome.lnk");
+ file_util::AppendToPath(&ql_shortcut, shortcut_name);
+ std::wstring old_desktop_shortcut = desktop_shortcut;
+ file_util::AppendToPath(&old_desktop_shortcut, L"Chrome.lnk");
+ file_util::AppendToPath(&desktop_shortcut, shortcut_name);
+
+ if (file_util::Move(old_ql_shortcut, ql_shortcut)) {
+ // Notify the Windows Shell that we renamed the file so it can remove the
+ // old icon. It's safe to not cehck for MAX_PATH because file_util::Move
+ // does the check for us.
+ SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH, old_ql_shortcut.c_str(),
+ ql_shortcut.c_str());
+ }
+ if (file_util::Move(old_desktop_shortcut, desktop_shortcut)) {
+ SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH, old_desktop_shortcut.c_str(),
+ desktop_shortcut.c_str());
+ }
+
+ // Go ahead and update the shortcuts if they exist.
+ ShellUtil::UpdateChromeShortcut(chrome_exe, ql_shortcut, false);
+ ShellUtil::UpdateChromeShortcut(chrome_exe, desktop_shortcut, false);
+}
+
+// This method creates Chrome shortcuts in Start->Programs for all users or
+// only for current user depending on whether it is system wide install or
+// user only install.
+//
+// If first_install is true, it creates shortcuts for launching and
+// uninstalling chrome.
+// If first_install is false, the function only updates the shortcut for
+// uninstalling chrome. According to
+// http://blogs.msdn.com/oldnewthing/archive/2005/11/24/496690.aspx,
+// updating uninstall shortcut should not trigger Windows "new application
+// installed" notification.
+//
+// If the shortcuts do not exist, the function does not recreate them during
+// update.
+bool CreateOrUpdateChromeShortcuts(const std::wstring& exe_path,
+ bool system_install,
+ installer_util::InstallStatus install_status,
+ const std::wstring& install_path,
+ const std::wstring& new_version) {
+ std::wstring shortcut_path;
+ int dir_enum = (system_install) ? base::DIR_COMMON_START_MENU :
+ base::DIR_START_MENU;
+ if (!PathService::Get(dir_enum, &shortcut_path)) {
+ LOG(ERROR) << "Failed to get location for shortcut.";
+ return false;
+ }
+
+ // Check for existence of old shortcuts
+ bool old_shortcuts_existed = DeleteOldShortcuts(shortcut_path);
+
+ // The location of Start->Programs->Google Chrome folder
+ const std::wstring& product_name =
+ installer_util::GetLocalizedString(IDS_PRODUCT_NAME_BASE);
+ file_util::AppendToPath(&shortcut_path, product_name);
+
+ // Create/update Chrome link (points to chrome.exe) & Uninstall Chrome link
+ // (which points to setup.exe) under this folder only if:
+ // - This is a new install or install repair
+ // OR
+ // - The shortcut already exists in case of updates (user may have deleted
+ // shortcuts since our install. So on updates we only update if shortcut
+ // already exists)
+ bool ret1 = true;
+ std::wstring chrome_link(shortcut_path); // Chrome link (launches Chrome)
+ file_util::AppendToPath(&chrome_link, product_name + L".lnk");
+ std::wstring chrome_exe(install_path); // Chrome link target
+ file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe);
+
+ if ((install_status == installer_util::FIRST_INSTALL_SUCCESS) ||
+ (install_status == installer_util::INSTALL_REPAIRED) ||
+ (old_shortcuts_existed)) {
+ if (!file_util::PathExists(shortcut_path))
+ file_util::CreateDirectoryW(shortcut_path);
+
+ LOG(INFO) << "Creating shortcut to " << chrome_exe << " at " << chrome_link;
+ ShellUtil::UpdateChromeShortcut(chrome_exe, chrome_link, true);
+ } else if (file_util::PathExists(chrome_link)) {
+ LOG(INFO) << "Updating shortcut at " << chrome_link
+ << " to point to " << chrome_exe;
+ ShellUtil::UpdateChromeShortcut(chrome_exe, chrome_link, false);
+ }
+
+ // Create/update uninstall link
+ bool ret2 = true;
+ std::wstring uninstall_link(shortcut_path); // Uninstall Chrome link
+
+ file_util::AppendToPath(&uninstall_link,
+ installer_util::GetLocalizedString(IDS_UNINSTALL_CHROME_BASE) + L".lnk");
+ if ((install_status == installer_util::FIRST_INSTALL_SUCCESS) ||
+ (install_status == installer_util::INSTALL_REPAIRED) ||
+ (old_shortcuts_existed) ||
+ (file_util::PathExists(uninstall_link))) {
+ if (!file_util::PathExists(shortcut_path))
+ file_util::CreateDirectoryW(shortcut_path);
+ std::wstring setup_exe(installer::GetInstallerPathUnderChrome(install_path,
+ new_version));
+ file_util::AppendToPath(&setup_exe,
+ file_util::GetFilenameFromPath(exe_path));
+ std::wstring arguments(L" --");
+ arguments.append(installer_util::switches::kUninstall);
+ LOG(INFO) << "Creating/updating uninstall link at " << uninstall_link;
+ ret2 = file_util::CreateShortcutLink(setup_exe.c_str(),
+ uninstall_link.c_str(),
+ install_path.c_str(),
+ arguments.c_str(),
+ NULL,
+ setup_exe.c_str(),
+ 0);
+ }
+
+ // Update Desktop and Quick Launch shortcuts (only if they already exist)
+ UpdateChromeExeShortcuts(chrome_exe);
+
+ return ret1 && ret2;
+}
+} // namespace
+
+
+std::wstring installer::GetInstallerPathUnderChrome(
+ const std::wstring& install_path, const std::wstring& new_version) {
+ std::wstring installer_path(install_path);
+ file_util::AppendToPath(&installer_path, new_version);
+ file_util::AppendToPath(&installer_path, installer::kInstallerDir);
+ return installer_path;
+}
+
+
+installer_util::InstallStatus installer::InstallOrUpdateChrome(
+ const std::wstring& exe_path, const std::wstring& archive_path,
+ const std::wstring& install_temp_path, bool system_install,
+ const Version& new_version, const Version* installed_version) {
+
+ std::wstring install_path(GetChromeInstallPath(system_install));
+ if (install_path.empty()) {
+ LOG(ERROR) << "Couldn't get installation destination path";
+ return installer_util::INSTALL_FAILED;
+ } else {
+ LOG(INFO) << "install destination path: " << install_path;
+ }
+
+ std::wstring src_path(install_temp_path);
+ file_util::AppendToPath(&src_path, std::wstring(kInstallSourceDir));
+ file_util::AppendToPath(&src_path, std::wstring(kInstallSourceChromeDir));
+
+ HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ bool install_success = InstallNewVersion(exe_path, archive_path, src_path,
+ install_path, install_temp_path, reg_root, new_version);
+
+ installer_util::InstallStatus result;
+ if (!install_success) {
+ LOG(ERROR) << "Install failed.";
+ result = installer_util::INSTALL_FAILED;
+ } else {
+ if (!installed_version) {
+ LOG(INFO) << "First install of version " << new_version.GetString();
+ result = installer_util::FIRST_INSTALL_SUCCESS;
+ } else if (new_version.GetString() == installed_version->GetString()) {
+ LOG(INFO) << "Install repaired of version " << new_version.GetString();
+ result = installer_util::INSTALL_REPAIRED;
+ } else if (new_version.IsHigherThan(installed_version)) {
+ LOG(INFO) << "Version updated to " << new_version.GetString();
+ result = installer_util::NEW_VERSION_UPDATED;
+ } else {
+ NOTREACHED();
+ }
+
+ if (!CreateOrUpdateChromeShortcuts(exe_path, system_install, result,
+ install_path, new_version.GetString()))
+ LOG(WARNING) << "Failed to create/update start menu shortcut.";
+
+ std::wstring chrome_exe(install_path);
+ file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe);
+ if (result == installer_util::FIRST_INSTALL_SUCCESS ||
+ result == installer_util::INSTALL_REPAIRED) {
+ // Try to add Chrome to Media Player shim inclusion list. We don't do any
+ // error checking here because this operation will fail if user doesn't
+ // have admin rights and we want to ignore the error.
+ AddChromeToMediaPlayerList();
+
+ // We try to register Chrome as a valid browser on local machine. This
+ // will work only if current user has admin rights.
+ LOG(INFO) << "Registering Chrome as browser";
+ ShellUtil::RegisterStatus ret =
+ ShellUtil::AddChromeToSetAccessDefaults(chrome_exe, true);
+ LOG(ERROR) << "Return status of Chrome browser registration " << ret;
+ } else {
+ UpdateChromeExeShortcuts(chrome_exe);
+ RemoveOldVersionDirs(install_path, new_version.GetString());
+ }
+ }
+
+ return result;
+}
diff --git a/chrome/installer/setup/setup.exe.manifest b/chrome/installer/setup/setup.exe.manifest
new file mode 100644
index 0000000..28469a3
--- /dev/null
+++ b/chrome/installer/setup/setup.exe.manifest
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
+ <ms_asmv2:security>
+ <ms_asmv2:requestedPrivileges>
+ <ms_asmv2:requestedExecutionLevel level="asInvoker">
+ </ms_asmv2:requestedExecutionLevel>
+ </ms_asmv2:requestedPrivileges>
+ </ms_asmv2:security>
+ </ms_asmv2:trustInfo>
+</assembly>
diff --git a/chrome/installer/setup/setup.h b/chrome/installer/setup/setup.h
new file mode 100644
index 0000000..0f3ebc5
--- /dev/null
+++ b/chrome/installer/setup/setup.h
@@ -0,0 +1,104 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This file contains the specification of setup main functions.
+
+#ifndef CHROME_INSTALLER_SETUP_SETUP_H__
+#define CHROME_INSTALLER_SETUP_SETUP_H__
+
+#include <string>
+#include <windows.h>
+
+#include "chrome/installer/util/util_constants.h"
+#include "chrome/installer/util/version.h"
+
+namespace installer {
+// Get path to the installer under Chrome version folder
+// (for example <path>\Google\Chrome\<Version>\installer)
+std::wstring GetInstallerPathUnderChrome(const std::wstring& install_path,
+ const std::wstring& new_version);
+
+// This function installs or updates a new version of Chrome. It returns
+// install status (failed, new_install, updated etc).
+//
+// exe_path: Path to the executable (setup.exe) as it will be copied
+// to Chrome install folder after install is complete
+// archive_path: Path to the archive (chrome.7z) as it will be copied
+// to Chrome install folder after install is complete
+// install_temp_path: working directory used during install/update. It should
+// also has a sub dir source that contains a complete
+// and unpacked Chrome package.
+// system_install: if true, the function performs a system wide install/update.
+// Otherwise it installs/updates Chrome for the current user.
+// new_version: new Chrome version that needs to be installed
+// installed_version: currently installed version of Chrome, if any, or
+// NULL otherwise
+//
+// Note: since caller unpacks Chrome to install_temp_path\source, the caller
+// is responsible for cleaning up install_temp_path.
+installer_util::InstallStatus InstallOrUpdateChrome(
+ const std::wstring& exe_path, const std::wstring& archive_path,
+ const std::wstring& install_temp_path, bool system_install,
+ const Version& new_version, const Version* installed_version);
+
+// This function installs a new version of Chrome to the specified location.
+// It returns true if install was successful and false in case of an error.
+//
+// exe_path: Path to the executable (setup.exe) as it will be copied
+// to Chrome install folder after install is complete
+// archive_path: Path to the archive (chrome.7z) as it will be copied
+// to Chrome install folder after install is complete
+// src_path: the path that contains a complete and unpacked Chrome package
+// to be installed.
+// install_path: the destination path for Chrome to be installed to. This
+// path does not need to exist.
+// temp_dir: the path of working directory used during installation. This path
+// does not need to exist.
+// reg_root: the root of registry where the function applies settings for the
+// new Chrome version. It should be either HKLM or HKCU.
+// new_version: new Chrome version that needs to be installed
+//
+// This function makes best effort to do installation in a transactional
+// manner. If failed it tries to rollback all changes on the file system
+// and registry. For example, if install_path exists before calling the
+// function, it rolls back all new file and directory changes under
+// install_path. If install_path does not exist before calling the function
+// (typical new install), the function creates install_path during install
+// and removes the whole directory during rollback.
+bool InstallNewVersion(const std::wstring& exe_path,
+ const std::wstring& archive_path,
+ const std::wstring& src_path,
+ const std::wstring& install_path,
+ const std::wstring& temp_dir,
+ const HKEY reg_root,
+ const Version& new_version);
+
+}
+
+#endif // CHROME_INSTALLER_SETUP_SETUP_H__
diff --git a/chrome/installer/setup/setup.ico b/chrome/installer/setup/setup.ico
new file mode 100644
index 0000000..5ecfcbd
--- /dev/null
+++ b/chrome/installer/setup/setup.ico
Binary files differ
diff --git a/chrome/installer/setup/setup.rc b/chrome/installer/setup/setup.rc
new file mode 100644
index 0000000..2423a76
--- /dev/null
+++ b/chrome/installer/setup/setup.rc
@@ -0,0 +1,82 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "setup_resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.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
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "setup_resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""setup_exe_version.rc""\r\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_SETUP ICON "setup.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_UNINSTALL_SURVEY_URL "http://go/chromeuninstall?hl=$1&contact_type=uninstall"
+END
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "setup_exe_version.rc"
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/chrome/installer/setup/setup.vcproj b/chrome/installer/setup/setup.vcproj
new file mode 100644
index 0000000..e6c6abf
--- /dev/null
+++ b/chrome/installer/setup/setup.vcproj
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="setup"
+ ProjectGUID="{21C76E6E-8B38-44D6-8148-B589C13B9554}"
+ RootNamespace="setup"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ <ToolFile
+ RelativePath="..\..\tools\build\win\version.rules"
+ />
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\setup_debug.vsprops;..\util\using_util.vsprops;..\util\prebuild\util_prebuild.vsprops"
+ >
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="1"
+ InheritedPropertySheets=".\setup_release.vsprops;..\util\using_util.vsprops;..\util\prebuild\util_prebuild.vsprops"
+ >
+ <Tool
+ Name="Version"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="resources"
+ >
+ <File
+ RelativePath=".\setup_resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\setup.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\setup.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\setup_exe_version.rc.version"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\..\util_prebuild\setup_strings.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\..\util_prebuild\setup_strings.rc"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\install.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\main.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\setup.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\setup.h"
+ >
+ </File>
+ <File
+ RelativePath=".\setup_constants.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\setup_constants.h"
+ >
+ </File>
+ <File
+ RelativePath=".\uninstall.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\uninstall.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/chrome/installer/setup/setup.vsprops b/chrome/installer/setup/setup.vsprops
new file mode 100644
index 0000000..53258e4
--- /dev/null
+++ b/chrome/installer/setup/setup.vsprops
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="setup"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="$(OutDir);$(IntDir)"
+ EnableIntrinsicFunctions="true"
+ BasicRuntimeChecks="0"
+ BufferSecurityCheck="false"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="msi.lib"
+ GenerateMapFile="true"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ AdditionalIncludeDirectories="$(OutDir);$(IntDir)"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AdditionalManifestFiles="$(SolutionDir)installer\setup\setup.exe.manifest"
+ />
+</VisualStudioPropertySheet>
diff --git a/chrome/installer/setup/setup_constants.cc b/chrome/installer/setup/setup_constants.cc
new file mode 100644
index 0000000..3397836
--- /dev/null
+++ b/chrome/installer/setup/setup_constants.cc
@@ -0,0 +1,49 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/installer/setup/setup_constants.h"
+
+namespace installer {
+// Elements that makes up install target path.
+const wchar_t kChromeOldExe[] = L"old_chrome.exe";
+const wchar_t kChromeNewExe[] = L"new_chrome.exe";
+const wchar_t kWowHelperExe[] = L"wow_helper.exe";
+const wchar_t kChromeArchive[] = L"chrome.7z";
+const wchar_t kChromePatchArchive[] = L"patch.7z";
+const wchar_t kChromeCompressedArchive[] = L"chrome.packed.7z";
+const wchar_t kChromeCompressedPatchArchivePrefix[] = L"patch";
+
+// Sub directory of install source package under install temporary directory.
+const wchar_t kInstallSourceDir[] = L"source";
+const wchar_t kInstallSourceChromeDir[] = L"Chrome-bin";
+
+const wchar_t kInstallerDir[] = L"Installer";
+
+const wchar_t kMediaPlayerRegPath[] = L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList";
+} // namespace installer
diff --git a/chrome/installer/setup/setup_constants.h b/chrome/installer/setup/setup_constants.h
new file mode 100644
index 0000000..7e4bc48
--- /dev/null
+++ b/chrome/installer/setup/setup_constants.h
@@ -0,0 +1,53 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Defines all the command-line switches used by Chrome installer.
+
+#ifndef CHROME_INSTALLER_SETUP_SETUP_CONSTANTS_H__
+#define CHROME_INSTALLER_SETUP_SETUP_CONSTANTS_H__
+
+namespace installer {
+
+extern const wchar_t kChromeOldExe[];
+extern const wchar_t kChromeNewExe[];
+extern const wchar_t kWowHelperExe[];
+extern const wchar_t kChromeArchive[];
+extern const wchar_t kChromePatchArchive[];
+extern const wchar_t kChromeCompressedArchive[];
+extern const wchar_t kChromeCompressedPatchArchivePrefix[];
+
+extern const wchar_t kInstallSourceDir[];
+extern const wchar_t kInstallSourceChromeDir[];
+
+extern const wchar_t kInstallerDir[];
+
+extern const wchar_t kMediaPlayerRegPath[];
+} // namespace installer
+
+#endif // CHROME_INSTALLER_SETUP_SETUP_CONSTANTS_H__
diff --git a/chrome/installer/setup/setup_debug.vsprops b/chrome/installer/setup/setup_debug.vsprops
new file mode 100644
index 0000000..873c6f1
--- /dev/null
+++ b/chrome/installer/setup/setup_debug.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="setup_debug"
+ InheritedPropertySheets="$(SolutionDir)..\build\debug.vsprops;.\setup.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/chrome/installer/setup/setup_exe_version.rc.version b/chrome/installer/setup/setup_exe_version.rc.version
new file mode 100644
index 0000000..5c41cf0
--- /dev/null
+++ b/chrome/installer/setup/setup_exe_version.rc.version
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @MAJOR@,@MINOR@,@BUILD@,@PATCH@
+ PRODUCTVERSION @MAJOR@,@MINOR@,@BUILD@,@PATCH@
+ 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", "@COMPANY_FULLNAME@"
+ VALUE "FileDescription", "@PRODUCT_FULLNAME@"
+ VALUE "FileVersion", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"
+ VALUE "InternalName", "setup"
+ VALUE "LegalCopyright", "@COPYRIGHT@"
+ VALUE "ProductName", "@PRODUCT_FULLNAME@"
+ VALUE "ProductVersion", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"
+ VALUE "CompanyShortName", "@COMPANY_SHORTNAME@"
+ VALUE "ProductShortName", "@PRODUCT_SHORTNAME@"
+ VALUE "LastChange", "@LASTCHANGE@"
+ VALUE "Official Build", "@OFFICIAL_BUILD@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/chrome/installer/setup/setup_release.vsprops b/chrome/installer/setup/setup_release.vsprops
new file mode 100644
index 0000000..ee6094c
--- /dev/null
+++ b/chrome/installer/setup/setup_release.vsprops
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="setup_release"
+ InheritedPropertySheets="$(SolutionDir)..\build\release.vsprops;.\setup.vsprops"
+ >
+</VisualStudioPropertySheet>
diff --git a/chrome/installer/setup/setup_resource.h b/chrome/installer/setup/setup_resource.h
new file mode 100644
index 0000000..6915d21
--- /dev/null
+++ b/chrome/installer/setup/setup_resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by setup.rc
+//
+#define IDI_SETUP 101
+#define IDS_UNINSTALL_SURVEY_URL 102
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
new file mode 100644
index 0000000..9403a8a
--- /dev/null
+++ b/chrome/installer/setup/uninstall.cc
@@ -0,0 +1,303 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This file defines the methods useful for uninstalling Chrome.
+
+#include "chrome/installer/setup/uninstall.h"
+
+#include <atlbase.h>
+#include <windows.h>
+#include <msi.h>
+
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/registry.h"
+#include "base/scoped_ptr.h"
+#include "base/string_util.h"
+#include "base/win_util.h"
+#include "base/wmi_util.h"
+#include "chrome/app/google_update_settings.h"
+#include "chrome/app/result_codes.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/installer/setup/setup_constants.h"
+#include "chrome/installer/util/helper.h"
+#include "chrome/installer/util/install_util.h"
+#include "chrome/installer/util/l10n_string_util.h"
+#include "chrome/installer/util/logging_installer.h"
+#include "chrome/installer/util/google_update_constants.h"
+#include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/util_constants.h"
+#include "chrome/installer/util/version.h"
+
+#include "setup_resource.h"
+#include "setup_strings.h"
+
+namespace {
+
+// This method deletes Chrome shortcut folder from Windows Start menu. It
+// checks system_uninstall to see if the shortcut is in all users start menu
+// or current user start menu.
+void DeleteChromeShortcut(bool system_uninstall) {
+ std::wstring shortcut_path;
+ if (system_uninstall) {
+ PathService::Get(base::DIR_COMMON_START_MENU, &shortcut_path);
+ } else {
+ PathService::Get(base::DIR_START_MENU, &shortcut_path);
+ }
+ if (shortcut_path.empty()) {
+ LOG(ERROR) << "failed to get location for shortcut";
+ } else {
+ file_util::AppendToPath(&shortcut_path,
+ installer_util::GetLocalizedString(IDS_PRODUCT_NAME_BASE));
+ LOG(INFO) << "Deleting shortcut " << shortcut_path;
+ if (!file_util::Delete(shortcut_path, true))
+ LOG(ERROR) << "Failed to delete folder: " << shortcut_path;
+ }
+}
+
+// This method tries to delete a registry key and logs an error message
+// in case of failure. It returns true if deletion is successful,
+// otherwise false.
+bool DeleteRegistryKey(RegKey& key, const std::wstring& key_path) {
+ LOG(INFO) << "Deleting registry key " << key_path;
+ if (!key.DeleteKey(key_path.c_str())) {
+ LOG(ERROR) << "Failed to delete registry key: " << key_path
+ << " and the error is " << InstallUtil::FormatLastWin32Error();
+ return false;
+ }
+ return true;
+}
+
+// This method tries to delete a registry value and logs an error message
+// in case of failure. It returns true if deletion is successful,
+// otherwise false.
+bool DeleteRegistryValue(HKEY reg_root, const std::wstring& key_path,
+ const std::wstring& value_name) {
+ RegKey key(reg_root, key_path.c_str(), KEY_ALL_ACCESS);
+ LOG(INFO) << "Deleting registry value " << value_name;
+ if (!key.DeleteValue(value_name.c_str())) {
+ LOG(ERROR) << "Failed to delete registry value: " << value_name
+ << " and the error is " << InstallUtil::FormatLastWin32Error();
+ return false;
+ }
+ return true;
+}
+
+// This method checks if Chrome is currently running or if the user has
+// cancelled the uninstall operation by clicking Cancel on the confirmation
+// box that Chrome pops up.
+installer_util::InstallStatus IsChromeActiveOrUserCancelled(
+ bool system_uninstall) {
+ static const std::wstring kCmdLineOptions(L" --uninstall");
+ static const int32 kTimeOutMs = 30000;
+ int32 exit_code = ResultCodes::NORMAL_EXIT;
+ bool is_timeout = false;
+
+ // We ignore all other errors such as whether launching chrome fails,
+ // whether chrome returns UNINSTALL_ERROR, etc.
+ LOG(INFO) << "Launching Chrome to do uninstall tasks.";
+ if (installer::LaunchChromeAndWaitForResult(system_uninstall,
+ kCmdLineOptions,
+ kTimeOutMs,
+ &exit_code,
+ &is_timeout)) {
+ if (is_timeout || exit_code == ResultCodes::UNINSTALL_CHROME_ALIVE) {
+ LOG(ERROR) << "Can't uninstall when chrome is still running";
+ return installer_util::CHROME_RUNNING;
+ } else if (exit_code == ResultCodes::UNINSTALL_USER_CANCEL) {
+ LOG(INFO) << "User cancelled uninstall operation";
+ return installer_util::UNINSTALL_CANCELLED;
+ } else if (exit_code == ResultCodes::UNINSTALL_ERROR) {
+ LOG(ERROR) << "chrome.exe reported error while uninstalling.";
+ return installer_util::UNINSTALL_FAILED;
+ }
+ }
+
+ return installer_util::UNINSTALL_CONFIRMED;
+}
+
+// Read the URL from the resource file and substitute the locale parameter
+// with whatever Google Update tells us is the locale. In case we fail to find
+// the locale, we use US English.
+std::wstring GetUninstallSurveyUrl() {
+ const ATLSTRINGRESOURCEIMAGE* image = AtlGetStringResourceImage(
+ _AtlBaseModule.GetModuleInstance(), IDS_UNINSTALL_SURVEY_URL);
+ DCHECK(image);
+ std::wstring url = std::wstring(image->achString, image->nLength);
+ DCHECK(!url.empty());
+
+ std::wstring language;
+ if (!GoogleUpdateSettings::GetLanguage(&language))
+ language = L"en-US"; // Default to US English.
+
+ return ReplaceStringPlaceholders(url.c_str(), language.c_str(), NULL);
+}
+
+// This method launches an uninstall survey and is called at the end of
+// uninstall process. We are not doing any error checking here as it is
+// not critical to have this survey. If we fail to launch it, we just
+// ignore it silently.
+void LaunchUninstallSurvey(const installer::Version& installed_version) {
+ // Send the Chrome version and OS version as params to the form.
+ // It would be nice to send the locale, too, but I don't see an
+ // easy way to get that in the existing code. It's something we
+ // can add later, if needed.
+ // We depend on installed_version.GetString() not having spaces or other
+ // characters that need escaping: 0.2.13.4. Should that change, we will
+ // need to escape the string before using it in a URL.
+ const std::wstring kVersionParam = L"crversion";
+ const std::wstring kVersion = installed_version.GetString();
+ const std::wstring kOSParam = L"os";
+ std::wstring os_version = L"na";
+ OSVERSIONINFO version_info;
+ version_info.dwOSVersionInfoSize = sizeof version_info;
+ if (GetVersionEx(&version_info)) {
+ os_version = StringPrintf(L"%d.%d.%d",
+ version_info.dwMajorVersion,
+ version_info.dwMinorVersion,
+ version_info.dwBuildNumber);
+ }
+
+ std::wstring iexplore;
+ if (!PathService::Get(base::DIR_PROGRAM_FILES, &iexplore))
+ return;
+
+ file_util::AppendToPath(&iexplore, L"Internet Explorer");
+ file_util::AppendToPath(&iexplore, L"iexplore.exe");
+
+ std::wstring command = iexplore + L" " + GetUninstallSurveyUrl() + L"&" +
+ kVersionParam + L"=" + kVersion + L"&" + kOSParam + L"=" + os_version;
+ int pid = 0;
+ WMIProcessUtil::Launch(command, &pid);
+}
+
+// Uninstall Chrome specific Gears. First we find Gears MSI ProductId (that
+// changes with every new version of Gears) using Gears MSI UpgradeCode (that
+// does not change) and then uninstall Gears using API.
+void UninstallGears() {
+ wchar_t product[39]; // GUID + '\0'
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); // Don't show any UI to user.
+ for (int i = 0; MsiEnumRelatedProducts(google_update::kGearsUpgradeCode, 0, i,
+ product) != ERROR_NO_MORE_ITEMS; ++i) {
+ LOG(INFO) << "Uninstalling Gears - " << product;
+ unsigned int ret = MsiConfigureProduct(product, INSTALLLEVEL_MAXIMUM,
+ INSTALLSTATE_ABSENT);
+ if (ret != ERROR_SUCCESS)
+ LOG(ERROR) << "Failed to uninstall Gears " << product
+ << " because of error " << ret;
+ }
+}
+
+} // namespace
+
+
+installer_util::InstallStatus installer_setup::UninstallChrome(
+ const std::wstring& exe_path, bool system_uninstall,
+ const installer::Version& installed_version, bool remove_all) {
+ installer_util::InstallStatus status =
+ IsChromeActiveOrUserCancelled(system_uninstall);
+ if (status == installer_util::CHROME_RUNNING ||
+ status == installer_util::UNINSTALL_CANCELLED)
+ return status;
+
+ // Uninstall Gears first.
+ UninstallGears();
+
+ // Chrome is not in use so lets uninstall Chrome by deleting various files
+ // and registry entries. Here we will just make best effort and keep going
+ // in case of errors.
+ // First delete shortcut from Start->Programs.
+ DeleteChromeShortcut(system_uninstall);
+
+ // Delete the registry keys (Uninstall key and Google Update update key).
+ HKEY reg_root = system_uninstall ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ RegKey key(reg_root, L"", KEY_ALL_ACCESS);
+ DeleteRegistryKey(key, installer_util::kUninstallRegPath);
+ DeleteRegistryKey(key, InstallUtil::GetChromeGoogleUpdateKey());
+
+ // Delete Software\Classes\ChromeHTML,
+ // Software\Clients\StartMenuInternet\chrome.exe and
+ // Software\RegisteredApplications\Chrome
+ std::wstring html_prog_id(ShellUtil::kRegClasses);
+ file_util::AppendToPath(&html_prog_id, ShellUtil::kChromeHTMLProgId);
+ DeleteRegistryKey(key, html_prog_id);
+
+ std::wstring set_access_key(ShellUtil::kRegStartMenuInternet);
+ file_util::AppendToPath(&set_access_key, installer_util::kChromeExe);
+ DeleteRegistryKey(key, set_access_key);
+
+ DeleteRegistryValue(reg_root, ShellUtil::kRegRegisteredApplications,
+ installer_util::kApplicationName);
+ key.Close();
+
+ // Delete shared registry keys as well (these require admin rights) if
+ // remove_all option is specified.
+ if (remove_all) {
+ RegKey hklm_key(HKEY_LOCAL_MACHINE, L"", KEY_ALL_ACCESS);
+ DeleteRegistryKey(hklm_key, set_access_key);
+ DeleteRegistryKey(hklm_key, html_prog_id);
+ DeleteRegistryValue(HKEY_LOCAL_MACHINE,
+ ShellUtil::kRegRegisteredApplications,
+ installer_util::kApplicationName);
+
+ // Delete media player registry key that exists only in HKLM.
+ std::wstring reg_path(installer::kMediaPlayerRegPath);
+ file_util::AppendToPath(&reg_path, installer_util::kChromeExe);
+ DeleteRegistryKey(hklm_key, reg_path);
+ hklm_key.Close();
+ }
+
+ // Finally delete all the files from Chrome folder after moving setup.exe
+ // to a temp location.
+ std::wstring install_path(installer::GetChromeInstallPath(system_uninstall));
+ if (install_path.empty()) {
+ LOG(ERROR) << "Couldn't get installation destination path";
+ // Nothing else we could do for uninstall, so we return.
+ return installer_util::UNINSTALL_FAILED;
+ } else {
+ LOG(INFO) << "install destination path: " << install_path;
+ }
+
+ std::wstring setup_exe(install_path);
+ file_util::AppendToPath(&setup_exe, installed_version.GetString());
+ file_util::AppendToPath(&setup_exe, installer::kInstallerDir);
+ file_util::AppendToPath(&setup_exe, file_util::GetFilenameFromPath(exe_path));
+
+ std::wstring temp_file;
+ file_util::CreateTemporaryFileName(&temp_file);
+ file_util::Move(setup_exe, temp_file);
+
+ LOG(INFO) << "Deleting install path " << install_path;
+ if (!file_util::Delete(install_path, true))
+ LOG(ERROR) << "Failed to delete folder: " << install_path;
+
+ LOG(INFO) << "Uninstallation complete. Launching Uninstall survey.";
+ LaunchUninstallSurvey(installed_version);
+ return installer_util::UNINSTALL_SUCCESSFUL;
+}
diff --git a/chrome/installer/setup/uninstall.h b/chrome/installer/setup/uninstall.h
new file mode 100644
index 0000000..9308859
--- /dev/null
+++ b/chrome/installer/setup/uninstall.h
@@ -0,0 +1,56 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This file declares Chrome uninstall related functions.
+
+#ifndef CHROME_INSTALLER_SETUP_UNINSTALL_H__
+#define CHROME_INSTALLER_SETUP_UNINSTALL_H__
+
+#include <string>
+
+#include "chrome/installer/util/util_constants.h"
+#include "chrome/installer/util/version.h"
+
+namespace installer_setup {
+// This function uninstalls Chrome.
+//
+// exe_path: Path to the executable (setup.exe) as it will be copied
+// to temp folder before deleting Chrome folder.
+// system_uninstall: if true, the function uninstalls Chrome installed system
+// wise. otherwise, it uninstalls Chrome installed for the
+// current user.
+// installed_version: currently installed version of Chrome.
+// remove_all: Remove all shared files, registry entries as well.
+installer_util::InstallStatus UninstallChrome(
+ const std::wstring& exe_path, bool system_uninstall,
+ const installer::Version& installed_version, bool remove_all);
+
+} // namespace installer_setup
+
+#endif // CHROME_INSTALLER_SETUP_UNINSTALL_H__