diff options
-rw-r--r-- | chrome/chrome_installer.gypi | 2 | ||||
-rw-r--r-- | chrome/installer/setup/chrome_frame_quick_enable.cc | 130 | ||||
-rw-r--r-- | chrome/installer/setup/chrome_frame_quick_enable.h | 25 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.cc | 9 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.h | 25 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 35 | ||||
-rw-r--r-- | chrome/installer/setup/uninstall.cc | 2 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.cc | 3 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.h | 3 |
9 files changed, 216 insertions, 18 deletions
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi index cba6d33..d818cdd 100644 --- a/chrome/chrome_installer.gypi +++ b/chrome/chrome_installer.gypi @@ -201,6 +201,8 @@ }, 'sources': [ 'installer/mini_installer/chrome.release', + 'installer/setup/chrome_frame_quick_enable.cc', + 'installer/setup/chrome_frame_quick_enable.h', 'installer/setup/chrome_frame_ready_mode.cc', 'installer/setup/chrome_frame_ready_mode.h', 'installer/setup/install.cc', diff --git a/chrome/installer/setup/chrome_frame_quick_enable.cc b/chrome/installer/setup/chrome_frame_quick_enable.cc new file mode 100644 index 0000000..22b4615 --- /dev/null +++ b/chrome/installer/setup/chrome_frame_quick_enable.cc @@ -0,0 +1,130 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/installer/setup/chrome_frame_quick_enable.h" + +#include <windows.h> + +#include "base/logging.h" +#include "base/string_util.h" +#include "base/win/registry.h" +#include "chrome/installer/setup/install_worker.h" +#include "chrome/installer/util/google_update_constants.h" +#include "chrome/installer/util/install_util.h" +#include "chrome/installer/util/installation_state.h" +#include "chrome/installer/util/installer_state.h" +#include "chrome/installer/util/product.h" +#include "chrome/installer/util/work_item.h" +#include "chrome/installer/util/work_item_list.h" + +#include "installer_util_strings.h" // NOLINT + +using base::win::RegKey; + +namespace installer { + +namespace { + +InstallStatus CheckQuickEnablePreconditions( + const InstallationState& machine_state, + const InstallerState& installer_state) { + // Make sure Chrome is multi-installed. + const ProductState* chrome_state = + machine_state.GetProductState(installer_state.system_install(), + BrowserDistribution::CHROME_BROWSER); + if (chrome_state == NULL) { + LOG(ERROR) << "Chrome Frame quick enable requires Chrome to be installed."; + return CHROME_NOT_INSTALLED; + } else if (!chrome_state->is_multi_install()) { + LOG(ERROR) << "Chrome Frame quick enable requires multi-install of Chrome."; + return NON_MULTI_INSTALLATION_EXISTS; + } + + // Chrome Frame must not be installed. + const ProductState* cf_state = + machine_state.GetProductState(installer_state.system_install(), + BrowserDistribution::CHROME_FRAME); + // Make sure we check both user and system installations. + if (!cf_state) { + cf_state = machine_state.GetProductState(!installer_state.system_install(), + BrowserDistribution::CHROME_FRAME); + } + + if (cf_state != NULL) { + LOG(ERROR) << "Chrome Frame already installed."; + return installer_state.system_install() ? + SYSTEM_LEVEL_INSTALL_EXISTS : USER_LEVEL_INSTALL_EXISTS; + } + + return FIRST_INSTALL_SUCCESS; +} + +} // end namespace + +InstallStatus ChromeFrameQuickEnable(const InstallationState& machine_state, + InstallerState* installer_state) { + DCHECK(installer_state); + VLOG(1) << "Chrome Frame Quick Enable"; + InstallStatus status = CheckQuickEnablePreconditions(machine_state, + *installer_state); + + if (status == FIRST_INSTALL_SUCCESS) { + scoped_ptr<Product> multi_cf(new Product( + BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_FRAME))); + multi_cf->SetOption(installer::kOptionMultiInstall, true); + Product* cf = installer_state->AddProduct(&multi_cf); + if (!cf) { + LOG(ERROR) << "AddProduct failed"; + status = INSTALL_FAILED; + } else { + scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); + const ProductState* chrome_state = + machine_state.GetProductState(installer_state->system_install(), + BrowserDistribution::CHROME_BROWSER); + DCHECK(chrome_state); // Checked in CheckQuickEnablePreconditions. + + // Temporarily remove Chrome from the product list. + // This is so that the operations below do not affect the installation + // state of Chrome. + installer_state->RemoveProduct( + installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER)); + + FilePath setup_path(chrome_state->GetSetupPath()); + const Version& new_version = chrome_state->version(); + FilePath new_chrome_exe( + installer_state->target_path().Append(installer::kChromeNewExe)); + + // This creates the uninstallation entry for GCF. + AddUninstallShortcutWorkItems(*installer_state, setup_path, new_version, + item_list.get(), *cf); + AddVersionKeyWorkItems(installer_state->root_key(), cf->distribution(), + new_version, item_list.get()); + AddChromeFrameWorkItems(machine_state, *installer_state, setup_path, + new_version, *cf, item_list.get()); + + const Version* opv = chrome_state->old_version(); + AppendPostInstallTasks(*installer_state, setup_path, new_chrome_exe, opv, + new_version, item_list.get()); + + // Before updating the channel values, add Chrome back to the mix so that + // all multi-installed products' channel values get updated. + installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, + *chrome_state); + AddGoogleUpdateWorkItems(*installer_state, item_list.get()); + + if (!item_list->Do()) { + item_list->Rollback(); + status = INSTALL_FAILED; + } else { + DCHECK_EQ(FIRST_INSTALL_SUCCESS, status); + VLOG(1) << "Chrome Frame successfully activated."; + } + } + } + + return status; +} + +} // namespace installer diff --git a/chrome/installer/setup/chrome_frame_quick_enable.h b/chrome/installer/setup/chrome_frame_quick_enable.h new file mode 100644 index 0000000..b09f4ba --- /dev/null +++ b/chrome/installer/setup/chrome_frame_quick_enable.h @@ -0,0 +1,25 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Support for Chrome Frame quick enable. + +#ifndef CHROME_INSTALLER_SETUP_CHROME_FRAME_QUICK_ENABLE_H_ +#define CHROME_INSTALLER_SETUP_CHROME_FRAME_QUICK_ENABLE_H_ +#pragma once + +#include "chrome/installer/util/util_constants.h" + +namespace installer { + +class InstallationState; +class InstallerState; + +// Installs Chrome Frame in the same location as Chrome is currently installed +// in. Setup is assumed to be running from the Installer directory. +InstallStatus ChromeFrameQuickEnable(const InstallationState& machine_state, + InstallerState* installer_state); + +} // namespace installer + +#endif // CHROME_INSTALLER_SETUP_CHROME_FRAME_QUICK_ENABLE_H_ diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc index 1ba32bb..bfb03eb 100644 --- a/chrome/installer/setup/install_worker.cc +++ b/chrome/installer/setup/install_worker.cc @@ -280,8 +280,11 @@ void AddProductSpecificWorkItems(const InstallationState& original_state, void AddGoogleUpdateWorkItems(const InstallerState& installer_state, WorkItemList* install_list) { // Is a multi-install product being installed or over-installed? - if (installer_state.operation() != InstallerState::MULTI_INSTALL) + if (installer_state.operation() != InstallerState::MULTI_INSTALL && + installer_state.operation() != InstallerState::MULTI_UPDATE) { + VLOG(1) << "AddGoogleUpdateWorkItems noop: " << installer_state.operation(); return; + } const HKEY reg_root = installer_state.root_key(); const std::wstring key_path = installer_state.state_key(); @@ -300,11 +303,15 @@ void AddGoogleUpdateWorkItems(const InstallerState& installer_state, // Add the appropriate modifiers for all products and their options. modified |= installer_state.SetChannelFlags(true, &channel_info); + VLOG(1) << "ap: " << channel_info.value(); + // Write the results if needed. if (modified) { install_list->AddSetRegValueWorkItem(reg_root, key_path, google_update::kRegApField, channel_info.value(), true); + } else { + VLOG(1) << "Channel flags not modified"; } // Synchronize the other products and the package with this one. diff --git a/chrome/installer/setup/install_worker.h b/chrome/installer/setup/install_worker.h index 2762672..596b367 100644 --- a/chrome/installer/setup/install_worker.h +++ b/chrome/installer/setup/install_worker.h @@ -9,6 +9,8 @@ #define CHROME_INSTALLER_SETUP_INSTALL_WORKER_H_ #pragma once +#include <windows.h> + #include <vector> #include "base/scoped_ptr.h" @@ -35,6 +37,22 @@ class Product; void AddGoogleUpdateWorkItems(const InstallerState& installer_state, WorkItemList* install_list); +// After a successful copying of all the files, this function is called to +// do a few post install tasks: +// - Handle the case of in-use-update by updating "opv" (old version) key or +// deleting it if not required. +// - Register any new dlls and unregister old dlls. +// - If this is an MSI install, ensures that the MSI marker is set, and sets +// it if not. +// If these operations are successful, the function returns true, otherwise +// false. +bool AppendPostInstallTasks(const InstallerState& installer_state, + const FilePath& setup_path, + const FilePath& new_chrome_exe, + const Version* current_version, + const Version& new_version, + WorkItemList* post_install_task_list); + // Builds the complete WorkItemList used to build the set of installation steps // needed to lay down one or more installed products. // @@ -96,6 +114,13 @@ void AddUninstallShortcutWorkItems(const InstallerState& installer_state, WorkItemList* install_list, const Product& product); +// Create Version key for a product (if not already present) and sets the new +// product version as the last step. +void AddVersionKeyWorkItems(HKEY root, + BrowserDistribution* dist, + const Version& new_version, + WorkItemList* list); + // [Un]Registers Chrome and ChromeLauncher in IE's low rights elevation policy. void AddElevationPolicyWorkItems(const InstallationState& original_state, const InstallerState& installer_state, diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index f0b7b4b..1c2d648 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -26,6 +26,7 @@ #include "base/win/windows_version.h" #include "breakpad/src/client/windows/handler/exception_handler.h" #include "chrome/common/chrome_switches.h" +#include "chrome/installer/setup/chrome_frame_quick_enable.h" #include "chrome/installer/setup/chrome_frame_ready_mode.h" #include "chrome/installer/setup/install.h" #include "chrome/installer/setup/setup_constants.h" @@ -130,7 +131,6 @@ DWORD UnPackArchive(const FilePath& archive, output_directory.value(), &unpacked_file); } - // This function is called when --rename-chrome-exe option is specified on // setup.exe command line. This function assumes an in-use update has happened // for Chrome so there should be a file called new_chrome.exe on the file @@ -745,7 +745,7 @@ installer::InstallStatus ShowEULADialog(const std::wstring& inner_frame) { // has been found and processed (so setup.exe should exit at that point). bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, const CommandLine& cmd_line, - const InstallerState& installer_state, + InstallerState* installer_state, int* exit_code) { bool handled = true; // TODO(tommi): Split these checks up into functions and use a data driven @@ -779,8 +779,8 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, *exit_code = InstallUtil::GetInstallReturnCode(status); if (*exit_code) { LOG(WARNING) << "setup.exe patching failed."; - InstallUtil::WriteInstallerResult(installer_state.system_install(), - installer_state.state_key(), status, IDS_SETUP_PATCH_FAILED_BASE, + InstallUtil::WriteInstallerResult(installer_state->system_install(), + installer_state->state_key(), status, IDS_SETUP_PATCH_FAILED_BASE, NULL); } file_util::Delete(temp_path, true); @@ -791,11 +791,11 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, cmd_line.GetSwitchValueNative(installer::switches::kShowEula); *exit_code = ShowEULADialog(inner_frame); if (installer::EULA_REJECTED != *exit_code) - GoogleUpdateSettings::SetEULAConsent(installer_state, true); + GoogleUpdateSettings::SetEULAConsent(*installer_state, true); } else if (cmd_line.HasSwitch( installer::switches::kRegisterChromeBrowser)) { const Product* chrome_install = - installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); + installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); if (chrome_install) { // If --register-chrome-browser option is specified, register all // Chrome protocol/file associations as well as register it as a valid @@ -819,7 +819,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, } else if (cmd_line.HasSwitch(installer::switches::kRenameChromeExe)) { // If --rename-chrome-exe is specified, we want to rename the executables // and exit. - *exit_code = RenameChromeExecutables(installer_state); + *exit_code = RenameChromeExecutables(*installer_state); } else if (cmd_line.HasSwitch( installer::switches::kRemoveChromeRegistration)) { // This is almost reverse of --register-chrome-browser option above. @@ -834,7 +834,7 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, } installer::InstallStatus tmp = installer::UNKNOWN_STATUS; const Product* chrome_install = - installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); + installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); DCHECK(chrome_install); if (chrome_install) { installer::DeleteChromeRegistrationKeys(chrome_install->distribution(), @@ -850,16 +850,16 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, if (flavor == -1) { *exit_code = installer::UNKNOWN_STATUS; } else { - const Products& products = installer_state.products(); + const Products& products = installer_state->products(); for (size_t i = 0; i < products.size(); ++i) { const Product* product = products[i]; BrowserDistribution* browser_dist = product->distribution(); browser_dist->InactiveUserToastExperiment(flavor, *product, - installer_state.target_path()); + installer_state->target_path()); } } } else if (cmd_line.HasSwitch(installer::switches::kSystemLevelToast)) { - const Products& products = installer_state.products(); + const Products& products = installer_state->products(); for (size_t i = 0; i < products.size(); ++i) { const Product* product = products[i]; BrowserDistribution* browser_dist = product->distribution(); @@ -867,24 +867,27 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, // to continue with the toast experiment. scoped_ptr<Version> installed_version( InstallUtil::GetChromeVersion(browser_dist, - installer_state.system_install())); + installer_state->system_install())); browser_dist->LaunchUserExperiment(installer::REENTRY_SYS_UPDATE, *installed_version, *product, true); } } else if (cmd_line.HasSwitch( installer::switches::kChromeFrameReadyModeOptIn)) { *exit_code = InstallUtil::GetInstallReturnCode( - installer::ChromeFrameReadyModeOptIn(original_state, installer_state)); + installer::ChromeFrameReadyModeOptIn(original_state, *installer_state)); } else if (cmd_line.HasSwitch( installer::switches::kChromeFrameReadyModeTempOptOut)) { *exit_code = InstallUtil::GetInstallReturnCode( installer::ChromeFrameReadyModeTempOptOut(original_state, - installer_state)); + *installer_state)); } else if (cmd_line.HasSwitch( installer::switches::kChromeFrameReadyModeEndTempOptOut)) { *exit_code = InstallUtil::GetInstallReturnCode( installer::ChromeFrameReadyModeEndTempOptOut(original_state, - installer_state)); + *installer_state)); + } else if (cmd_line.HasSwitch(installer::switches::kChromeFrameQuickEnable)) { + *exit_code = installer::ChromeFrameQuickEnable(original_state, + installer_state); } else { handled = false; } @@ -1078,7 +1081,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, } int exit_code = 0; - if (HandleNonInstallCmdLineOptions(original_state, cmd_line, installer_state, + if (HandleNonInstallCmdLineOptions(original_state, cmd_line, &installer_state, &exit_code)) return exit_code; diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc index 54077f2..21a1dcb 100644 --- a/chrome/installer/setup/uninstall.cc +++ b/chrome/installer/setup/uninstall.cc @@ -86,7 +86,7 @@ void ProcessGoogleUpdateItems( update_list->AddSetRegValueWorkItem(reg_root, other_dist->GetStateKey(), google_update::kRegApField, channel_info.value(), true); } else { - LOG_IF(DFATAL, + LOG_IF(ERROR, product_state != NULL && product_state->is_multi_install()) << "Channel value for " << BrowserDistribution::GetSpecificDistribution( diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index 0026ad7..d815498 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -18,6 +18,9 @@ const char kChrome[] = "chrome"; // Install Chrome Frame. const char kChromeFrame[] = "chrome-frame"; +// Installs Chrome Frame from an already installed multi-install of Chrome. +const char kChromeFrameQuickEnable[] = "quick-enable-cf"; + // When installing Chrome Frame, install it in ready mode. // If --chrome-frame is not on the command line, this switch has no effect. const char kChromeFrameReadyMode[] = "ready-mode"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index 3c20cc3..997f87b 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -69,6 +69,8 @@ enum InstallStatus { CONFLICTING_CHANNEL_EXISTS, // 39. A multi-install product on a different // update channel exists. READY_MODE_REQUIRES_CHROME, // 40. Chrome Frame in ready-mode requires Chrome + REQUIRES_MULTI_INSTALL, // 41. --multi-install was missing from the + // command line. }; // The type of an update archive. @@ -82,6 +84,7 @@ namespace switches { extern const char kCeee[]; extern const char kChrome[]; extern const char kChromeFrame[]; +extern const char kChromeFrameQuickEnable[]; extern const char kChromeFrameReadyMode[]; extern const char kChromeFrameReadyModeOptIn[]; extern const char kChromeFrameReadyModeTempOptOut[]; |