diff options
author | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-12 19:28:50 +0000 |
---|---|---|
committer | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-12 19:28:50 +0000 |
commit | 6e58a95b99e1c88172d5eae8925c8dfa39c2b765 (patch) | |
tree | 77e93bb7e93198024c36e5a6bba434b9412820ac /chrome/installer | |
parent | f24a74a242f8605d43085d6cc0cb36e5e376b2d4 (diff) | |
download | chromium_src-6e58a95b99e1c88172d5eae8925c8dfa39c2b765.zip chromium_src-6e58a95b99e1c88172d5eae8925c8dfa39c2b765.tar.gz chromium_src-6e58a95b99e1c88172d5eae8925c8dfa39c2b765.tar.bz2 |
Integrate the Ready Mode prompt with IE and Chrome Frame. In Ready Mode, prompts are displayed when the user browses to GCF-enabled sites, allowing the user to permanently activate, permanently decline, or temporarily decline Chrome Frame.
BUG=None
TEST=chrome_frame_unittests --gtest_filter=Ready* && chrome_frame_unittests --gtest_filter=Infobar* && setup.exe --chrome-frame --ready-mode --multi-install --system--level --chrome
Review URL: http://codereview.chromium.org/6040003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71215 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
20 files changed, 641 insertions, 253 deletions
diff --git a/chrome/installer/setup/chrome_frame_ready_mode.cc b/chrome/installer/setup/chrome_frame_ready_mode.cc new file mode 100644 index 0000000..3523237 --- /dev/null +++ b/chrome/installer/setup/chrome_frame_ready_mode.cc @@ -0,0 +1,215 @@ +// 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_ready_mode.h" + +#include "base/command_line.h" +#include "base/file_path.h" +#include "base/logging.h" +#include "base/ref_counted.h" +#include "base/string_util.h" +#include "base/time.h" +#include "base/utf_string_conversions.h" +#include "base/win/registry.h" +#include "chrome/installer/setup/install.h" +#include "chrome/installer/util/browser_distribution.h" +#include "chrome/installer/util/google_update_constants.h" +#include "chrome/installer/util/helper.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/master_preferences.h" +#include "chrome/installer/util/master_preferences_constants.h" +#include "chrome/installer/util/package.h" +#include "chrome/installer/util/package_properties.h" +#include "chrome/installer/util/product.h" +#include "chrome/installer/util/util_constants.h" +#include "chrome/installer/util/work_item.h" +#include "chrome/installer/util/work_item_list.h" + +namespace installer { + +InstallStatus ChromeFrameReadyModeOptIn(const InstallerState& installer_state, + const CommandLine& cmd_line) { + VLOG(1) << "Opting into Chrome Frame"; + InstallStatus status = INSTALL_REPAIRED; + + const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); + bool system_install = false; + prefs.GetBool(master_preferences::kSystemLevel, &system_install); + BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_FRAME, prefs); + DCHECK(cf->ShouldCreateUninstallEntry()) + << "Opting into CF should create an uninstall entry"; + BrowserDistribution* chrome = BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_BROWSER, prefs); + + ActivePackageProperties package_properties; + + // Remove ChromeFrameReadyMode, update Chrome's uninstallation commands to + // only uninstall Chrome, and add an entry to the Add/Remove Programs + // dialog for GCF. + + FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); + if (path.empty()) { + LOG(ERROR) << "Conflicting installations"; + status = NON_MULTI_INSTALLATION_EXISTS; + } else { + InstallationState original_state; + original_state.Initialize(prefs); + + scoped_refptr<Package> package(new Package(prefs.is_multi_install(), + system_install, path, &package_properties)); + scoped_refptr<Product> cf_product(new Product(cf, package)); + DCHECK(cf_product->ShouldCreateUninstallEntry() || cf_product->IsMsi()); + scoped_refptr<Product> chrome_product(new Product(chrome, package)); + const ProductState* product_state = + original_state.GetProductState(system_install, cf->GetType()); + if (product_state == NULL) { + LOG(ERROR) << "No Chrome Frame installation found for opt-in."; + return CHROME_NOT_INSTALLED; + } + scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); + + // This creates the uninstallation entry for GCF. + AddUninstallShortcutWorkItems(cmd_line.GetProgram(), + product_state->version(), item_list.get(), *cf_product.get()); + // This updates the Chrome uninstallation entries. + AddUninstallShortcutWorkItems(cmd_line.GetProgram(), + product_state->version(), item_list.get(), *chrome_product.get()); + + // Add a work item to delete the ChromeFrameReadyMode registry value. + HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + item_list->AddDeleteRegValueWorkItem(root, package_properties.GetStateKey(), + kChromeFrameReadyModeField, REG_QWORD); + + // Delete the command elevation registry keys + std::wstring version_key(cf->GetVersionKey()); + item_list->AddDeleteRegValueWorkItem( + root, version_key, google_update::kRegCFTempOptOutCmdField, REG_SZ); + item_list->AddDeleteRegValueWorkItem( + root, version_key, google_update::kRegCFEndTempOptOutCmdField, REG_SZ); + item_list->AddDeleteRegValueWorkItem(root, version_key, + google_update::kRegCFOptOutCmdField, + REG_SZ); + item_list->AddDeleteRegValueWorkItem(root, version_key, + google_update::kRegCFOptInCmdField, + REG_SZ); + + if (!item_list->Do()) { + LOG(ERROR) << "Failed to opt into GCF"; + item_list->Rollback(); + status = READY_MODE_OPT_IN_FAILED; + } + } + + return status; +} + +const wchar_t kPostPlatformUAKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\" + L"User Agent\\Post Platform"; +const wchar_t kChromeFramePrefix[] = L"chromeframe/"; + +InstallStatus ChromeFrameReadyModeTempOptOut(const CommandLine& cmd_line) { + VLOG(1) << "Temporarily opting out of Chrome Frame"; + InstallStatus status = INSTALL_REPAIRED; + + const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); + bool system_install = false; + prefs.GetBool(master_preferences::kSystemLevel, &system_install); + BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_FRAME, prefs); + + installer::ActivePackageProperties package_properties; + + // Remove the ChromeFrame user agent string from the registry, modify the + // ReadyMode state flag. + FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); + if (path.empty()) { + LOG(ERROR) << "Conflicting installations"; + status = NON_MULTI_INSTALLATION_EXISTS; + } else { + scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); + + HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + + // Add a work item to delete the ChromeFrame user agent registry value. + base::win::RegistryValueIterator values(root, kPostPlatformUAKey); + while (values.Valid()) { + const wchar_t* name = values.Name(); + if (StartsWith(name, kChromeFramePrefix, true)) { + item_list->AddDeleteRegValueWorkItem(root, kPostPlatformUAKey, name, + REG_SZ); + } + ++values; + } + + // Add a work item to update the Ready Mode state flag + int64 timestamp = base::Time::Now().ToInternalValue(); + item_list->AddSetRegValueWorkItem(root, package_properties.GetStateKey(), + kChromeFrameReadyModeField, timestamp, + true); + + if (!item_list->Do()) { + LOG(ERROR) << "Failed to temporarily opt out of GCF"; + item_list->Rollback(); + status = READY_MODE_TEMP_OPT_OUT_FAILED; + } + } + + return status; +} + +InstallStatus ChromeFrameReadyModeEndTempOptOut(const CommandLine& cmd_line) { + VLOG(1) << "Ending temporary opt-out of Chrome Frame"; + InstallStatus status = INSTALL_REPAIRED; + + const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); + bool system_install = false; + prefs.GetBool(master_preferences::kSystemLevel, &system_install); + BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_FRAME, prefs); + + installer::ActivePackageProperties package_properties; + + // Replace the ChromeFrame user agent string in the registry, modify the + // ReadyMode state flag. + FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); + scoped_ptr<Version> installed_version( + InstallUtil::GetChromeVersion(cf, system_install)); + + if (path.empty()) { + LOG(ERROR) << "Conflicting installations"; + status = NON_MULTI_INSTALLATION_EXISTS; + } else if (installed_version == NULL) { + LOG(ERROR) << "Failed to query installed version of Chrome Frame"; + status = READY_MODE_END_TEMP_OPT_OUT_FAILED; + } else { + scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); + + HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + + std::wstring chrome_frame_ua_value_name = kChromeFramePrefix; + chrome_frame_ua_value_name += ASCIIToWide(installed_version->GetString()); + + // Store the Chrome Frame user agent string + item_list->AddSetRegValueWorkItem(root, kPostPlatformUAKey, + chrome_frame_ua_value_name, L"", true); + // Add a work item to update the Ready Mode state flag + item_list->AddSetRegValueWorkItem(root, package_properties.GetStateKey(), + kChromeFrameReadyModeField, + static_cast<int64>(1), true); + + if (!item_list->Do()) { + LOG(ERROR) << "Failed to end temporary opt out of GCF"; + item_list->Rollback(); + status = READY_MODE_END_TEMP_OPT_OUT_FAILED; + } + } + + return status; +} + +} // namespace installer diff --git a/chrome/installer/setup/chrome_frame_ready_mode.h b/chrome/installer/setup/chrome_frame_ready_mode.h new file mode 100644 index 0000000..35c9507 --- /dev/null +++ b/chrome/installer/setup/chrome_frame_ready_mode.h @@ -0,0 +1,34 @@ +// 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. +// +// This file contains the specification of setup main functions. + +#ifndef CHROME_INSTALLER_SETUP_CHROME_FRAME_READY_MODE_H_ +#define CHROME_INSTALLER_SETUP_CHROME_FRAME_READY_MODE_H_ +#pragma once + +class CommandLine; + +namespace installer { + +enum InstallStatus; +class InstallerState; + +// Removes the ChromeFrameReadyMode flag from the registry, updates Chrome's +// uninstallation commands to only uninstall Chrome, and adds an entry to the +// Add/Remove Programs list for GCF. +InstallStatus ChromeFrameReadyModeOptIn(const InstallerState& installer_state, + const CommandLine& cmd_line); + +// Unregisters the ChromeFrame user agent modification, sets a timestamp for +// restoring it. +InstallStatus ChromeFrameReadyModeTempOptOut(const CommandLine& cmd_line); + +// Re-registers the ChromeFrame user agent modification, restores Ready Mode +// active state flag. +InstallStatus ChromeFrameReadyModeEndTempOptOut(const CommandLine& cmd_line); + +} // namespace installer + +#endif // CHROME_INSTALLER_SETUP_CHROME_FRAME_READY_MODE_H_ diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index ec36f79..dc545a7 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -121,108 +121,6 @@ void AppendUninstallCommandLineFlags(CommandLine* uninstall_cmd, uninstall_cmd->AppendSwitch(installer::switches::kVerboseLogging); } -// This method adds work items to create (or update) Chrome uninstall entry in -// either the Control Panel->Add/Remove Programs list or in the Omaha client -// state key if running under an MSI installer. -void AddUninstallShortcutWorkItems(const FilePath& setup_path, - const Version& new_version, - WorkItemList* install_list, - const Product& product) { - HKEY reg_root = product.system_level() ? HKEY_LOCAL_MACHINE : - HKEY_CURRENT_USER; - BrowserDistribution* browser_dist = product.distribution(); - DCHECK(browser_dist); - - // When we are installed via an MSI, we need to store our uninstall strings - // in the Google Update client state key. We do this even for non-MSI - // managed installs to avoid breaking the edge case whereby an MSI-managed - // install is updated by a non-msi installer (which would confuse the MSI - // machinery if these strings were not also updated). - // Do not quote the command line for the MSI invocation. - FilePath install_path(product.package().path()); - FilePath installer_path( - product.package().GetInstallerDirectory(new_version)); - installer_path = installer_path.Append(setup_path.BaseName()); - - CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); - AppendUninstallCommandLineFlags(&uninstall_arguments, product); - - if (product.is_chrome()) { - // The Chrome uninstallation command serves as the master uninstall - // command for Chrome + all other products (i.e. Chrome Frame) that do - // not have an uninstall entry in the Add/Remove Programs dialog. - const Products& products = product.package().products(); - for (size_t i = 0; i < products.size(); ++i) { - const Product& p = *products[i]; - if (!p.is_chrome() && !p.ShouldCreateUninstallEntry()) { - p.distribution()->AppendUninstallCommandLineFlags(&uninstall_arguments); - } - } - } - - std::wstring update_state_key(browser_dist->GetStateKey()); - install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); - install_list->AddSetRegValueWorkItem(reg_root, update_state_key, - installer::kUninstallStringField, installer_path.value(), true); - install_list->AddSetRegValueWorkItem(reg_root, update_state_key, - installer::kUninstallArgumentsField, - uninstall_arguments.command_line_string(), true); - - if (product.ShouldCreateUninstallEntry()) { - // We need to quote the command line for the Add/Remove Programs dialog. - CommandLine quoted_uninstall_cmd(installer_path); - DCHECK_EQ(quoted_uninstall_cmd.command_line_string()[0], '"'); - quoted_uninstall_cmd.AppendArguments(uninstall_arguments, false); - - std::wstring uninstall_reg = browser_dist->GetUninstallRegPath(); - install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - installer::kUninstallDisplayNameField, - browser_dist->GetAppShortCutName(), true); - install_list->AddSetRegValueWorkItem(reg_root, - uninstall_reg, installer::kUninstallStringField, - quoted_uninstall_cmd.command_line_string(), true); - install_list->AddSetRegValueWorkItem(reg_root, - uninstall_reg, - L"InstallLocation", - install_path.value(), - true); - - // DisplayIcon, NoModify and NoRepair - FilePath chrome_icon(install_path.Append(installer::kChromeExe)); - ShellUtil::GetChromeIcon(product.distribution(), chrome_icon.value()); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"DisplayIcon", chrome_icon.value(), - true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"NoModify", 1, true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"NoRepair", 1, true); - - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"Publisher", - browser_dist->GetPublisherName(), - true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"Version", - UTF8ToWide(new_version.GetString()), - true); - install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, - L"DisplayVersion", - UTF8ToWide(new_version.GetString()), - 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, uninstall_reg, - L"InstallDate", - buffer, false); - } - } -} - // Adds work items that make registry adjustments for Google Update. When a // product is installed (including overinstall), Google Update will write the // channel ("ap") value into either Chrome or Chrome Frame's ClientState key. @@ -647,10 +545,10 @@ bool AppendPostInstallTasks(bool multi_install, std::wstring version_key(dist->GetVersionKey()); regular_update_work_items->AddDeleteRegValueWorkItem(root, version_key, google_update::kRegOldVersionField, - true); + REG_SZ); regular_update_work_items->AddDeleteRegValueWorkItem(root, version_key, google_update::kRegRenameCmdField, - true); + REG_SZ); } post_install_task_list->AddWorkItem(regular_update_work_items.release()); @@ -737,7 +635,8 @@ void AddVersionKeyWorkItems(HKEY root, list->AddSetRegValueWorkItem(root, version_key, google_update::kRegNameField, product_name, true); // overwrite name also list->AddSetRegValueWorkItem(root, version_key, - google_update::kRegOopcrashesField, 1, + google_update::kRegOopcrashesField, + static_cast<DWORD>(1), false); // set during first install list->AddSetRegValueWorkItem(root, version_key, google_update::kRegVersionField, @@ -1048,6 +947,107 @@ void AddSetMsiMarkerWorkItem(const Product& product, set_msi_work_item->set_log_message("Could not write MSI marker!"); } +void AddUninstallShortcutWorkItems(const FilePath& setup_path, + const Version& new_version, + WorkItemList* install_list, + const Product& product) { + HKEY reg_root = product.system_level() ? HKEY_LOCAL_MACHINE : + HKEY_CURRENT_USER; + BrowserDistribution* browser_dist = product.distribution(); + DCHECK(browser_dist); + + // When we are installed via an MSI, we need to store our uninstall strings + // in the Google Update client state key. We do this even for non-MSI + // managed installs to avoid breaking the edge case whereby an MSI-managed + // install is updated by a non-msi installer (which would confuse the MSI + // machinery if these strings were not also updated). + // Do not quote the command line for the MSI invocation. + FilePath install_path(product.package().path()); + FilePath installer_path( + product.package().GetInstallerDirectory(new_version)); + installer_path = installer_path.Append(setup_path.BaseName()); + + CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); + AppendUninstallCommandLineFlags(&uninstall_arguments, product); + + if (product.is_chrome()) { + // The Chrome uninstallation command serves as the master uninstall + // command for Chrome + all other products (i.e. Chrome Frame) that do + // not have an uninstall entry in the Add/Remove Programs dialog. + const Products& products = product.package().products(); + for (size_t i = 0; i < products.size(); ++i) { + const Product& p = *products[i]; + if (!p.is_chrome() && !p.ShouldCreateUninstallEntry()) { + p.distribution()->AppendUninstallCommandLineFlags(&uninstall_arguments); + } + } + } + + std::wstring update_state_key(browser_dist->GetStateKey()); + install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); + install_list->AddSetRegValueWorkItem(reg_root, update_state_key, + installer::kUninstallStringField, installer_path.value(), true); + install_list->AddSetRegValueWorkItem(reg_root, update_state_key, + installer::kUninstallArgumentsField, + uninstall_arguments.command_line_string(), true); + + if (product.ShouldCreateUninstallEntry()) { + // We need to quote the command line for the Add/Remove Programs dialog. + CommandLine quoted_uninstall_cmd(installer_path); + DCHECK_EQ(quoted_uninstall_cmd.command_line_string()[0], '"'); + quoted_uninstall_cmd.AppendArguments(uninstall_arguments, false); + + std::wstring uninstall_reg = browser_dist->GetUninstallRegPath(); + install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg); + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + installer::kUninstallDisplayNameField, + browser_dist->GetAppShortCutName(), true); + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, installer::kUninstallStringField, + quoted_uninstall_cmd.command_line_string(), true); + install_list->AddSetRegValueWorkItem(reg_root, + uninstall_reg, + L"InstallLocation", + install_path.value(), + true); + + // DisplayIcon, NoModify and NoRepair + FilePath chrome_icon(install_path.Append(installer::kChromeExe)); + ShellUtil::GetChromeIcon(product.distribution(), chrome_icon.value()); + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + L"DisplayIcon", chrome_icon.value(), + true); + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + L"NoModify", static_cast<DWORD>(1), + true); + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + L"NoRepair", static_cast<DWORD>(1), + true); + + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + L"Publisher", + browser_dist->GetPublisherName(), + true); + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + L"Version", + UTF8ToWide(new_version.GetString()), + true); + install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, + L"DisplayVersion", + UTF8ToWide(new_version.GetString()), + 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, uninstall_reg, + L"InstallDate", + buffer, false); + } + } +} + void AddChromeFrameWorkItems(bool install, const FilePath& setup_path, const Version& new_version, @@ -1059,6 +1059,12 @@ void AddChromeFrameWorkItems(bool install, return; } + const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); + + BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_FRAME, prefs); + std::wstring version_key(cf->GetVersionKey()); + // TODO(tommi): This assumes we know exactly how ShouldCreateUninstallEntry // is implemented. Since there is logic in ChromeFrameDistribution for how // to determine when this is enabled, this is how we have to figure out if @@ -1081,9 +1087,53 @@ void AddChromeFrameWorkItems(bool install, list->AddSetRegValueWorkItem(root, product.package().properties()->GetStateKey(), installer::kChromeFrameReadyModeField, - install ? 1 : 0, // The value we want to set. + static_cast<int64>(install ? 1 : 0), // The value we want to set. install ? false : true); // Overwrite existing value. - if (!install) { + if (install) { + FilePath installer_path(product.package() + .GetInstallerDirectory(new_version).Append(setup_path.BaseName())); + + CommandLine basic_cl(installer_path); + basic_cl.AppendSwitch(installer::switches::kChromeFrame); + basic_cl.AppendSwitch(installer::switches::kMultiInstall); + + if (product.package().system_level()) + basic_cl.AppendSwitch(installer::switches::kSystemLevel); + + if (InstallUtil::IsChromeSxSProcess()) + basic_cl.AppendSwitch(installer::switches::kChromeSxS); + + CommandLine temp_opt_out(basic_cl); + temp_opt_out.AppendSwitch( + installer::switches::kChromeFrameReadyModeTempOptOut); + + CommandLine end_temp_opt_out(basic_cl); + end_temp_opt_out.AppendSwitch( + installer::switches::kChromeFrameReadyModeEndTempOptOut); + + CommandLine opt_out(installer_path); + AppendUninstallCommandLineFlags(&opt_out, product); + // Force Uninstall silences the prompt to reboot to complete uninstall. + opt_out.AppendSwitch(installer::switches::kForceUninstall); + + CommandLine opt_in(basic_cl); + opt_in.AppendSwitch( + installer::switches::kChromeFrameReadyModeOptIn); + + list->AddSetRegValueWorkItem(root, version_key, + google_update::kRegCFTempOptOutCmdField, + temp_opt_out.command_line_string(), true); + list->AddSetRegValueWorkItem(root, version_key, + google_update::kRegCFEndTempOptOutCmdField, + end_temp_opt_out.command_line_string(), + true); + list->AddSetRegValueWorkItem(root, version_key, + google_update::kRegCFOptOutCmdField, + opt_out.command_line_string(), true); + list->AddSetRegValueWorkItem(root, version_key, + google_update::kRegCFOptInCmdField, + opt_in.command_line_string(), true); + } else { // If Chrome is not also being uninstalled, we need to update its command // line so that it doesn't include uninstalling Chrome Frame now. update_chrome_uninstall_command = @@ -1106,7 +1156,7 @@ void AddChromeFrameWorkItems(bool install, KEY_QUERY_VALUE).Valid()) { list->AddDeleteRegValueWorkItem(root, product.package().properties()->GetStateKey(), - installer::kChromeFrameReadyModeField, false); + installer::kChromeFrameReadyModeField, REG_QWORD); } const Product* chrome = installer::FindProduct(product.package().products(), @@ -1126,11 +1176,24 @@ void AddChromeFrameWorkItems(bool install, } } + if (!ready_mode || !install) { + list->AddDeleteRegValueWorkItem(root, version_key, + google_update::kRegCFTempOptOutCmdField, + REG_SZ); + list->AddDeleteRegValueWorkItem(root, version_key, + google_update::kRegCFEndTempOptOutCmdField, + REG_SZ); + list->AddDeleteRegValueWorkItem(root, version_key, + google_update::kRegCFOptOutCmdField, + REG_SZ); + list->AddDeleteRegValueWorkItem(root, version_key, + google_update::kRegCFOptInCmdField, REG_SZ); + } + if (update_chrome_uninstall_command) { // Chrome is not a part of this installation run, so we have to explicitly // check if Chrome is installed, and if so, update its uninstallation // command lines. - const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); BrowserDistribution* chrome_dist = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_BROWSER, prefs); @@ -1143,68 +1206,4 @@ void AddChromeFrameWorkItems(bool install, } } -InstallStatus ChromeFrameReadyModeOptIn(const InstallerState& installer_state, - const CommandLine& cmd_line) { - VLOG(1) << "Opting into Chrome Frame"; - InstallStatus status = INSTALL_REPAIRED; - - const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); - bool system_install = false; - prefs.GetBool(master_preferences::kSystemLevel, &system_install); - BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( - BrowserDistribution::CHROME_FRAME, prefs); - DCHECK(cf->ShouldCreateUninstallEntry()) - << "Opting into CF should create an uninstall entry"; - BrowserDistribution* chrome = BrowserDistribution::GetSpecificDistribution( - BrowserDistribution::CHROME_BROWSER, prefs); - - ActivePackageProperties package_properties; - - // Remove ChromeFrameReadyMode, update Chrome's uninstallation commands to - // only uninstall Chrome, and add an entry to the Add/Remove Programs - // dialog for GCF. - - FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); - if (path.empty()) { - LOG(ERROR) << "Conflicting installations"; - status = NON_MULTI_INSTALLATION_EXISTS; - } else { - InstallationState original_state; - original_state.Initialize(prefs); - - scoped_refptr<Package> package(new Package(prefs.is_multi_install(), - system_install, path, &package_properties)); - scoped_refptr<Product> cf_product(new Product(cf, package)); - DCHECK(cf_product->ShouldCreateUninstallEntry() || cf_product->IsMsi()); - scoped_refptr<Product> chrome_product(new Product(chrome, package)); - const ProductState* product_state = - original_state.GetProductState(system_install, cf->GetType()); - if (product_state == NULL) { - LOG(ERROR) << "No Chrome Frame installation found for opt-in."; - return CHROME_NOT_INSTALLED; - } - scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); - - // This creates the uninstallation entry for GCF. - AddUninstallShortcutWorkItems(cmd_line.GetProgram(), - product_state->version(), item_list.get(), *cf_product.get()); - // This updates the Chrome uninstallation entries. - AddUninstallShortcutWorkItems(cmd_line.GetProgram(), - product_state->version(), item_list.get(), *chrome_product.get()); - - // Add a work item to delete the ChromeFrameReadyMode registry value. - HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - item_list->AddDeleteRegValueWorkItem(root, package_properties.GetStateKey(), - kChromeFrameReadyModeField, false); - - if (!item_list->Do()) { - LOG(ERROR) << "Failed to opt into GCF"; - item_list->Rollback(); - status = READY_MODE_OPT_IN_FAILED; - } - } - - return status; -} - } // namespace installer diff --git a/chrome/installer/setup/install.h b/chrome/installer/setup/install.h index 40225c0..7e8d465 100644 --- a/chrome/installer/setup/install.h +++ b/chrome/installer/setup/install.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. // @@ -71,6 +71,14 @@ void AddSetMsiMarkerWorkItem(const Product& product, bool set, WorkItemList* work_item_list); +// This method adds work items to create (or update) Chrome uninstall entry in +// either the Control Panel->Add/Remove Programs list or in the Omaha client +// state key if running under an MSI installer. +void AddUninstallShortcutWorkItems(const FilePath& setup_path, + const Version& new_version, + WorkItemList* install_list, + const Product& product); + // Called for either installation or uninstallation. This method updates the // registry according to Chrome Frame specific options for the current // installation. This includes handling of the ready-mode option. @@ -78,12 +86,6 @@ void AddChromeFrameWorkItems(bool install, const FilePath& setup_path, const Version& new_version, const Product& product, WorkItemList* list); -// Removes the ChromeFrameReadyMode flag from the registry, updates Chrome's -// uninstallation commands to only uninstall Chrome, and adds an entry to the -// Add/Remove Programs list for GCF. -InstallStatus ChromeFrameReadyModeOptIn(const InstallerState& installer_state, - const CommandLine& cmd_line); - } // namespace installer #endif // CHROME_INSTALLER_SETUP_INSTALL_H_ diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 96f93b9..5158bc0 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -25,6 +25,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_ready_mode.h" #include "chrome/installer/setup/install.h" #include "chrome/installer/setup/setup_constants.h" #include "chrome/installer/setup/setup_util.h" @@ -167,11 +168,11 @@ installer::InstallStatus RenameChromeExecutables( install_list->AddDeleteRegValueWorkItem(reg_root, version_key, google_update::kRegOldVersionField, - true); + REG_SZ); install_list->AddDeleteRegValueWorkItem(reg_root, version_key, google_update::kRegRenameCmdField, - true); + REG_SZ); } installer::InstallStatus ret = installer::RENAME_SUCCESSFUL; if (!install_list->Do()) { @@ -675,6 +676,14 @@ bool HandleNonInstallCmdLineOptions(const InstallerState& installer_state, installer::switches::kChromeFrameReadyModeOptIn)) { *exit_code = InstallUtil::GetInstallReturnCode( installer::ChromeFrameReadyModeOptIn(installer_state, cmd_line)); + } else if (cmd_line.HasSwitch( + installer::switches::kChromeFrameReadyModeTempOptOut)) { + *exit_code = InstallUtil::GetInstallReturnCode( + installer::ChromeFrameReadyModeTempOptOut(cmd_line)); + } else if (cmd_line.HasSwitch( + installer::switches::kChromeFrameReadyModeEndTempOptOut)) { + *exit_code = InstallUtil::GetInstallReturnCode( + installer::ChromeFrameReadyModeEndTempOptOut(cmd_line)); } else { handled = false; } diff --git a/chrome/installer/util/chrome_frame_distribution.cc b/chrome/installer/util/chrome_frame_distribution.cc index 73aa3f6..2507f1d 100644 --- a/chrome/installer/util/chrome_frame_distribution.cc +++ b/chrome/installer/util/chrome_frame_distribution.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. // @@ -50,17 +50,12 @@ ChromeFrameDistribution::ChromeFrameDistribution( // If the user has already opted in to CF, we shouldn't set the ready-mode // flag. If we don't do this, we might have two entries in the Add/Remove - // Programs list that can uninstall GCF. Also, we can only enable - // ready-mode if Chrome is also being installed. Without it, there's no way - // to uninstall Chrome Frame. + // Programs list that can uninstall GCF. if (ready_mode_) { if (!uninstall.HasSwitch(installer::switches::kChromeFrameReadyMode)) { LOG(INFO) << "Ready mode was specified on the command line but GCF " "is already fully installed. Ignoring command line."; ready_mode_ = false; - } else if (!prefs.install_chrome()) { - LOG(WARNING) << "Cannot enable ready mode without installing Chrome."; - ready_mode_ = false; } } } diff --git a/chrome/installer/util/delete_reg_value_work_item.cc b/chrome/installer/util/delete_reg_value_work_item.cc index 5b0496d..1db853a 100644 --- a/chrome/installer/util/delete_reg_value_work_item.cc +++ b/chrome/installer/util/delete_reg_value_work_item.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -13,13 +13,15 @@ using base::win::RegKey; DeleteRegValueWorkItem::DeleteRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, const std::wstring& value_name, - bool is_str_type) + DWORD type) : predefined_root_(predefined_root), key_path_(key_path), value_name_(value_name), - is_str_type_(is_str_type), + type_(type), status_(DELETE_VALUE), - old_dw_(0) { + old_dw_(0), + old_qword_(0) { + DCHECK(type_ == REG_QWORD || type_ == REG_DWORD || type == REG_SZ); } DeleteRegValueWorkItem::~DeleteRegValueWorkItem() { @@ -52,16 +54,25 @@ bool DeleteRegValueWorkItem::Do() { RegKey key; bool result = false; + + // Used in REG_QWORD case only + DWORD value_size = sizeof(old_qword_); + DWORD type = 0; + if (!key.Open(predefined_root_, key_path_.c_str(), KEY_READ | KEY_WRITE)) { LOG(ERROR) << "can not open " << key_path_; } else if (!key.ValueExists(value_name_.c_str())) { status_ = VALUE_NOT_FOUND; result = true; // Read previous value for rollback and delete - } else if (((is_str_type_ && key.ReadValue(value_name_.c_str(), - &old_str_)) || - (!is_str_type_ && key.ReadValueDW(value_name_.c_str(), - &old_dw_))) && + } else if (((type_ == REG_SZ && key.ReadValue(value_name_.c_str(), + &old_str_)) || + (type_ == REG_DWORD && key.ReadValueDW(value_name_.c_str(), + &old_dw_)) || + (type_ == REG_QWORD && key.ReadValue(value_name_.c_str(), + &old_qword_, + &value_size, &type) && + type == REG_QWORD && value_size == sizeof(old_qword_))) && (key.DeleteValue(value_name_.c_str()))) { status_ = VALUE_DELETED; result = true; @@ -86,10 +97,14 @@ void DeleteRegValueWorkItem::Rollback() { if (!key.Open(predefined_root_, key_path_.c_str(), KEY_READ | KEY_WRITE)) { LOG(ERROR) << "rollback: can not open " << key_path_; // try to restore the previous value - } else if ((is_str_type_ && key.WriteValue(value_name_.c_str(), - old_str_.c_str())) || - (!is_str_type_ && key.WriteValue(value_name_.c_str(), - old_dw_))) { + } else if ((type_ == REG_SZ && key.WriteValue(value_name_.c_str(), + old_str_.c_str())) || + (type_ == REG_DWORD && key.WriteValue(value_name_.c_str(), + old_dw_)) || + (type_ == REG_QWORD && key.WriteValue(value_name_.c_str(), + &old_qword_, + sizeof(old_qword_), + REG_QWORD))) { status_ = VALUE_ROLLED_BACK; VLOG(1) << "rollback: restored " << value_name_; } else { diff --git a/chrome/installer/util/delete_reg_value_work_item.h b/chrome/installer/util/delete_reg_value_work_item.h index 0c0c228..7b477fe 100644 --- a/chrome/installer/util/delete_reg_value_work_item.h +++ b/chrome/installer/util/delete_reg_value_work_item.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -12,8 +12,9 @@ #include "chrome/installer/util/work_item.h" -// A WorkItem subclass that sets a registry value with REG_SZ or REG_DWORD -// type at the specified path. The value is only set if the target key exists. +// A WorkItem subclass that deletes a registry value with REG_SZ, REG_DWORD, or +// REG_QWORD type at the specified path. The value is only deleted if the target +// key exists. class DeleteRegValueWorkItem : public WorkItem { public: virtual ~DeleteRegValueWorkItem(); @@ -39,7 +40,7 @@ class DeleteRegValueWorkItem : public WorkItem { }; DeleteRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, - const std::wstring& value_name, bool is_str_type); + const std::wstring& value_name, DWORD type); // Root key of the target key under which the value is set. The root key can // only be one of the predefined keys on Windows. @@ -51,17 +52,19 @@ class DeleteRegValueWorkItem : public WorkItem { // Name of the value to be set. std::wstring value_name_; - // boolean that tells whether data value is of type REG_SZ or REG_DWORD. + // DWORD that tells whether data value is of type REG_SZ, REG_DWORD, or + // REG_QWORD // Ideally we do not need this information from user of this class and can // check the registry for the type. But to simpify implementation we are // going to put the burden on the caller for now to provide us the type. - bool is_str_type_; + DWORD type_; DeletionStatus status_; // Data of the previous value. std::wstring old_str_; // if data is of type REG_SZ DWORD old_dw_; // if data is of type REG_DWORD + int64 old_qword_; // if data is of type REG_QWORD }; #endif // CHROME_INSTALLER_UTIL_DELETE_REG_VALUE_WORK_ITEM_H_ diff --git a/chrome/installer/util/delete_reg_value_work_item_unittest.cc b/chrome/installer/util/delete_reg_value_work_item_unittest.cc index fcec35c..e8c37c0 100644 --- a/chrome/installer/util/delete_reg_value_work_item_unittest.cc +++ b/chrome/installer/util/delete_reg_value_work_item_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -54,10 +54,10 @@ TEST_F(DeleteRegValueWorkItemTest, DeleteExistingValue) { scoped_ptr<DeleteRegValueWorkItem> work_item1( WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_str, true)); + name_str, REG_SZ)); scoped_ptr<DeleteRegValueWorkItem> work_item2( WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_dword, false)); + name_dword, REG_DWORD)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); @@ -90,10 +90,10 @@ TEST_F(DeleteRegValueWorkItemTest, DeleteNonExistentValue) { scoped_ptr<DeleteRegValueWorkItem> work_item1( WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_str, true)); + name_str, REG_SZ)); scoped_ptr<DeleteRegValueWorkItem> work_item2( WorkItem::CreateDeleteRegValueWorkItem(HKEY_CURRENT_USER, parent_key, - name_dword, false)); + name_dword, REG_DWORD)); EXPECT_TRUE(work_item1->Do()); EXPECT_TRUE(work_item2->Do()); diff --git a/chrome/installer/util/google_update_constants.cc b/chrome/installer/util/google_update_constants.cc index aef9c0d..1419128 100644 --- a/chrome/installer/util/google_update_constants.cc +++ b/chrome/installer/util/google_update_constants.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -32,5 +32,9 @@ const wchar_t kRegVersionField[] = L"pv"; const wchar_t kRegReferralField[] = L"referral"; const wchar_t kRegEULAAceptedField[] = L"eulaaccepted"; const wchar_t kRegLastRunTimeField[] = L"lastrun"; +const wchar_t kRegCFTempOptOutCmdField[] = L"CFTempOptOutCmd"; +const wchar_t kRegCFEndTempOptOutCmdField[] = L"CFEndTempOptOutCmd"; +const wchar_t kRegCFOptOutCmdField[] = L"CFOptOutCmd"; +const wchar_t kRegCFOptInCmdField[] = L"CFOptInCmd"; } // namespace google_update diff --git a/chrome/installer/util/google_update_constants.h b/chrome/installer/util/google_update_constants.h index b371de4..e1125a7 100644 --- a/chrome/installer/util/google_update_constants.h +++ b/chrome/installer/util/google_update_constants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// 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. @@ -42,6 +42,10 @@ extern const wchar_t kRegUsageStatsField[]; extern const wchar_t kRegVersionField[]; extern const wchar_t kRegReferralField[]; extern const wchar_t kRegEULAAceptedField[]; +extern const wchar_t kRegCFTempOptOutCmdField[]; +extern const wchar_t kRegCFEndTempOptOutCmdField[]; +extern const wchar_t kRegCFOptOutCmdField[]; +extern const wchar_t kRegCFOptInCmdField[]; // last time that chrome ran in the Time internal format. extern const wchar_t kRegLastRunTimeField[]; diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc index 2223b15..f241cdd 100644 --- a/chrome/installer/util/install_util.cc +++ b/chrome/installer/util/install_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. // @@ -116,15 +116,15 @@ void InstallUtil::WriteInstallerResult(bool system_install, int string_resource_id, const std::wstring* const launch_cmd) { const HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - int installer_result = (GetInstallReturnCode(status) == 0) ? 0 : 1; + DWORD installer_result = (GetInstallReturnCode(status) == 0) ? 0 : 1; scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList()); install_list->AddCreateRegKeyWorkItem(root, state_key); install_list->AddSetRegValueWorkItem(root, state_key, installer::kInstallerResult, installer_result, true); install_list->AddSetRegValueWorkItem(root, state_key, - installer::kInstallerError, status, - true); + installer::kInstallerError, + static_cast<DWORD>(status), true); if (string_resource_id != 0) { std::wstring msg = installer::GetLocalizedString(string_resource_id); install_list->AddSetRegValueWorkItem(root, state_key, diff --git a/chrome/installer/util/set_reg_value_work_item.cc b/chrome/installer/util/set_reg_value_work_item.cc index 4a76040..08d0097 100644 --- a/chrome/installer/util/set_reg_value_work_item.cc +++ b/chrome/installer/util/set_reg_value_work_item.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -21,10 +21,12 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, value_name_(value_name), value_data_str_(value_data), value_data_dword_(0), + value_data_qword_(0), overwrite_(overwrite), status_(SET_VALUE), - is_str_type_(true), - previous_value_dword_(0) { + type_(REG_SZ), + previous_value_dword_(0), + previous_value_qword_(0) { } SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, @@ -36,10 +38,29 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, key_path_(key_path), value_name_(value_name), value_data_dword_(value_data), + value_data_qword_(0), overwrite_(overwrite), status_(SET_VALUE), - is_str_type_(false), - previous_value_dword_(0) { + type_(REG_DWORD), + previous_value_dword_(0), + previous_value_qword_(0) { +} + +SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + const std::wstring& value_name, + int64 value_data, + bool overwrite) + : predefined_root_(predefined_root), + key_path_(key_path), + value_name_(value_name), + value_data_dword_(0), + value_data_qword_(value_data), + overwrite_(overwrite), + status_(SET_VALUE), + type_(REG_QWORD), + previous_value_dword_(0), + previous_value_qword_(0) { } bool SetRegValueWorkItem::Do() { @@ -63,19 +84,32 @@ bool SetRegValueWorkItem::Do() { if (key.ValueExists(value_name_.c_str())) { if (overwrite_) { // Read previous value for rollback and write new value - if (is_str_type_) { + if (type_ == REG_SZ) { std::wstring data; if (key.ReadValue(value_name_.c_str(), &data)) { previous_value_str_.assign(data); } success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); - } else { + } else if (type_ == REG_DWORD) { DWORD data; if (key.ReadValueDW(value_name_.c_str(), &data)) { previous_value_dword_ = data; } success = key.WriteValue(value_name_.c_str(), value_data_dword_); + } else if (type_ == REG_QWORD) { + int64 data; + DWORD data_size = sizeof(data); + DWORD data_type = NULL; + + if (key.ReadValue(value_name_.c_str(), &data, &data_size, + &data_type)) { + previous_value_qword_ = data; + } + success = key.WriteValue(value_name_.c_str(), + &value_data_qword_, + sizeof(value_data_qword_), + REG_QWORD); } if (success) { VLOG(1) << "overwritten value for " << value_name_; @@ -89,10 +123,17 @@ bool SetRegValueWorkItem::Do() { status_ = VALUE_UNCHANGED; } } else { - if (is_str_type_) { + if (type_ == REG_SZ) { success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); - } else { + } else if (type_ == REG_DWORD) { success = key.WriteValue(value_name_.c_str(), value_data_dword_); + } else if (type_ == REG_QWORD) { + success = key.WriteValue(value_name_.c_str(), + &value_data_qword_, + sizeof(value_data_qword_), + REG_QWORD); + } else { + NOTREACHED() << "Unsupported value type."; } if (success) { VLOG(1) << "created value for " << value_name_; @@ -139,20 +180,25 @@ void SetRegValueWorkItem::Rollback() { } else if (status_ == VALUE_OVERWRITTEN) { // try restore the previous value bool success = true; - if (is_str_type_) { + if (type_ == REG_SZ) { success = key.WriteValue(value_name_.c_str(), previous_value_str_.c_str()); - } else { + } else if (type_ == REG_DWORD) { success = key.WriteValue(value_name_.c_str(), previous_value_dword_); + } else if (type_ == REG_QWORD) { + success = key.WriteValue(value_name_.c_str(), + &previous_value_qword_, + sizeof(previous_value_qword_), + REG_QWORD); + } else { + NOTREACHED(); } if (success) result_str.assign(L" succeeded"); VLOG(1) << "rollback: restoring " << value_name_ << result_str; - } else { - NOTREACHED(); - } - status_ = VALUE_ROLL_BACK; - return; + status_ = VALUE_ROLL_BACK; + return; + } } } diff --git a/chrome/installer/util/set_reg_value_work_item.h b/chrome/installer/util/set_reg_value_work_item.h index 1527784..1b51c5d 100644 --- a/chrome/installer/util/set_reg_value_work_item.h +++ b/chrome/installer/util/set_reg_value_work_item.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -12,8 +12,9 @@ #include "chrome/installer/util/work_item.h" -// A WorkItem subclass that sets a registry value with REG_SZ or REG_DWORD -// type at the specified path. The value is only set if the target key exists. +// A WorkItem subclass that sets a registry value with REG_SZ, REG_DWORD, or +// REG_QWORD type at the specified path. The value is only set if the target key +// exists. class SetRegValueWorkItem : public WorkItem { public: virtual ~SetRegValueWorkItem(); @@ -51,6 +52,10 @@ class SetRegValueWorkItem : public WorkItem { const std::wstring& value_name, DWORD value_data, bool overwrite); + SetRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, + const std::wstring& value_name, int64 value_data, + bool overwrite); + // Root key of the target key under which the value is set. The root key can // only be one of the predefined keys on Windows. HKEY predefined_root_; @@ -64,18 +69,20 @@ class SetRegValueWorkItem : public WorkItem { // Data of the value to be set. std::wstring value_data_str_; // if data is of type REG_SZ DWORD value_data_dword_; // if data is of type REG_DWORD + int64 value_data_qword_; // if data is of type REG_QWORD // Whether to overwrite the existing value under the target key. bool overwrite_; - // boolean that tells whether data value is of type REG_SZ. - bool is_str_type_; + // Type of data to store + DWORD type_; SettingStatus status_; // Data of the previous value. std::wstring previous_value_str_; // if data is of type REG_SZ DWORD previous_value_dword_; // if data is of type REG_DWORD + int64 previous_value_qword_; // if data is of type REG_QWORD }; #endif // CHROME_INSTALLER_UTIL_SET_REG_VALUE_WORK_ITEM_H__ diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index cda927d..f59d6a4 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -25,6 +25,14 @@ const char kChromeFrameReadyMode[] = "ready-mode"; // GCF ready mode opt-in. This enables a full installation of GCF. const char kChromeFrameReadyModeOptIn[] = "ready-mode-opt-in"; +// GCF ready mode temp opt-out. This disables the GCF user agent modification +// and detection of headers/meta tags. +const char kChromeFrameReadyModeTempOptOut[] = "ready-mode-temp-opt-out"; + +// End GCF ready mode temp opt-out. This re-enables the GCF user agent +// modification and detection of headers/meta tags. +const char kChromeFrameReadyModeEndTempOptOut[] = "ready-mode-end-temp-opt-out"; + // Run the installer for Chrome SxS. const char kChromeSxS[] = "chrome-sxs"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index 96bfb8a..5b2f230 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. // @@ -62,6 +62,10 @@ enum InstallStatus { // multi-install installation of the same product // on the system. READY_MODE_OPT_IN_FAILED, // 36. Failed to opt-into Chrome Frame. + READY_MODE_TEMP_OPT_OUT_FAILED, // 37. Failed to temporarily opt-out of + // Chrome Frame. + READY_MODE_END_TEMP_OPT_OUT_FAILED, // 38. Failed to end temporary opt-out + // of Chrome Frame. }; namespace switches { @@ -70,6 +74,8 @@ extern const char kChrome[]; extern const char kChromeFrame[]; extern const char kChromeFrameReadyMode[]; extern const char kChromeFrameReadyModeOptIn[]; +extern const char kChromeFrameReadyModeTempOptOut[]; +extern const char kChromeFrameReadyModeEndTempOptOut[]; extern const char kChromeSxS[]; extern const char kCreateAllShortcuts[]; extern const char kDeleteProfile[]; diff --git a/chrome/installer/util/work_item.cc b/chrome/installer/util/work_item.cc index d646051..5ed352b 100644 --- a/chrome/installer/util/work_item.cc +++ b/chrome/installer/util/work_item.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -50,9 +50,9 @@ DeleteRegValueWorkItem* WorkItem::CreateDeleteRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, const std::wstring& value_name, - bool is_str_type) { + DWORD type) { return new DeleteRegValueWorkItem(predefined_root, key_path, - value_name, is_str_type); + value_name, type); } DeleteTreeWorkItem* WorkItem::CreateDeleteTreeWorkItem( @@ -81,7 +81,18 @@ SetRegValueWorkItem* WorkItem::CreateSetRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, const std::wstring& value_name, - DWORD value_data, bool overwrite) { + DWORD value_data, + bool overwrite) { + return new SetRegValueWorkItem(predefined_root, key_path, + value_name, value_data, overwrite); +} + +SetRegValueWorkItem* WorkItem::CreateSetRegValueWorkItem( + HKEY predefined_root, + const std::wstring& key_path, + const std::wstring& value_name, + int64 value_data, + bool overwrite) { return new SetRegValueWorkItem(predefined_root, key_path, value_name, value_data, overwrite); } diff --git a/chrome/installer/util/work_item.h b/chrome/installer/util/work_item.h index 6b1d463..12446be 100644 --- a/chrome/installer/util/work_item.h +++ b/chrome/installer/util/work_item.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. // @@ -15,6 +15,8 @@ #include <string> #include <vector> +#include "base/basictypes.h" + class CopyTreeWorkItem; class CreateDirWorkItem; class CreateRegKeyWorkItem; @@ -81,7 +83,7 @@ class WorkItem { HKEY predefined_root, const std::wstring& key_path, const std::wstring& value_name, - bool is_str_type); + DWORD type); // Create a DeleteTreeWorkItem that recursively deletes a file system // hierarchy at the given root path. A key file can be optionally specified @@ -113,6 +115,14 @@ class WorkItem { const std::wstring& value_name, DWORD value_data, bool overwrite); + // Create a SetRegValueWorkItem that sets a registry value with REG_QWORD type + // at the key with specified path. + static SetRegValueWorkItem* CreateSetRegValueWorkItem( + HKEY predefined_root, + const std::wstring& key_path, + const std::wstring& value_name, + int64 value_data, bool overwrite); + // Add a SelfRegWorkItem that registers or unregisters a DLL at the // specified path. static SelfRegWorkItem* CreateSelfRegWorkItem(const std::wstring& dll_path, diff --git a/chrome/installer/util/work_item_list.cc b/chrome/installer/util/work_item_list.cc index 706ca10..41ee169 100644 --- a/chrome/installer/util/work_item_list.cc +++ b/chrome/installer/util/work_item_list.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -111,11 +111,11 @@ WorkItem* WorkItemList::AddDeleteRegValueWorkItem( HKEY predefined_root, const std::wstring& key_path, const std::wstring& value_name, - bool is_str_type) { + DWORD type) { WorkItem* item = WorkItem::CreateDeleteRegValueWorkItem(predefined_root, key_path, value_name, - is_str_type); + type); AddWorkItem(item); return item; } @@ -171,6 +171,18 @@ WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, return item; } +WorkItem* WorkItemList::AddSetRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + const std::wstring& value_name, + int64 value_data, + bool overwrite) { + WorkItem* item = reinterpret_cast<WorkItem*>( + WorkItem::CreateSetRegValueWorkItem(predefined_root, key_path, value_name, + value_data, overwrite)); + AddWorkItem(item); + return item; +} + WorkItem* WorkItemList::AddSelfRegWorkItem(const std::wstring& dll_path, bool do_register, bool user_level_registration) { diff --git a/chrome/installer/util/work_item_list.h b/chrome/installer/util/work_item_list.h index 30d332a..3474c34 100644 --- a/chrome/installer/util/work_item_list.h +++ b/chrome/installer/util/work_item_list.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -62,7 +62,7 @@ class WorkItemList : public WorkItem { WorkItem* AddDeleteRegValueWorkItem(HKEY predefined_root, const std::wstring& key_path, const std::wstring& value_name, - bool is_str_type); + DWORD type); // Add a DeleteTreeWorkItem that recursively deletes a file system // hierarchy at the given root path. A key file can be optionally specified @@ -94,6 +94,14 @@ class WorkItemList : public WorkItem { DWORD value_data, bool overwrite); + // Add a SetRegValueWorkItem that sets a registry value with REG_QWORD type + // at the key with specified path. + WorkItem* AddSetRegValueWorkItem(HKEY predefined_root, + const std::wstring& key_path, + const std::wstring& value_name, + int64 value_data, + bool overwrite); + // Add a SelfRegWorkItem that registers or unregisters a DLL at the // specified path. If user_level_registration is true, then alternate // registration and unregistration entry point names will be used. |