Index: chrome/installer/setup/install.cc |
=================================================================== |
--- chrome/installer/setup/install.cc (revision 72487) |
+++ chrome/installer/setup/install.cc (working copy) |
@@ -16,13 +16,9 @@ |
#include "base/scoped_ptr.h" |
#include "base/string_util.h" |
#include "base/utf_string_conversions.h" |
-#include "base/win/registry.h" |
#include "chrome/installer/setup/setup_constants.h" |
#include "chrome/installer/setup/install_worker.h" |
#include "chrome/installer/util/browser_distribution.h" |
-#include "chrome/installer/util/channel_info.h" |
-#include "chrome/installer/util/chrome_frame_distribution.h" |
-#include "chrome/installer/util/conditional_work_item_list.h" |
#include "chrome/installer/util/create_reg_key_work_item.h" |
#include "chrome/installer/util/delete_after_reboot_helper.h" |
#include "chrome/installer/util/google_update_constants.h" |
@@ -32,8 +28,6 @@ |
#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/set_reg_value_work_item.h" |
#include "chrome/installer/util/shell_util.h" |
@@ -44,15 +38,9 @@ |
#include "installer_util_strings.h" // NOLINT |
#include "registered_dlls.h" // NOLINT |
-using base::win::RegKey; |
-using installer::ChannelInfo; |
using installer::InstallerState; |
using installer::InstallationState; |
-using installer::MasterPreferences; |
-using installer::Products; |
using installer::Product; |
-using installer::Package; |
-using installer::PackageProperties; |
namespace { |
@@ -69,14 +57,14 @@ |
LOG(ERROR) << "Could not add Chrome to media player inclusion list."; |
} |
-void AddInstallerCopyTasks(const FilePath& setup_path, |
+void AddInstallerCopyTasks(const InstallerState& installer_state, |
+ const FilePath& setup_path, |
const FilePath& archive_path, |
const FilePath& temp_path, |
const Version& new_version, |
- WorkItemList* install_list, |
- const Package& package) { |
+ WorkItemList* install_list) { |
DCHECK(install_list); |
- FilePath installer_dir(package.GetInstallerDirectory(new_version)); |
+ FilePath installer_dir(installer_state.GetInstallerDirectory(new_version)); |
install_list->AddCreateDirWorkItem(installer_dir); |
FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); |
@@ -84,7 +72,7 @@ |
install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), |
temp_path.value(), WorkItem::ALWAYS); |
- if (package.system_level()) { |
+ if (installer_state.system_install()) { |
install_list->AddCopyTreeWorkItem(archive_path.value(), archive_dst.value(), |
temp_path.value(), WorkItem::ALWAYS); |
} else { |
@@ -93,139 +81,12 @@ |
} |
} |
-// 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. |
-// In the multi-install case, this value is used as the basis upon which the |
-// package's channel value is built (by adding the ordered list of installed |
-// products and their options). |
-void AddGoogleUpdateWorkItems(const InstallationState& original_state, |
- const InstallerState& installer_state, |
- const Package& package, |
- WorkItemList* install_list) { |
- // Is a multi-install product being installed or over-installed? |
- if (installer_state.operation() != InstallerState::MULTI_INSTALL) |
- return; |
- |
- const HKEY reg_root = package.system_level() ? HKEY_LOCAL_MACHINE : |
- HKEY_CURRENT_USER; |
- const std::wstring key_path = installer_state.state_key(); |
- ChannelInfo channel_info; |
- |
- // Update the "ap" value for the product being installed/updated. |
- // It is completely acceptable for there to be no "ap" value or even no |
- // ClientState key. Note that we check the registry rather than |
- // original_state since on a fresh install the "ap" value will be present |
- // sans "pv" value. |
- channel_info.Initialize(RegKey(reg_root, key_path.c_str(), KEY_QUERY_VALUE)); |
- |
- // This is a multi-install product. |
- bool modified = channel_info.SetMultiInstall(true); |
- |
- // Add the appropriate modifiers for all products and their options. |
- Products::const_iterator scan = package.products().begin(); |
- const Products::const_iterator end = package.products().end(); |
- for (; scan != end; ++scan) { |
- modified |= scan->get()->distribution()->SetChannelFlags(true, |
- &channel_info); |
- } |
- |
- // Write the results if needed. |
- if (modified) { |
- install_list->AddSetRegValueWorkItem(reg_root, key_path, |
- google_update::kRegApField, |
- channel_info.value(), true); |
- } |
- |
- // Synchronize the other products and the package with this one. |
- std::wstring other_key; |
- std::vector<std::wstring> keys; |
- |
- keys.reserve(package.products().size()); |
- other_key = package.properties()->GetStateKey(); |
- if (other_key != key_path) |
- keys.push_back(other_key); |
- scan = package.products().begin(); |
- for (; scan != end; ++scan) { |
- other_key = scan->get()->distribution()->GetStateKey(); |
- if (other_key != key_path) |
- keys.push_back(other_key); |
- } |
- |
- RegKey key; |
- ChannelInfo other_info; |
- std::vector<std::wstring>::const_iterator kscan = keys.begin(); |
- std::vector<std::wstring>::const_iterator kend = keys.end(); |
- for (; kscan != kend; ++kscan) { |
- // Handle the case where the ClientState key doesn't exist by creating it. |
- // This takes care of the multi-installer's package key, which is not |
- // created by Google Update for us. |
- if (key.Open(reg_root, kscan->c_str(), KEY_QUERY_VALUE) != ERROR_SUCCESS || |
- !other_info.Initialize(key)) { |
- other_info.set_value(std::wstring()); |
- } |
- if (!other_info.Equals(channel_info)) { |
- if (!key.Valid()) |
- install_list->AddCreateRegKeyWorkItem(reg_root, *kscan); |
- install_list->AddSetRegValueWorkItem(reg_root, *kscan, |
- google_update::kRegApField, |
- channel_info.value(), true); |
- } |
- } |
- // TODO(grt): check for other keys/values we should put in the package's |
- // ClientState and/or Clients key. |
-} |
- |
-// This is called when an MSI installation is run. It may be that a user is |
-// attempting to install the MSI on top of a non-MSI managed installation. |
-// If so, try and remove any existing uninstallation shortcuts, as we want the |
-// uninstall to be managed entirely by the MSI machinery (accessible via the |
-// Add/Remove programs dialog). |
-void AddDeleteUninstallShortcutsForMSIWorkItems(const Product& product, |
- WorkItemList* work_item_list) { |
- DCHECK(product.IsMsi()) << "This must only be called for MSI installations!"; |
- |
- // First attempt to delete the old installation's ARP dialog entry. |
- HKEY reg_root = product.system_level() ? HKEY_LOCAL_MACHINE : |
- HKEY_CURRENT_USER; |
- base::win::RegKey root_key(reg_root, L"", KEY_ALL_ACCESS); |
- std::wstring uninstall_reg(product.distribution()->GetUninstallRegPath()); |
- |
- WorkItem* delete_reg_key = work_item_list->AddDeleteRegKeyWorkItem( |
- reg_root, uninstall_reg); |
- delete_reg_key->set_ignore_failure(true); |
- |
- // Then attempt to delete the old installation's start menu shortcut. |
- FilePath uninstall_link; |
- if (product.system_level()) { |
- PathService::Get(base::DIR_COMMON_START_MENU, &uninstall_link); |
- } else { |
- PathService::Get(base::DIR_START_MENU, &uninstall_link); |
- } |
- |
- if (uninstall_link.empty()) { |
- LOG(ERROR) << "Failed to get location for shortcut."; |
- } else { |
- uninstall_link = uninstall_link.Append( |
- product.distribution()->GetAppShortCutName()); |
- uninstall_link = uninstall_link.Append( |
- product.distribution()->GetUninstallLinkName() + L".lnk"); |
- VLOG(1) << "Deleting old uninstall shortcut (if present): " |
- << uninstall_link.value(); |
- WorkItem* delete_link = work_item_list->AddDeleteTreeWorkItem( |
- uninstall_link); |
- delete_link->set_ignore_failure(true); |
- delete_link->set_log_message( |
- "Failed to delete old uninstall shortcut."); |
- } |
-} |
- |
// Copy master preferences file provided to installer, in the same folder |
// as chrome.exe so Chrome first run can find it. This function will be called |
// only on the first install of Chrome. |
-void CopyPreferenceFileForFirstRun(const Package& package, |
+void CopyPreferenceFileForFirstRun(const InstallerState& installer_state, |
const FilePath& prefs_source_path) { |
- FilePath prefs_dest_path(package.path().AppendASCII( |
+ FilePath prefs_dest_path(installer_state.target_path().AppendASCII( |
installer::kDefaultMasterPrefs)); |
if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) { |
VLOG(1) << "Failed to copy master preferences from:" |
@@ -247,7 +108,8 @@ |
// |
// If the shortcuts do not exist, the function does not recreate them during |
// update. |
-bool CreateOrUpdateChromeShortcuts(const FilePath& setup_path, |
+bool CreateOrUpdateChromeShortcuts(const InstallerState& installer_state, |
+ const FilePath& setup_path, |
const Version& new_version, |
installer::InstallStatus install_status, |
const Product& product, |
@@ -257,7 +119,7 @@ |
DCHECK(product.is_chrome()); |
FilePath shortcut_path; |
- int dir_enum = product.system_level() ? |
+ int dir_enum = installer_state.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."; |
@@ -283,7 +145,7 @@ |
chrome_link = chrome_link.Append(product_name + L".lnk"); |
// Chrome link target |
FilePath chrome_exe( |
- product.package().path().Append(installer::kChromeExe)); |
+ installer_state.target_path().Append(installer::kChromeExe)); |
if ((install_status == installer::FIRST_INSTALL_SUCCESS) || |
(install_status == installer::INSTALL_REPAIRED)) { |
@@ -309,7 +171,7 @@ |
// installations are, for the time being, managed only through the |
// Add/Remove Programs dialog. |
// TODO(robertshield): We could add a shortcut to msiexec /X {GUID} here. |
- if (ret && !product.IsMsi()) { |
+ if (ret && !installer_state.is_msi()) { |
FilePath uninstall_link(shortcut_path); // Uninstall Chrome link |
uninstall_link = uninstall_link.Append( |
browser_dist->GetUninstallLinkName() + L".lnk"); |
@@ -319,12 +181,11 @@ |
if (!file_util::PathExists(shortcut_path)) |
file_util::CreateDirectory(shortcut_path); |
- FilePath setup_exe( |
- product.package().GetInstallerDirectory(new_version) |
- .Append(setup_path.BaseName())); |
+ FilePath setup_exe(installer_state.GetInstallerDirectory(new_version) |
+ .Append(setup_path.BaseName())); |
CommandLine arguments(CommandLine::NO_PROGRAM); |
- AppendUninstallCommandLineFlags(&arguments, product); |
+ AppendUninstallCommandLineFlags(installer_state, product, &arguments); |
VLOG(1) << "Creating/updating uninstall link at " |
<< uninstall_link.value(); |
ret = file_util::CreateShortcutLink(setup_exe.value().c_str(), |
@@ -342,7 +203,7 @@ |
// is specified we want to create them, otherwise we update them only if |
// they exist. |
if (ret) { |
- if (product.system_level()) { |
+ if (installer_state.system_install()) { |
ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(), |
chrome_exe.value(), product_desc, ShellUtil::SYSTEM_LEVEL, |
alt_shortcut, create_all_shortcut); |
@@ -367,8 +228,8 @@ |
return ret; |
} |
- |
-void RegisterChromeOnMachine(const Product& product, |
+void RegisterChromeOnMachine(const InstallerState& installer_state, |
+ const Product& product, |
bool make_chrome_default) { |
DCHECK(product.is_chrome()); |
@@ -380,11 +241,11 @@ |
// Is --make-chrome-default option is given we make Chrome default browser |
// otherwise we only register it on the machine as a valid browser. |
FilePath chrome_exe( |
- product.package().path().Append(installer::kChromeExe)); |
+ installer_state.target_path().Append(installer::kChromeExe)); |
VLOG(1) << "Registering Chrome as browser: " << chrome_exe.value(); |
if (make_chrome_default) { |
int level = ShellUtil::CURRENT_USER; |
- if (product.system_level()) |
+ if (installer_state.system_install()) |
level = level | ShellUtil::SYSTEM_LEVEL; |
ShellUtil::MakeChromeDefault(product.distribution(), level, |
chrome_exe.value(), true); |
@@ -417,33 +278,29 @@ |
installer::InstallStatus InstallNewVersion( |
const InstallationState& original_state, |
const InstallerState& installer_state, |
- bool multi_install, |
const FilePath& setup_path, |
const FilePath& archive_path, |
const FilePath& src_path, |
const FilePath& temp_dir, |
const Version& new_version, |
- scoped_ptr<Version>* current_version, |
- const Package& package) { |
+ scoped_ptr<Version>* current_version) { |
DCHECK(current_version); |
- current_version->reset(package.GetCurrentVersion()); |
+ current_version->reset(installer_state.GetCurrentVersion(original_state)); |
scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList()); |
AddInstallWorkItems(original_state, |
installer_state, |
- multi_install, |
setup_path, |
archive_path, |
src_path, |
temp_dir, |
new_version, |
current_version, |
- package, |
install_list.get()); |
FilePath new_chrome_exe( |
- package.path().Append(installer::kChromeNewExe)); |
+ installer_state.target_path().Append(installer::kChromeNewExe)); |
if (!install_list->Do()) { |
installer::InstallStatus result = |
@@ -488,61 +345,63 @@ |
namespace installer { |
-installer::InstallStatus InstallOrUpdateProduct( |
+InstallStatus InstallOrUpdateProduct( |
const InstallationState& original_state, |
const InstallerState& installer_state, |
- const FilePath& setup_path, const FilePath& archive_path, |
- const FilePath& install_temp_path, const FilePath& prefs_path, |
- const installer::MasterPreferences& prefs, const Version& new_version, |
- const Package& install) { |
+ const FilePath& setup_path, |
+ const FilePath& archive_path, |
+ const FilePath& install_temp_path, |
+ const FilePath& prefs_path, |
+ const MasterPreferences& prefs, |
+ const Version& new_version) { |
FilePath src_path(install_temp_path); |
src_path = src_path.Append(kInstallSourceDir).Append(kInstallSourceChromeDir); |
// TODO(robertshield): Removing the pending on-reboot moves should be done |
// elsewhere. |
- const Products& products = install.products(); |
+ const Products& products = installer_state.products(); |
DCHECK(products.size()); |
- if (FindProduct(products, BrowserDistribution::CHROME_FRAME)) { |
+ if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { |
// Make sure that we don't end up deleting installed files on next reboot. |
- if (!RemoveFromMovesPendingReboot(install.path().value().c_str())) { |
+ if (!RemoveFromMovesPendingReboot( |
+ installer_state.target_path().value().c_str())) { |
LOG(ERROR) << "Error accessing pending moves value."; |
} |
} |
scoped_ptr<Version> existing_version; |
- installer::InstallStatus result = InstallNewVersion(original_state, |
- installer_state, prefs.is_multi_install(), setup_path, archive_path, |
- src_path, install_temp_path, new_version, &existing_version, install); |
+ InstallStatus result = InstallNewVersion(original_state, installer_state, |
+ setup_path, archive_path, src_path, install_temp_path, new_version, |
+ &existing_version); |
// TODO(robertshield): Everything below this line should instead be captured |
// by WorkItems. |
if (!InstallUtil::GetInstallReturnCode(result)) { |
- if (result == installer::FIRST_INSTALL_SUCCESS && !prefs_path.empty()) |
- CopyPreferenceFileForFirstRun(install, prefs_path); |
+ if (result == FIRST_INSTALL_SUCCESS && !prefs_path.empty()) |
+ CopyPreferenceFileForFirstRun(installer_state, prefs_path); |
bool do_not_create_shortcuts = false; |
- prefs.GetBool(installer::master_preferences::kDoNotCreateShortcuts, |
+ prefs.GetBool(master_preferences::kDoNotCreateShortcuts, |
&do_not_create_shortcuts); |
// Currently this only creates shortcuts for Chrome, but for other products |
// we might want to create shortcuts. |
const Product* chrome_install = |
- FindProduct(install.products(), BrowserDistribution::CHROME_BROWSER); |
+ installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); |
if (chrome_install && !do_not_create_shortcuts) { |
bool create_all_shortcut = false; |
- prefs.GetBool(installer::master_preferences::kCreateAllShortcuts, |
+ prefs.GetBool(master_preferences::kCreateAllShortcuts, |
&create_all_shortcut); |
bool alt_shortcut = false; |
- prefs.GetBool(installer::master_preferences::kAltShortcutText, |
- &alt_shortcut); |
- if (!CreateOrUpdateChromeShortcuts(setup_path, new_version, result, |
- *chrome_install, create_all_shortcut, |
- alt_shortcut)) { |
+ prefs.GetBool(master_preferences::kAltShortcutText, &alt_shortcut); |
+ if (!CreateOrUpdateChromeShortcuts(installer_state, setup_path, |
+ new_version, result, *chrome_install, |
+ create_all_shortcut, alt_shortcut)) { |
PLOG(WARNING) << "Failed to create/update start menu shortcut."; |
} |
bool make_chrome_default = false; |
- prefs.GetBool(installer::master_preferences::kMakeChromeDefault, |
+ prefs.GetBool(master_preferences::kMakeChromeDefault, |
&make_chrome_default); |
// If this is not the user's first Chrome install, but they have chosen |
@@ -550,18 +409,17 @@ |
// force it here because the master_preferences file will not get copied |
// into the build. |
bool force_chrome_default_for_user = false; |
- if (result == installer::NEW_VERSION_UPDATED || |
- result == installer::INSTALL_REPAIRED) { |
- prefs.GetBool( |
- installer::master_preferences::kMakeChromeDefaultForUser, |
- &force_chrome_default_for_user); |
+ if (result == NEW_VERSION_UPDATED || |
+ result == INSTALL_REPAIRED) { |
+ prefs.GetBool(master_preferences::kMakeChromeDefaultForUser, |
+ &force_chrome_default_for_user); |
} |
- RegisterChromeOnMachine(*chrome_install, |
+ RegisterChromeOnMachine(installer_state, *chrome_install, |
make_chrome_default || force_chrome_default_for_user); |
} |
- install.RemoveOldVersionDirectories(existing_version.get() ? |
+ installer_state.RemoveOldVersionDirectories(existing_version.get() ? |
*existing_version.get() : new_version); |
} |