summaryrefslogtreecommitdiffstats
path: root/chrome/installer/setup/install.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/installer/setup/install.cc')
-rw-r--r--chrome/installer/setup/install.cc827
1 files changed, 434 insertions, 393 deletions
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
index 8aefcf3..3817aa1 100644
--- a/chrome/installer/setup/install.cc
+++ b/chrome/installer/setup/install.cc
@@ -22,6 +22,8 @@
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/master_preferences_constants.h"
+#include "chrome/installer/util/package.h"
+#include "chrome/installer/util/product.h"
#include "chrome/installer/util/set_reg_value_work_item.h"
#include "chrome/installer/util/shell_util.h"
#include "chrome/installer/util/util_constants.h"
@@ -33,12 +35,10 @@
namespace {
-std::wstring AppendPath(const std::wstring& parent_path,
- const std::wstring& path) {
- std::wstring new_path(parent_path);
- file_util::AppendToPath(&new_path, path);
- return new_path;
-}
+using installer::Products;
+using installer::Product;
+using installer::Package;
+using installer::Version;
void AddChromeToMediaPlayerList() {
std::wstring reg_path(installer::kMediaPlayerRegPath);
@@ -53,87 +53,95 @@ void AddChromeToMediaPlayerList() {
LOG(ERROR) << "Could not add Chrome to media player inclusion list.";
}
-void AddInstallerCopyTasks(const std::wstring& exe_path,
- const std::wstring& archive_path,
- const std::wstring& temp_path,
- const std::wstring& install_path,
- const std::wstring& new_version,
+void AddInstallerCopyTasks(const FilePath& setup_path,
+ const FilePath& archive_path,
+ const FilePath& temp_path,
+ const Version& new_version,
WorkItemList* install_list,
- bool system_level) {
- std::wstring installer_dir(installer::GetInstallerPathUnderChrome(
- install_path, new_version));
- install_list->AddCreateDirWorkItem(
- FilePath::FromWStringHack(installer_dir));
-
- std::wstring exe_dst(installer_dir);
- std::wstring archive_dst(installer_dir);
- file_util::AppendToPath(&exe_dst,
- file_util::GetFilenameFromPath(exe_path));
- file_util::AppendToPath(&archive_dst,
- file_util::GetFilenameFromPath(archive_path));
-
- install_list->AddCopyTreeWorkItem(exe_path, exe_dst, temp_path,
- WorkItem::ALWAYS);
- if (system_level) {
- install_list->AddCopyTreeWorkItem(archive_path, archive_dst, temp_path,
- WorkItem::ALWAYS);
+ const Package& package) {
+ DCHECK(install_list);
+ FilePath installer_dir(package.GetInstallerDirectory(new_version));
+ install_list->AddCreateDirWorkItem(installer_dir);
+
+ FilePath exe_dst(installer_dir.Append(setup_path.BaseName()));
+ FilePath archive_dst(installer_dir.Append(archive_path.BaseName()));
+
+ install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(),
+ temp_path.value(), WorkItem::ALWAYS);
+ if (package.system_level()) {
+ install_list->AddCopyTreeWorkItem(archive_path.value(), archive_dst.value(),
+ temp_path.value(), WorkItem::ALWAYS);
} else {
- install_list->AddMoveTreeWorkItem(archive_path, archive_dst, temp_path);
+ install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(),
+ temp_path.value());
}
}
void AppendUninstallCommandLineFlags(CommandLine* uninstall_cmd,
- bool is_system) {
+ const Product& product) {
DCHECK(uninstall_cmd);
+
uninstall_cmd->AppendSwitch(installer_util::switches::kUninstall);
- // TODO(tommi): In case of multiple installations, we need to create multiple
- // uninstall entries, and not one magic one for all.
const installer_util::MasterPreferences& prefs =
InstallUtil::GetMasterPreferencesForCurrentProcess();
- DCHECK(!prefs.is_multi_install());
- if (prefs.install_chrome_frame()) {
+ bool cf_switch_added = false;
+
+ if (prefs.is_multi_install()) {
+ uninstall_cmd->AppendSwitch(installer_util::switches::kMultiInstall);
+ switch (product.distribution()->GetType()) {
+ case BrowserDistribution::CHROME_BROWSER:
+ uninstall_cmd->AppendSwitch(installer_util::switches::kChrome);
+ break;
+ case BrowserDistribution::CHROME_FRAME:
+ uninstall_cmd->AppendSwitch(installer_util::switches::kChromeFrame);
+ cf_switch_added = true;
+ break;
+ case BrowserDistribution::CEEE:
+ uninstall_cmd->AppendSwitch(installer_util::switches::kCeee);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ if (product.distribution()->GetType() == BrowserDistribution::CHROME_FRAME) {
+ DCHECK(prefs.install_chrome_frame());
uninstall_cmd->AppendSwitch(installer_util::switches::kDeleteProfile);
- uninstall_cmd->AppendSwitch(installer_util::switches::kChromeFrame);
+ if (!cf_switch_added) {
+ uninstall_cmd->AppendSwitch(installer_util::switches::kChromeFrame);
+ }
}
- if (InstallUtil::IsChromeSxSProcess()) {
+ if (InstallUtil::IsChromeSxSProcess())
uninstall_cmd->AppendSwitch(installer_util::switches::kChromeSxS);
- }
- if (InstallUtil::IsMSIProcess(is_system)) {
+ if (product.IsMsi())
uninstall_cmd->AppendSwitch(installer_util::switches::kMsi);
- }
// Propagate the verbose logging switch to uninstalls too.
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(installer_util::switches::kVerboseLogging)) {
+ bool value = false;
+ if (prefs.GetBool(installer_util::master_preferences::kVerboseLogging,
+ &value) && value)
uninstall_cmd->AppendSwitch(installer_util::switches::kVerboseLogging);
- }
- if (is_system) {
+ if (product.system_level())
uninstall_cmd->AppendSwitch(installer_util::switches::kSystemLevel);
- }
}
// 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(HKEY reg_root,
- const std::wstring& exe_path,
- const std::wstring& install_path,
- const std::wstring& product_name,
- const std::wstring& new_version,
- WorkItemList* install_list) {
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-
- // TODO(tommi): Support this for multi-install. We need to add work items
- // for each product being installed.
- const installer_util::MasterPreferences& prefs =
- InstallUtil::GetMasterPreferencesForCurrentProcess();
- DCHECK(!prefs.is_multi_install()) << "TODO";
+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
@@ -141,16 +149,15 @@ void AddUninstallShortcutWorkItems(HKEY reg_root,
// 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 installer_path(installer::GetInstallerPathUnderChrome(install_path,
- new_version));
- installer_path = installer_path.Append(
- file_util::GetFilenameFromPath(exe_path));
+ 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,
- reg_root == HKEY_LOCAL_MACHINE);
+ AppendUninstallCommandLineFlags(&uninstall_arguments, product);
- std::wstring update_state_key = dist->GetStateKey();
+ 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_util::kUninstallStringField, installer_path.value(), true);
@@ -159,31 +166,32 @@ void AddUninstallShortcutWorkItems(HKEY reg_root,
uninstall_arguments.command_line_string(), true);
// MSI installations will manage their own uninstall shortcuts.
- if (!InstallUtil::IsMSIProcess(reg_root == HKEY_LOCAL_MACHINE)) {
+ if (!product.IsMsi()) {
// 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 = dist->GetUninstallRegPath();
+ std::wstring uninstall_reg = browser_dist->GetUninstallRegPath();
install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg);
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
- installer_util::kUninstallDisplayNameField, product_name, true);
+ installer_util::kUninstallDisplayNameField,
+ browser_dist->GetAppShortCutName(), true);
install_list->AddSetRegValueWorkItem(reg_root,
uninstall_reg, installer_util::kUninstallStringField,
quoted_uninstall_cmd.command_line_string(), true);
install_list->AddSetRegValueWorkItem(reg_root,
uninstall_reg,
L"InstallLocation",
- install_path,
+ install_path.value(),
true);
// DisplayIcon, NoModify and NoRepair
- std::wstring chrome_icon = AppendPath(install_path,
- installer_util::kChromeExe);
- ShellUtil::GetChromeIcon(chrome_icon);
+ FilePath chrome_icon(install_path.Append(installer_util::kChromeExe));
+ ShellUtil::GetChromeIcon(product.distribution(), chrome_icon.value());
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
- L"DisplayIcon", chrome_icon, true);
+ L"DisplayIcon", chrome_icon.value(),
+ true);
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
L"NoModify", 1, true);
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
@@ -191,12 +199,14 @@ void AddUninstallShortcutWorkItems(HKEY reg_root,
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
L"Publisher",
- dist->GetPublisherName(), true);
+ browser_dist->GetPublisherName(),
+ true);
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
- L"Version", new_version.c_str(), true);
+ L"Version", new_version.GetString(),
+ true);
install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
L"DisplayVersion",
- new_version.c_str(), true);
+ new_version.GetString(), true);
time_t rawtime = time(NULL);
struct tm timeinfo = {0};
localtime_s(&timeinfo, &rawtime);
@@ -214,31 +224,31 @@ void AddUninstallShortcutWorkItems(HKEY reg_root,
// 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 DeleteUninstallShortcutsForMSI(bool is_system_install) {
- DCHECK(InstallUtil::IsMSIProcess(is_system_install))
- << "This must only be called for MSI installations!";
+void DeleteUninstallShortcutsForMSI(const Product& product) {
+ 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 = is_system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+ HKEY reg_root = product.system_level() ? HKEY_LOCAL_MACHINE :
+ HKEY_CURRENT_USER;
base::win::RegKey root_key(reg_root, L"", KEY_ALL_ACCESS);
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- std::wstring uninstall_reg = dist->GetUninstallRegPath();
+ std::wstring uninstall_reg(product.distribution()->GetUninstallRegPath());
InstallUtil::DeleteRegistryKey(root_key, uninstall_reg);
// Then attempt to delete the old installation's start menu shortcut.
FilePath uninstall_link;
- if (is_system_install) {
+ 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 {
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- uninstall_link = uninstall_link.Append(dist->GetAppShortCutName());
uninstall_link = uninstall_link.Append(
- dist->GetUninstallLinkName() + L".lnk");
+ product.distribution()->GetAppShortCutName());
+ uninstall_link = uninstall_link.Append(
+ product.distribution()->GetUninstallLinkName() + L".lnk");
VLOG(1) << "Deleting old uninstall shortcut (if present): "
<< uninstall_link.value();
if (!file_util::Delete(uninstall_link, true))
@@ -249,15 +259,14 @@ void DeleteUninstallShortcutsForMSI(bool is_system_install) {
// 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(bool system_level,
- const std::wstring& prefs_source_path) {
- FilePath prefs_dest_path = FilePath::FromWStringHack(
- installer::GetChromeInstallPath(system_level));
- prefs_dest_path = prefs_dest_path.AppendASCII(
- installer_util::kDefaultMasterPrefs);
- if (!file_util::CopyFile(FilePath::FromWStringHack(prefs_source_path),
- prefs_dest_path))
- VLOG(1) << "Failed to copy master preferences.";
+void CopyPreferenceFileForFirstRun(const Package& package,
+ const FilePath& prefs_source_path) {
+ FilePath prefs_dest_path(package.path().AppendASCII(
+ installer_util::kDefaultMasterPrefs));
+ if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) {
+ VLOG(1) << "Failed to copy master preferences from:"
+ << prefs_source_path.value() << " gle: " << ::GetLastError();
+ }
}
// This method creates Chrome shortcuts in Start->Programs for all users or
@@ -274,25 +283,32 @@ void CopyPreferenceFileForFirstRun(bool system_level,
//
// If the shortcuts do not exist, the function does not recreate them during
// update.
-bool CreateOrUpdateChromeShortcuts(const std::wstring& exe_path,
- const std::wstring& install_path,
- const std::wstring& new_version,
+bool CreateOrUpdateChromeShortcuts(const FilePath& setup_path,
+ const Version& new_version,
installer_util::InstallStatus install_status,
- bool system_install,
+ const Product& product,
bool create_all_shortcut,
bool alt_shortcut) {
+ // TODO(tommi): Change this function to use WorkItemList.
+#ifndef NDEBUG
+ const installer_util::MasterPreferences& prefs =
+ InstallUtil::GetMasterPreferencesForCurrentProcess();
+ DCHECK(prefs.install_chrome());
+#endif
+
FilePath shortcut_path;
- int dir_enum = (system_install) ? base::DIR_COMMON_START_MENU :
- base::DIR_START_MENU;
+ int dir_enum = product.system_level() ? base::DIR_COMMON_START_MENU :
+ base::DIR_START_MENU;
if (!PathService::Get(dir_enum, &shortcut_path)) {
LOG(ERROR) << "Failed to get location for shortcut.";
return false;
}
+ BrowserDistribution* browser_dist = product.distribution();
+
// The location of Start->Programs->Google Chrome folder
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- const std::wstring& product_name = dist->GetAppShortCutName();
- const std::wstring& product_desc = dist->GetAppDescription();
+ const std::wstring product_name(browser_dist->GetAppShortCutName());
+ const std::wstring product_desc(browser_dist->GetAppDescription());
shortcut_path = shortcut_path.Append(product_name);
// Create/update Chrome link (points to chrome.exe) & Uninstall Chrome link
@@ -305,151 +321,191 @@ bool CreateOrUpdateChromeShortcuts(const std::wstring& exe_path,
bool ret = true;
FilePath chrome_link(shortcut_path); // Chrome link (launches Chrome)
chrome_link = chrome_link.Append(product_name + L".lnk");
- std::wstring chrome_exe(install_path); // Chrome link target
- file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe);
+ // Chrome link target
+ FilePath chrome_exe(
+ product.package().path().Append(installer_util::kChromeExe));
if ((install_status == installer_util::FIRST_INSTALL_SUCCESS) ||
(install_status == installer_util::INSTALL_REPAIRED)) {
if (!file_util::PathExists(shortcut_path))
file_util::CreateDirectoryW(shortcut_path);
- VLOG(1) << "Creating shortcut to " << chrome_exe << " at "
+ VLOG(1) << "Creating shortcut to " << chrome_exe.value() << " at "
<< chrome_link.value();
- ret = ret && ShellUtil::UpdateChromeShortcut(chrome_exe,
- chrome_link.value(),
- product_desc, true);
+ ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(),
+ chrome_link.value(), product_desc, true);
} else if (file_util::PathExists(chrome_link)) {
VLOG(1) << "Updating shortcut at " << chrome_link.value()
- << " to point to " << chrome_exe;
- ret = ret && ShellUtil::UpdateChromeShortcut(chrome_exe,
- chrome_link.value(),
- product_desc, false);
+ << " to point to " << chrome_exe.value();
+ ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(),
+ chrome_link.value(), product_desc, false);
+ } else {
+ VLOG(1)
+ << "not first or repaired install, link file doesn't exist. status: "
+ << install_status;
}
// Create/update uninstall link if we are not an MSI install. MSI
// 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 (!InstallUtil::IsMSIProcess(system_install)) {
+ if (ret && !product.IsMsi()) {
FilePath uninstall_link(shortcut_path); // Uninstall Chrome link
uninstall_link = uninstall_link.Append(
- dist->GetUninstallLinkName() + L".lnk");
+ browser_dist->GetUninstallLinkName() + L".lnk");
if ((install_status == installer_util::FIRST_INSTALL_SUCCESS) ||
(install_status == installer_util::INSTALL_REPAIRED) ||
(file_util::PathExists(uninstall_link))) {
if (!file_util::PathExists(shortcut_path))
- file_util::CreateDirectoryW(shortcut_path);
- std::wstring setup_exe(installer::GetInstallerPathUnderChrome(
- install_path, new_version));
- file_util::AppendToPath(&setup_exe,
- file_util::GetFilenameFromPath(exe_path));
-
- CommandLine arguments(CommandLine::NO_PROGRAM);
- AppendUninstallCommandLineFlags(&arguments, system_install);
- VLOG(1) << "Creating/updating uninstall link at "
- << uninstall_link.value();
- ret = ret && file_util::CreateShortcutLink(setup_exe.c_str(),
- uninstall_link.value().c_str(),
- NULL,
- arguments.command_line_string().c_str(),
- NULL,
- setup_exe.c_str(),
- 0,
- NULL);
+ file_util::CreateDirectory(shortcut_path);
+
+ FilePath setup_exe(
+ product.package().GetInstallerDirectory(new_version)
+ .Append(setup_path.BaseName()));
+
+ CommandLine arguments(CommandLine::NO_PROGRAM);
+ AppendUninstallCommandLineFlags(&arguments, product);
+ VLOG(1) << "Creating/updating uninstall link at "
+ << uninstall_link.value();
+ ret = file_util::CreateShortcutLink(setup_exe.value().c_str(),
+ uninstall_link.value().c_str(),
+ NULL,
+ arguments.command_line_string().c_str(),
+ NULL,
+ setup_exe.value().c_str(),
+ 0,
+ NULL);
}
}
// Update Desktop and Quick Launch shortcuts. If --create-new-shortcuts
// is specified we want to create them, otherwise we update them only if
// they exist.
- if (system_install) {
- ret = ret && ShellUtil::CreateChromeDesktopShortcut(chrome_exe,
- product_desc, ShellUtil::SYSTEM_LEVEL, alt_shortcut,
- create_all_shortcut);
- ret = ret && ShellUtil::CreateChromeQuickLaunchShortcut(chrome_exe,
- ShellUtil::CURRENT_USER | ShellUtil::SYSTEM_LEVEL, create_all_shortcut);
- } else {
- ret = ret && ShellUtil::CreateChromeDesktopShortcut(chrome_exe,
- product_desc, ShellUtil::CURRENT_USER, alt_shortcut,
- create_all_shortcut);
- ret = ret && ShellUtil::CreateChromeQuickLaunchShortcut(chrome_exe,
- ShellUtil::CURRENT_USER, create_all_shortcut);
+ if (ret) {
+ if (product.system_level()) {
+ ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(),
+ chrome_exe.value(), product_desc, ShellUtil::SYSTEM_LEVEL,
+ alt_shortcut, create_all_shortcut);
+ if (ret) {
+ ret = ShellUtil::CreateChromeQuickLaunchShortcut(
+ product.distribution(), chrome_exe.value(),
+ ShellUtil::CURRENT_USER | ShellUtil::SYSTEM_LEVEL,
+ create_all_shortcut);
+ }
+ } else {
+ ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(),
+ chrome_exe.value(), product_desc, ShellUtil::CURRENT_USER,
+ alt_shortcut, create_all_shortcut);
+ if (ret) {
+ ret = ShellUtil::CreateChromeQuickLaunchShortcut(
+ product.distribution(), chrome_exe.value(), ShellUtil::CURRENT_USER,
+ create_all_shortcut);
+ }
+ }
}
return ret;
}
+bool RegisterComDlls(const Package& install,
+ const Version* current_version,
+ const Version& new_version) {
+ // TODO(tommi): setup.exe should always have at least one DLL to register.
+ // Currently we rely on scan_server_dlls.py to populate the array for us,
+ // but we might as well use an explicit static array of required components.
+ if (kNumDllsToRegister <= 0) {
+ NOTREACHED() << "no dlls to register";
+ return false;
+ }
+
+ // Unregister DLLs that were left from the old version that is being upgraded.
+ if (current_version) {
+ FilePath old_dll_path(install.path().Append(current_version->GetString()));
+ // Ignore failures to unregister old DLLs.
+ installer::RegisterComDllList(old_dll_path, install.system_level(), false,
+ false);
+ }
+
+ FilePath dll_path(install.path().Append(new_version.GetString()));
+ return installer::RegisterComDllList(dll_path, install.system_level(), true,
+ true);
+}
+
// 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" key or deleting it if
-// not required.
+// - 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 DoPostInstallTasks(HKEY reg_root,
- const std::wstring& exe_path,
- const std::wstring& install_path,
- const std::wstring& new_chrome_exe,
- const std::wstring& current_version,
- const installer::Version& new_version) {
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- std::wstring version_key = dist->GetVersionKey();
-
- bool is_system_install = (reg_root == HKEY_LOCAL_MACHINE);
- const installer_util::MasterPreferences& prefs =
- InstallUtil::GetMasterPreferencesForCurrentProcess();
-
- if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe))) {
+bool DoPostInstallTasks(const FilePath& setup_path,
+ const FilePath& new_chrome_exe,
+ const Version* current_version,
+ const Version& new_version,
+ const Package& package) {
+ HKEY root = package.system_level() ? HKEY_LOCAL_MACHINE :
+ HKEY_CURRENT_USER;
+ const Products& products = package.products();
+
+ if (file_util::PathExists(new_chrome_exe)) {
// Looks like this was in use update. So make sure we update the 'opv' key
// with the current version that is active and 'cmd' key with the rename
// command to run.
- if (current_version.empty()) {
- LOG(ERROR) << "New chrome.exe exists but current version is empty!";
+ if (!current_version) {
+ LOG(ERROR) << "New chrome.exe exists but current version is NULL!";
return false;
}
- scoped_ptr<WorkItemList> inuse_list(WorkItem::CreateWorkItemList());
- inuse_list->AddSetRegValueWorkItem(reg_root,
- version_key,
- google_update::kRegOldVersionField,
- current_version.c_str(),
- true);
- FilePath installer_path(installer::GetInstallerPathUnderChrome(install_path,
- new_version.GetString()));
- installer_path = installer_path.Append(
- file_util::GetFilenameFromPath(exe_path));
- CommandLine rename_cmd(installer_path);
- rename_cmd.AppendSwitch(installer_util::switches::kRenameChromeExe);
- if (is_system_install)
- rename_cmd.AppendSwitch(installer_util::switches::kSystemLevel);
+ scoped_ptr<WorkItemList> inuse_list(WorkItem::CreateWorkItemList());
+ FilePath installer_path(package.GetInstallerDirectory(new_version)
+ .Append(setup_path.BaseName()));
- if (prefs.install_chrome_frame())
- rename_cmd.AppendSwitch(installer_util::switches::kChromeFrame);
+ CommandLine rename(installer_path);
+ rename.AppendSwitch(installer_util::switches::kRenameChromeExe);
+ if (package.system_level())
+ rename.AppendSwitch(installer_util::switches::kSystemLevel);
if (InstallUtil::IsChromeSxSProcess())
- rename_cmd.AppendSwitch(installer_util::switches::kChromeSxS);
+ rename.AppendSwitch(installer_util::switches::kChromeSxS);
+
+ for (size_t i = 0; i < products.size(); ++i) {
+ BrowserDistribution* dist = products[i]->distribution();
+ std::wstring version_key(dist->GetVersionKey());
+ inuse_list->AddSetRegValueWorkItem(root, version_key,
+ google_update::kRegOldVersionField,
+ current_version->GetString(), true);
+
+ // Adding this registry entry for all products is overkill.
+ // However, as it stands, we don't have a way to know which distribution
+ // will check the key and run the command, so we add it for all.
+ // After the first run, the subsequent runs should just be noops.
+ // (see Upgrade::SwapNewChromeExeIfPresent).
+ inuse_list->AddSetRegValueWorkItem(root, version_key,
+ google_update::kRegRenameCmdField,
+ rename.command_line_string(), true);
+ }
- inuse_list->AddSetRegValueWorkItem(reg_root,
- version_key,
- google_update::kRegRenameCmdField,
- rename_cmd.command_line_string(),
- true);
if (!inuse_list->Do()) {
LOG(ERROR) << "Couldn't write opv/cmd values to registry.";
inuse_list->Rollback();
return false;
}
} else {
- // Since this was not in-use-update, delete 'opv' and 'cmd' keys.
+ // Since this was not an in-use-update, delete 'opv' and 'cmd' keys.
scoped_ptr<WorkItemList> inuse_list(WorkItem::CreateWorkItemList());
- inuse_list->AddDeleteRegValueWorkItem(reg_root, version_key,
- google_update::kRegOldVersionField,
- true);
- inuse_list->AddDeleteRegValueWorkItem(reg_root, version_key,
- google_update::kRegRenameCmdField,
- true);
+ for (size_t i = 0; i < products.size(); ++i) {
+ BrowserDistribution* dist = products[i]->distribution();
+ std::wstring version_key(dist->GetVersionKey());
+ inuse_list->AddDeleteRegValueWorkItem(root, version_key,
+ google_update::kRegOldVersionField,
+ true);
+ inuse_list->AddDeleteRegValueWorkItem(root, version_key,
+ google_update::kRegRenameCmdField,
+ true);
+ }
+
if (!inuse_list->Do()) {
LOG(ERROR) << "Couldn't delete opv/cmd values from registry.";
inuse_list->Rollback();
@@ -457,55 +513,27 @@ bool DoPostInstallTasks(HKEY reg_root,
}
}
- if (prefs.install_chrome_frame()) {
- // TODO(tommi): setup.exe should always have at least one DLL to
- // register. Currently we rely on scan_server_dlls.py to populate
- // the array for us, but we might as well use an explicit static
- // array of required components.
- if (kNumDllsToRegister <= 0) {
- NOTREACHED() << "no dlls to register";
- return false;
- }
-
- // any that were left from the old version that is being upgraded:
- if (!current_version.empty()) {
- std::wstring old_dll_path(install_path);
- file_util::AppendToPath(&old_dll_path, current_version);
- scoped_ptr<WorkItemList> old_dll_list(WorkItem::CreateWorkItemList());
- if (InstallUtil::BuildDLLRegistrationList(old_dll_path, kDllsToRegister,
- kNumDllsToRegister, false,
- !is_system_install,
- old_dll_list.get())) {
- // Don't abort the install as a result of a failure to unregister old
- // DLLs.
- old_dll_list->Do();
- }
- }
-
- std::wstring dll_path(install_path);
- file_util::AppendToPath(&dll_path, new_version.GetString());
- scoped_ptr<WorkItemList> dll_list(WorkItem::CreateWorkItemList());
- if (InstallUtil::BuildDLLRegistrationList(dll_path, kDllsToRegister,
- kNumDllsToRegister, true,
- !is_system_install,
- dll_list.get())) {
- if (!dll_list->Do()) {
- dll_list->Rollback();
- return false;
- }
- }
+ if (FindProduct(products, BrowserDistribution::CHROME_FRAME) ||
+ FindProduct(products, BrowserDistribution::CEEE)) {
+ // TODO(robershield): move the "which DLLs should be registered" policy
+ // into the installer.
+ RegisterComDlls(package, current_version, new_version);
}
// If we're told that we're an MSI install, make sure to set the marker
// in the client state key so that future updates do the right thing.
- if (InstallUtil::IsMSIProcess(is_system_install)) {
- if (!InstallUtil::SetMSIMarker(is_system_install, true))
- return false;
+ for (size_t i = 0; i < products.size(); ++i) {
+ const Product* product = products[i];
+ if (product->IsMsi()) {
+ if (!product->SetMsiMarker(true))
+ return false;
- // We want MSI installs to take over the Add/Remove Programs shortcut. Make
- // a best-effort attempt to delete any shortcuts left over from previous
- // non-MSI installations for the same type of install (system or per user).
- DeleteUninstallShortcutsForMSI(is_system_install);
+ // We want MSI installs to take over the Add/Remove Programs shortcut.
+ // Make a best-effort attempt to delete any shortcuts left over from
+ // previous non-MSI installations for the same type of install (system or
+ // per user).
+ DeleteUninstallShortcutsForMSI(*product);
+ }
}
return true;
@@ -529,9 +557,11 @@ bool Is64bit() {
return false;
}
-void RegisterChromeOnMachine(const std::wstring& install_path,
- bool system_level,
+void RegisterChromeOnMachine(const Product& product,
bool make_chrome_default) {
+ DCHECK_EQ(product.distribution()->GetType(),
+ BrowserDistribution::CHROME_BROWSER);
+
// Try to add Chrome to Media Player shim inclusion list. We don't do any
// error checking here because this operation will fail if user doesn't
// have admin rights and we want to ignore the error.
@@ -539,246 +569,229 @@ void RegisterChromeOnMachine(const std::wstring& install_path,
// Is --make-chrome-default option is given we make Chrome default browser
// otherwise we only register it on the machine as a valid browser.
- std::wstring chrome_exe(install_path);
- file_util::AppendToPath(&chrome_exe, installer_util::kChromeExe);
- VLOG(1) << "Registering Chrome as browser";
+ FilePath chrome_exe(
+ product.package().path().Append(installer_util::kChromeExe));
+ VLOG(1) << "Registering Chrome as browser: " << chrome_exe.value();
if (make_chrome_default) {
int level = ShellUtil::CURRENT_USER;
- if (system_level)
+ if (product.system_level())
level = level | ShellUtil::SYSTEM_LEVEL;
- ShellUtil::MakeChromeDefault(level, chrome_exe, true);
+ ShellUtil::MakeChromeDefault(product.distribution(), level,
+ chrome_exe.value(), true);
} else {
- ShellUtil::RegisterChromeBrowser(chrome_exe, L"", false);
+ ShellUtil::RegisterChromeBrowser(product.distribution(), chrome_exe.value(),
+ L"", false);
}
}
// This function installs a new version of Chrome to the specified location.
//
-// exe_path: Path to the executable (setup.exe) as it will be copied
+// setup_path: Path to the executable (setup.exe) as it will be copied
// to Chrome install folder after install is complete
// archive_path: Path to the archive (chrome.7z) as it will be copied
// to Chrome install folder after install is complete
// src_path: the path that contains a complete and unpacked Chrome package
// to be installed.
-// install_path: the destination path for Chrome to be installed to. This
-// path does not need to exist.
// temp_dir: the path of working directory used during installation. This path
// does not need to exist.
-// reg_root: the root of registry where the function applies settings for the
-// new Chrome version. It should be either HKLM or HKCU.
// new_version: new Chrome version that needs to be installed
-// current_version: returns the current active version (if any)
+// oldest_installed_version: returns the oldest active version (if any)
//
// This function makes best effort to do installation in a transactional
// manner. If failed it tries to rollback all changes on the file system
-// and registry. For example, if install_path exists before calling the
+// and registry. For example, if package exists before calling the
// function, it rolls back all new file and directory changes under
-// install_path. If install_path does not exist before calling the function
-// (typical new install), the function creates install_path during install
+// package. If package does not exist before calling the function
+// (typical new install), the function creates package during install
// and removes the whole directory during rollback.
installer_util::InstallStatus InstallNewVersion(
- const std::wstring& exe_path,
- const std::wstring& archive_path,
- const std::wstring& src_path,
- const std::wstring& install_path,
- const std::wstring& temp_dir,
- const HKEY reg_root,
- const installer::Version& new_version,
- std::wstring* current_version) {
- if (reg_root != HKEY_LOCAL_MACHINE && reg_root != HKEY_CURRENT_USER)
- return installer_util::INSTALL_FAILED;
-
- if (InstallUtil::IsChromeFrameProcess()) {
+ 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) {
+ DCHECK(current_version);
+
+ const Products& products = package.products();
+ DCHECK(products.size());
+
+ if (FindProduct(products, BrowserDistribution::CHROME_FRAME)) {
// Make sure that we don't end up deleting installed files on next reboot.
- if (!RemoveFromMovesPendingReboot(install_path.c_str())) {
+ if (!RemoveFromMovesPendingReboot(package.path().value().c_str())) {
LOG(ERROR) << "Error accessing pending moves value.";
}
}
+ // TODO(tommi): See if we can't get rid of this parameter.
+ current_version->reset(package.GetCurrentVersion());
+
scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList());
// A temp directory that work items need and the actual install directory.
- install_list->AddCreateDirWorkItem(FilePath::FromWStringHack(temp_dir));
- install_list->AddCreateDirWorkItem(FilePath::FromWStringHack(install_path));
+ install_list->AddCreateDirWorkItem(temp_dir);
+ install_list->AddCreateDirWorkItem(package.path());
// Delete any new_chrome.exe if present (we will end up creating a new one
// if required) and then copy chrome.exe
- std::wstring new_chrome_exe = AppendPath(install_path,
- installer_util::kChromeNewExe);
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- base::win::RegKey chrome_key(reg_root, dist->GetVersionKey().c_str(),
- KEY_READ);
- if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe)))
- chrome_key.ReadValue(google_update::kRegOldVersionField, current_version);
-
- if (current_version->empty())
- chrome_key.ReadValue(google_update::kRegVersionField, current_version);
-
- chrome_key.Close();
+ FilePath new_chrome_exe(
+ package.path().Append(installer_util::kChromeNewExe));
- install_list->AddDeleteTreeWorkItem(new_chrome_exe, std::wstring());
+ install_list->AddDeleteTreeWorkItem(new_chrome_exe.value(), std::wstring());
install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, installer_util::kChromeExe),
- AppendPath(install_path, installer_util::kChromeExe),
- temp_dir, WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe);
+ src_path.Append(installer_util::kChromeExe).value(),
+ package.path().Append(installer_util::kChromeExe).value(),
+ temp_dir.value(), WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe.value());
// Extra executable for 64 bit systems.
if (Is64bit()) {
install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, installer::kWowHelperExe),
- AppendPath(install_path, installer::kWowHelperExe),
- temp_dir, WorkItem::ALWAYS);
+ src_path.Append(installer::kWowHelperExe).value(),
+ package.path().Append(installer::kWowHelperExe).value(),
+ temp_dir.value(), WorkItem::ALWAYS);
}
// If it is system level install copy the version folder (since we want to
// take the permissions of %ProgramFiles% folder) otherwise just move it.
- if (reg_root == HKEY_LOCAL_MACHINE) {
+ if (package.system_level()) {
install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, new_version.GetString()),
- AppendPath(install_path, new_version.GetString()),
- temp_dir, WorkItem::ALWAYS);
+ src_path.Append(new_version.GetString()).value(),
+ package.path().Append(new_version.GetString()).value(),
+ temp_dir.value(), WorkItem::ALWAYS);
} else {
install_list->AddMoveTreeWorkItem(
- AppendPath(src_path, new_version.GetString()),
- AppendPath(install_path, new_version.GetString()),
- temp_dir);
+ src_path.Append(new_version.GetString()).value(),
+ package.path().Append(new_version.GetString()).value(),
+ temp_dir.value());
}
- // Copy the default Dictionaries only if the folder doesnt exist already
+ // Copy the default Dictionaries only if the folder doesn't exist already.
install_list->AddCopyTreeWorkItem(
- AppendPath(src_path, installer::kDictionaries),
- AppendPath(install_path, installer::kDictionaries),
- temp_dir, WorkItem::IF_NOT_PRESENT);
-
- // Copy installer in install directory and
- // add shortcut in Control Panel->Add/Remove Programs.
- AddInstallerCopyTasks(exe_path, archive_path, temp_dir, install_path,
- new_version.GetString(), install_list.get(),
- (reg_root == HKEY_LOCAL_MACHINE));
- std::wstring product_name = dist->GetAppShortCutName();
-
- AddUninstallShortcutWorkItems(reg_root, exe_path, install_path,
- product_name, new_version.GetString(), install_list.get());
+ src_path.Append(installer::kDictionaries).value(),
+ package.path().Append(installer::kDictionaries).value(),
+ temp_dir.value(), WorkItem::IF_NOT_PRESENT);
// Delete any old_chrome.exe if present.
install_list->AddDeleteTreeWorkItem(
- AppendPath(install_path, installer_util::kChromeOldExe), std::wstring());
-
- // Create Version key (if not already present) and set the new Chrome
- // version as last step.
- std::wstring version_key = dist->GetVersionKey();
- install_list->AddCreateRegKeyWorkItem(reg_root, version_key);
- install_list->AddSetRegValueWorkItem(reg_root, version_key,
- google_update::kRegNameField,
- product_name,
- true); // overwrite name also
- install_list->AddSetRegValueWorkItem(reg_root, version_key,
- google_update::kRegOopcrashesField,
- 1,
- false); // set during first install
- install_list->AddSetRegValueWorkItem(reg_root, version_key,
- google_update::kRegVersionField,
- new_version.GetString(),
- true); // overwrite version
+ package.path().Append(installer_util::kChromeOldExe).value(),
+ std::wstring());
+
+ // Copy installer in install directory and
+ // add shortcut in Control Panel->Add/Remove Programs.
+ AddInstallerCopyTasks(setup_path, archive_path, temp_dir, new_version,
+ install_list.get(), package);
+
+ for (size_t i = 0; i < products.size(); ++i) {
+ const Product* product = products[i];
+
+ AddUninstallShortcutWorkItems(setup_path, new_version, install_list.get(),
+ *product);
+
+ // Create Version key for each distribution (if not already present) and set
+ // the new product version as the last step.
+ HKEY root = product->system_level() ? HKEY_LOCAL_MACHINE :
+ HKEY_CURRENT_USER;
+ std::wstring version_key(product->distribution()->GetVersionKey());
+ install_list->AddCreateRegKeyWorkItem(root, version_key);
+
+ std::wstring product_name(product->distribution()->GetAppShortCutName());
+ install_list->AddSetRegValueWorkItem(root, version_key,
+ google_update::kRegNameField,
+ product_name,
+ true); // overwrite name also
+ install_list->AddSetRegValueWorkItem(root, version_key,
+ google_update::kRegOopcrashesField,
+ 1,
+ false); // set during first install
+ install_list->AddSetRegValueWorkItem(root, version_key,
+ google_update::kRegVersionField,
+ new_version.GetString(),
+ true); // overwrite version
+ }
if (!install_list->Do() ||
- !DoPostInstallTasks(reg_root, exe_path, install_path,
- new_chrome_exe, *current_version, new_version)) {
+ !DoPostInstallTasks(setup_path, new_chrome_exe, current_version->get(),
+ new_version, package)) {
installer_util::InstallStatus result =
- (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe)) &&
- !current_version->empty() &&
- (new_version.GetString() == *current_version)) ?
+ file_util::PathExists(new_chrome_exe) && current_version->get() &&
+ new_version.IsEqual(*current_version->get()) ?
installer_util::SAME_VERSION_REPAIR_FAILED :
installer_util::INSTALL_FAILED;
- LOG(ERROR) << "Install failed, rolling back... ";
+ LOG(ERROR) << "Install failed, rolling back... result: " << result;
install_list->Rollback();
LOG(ERROR) << "Rollback complete. ";
return result;
}
- scoped_ptr<installer::Version> installed_version;
- if (!current_version->empty())
- installed_version.reset(
- installer::Version::GetVersionFromString(*current_version));
- if (!installed_version.get()) {
+
+ if (!current_version->get()) {
VLOG(1) << "First install of version " << new_version.GetString();
return installer_util::FIRST_INSTALL_SUCCESS;
}
- if (new_version.GetString() == installed_version->GetString()) {
+
+ if (new_version.IsEqual(*current_version->get())) {
VLOG(1) << "Install repaired of version " << new_version.GetString();
return installer_util::INSTALL_REPAIRED;
}
- if (new_version.IsHigherThan(installed_version.get())) {
- if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe))) {
+
+ if (new_version.IsHigherThan(current_version->get())) {
+ if (file_util::PathExists(new_chrome_exe)) {
VLOG(1) << "Version updated to " << new_version.GetString()
- << " while running " << installed_version->GetString();
+ << " while running " << (*current_version)->GetString();
return installer_util::IN_USE_UPDATED;
}
VLOG(1) << "Version updated to " << new_version.GetString();
return installer_util::NEW_VERSION_UPDATED;
}
+
LOG(ERROR) << "Not sure how we got here while updating"
<< ", new version: " << new_version.GetString()
- << ", old version: " << installed_version->GetString();
+ << ", old version: " << (*current_version)->GetString();
+
return installer_util::INSTALL_FAILED;
}
-} // namespace
+} // end namespace
-std::wstring installer::GetInstallerPathUnderChrome(
- const std::wstring& install_path, const std::wstring& new_version) {
- std::wstring installer_path(install_path);
- file_util::AppendToPath(&installer_path, new_version);
- file_util::AppendToPath(&installer_path, installer_util::kInstallerDir);
- return installer_path;
-}
+namespace installer {
-installer_util::InstallStatus installer::InstallOrUpdateChrome(
- const std::wstring& exe_path, const std::wstring& archive_path,
- const std::wstring& install_temp_path, const std::wstring& prefs_path,
+installer_util::InstallStatus InstallOrUpdateChrome(
+ const FilePath& setup_path, const FilePath& archive_path,
+ const FilePath& install_temp_path, const FilePath& prefs_path,
const installer_util::MasterPreferences& prefs, const Version& new_version,
- const Version* installed_version) {
- bool system_install = false;
- prefs.GetBool(installer_util::master_preferences::kSystemLevel,
- &system_install);
- std::wstring install_path(GetChromeInstallPath(system_install));
- if (install_path.empty()) {
- LOG(ERROR) << "Could not get installation destination path.";
- return installer_util::INSTALL_FAILED;
- }
- VLOG(1) << "install destination path: " << install_path;
+ const Package& install) {
+ bool system_install = install.system_level();
- std::wstring src_path(install_temp_path);
- file_util::AppendToPath(&src_path, std::wstring(kInstallSourceDir));
- file_util::AppendToPath(&src_path, std::wstring(kInstallSourceChromeDir));
+ FilePath src_path(install_temp_path);
+ src_path = src_path.Append(kInstallSourceDir).Append(kInstallSourceChromeDir);
- HKEY reg_root = (system_install) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
- std::wstring current_version;
- installer_util::InstallStatus result = InstallNewVersion(exe_path,
- archive_path, src_path, install_path, install_temp_path, reg_root,
- new_version, &current_version);
+ scoped_ptr<Version> existing_version;
+ installer_util::InstallStatus result = InstallNewVersion(setup_path,
+ archive_path, src_path, install_temp_path, new_version,
+ &existing_version, install);
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- if (!dist->GetInstallReturnCode(result)) {
+ if (!BrowserDistribution::GetInstallReturnCode(result)) {
if (result == installer_util::FIRST_INSTALL_SUCCESS)
- CopyPreferenceFileForFirstRun(system_install, prefs_path);
-
- bool value = false;
- // TODO(tommi): Currently this only creates shortcuts for Chrome, but
- // for other products we might want to create shortcuts.
- if (prefs.install_chrome() &&
- (!prefs.GetBool(
- installer_util::master_preferences::kDoNotCreateShortcuts,
- &value) || !value)) {
+ CopyPreferenceFileForFirstRun(install, prefs_path);
+
+ bool do_not_create_shortcuts = false;
+ prefs.GetBool(installer_util::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);
+ if (chrome_install && !do_not_create_shortcuts) {
bool create_all_shortcut = false;
prefs.GetBool(installer_util::master_preferences::kCreateAllShortcuts,
&create_all_shortcut);
bool alt_shortcut = false;
prefs.GetBool(installer_util::master_preferences::kAltShortcutText,
&alt_shortcut);
- if (!CreateOrUpdateChromeShortcuts(exe_path, install_path,
- new_version.GetString(), result,
- system_install, create_all_shortcut,
+ if (!CreateOrUpdateChromeShortcuts(setup_path, new_version, result,
+ *chrome_install, create_all_shortcut,
alt_shortcut)) {
- LOG(WARNING) << "Failed to create/update start menu shortcut.";
+ PLOG(WARNING) << "Failed to create/update start menu shortcut.";
}
bool make_chrome_default = false;
@@ -797,15 +810,43 @@ installer_util::InstallStatus installer::InstallOrUpdateChrome(
&force_chrome_default_for_user);
}
- RegisterChromeOnMachine(install_path, system_install,
+ RegisterChromeOnMachine(*chrome_install,
make_chrome_default || force_chrome_default_for_user);
}
- std::wstring latest_version_to_keep(new_version.GetString());
- if (!current_version.empty())
- latest_version_to_keep.assign(current_version);
- RemoveOldVersionDirs(install_path, latest_version_to_keep);
+ install.RemoveOldVersionDirectories(existing_version.get() ?
+ *existing_version.get() : new_version);
}
return result;
}
+
+bool RegisterComDllList(const FilePath& dll_folder, bool system_level,
+ bool do_register, bool rollback_on_failure) {
+ bool success = false;
+ scoped_ptr<WorkItemList> work_item_list;
+ if (rollback_on_failure) {
+ work_item_list.reset(WorkItem::CreateWorkItemList());
+ } else {
+ work_item_list.reset(WorkItem::CreateNoRollbackWorkItemList());
+ }
+
+ // TODO(robertshield): What if the list of old dlls and new ones isn't
+ // the same? I (elmo) think we should start storing the list of DLLs
+ // somewhere.
+ if (InstallUtil::BuildDLLRegistrationList(dll_folder.value(), kDllsToRegister,
+ kNumDllsToRegister, do_register,
+ !system_level,
+ work_item_list.get())) {
+ // Ignore failures to unregister old DLLs.
+ success = work_item_list->Do();
+ if (!success && rollback_on_failure) {
+ work_item_list->Rollback();
+ }
+ }
+
+ return success;
+}
+
+} // namespace installer
+