15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/installer_state.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <functional> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/delete_tree_work_item.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/helper.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/install_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/installation_state.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/master_preferences.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/master_preferences_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/product.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/work_item.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/work_item_list.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace installer { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles)bool InstallerState::IsMultiInstallUpdate( 34d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) const MasterPreferences& prefs, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) { 36d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) // First, are the binaries present? 37d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) const ProductState* binaries = 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES); 40d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) if (binaries == NULL) { 41d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) // The multi-install binaries have not been installed, so they certainly 42d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) // aren't being updated. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) if (prefs.install_chrome()) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* product = 48d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, 49d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) BrowserDistribution::CHROME_BROWSER); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product == NULL) { 51d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) VLOG(2) << "It seems that chrome is being installed for the first time."; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 54d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) if (!product->channel().Equals(binaries->channel())) { 55d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) VLOG(2) << "It seems that chrome is being over installed."; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) VLOG(2) << "It seems that the binaries are being updated."; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstallerState::InstallerState() 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : operation_(UNINITIALIZED), 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_type_(BrowserDistribution::CHROME_BROWSER), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_(NULL), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_(UNKNOWN_LEVEL), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_(UNKNOWN_PACKAGE_TYPE), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_(NULL), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_(false), 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verbose_logging_(false), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ensure_google_update_present_(false) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstallerState::InstallerState(Level level) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : operation_(UNINITIALIZED), 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_type_(BrowserDistribution::CHROME_BROWSER), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_(NULL), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_(UNKNOWN_LEVEL), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_(UNKNOWN_PACKAGE_TYPE), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_(NULL), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_(false), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verbose_logging_(false), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ensure_google_update_present_(false) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use set_level() so that root_key_ is updated properly. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_level(level); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::Initialize(const CommandLine& command_line, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MasterPreferences& prefs, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) { 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Clear(); 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pref_bool; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kSystemLevel, &pref_bool)) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_bool = false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_level(pref_bool ? SYSTEM_LEVEL : USER_LEVEL); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kVerboseLogging, &verbose_logging_)) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verbose_logging_ = false; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kMultiInstall, &pref_bool)) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_bool = false; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_package_type(pref_bool ? MULTI_PACKAGE : SINGLE_PACKAGE); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kMsi, &msi_)) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_ = false; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ensure_google_update_present_ = 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(installer::switches::kEnsureGoogleUpdatePresent); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool is_uninstall = command_line.HasSwitch(switches::kUninstall); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome()) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BROWSER, prefs, machine_state); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prefs.install_chrome_app_launcher()) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_APP_HOST, prefs, machine_state); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_uninstall && is_multi_install()) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool need_binaries = false; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_APP_HOST)) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App Host will happily use Chrome at system level, or binaries at system 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // level, even if app host is user level. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* chrome_state = machine_state.GetProductState( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system level 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BROWSER); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If Chrome is at system-level, multi- or otherwise. We'll use it. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!chrome_state) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* binaries_state = machine_state.GetProductState( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system level 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!binaries_state) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_binaries = true; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) // Chrome multi needs Binaries at its own level. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_BROWSER)) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_binaries = true; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (need_binaries && !FindProduct(BrowserDistribution::CHROME_BINARIES)) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force binaries to be installed/updated. 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BINARIES, prefs, machine_state); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Install distribution: " 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << p->distribution()->GetDisplayName(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_uninstall && prefs.is_multi_install()) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_BROWSER)) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Uninstall each product of type |type| listed below based on the 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // presence or absence of |switch_name| in that product's uninstall 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // command. 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const struct { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::Type type; 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* switch_name; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool switch_expected; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } conditional_additions[] = { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the App Host is installed, but not the App Launcher, remove it 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // with Chrome. Note however that for system-level Chrome uninstalls, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // any installed user-level App Host will remain even if there is no 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // App Launcher present (the orphaned app_host.exe will prompt the user 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for further action when executed). 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { BrowserDistribution::CHROME_APP_HOST, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kChromeAppLauncher, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false }, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(conditional_additions); ++i) { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ProductState* product_state = machine_state.GetProductState( 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_install(), conditional_additions[i].type); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (product_state != NULL && 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) product_state->uninstall_command().HasSwitch( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) conditional_additions[i].switch_name) == 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) conditional_additions[i].switch_expected && 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !FindProduct(conditional_additions[i].type)) { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) conditional_additions[i].type, prefs, machine_state); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Uninstall distribution: " 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << p->distribution()->GetDisplayName(); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool keep_binaries = false; 198bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Look for a multi-install product that is not the binaries and that is not 199bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // being uninstalled. If not found, binaries are uninstalled too. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type type = 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<BrowserDistribution::Type>(i); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == BrowserDistribution::CHROME_BINARIES) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 207bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const ProductState* product_state = 208bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch machine_state.GetProductState(system_install(), type); 209bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (product_state == NULL) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is not installed. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 214bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!product_state->is_multi_install() && 215bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch type != BrowserDistribution::CHROME_BROWSER) { 216bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // The product is not sharing the binaries. It is ordinarily impossible 217bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // for single-install Chrome to be installed along with any 218bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // multi-install product. Treat single-install Chrome the same as any 219bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // multi-install product just in case the impossible happens. 220bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch continue; 221bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 222bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is installed. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FindProduct(type)) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is not being uninstalled. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type != BrowserDistribution::CHROME_APP_HOST) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keep_binaries = true; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If binaries/chrome are at system-level, we can discard them at 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user-level... 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!machine_state.GetProductState( 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system-level 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BROWSER) && 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !machine_state.GetProductState( 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system-level 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES)) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... otherwise keep them. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keep_binaries = true; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is being uninstalled. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!keep_binaries && 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) machine_state.GetProductState(system_install(), 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BINARIES)) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BINARIES, prefs, machine_state); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution* operand = NULL; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_uninstall) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = UNINSTALL; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!prefs.is_multi_install()) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For a single-install, the current browser dist is the operand. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand = BrowserDistribution::GetDistribution(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = SINGLE_INSTALL_OR_UPDATE; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (IsMultiInstallUpdate(prefs, machine_state)) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Updates driven by Google Update take place under the multi-installer's 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // app guid. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand = multi_package_distribution_; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = MULTI_UPDATE; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = MULTI_INSTALL; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 276d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) // Initial, over, and un-installs will take place under one of the product app 277d8f2b4b00825da44f52b775a415bc945dcd54811Torne (Richard Coles) // guids (Chrome, App Host, or Binaries, in order of preference). 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (operand == NULL) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type operand_distribution_type = 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome()) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type = BrowserDistribution::CHROME_BROWSER; 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (prefs.install_chrome_app_launcher()) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type = BrowserDistribution::CHROME_APP_HOST; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand = BrowserDistribution::GetSpecificDistribution( 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_key_ = operand->GetStateKey(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_type_ = operand->GetType(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse --critical-update-version=W.X.Y.Z 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string critical_version_value( 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) critical_update_version_ = Version(critical_version_value); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::set_level(Level level) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_ = level; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (level) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case USER_LEVEL: 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_ = HKEY_CURRENT_USER; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SYSTEM_LEVEL: 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_ = HKEY_LOCAL_MACHINE; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(level == UNKNOWN_LEVEL); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_ = UNKNOWN_LEVEL; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_ = NULL; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::set_package_type(PackageType type) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_ = type; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SINGLE_PACKAGE: 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_ = NULL; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MULTI_PACKAGE: 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_ = 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::GetSpecificDistribution( 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == UNKNOWN_PACKAGE_TYPE); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_ = UNKNOWN_PACKAGE_TYPE; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_ = NULL; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the Chrome binaries directory for multi-install or |dist|'s directory 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// otherwise. 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath InstallerState::GetDefaultProductInstallPath( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution* dist) const { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dist); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(package_type_ != UNKNOWN_PACKAGE_TYPE); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package_type_ == SINGLE_PACKAGE) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetChromeInstallPath(system_install(), dist); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetChromeInstallPath(system_install(), 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::GetSpecificDistribution( 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Evaluates a product's eligibility for participation in this operation. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We never expect these checks to fail, hence they all terminate the process in 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// debug builds. See the log messages for details. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::CanAddProduct(const Product& product, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath* product_dir) const { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (package_type_) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SINGLE_PACKAGE: 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!products_.empty()) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process more than one single-install product."; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MULTI_PACKAGE: 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!product.HasOption(kOptionMultiInstall)) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process a single-install product with a " 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "multi-install state."; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(product.distribution()->GetType()) != NULL) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process more than one product of the same type."; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!target_path_.empty()) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath default_dir; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_dir == NULL) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_dir = GetDefaultProductInstallPath(product.distribution()); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::FilePath::CompareEqualIgnoreCase( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (product_dir == NULL ? default_dir : *product_dir).value(), 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path_.value())) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process products in different directories."; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(UNKNOWN_PACKAGE_TYPE, package_type_); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds |product|, installed in |product_dir| to this object's collection. If 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |product_dir| is NULL, the product's default install location is used. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns NULL if |product| is incompatible with this object. Otherwise, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returns a pointer to the product (ownership is held by this object). 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Product* InstallerState::AddProductInDirectory( 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath* product_dir, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Product>* product) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(product != NULL); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(product->get() != NULL); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Product& the_product = *product->get(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CanAddProduct(the_product, product_dir)) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package_type_ == UNKNOWN_PACKAGE_TYPE) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_package_type(the_product.HasOption(kOptionMultiInstall) ? 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MULTI_PACKAGE : SINGLE_PACKAGE); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_path_.empty()) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_dir == NULL) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path_ = GetDefaultProductInstallPath(the_product.distribution()); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path_ = *product_dir; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_key_.empty()) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_key_ = the_product.distribution()->GetStateKey(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) products_.push_back(product->release()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return products_[products_.size() - 1]; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product* InstallerState::AddProduct(scoped_ptr<Product>* product) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddProductInDirectory(NULL, product); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a product of type |distribution_type| constructed on the basis of 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |prefs|, setting this object's msi flag if the product is represented in 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |machine_state| and is msi-installed. Returns the product that was added, 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or NULL if |state| is incompatible with this object. Ownership is not passed 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the caller. 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product* InstallerState::AddProductFromPreferences( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type distribution_type, 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MasterPreferences& prefs, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Product> product_ptr( 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new Product(BrowserDistribution::GetSpecificDistribution( 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) distribution_type))); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_ptr->InitializeFromPreferences(prefs); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Product* product = AddProductInDirectory(NULL, &product_ptr); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product != NULL && !msi_) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* product_state = machine_state.GetProductState( 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_install(), distribution_type); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_state != NULL) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_ = product_state->is_msi(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return product; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product* InstallerState::AddProductFromState( 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type type, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState& state) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Product> product_ptr( 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new Product(BrowserDistribution::GetSpecificDistribution(type))); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_ptr->InitializeFromUninstallCommand(state.uninstall_command()); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strip off <version>/Installer/setup.exe; see GetInstallerDirectory(). 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath product_dir = 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state.GetSetupPath().DirName().DirName().DirName(); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Product* product = AddProductInDirectory(&product_dir, &product_ptr); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product != NULL) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_ |= state.is_msi(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return product; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::system_install() const { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(level_ == USER_LEVEL || level_ == SYSTEM_LEVEL); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return level_ == SYSTEM_LEVEL; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::is_multi_install() const { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(package_type_ == SINGLE_PACKAGE || package_type_ == MULTI_PACKAGE); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return package_type_ != SINGLE_PACKAGE; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::RemoveProduct(const Product* product) { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<Product>::iterator it = 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(products_.begin(), products_.end(), product); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != products_.end()) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) products_.weak_erase(it); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Product* InstallerState::FindProduct( 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type distribution_type) const { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products_.begin(), end = products_.end(); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scan != end; ++scan) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*scan)->is_type(distribution_type)) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *scan; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Version* InstallerState::GetCurrentVersion( 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) const { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!products_.empty()); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Version> current_version; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're doing a multi-install, the current version may be either an 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // existing multi or an existing single product that is being migrated 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in place (i.e., Chrome). In the latter case, there is no existing 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CHROME_BINARIES installation so we need to search for the product. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type prod_type; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package_type_ == MULTI_PACKAGE) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type = BrowserDistribution::CHROME_BINARIES; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type) == NULL) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for a product on which we're operating that is installed in our 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target directory. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Products::const_iterator end = products().end(); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products().begin(); scan != end; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++scan) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type product_type = 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*scan)->distribution()->GetType(); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* state = 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, product_type); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state != NULL && target_path_.IsParent(state->GetSetupPath())) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type = product_type; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type = products_[0]->distribution()->GetType(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* product_state = 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_state != NULL) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version* version = NULL; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Be aware that there might be a pending "new_chrome.exe" already in the 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installation path. If so, we use old_version, which holds the version of 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "chrome.exe" itself. 5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (base::PathExists(target_path().Append(kChromeNewExe))) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = product_state->old_version(); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version == NULL) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = &product_state->version(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_version.reset(new Version(*version)); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_version.release(); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Version InstallerState::DetermineCriticalVersion( 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version* current_version, 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version& new_version) const { 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(current_version == NULL || current_version->IsValid()); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_version.IsValid()); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (critical_update_version_.IsValid() && 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (current_version == NULL || 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (current_version->CompareTo(critical_update_version_) < 0)) && 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_version.CompareTo(critical_update_version_) >= 0) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return critical_update_version_; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Version(); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::IsChromeFrameRunning( 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) const { 5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AnyExistsAndIsInUse(machine_state, CHROME_FRAME_DLL); 5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool InstallerState::AreBinariesInUse( 5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const InstallationState& machine_state) const { 5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AnyExistsAndIsInUse( 5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) machine_state, 579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (CHROME_FRAME_HELPER_EXE | CHROME_FRAME_HELPER_DLL | 580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHROME_FRAME_DLL | CHROME_DLL)); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath InstallerState::GetInstallerDirectory( 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Version& version) const { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_path().Append(ASCIIToWide(version.GetString())) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(kInstallerDir); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool InstallerState::IsFileInUse(const base::FilePath& file) { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call CreateFile with a share mode of 0 which should cause this to fail 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with ERROR_SHARING_VIOLATION if the file exists and is in-use. 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !base::win::ScopedHandle(CreateFile(file.value().c_str(), 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GENERIC_WRITE, 0, NULL, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPEN_EXISTING, 0, 0)).IsValid(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 598a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void InstallerState::Clear() { 599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) operation_ = UNINITIALIZED; 600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) target_path_.clear(); 601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_key_.clear(); 602a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_type_ = BrowserDistribution::CHROME_BROWSER; 603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) products_.clear(); 604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) multi_package_distribution_ = NULL; 605a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) critical_update_version_ = base::Version(); 606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) level_ = UNKNOWN_LEVEL; 607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) package_type_ = UNKNOWN_PACKAGE_TYPE; 608a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) root_key_ = NULL; 609a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) msi_ = false; 610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) verbose_logging_ = false; 611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ensure_google_update_present_ = false; 612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool InstallerState::AnyExistsAndIsInUse( 6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const InstallationState& machine_state, 6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 file_bits) const { 6174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const wchar_t* const kBinaryFileNames[] = { 618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kChromeDll, 6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kChromeFrameDll, 620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kChromeFrameHelperDll, 6214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kChromeFrameHelperExe, 6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_NE(file_bits, 0U); 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_LT(file_bits, 1U << NUM_BINARIES); 625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_DLL == 1, no_youre_out_of_order); 626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_FRAME_DLL == 2, no_youre_out_of_order); 627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_FRAME_HELPER_DLL == 4, no_youre_out_of_order); 628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_FRAME_HELPER_EXE == 8, no_youre_out_of_order); 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check only for the current version (i.e., the version we are upgrading 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // _from_). Later versions from pending in-use updates need not be checked 6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // since the current version is guaranteed to be in use if any such are. 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool in_use = false; 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<Version> current_version(GetCurrentVersion(machine_state)); 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!current_version) 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::FilePath directory( 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) target_path().AppendASCII(current_version->GetString())); 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < NUM_BINARIES; ++i) { 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!(file_bits & (1U << i))) 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::FilePath file(directory.Append(kBinaryFileNames[i])); 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (base::PathExists(file) && IsFileInUse(file)) 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::GetExistingExeVersions( 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>* existing_versions) const { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const wchar_t* const kChromeFilenames[] = { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::kChromeExe, 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::kChromeNewExe, 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::kChromeOldExe, 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < arraysize(kChromeFilenames); ++i) { 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath chrome_exe(target_path().Append(kChromeFilenames[i])); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FileVersionInfo> file_version_info( 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileVersionInfo::CreateFileVersionInfo(chrome_exe)); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_version_info) { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 version_string = file_version_info->file_version(); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!version_string.empty() && IsStringASCII(version_string)) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_versions->insert(WideToASCII(version_string)); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::RemoveOldVersionDirectories( 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version& new_version, 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version* existing_version, 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& temp_path) const { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version version; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WorkItem> item; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string> existing_version_strings; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_version_strings.insert(new_version.GetString()); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_version) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_version_strings.insert(existing_version->GetString()); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure not to delete any version dir that is "referenced" by an existing 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome executable. 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetExistingExeVersions(&existing_version_strings); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to delete all directories that are not in the set we care to keep. 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator version_enum(target_path(), false, 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator::DIRECTORIES); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::FilePath next_version = version_enum.Next(); !next_version.empty(); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_version = version_enum.Next()) { 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath dir_name(next_version.BaseName()); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = Version(WideToASCII(dir_name.value())); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the version folder if it is less than the new version and not 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // equal to the old version (if we have an old version). 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version.IsValid() && 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_version_strings.count(version.GetString()) == 0) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: temporarily log old version deletion at ERROR level to make it 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more likely we see this in the installer log. 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Deleting old version directory: " << next_version.value(); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt to recursively delete the old version dir. 7027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool delete_succeeded = base::DeleteFile(next_version, true); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: temporarily log old version deletion at ERROR level to make it 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more likely we see this in the installer log. 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(ERROR, !delete_succeeded) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Failed to delete old version directory: " << next_version.value(); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallerState::AddComDllList( 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath>* com_dll_list) const { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::for_each(products_.begin(), products_.end(), 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::bind2nd(std::mem_fun(&Product::AddComDllList), 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) com_dll_list)); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::SetChannelFlags(bool set, 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelInfo* channel_info) const { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool modified = false; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products_.begin(), end = products_.end(); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scan != end; ++scan) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified |= (*scan)->SetChannelFlags(set, channel_info); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::UpdateStage(installer::InstallerStage stage) const { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallUtil::UpdateInstallerStage(system_install(), state_key_, stage); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::UpdateChannels() const { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (operation_ != MULTI_INSTALL && operation_ != MULTI_UPDATE) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "InstallerState::UpdateChannels noop: " << operation_; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the "ap" value for the product being installed/updated. We get the 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current value from the registry since the InstallationState instance used 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the bulk of the installer does not track changes made by UpdateStage. 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the app's ClientState key if it doesn't exist. 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelInfo channel_info; 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey state_key; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LONG result = state_key.Create(root_key_, state_key_.c_str(), 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERROR_SUCCESS) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.Initialize(state_key); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a multi-install product. 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool modified = channel_info.SetMultiInstall(true); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the appropriate modifiers for all products and their options. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified |= SetChannelFlags(true, &channel_info); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "ap: " << channel_info.value(); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the results if needed. 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modified) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.Write(&state_key); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the -stage: modifier since we don't want to propagate that to the 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // other app_guids. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.SetStage(NULL); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synchronize the other products and the package with this one. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelInfo other_info; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type type = 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<BrowserDistribution::Type>(i); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip the app_guid we started with. 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == state_type_) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution* dist = NULL; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always operate on the binaries. 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == BrowserDistribution::CHROME_BINARIES) { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dist = multi_package_distribution_; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Product* product = FindProduct(type); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip this one if it's for a product we're not operating on. 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product == NULL) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dist = product->distribution(); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = state_key.Create(root_key_, dist->GetStateKey().c_str(), 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERROR_SUCCESS) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_info.Initialize(state_key); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!other_info.Equals(channel_info)) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.Write(&state_key); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed opening key " << dist->GetStateKey() 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " to update app channels; result: " << result; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed opening key " << state_key_ 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " to update app channels; result: " << result; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::WriteInstallerResult( 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallStatus status, 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int string_resource_id, 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring* const launch_cmd) const { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a no-rollback list since this is a best-effort deal. 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WorkItemList> install_list( 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkItem::CreateNoRollbackWorkItemList()); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool system_install = this->system_install(); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the value for all products upon which we're operating. 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Products::const_iterator end = products().end(); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products().begin(); scan != end; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++scan) { 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallUtil::AddInstallerResultItems( 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_install, (*scan)->distribution()->GetStateKey(), status, 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_resource_id, launch_cmd, install_list.get()); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And for the binaries if this is a multi-install. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_multi_install()) { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallUtil::AddInstallerResultItems( 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_install, multi_package_binaries_distribution()->GetStateKey(), 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status, string_resource_id, launch_cmd, install_list.get()); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!install_list->Do()) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to record installer error information in registry."; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool InstallerState::RequiresActiveSetup() const { 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace installer 833