installer_state.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::IsMultiInstallUpdate(const MasterPreferences& prefs, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, is the package present? 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* package = 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package == NULL) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The multi-install package has not been installed, so it certainly isn't 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // being updated. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type types[2]; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_types = 0; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome()) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types[num_types++] = BrowserDistribution::CHROME_BROWSER; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome_frame()) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) types[num_types++] = BrowserDistribution::CHROME_FRAME; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const BrowserDistribution::Type* scan = &types[0], 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *end = &types[num_types]; scan != end; ++scan) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* product = 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, *scan); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product == NULL) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "It seems that distribution type " << *scan 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " is being installed for the first time."; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!product->channel().Equals(package->channel())) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "It seems that distribution type " << *scan 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " is being over installed."; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "It seems that the package is being updated."; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstallerState::InstallerState() 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : operation_(UNINITIALIZED), 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_type_(BrowserDistribution::CHROME_BROWSER), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_(NULL), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_(UNKNOWN_LEVEL), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_(UNKNOWN_PACKAGE_TYPE), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_(NULL), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_(false), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verbose_logging_(false), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ensure_google_update_present_(false) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstallerState::InstallerState(Level level) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : operation_(UNINITIALIZED), 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_type_(BrowserDistribution::CHROME_BROWSER), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_(NULL), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_(UNKNOWN_LEVEL), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_(UNKNOWN_PACKAGE_TYPE), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_(NULL), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_(false), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verbose_logging_(false), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ensure_google_update_present_(false) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use set_level() so that root_key_ is updated properly. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_level(level); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::Initialize(const CommandLine& command_line, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MasterPreferences& prefs, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) { 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Clear(); 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pref_bool; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kSystemLevel, &pref_bool)) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_bool = false; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_level(pref_bool ? SYSTEM_LEVEL : USER_LEVEL); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kVerboseLogging, &verbose_logging_)) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) verbose_logging_ = false; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kMultiInstall, &pref_bool)) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_bool = false; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_package_type(pref_bool ? MULTI_PACKAGE : SINGLE_PACKAGE); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prefs.GetBool(master_preferences::kMsi, &msi_)) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_ = false; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ensure_google_update_present_ = 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(installer::switches::kEnsureGoogleUpdatePresent); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool is_uninstall = command_line.HasSwitch(switches::kUninstall); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome()) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BROWSER, prefs, machine_state); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome_frame()) { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_FRAME, prefs, machine_state); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prefs.install_chrome_app_launcher()) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_APP_HOST, prefs, machine_state); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_uninstall && is_multi_install()) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool need_binaries = false; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_APP_HOST)) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App Host will happily use Chrome at system level, or binaries at system 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // level, even if app host is user level. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* chrome_state = machine_state.GetProductState( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system level 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BROWSER); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If Chrome is at system-level, multi- or otherwise. We'll use it. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!chrome_state) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* binaries_state = machine_state.GetProductState( 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system level 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!binaries_state) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_binaries = true; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome/Chrome Frame multi need Binaries at their own level. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_BROWSER)) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_binaries = true; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_FRAME)) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_binaries = true; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (need_binaries && !FindProduct(BrowserDistribution::CHROME_BINARIES)) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force binaries to be installed/updated. 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BINARIES, prefs, machine_state); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Install distribution: " 1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << p->distribution()->GetDisplayName(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_uninstall && prefs.is_multi_install()) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(BrowserDistribution::CHROME_BROWSER)) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Uninstall each product of type |type| listed below based on the 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // presence or absence of |switch_name| in that product's uninstall 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // command. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const struct { 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::Type type; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* switch_name; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool switch_expected; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } conditional_additions[] = { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If Chrome Frame is installed in Ready Mode, remove it with Chrome. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { BrowserDistribution::CHROME_FRAME, 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kChromeFrameReadyMode, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true }, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the App Host is installed, but not the App Launcher, remove it 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // with Chrome. Note however that for system-level Chrome uninstalls, 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // any installed user-level App Host will remain even if there is no 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // App Launcher present (the orphaned app_host.exe will prompt the user 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for further action when executed). 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { BrowserDistribution::CHROME_APP_HOST, 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kChromeAppLauncher, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false }, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(conditional_additions); ++i) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ProductState* product_state = machine_state.GetProductState( 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) system_install(), conditional_additions[i].type); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (product_state != NULL && 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) product_state->uninstall_command().HasSwitch( 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) conditional_additions[i].switch_name) == 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) conditional_additions[i].switch_expected && 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !FindProduct(conditional_additions[i].type)) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) conditional_additions[i].type, prefs, machine_state); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Uninstall distribution: " 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << p->distribution()->GetDisplayName(); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool keep_binaries = false; 219bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Look for a multi-install product that is not the binaries and that is not 220bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // being uninstalled. If not found, binaries are uninstalled too. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type type = 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<BrowserDistribution::Type>(i); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == BrowserDistribution::CHROME_BINARIES) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 228bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const ProductState* product_state = 229bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch machine_state.GetProductState(system_install(), type); 230bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (product_state == NULL) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is not installed. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (!product_state->is_multi_install() && 236bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch type != BrowserDistribution::CHROME_BROWSER) { 237bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // The product is not sharing the binaries. It is ordinarily impossible 238bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // for single-install Chrome to be installed along with any 239bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // multi-install product. Treat single-install Chrome the same as any 240bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // multi-install product just in case the impossible happens. 241bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch continue; 242bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 243bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is installed. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FindProduct(type)) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is not being uninstalled. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type != BrowserDistribution::CHROME_APP_HOST) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keep_binaries = true; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If binaries/chrome are at system-level, we can discard them at 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user-level... 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!machine_state.GetProductState( 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system-level 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BROWSER) && 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !machine_state.GetProductState( 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // system-level 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES)) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ... otherwise keep them. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keep_binaries = true; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The product is being uninstalled. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!keep_binaries && 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) machine_state.GetProductState(system_install(), 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BINARIES)) { 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Product* p = AddProductFromPreferences( 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserDistribution::CHROME_BINARIES, prefs, machine_state); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << (is_uninstall ? "Uninstall" : "Install") 2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << " distribution: " << p->distribution()->GetDisplayName(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution* operand = NULL; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_uninstall) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = UNINSTALL; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!prefs.is_multi_install()) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For a single-install, the current browser dist is the operand. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand = BrowserDistribution::GetDistribution(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = SINGLE_INSTALL_OR_UPDATE; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (IsMultiInstallUpdate(prefs, machine_state)) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Updates driven by Google Update take place under the multi-installer's 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // app guid. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand = multi_package_distribution_; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = MULTI_UPDATE; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_ = MULTI_INSTALL; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial, over, and un-installs will take place under one of the 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // product app guids (Chrome, Chrome Frame, App Host, or Binaries, in order of 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preference). 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (operand == NULL) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type operand_distribution_type = 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefs.install_chrome()) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type = BrowserDistribution::CHROME_BROWSER; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (prefs.install_chrome_frame()) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type = BrowserDistribution::CHROME_FRAME; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (prefs.install_chrome_app_launcher()) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type = BrowserDistribution::CHROME_APP_HOST; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand = BrowserDistribution::GetSpecificDistribution( 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operand_distribution_type); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_key_ = operand->GetStateKey(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_type_ = operand->GetType(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse --critical-update-version=W.X.Y.Z 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string critical_version_value( 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) critical_update_version_ = Version(critical_version_value); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::set_level(Level level) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_ = level; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (level) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case USER_LEVEL: 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_ = HKEY_CURRENT_USER; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SYSTEM_LEVEL: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_ = HKEY_LOCAL_MACHINE; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(level == UNKNOWN_LEVEL); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_ = UNKNOWN_LEVEL; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_key_ = NULL; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::set_package_type(PackageType type) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_ = type; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SINGLE_PACKAGE: 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_ = NULL; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MULTI_PACKAGE: 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_ = 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::GetSpecificDistribution( 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == UNKNOWN_PACKAGE_TYPE); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) package_type_ = UNKNOWN_PACKAGE_TYPE; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multi_package_distribution_ = NULL; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the Chrome binaries directory for multi-install or |dist|'s directory 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// otherwise. 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath InstallerState::GetDefaultProductInstallPath( 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution* dist) const { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(dist); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(package_type_ != UNKNOWN_PACKAGE_TYPE); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package_type_ == SINGLE_PACKAGE) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetChromeInstallPath(system_install(), dist); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetChromeInstallPath(system_install(), 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::GetSpecificDistribution( 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::CHROME_BINARIES)); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Evaluates a product's eligibility for participation in this operation. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We never expect these checks to fail, hence they all terminate the process in 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// debug builds. See the log messages for details. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::CanAddProduct(const Product& product, 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath* product_dir) const { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (package_type_) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SINGLE_PACKAGE: 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!products_.empty()) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process more than one single-install product."; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MULTI_PACKAGE: 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!product.HasOption(kOptionMultiInstall)) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process a single-install product with a " 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "multi-install state."; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FindProduct(product.distribution()->GetType()) != NULL) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process more than one product of the same type."; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!target_path_.empty()) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath default_dir; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_dir == NULL) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_dir = GetDefaultProductInstallPath(product.distribution()); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!base::FilePath::CompareEqualIgnoreCase( 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (product_dir == NULL ? default_dir : *product_dir).value(), 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path_.value())) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(DFATAL) << "Cannot process products in different directories."; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(UNKNOWN_PACKAGE_TYPE, package_type_); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds |product|, installed in |product_dir| to this object's collection. If 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |product_dir| is NULL, the product's default install location is used. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns NULL if |product| is incompatible with this object. Otherwise, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returns a pointer to the product (ownership is held by this object). 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Product* InstallerState::AddProductInDirectory( 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath* product_dir, 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Product>* product) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(product != NULL); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(product->get() != NULL); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Product& the_product = *product->get(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CanAddProduct(the_product, product_dir)) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package_type_ == UNKNOWN_PACKAGE_TYPE) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_package_type(the_product.HasOption(kOptionMultiInstall) ? 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MULTI_PACKAGE : SINGLE_PACKAGE); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_path_.empty()) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_dir == NULL) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path_ = GetDefaultProductInstallPath(the_product.distribution()); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path_ = *product_dir; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_key_.empty()) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_key_ = the_product.distribution()->GetStateKey(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) products_.push_back(product->release()); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return products_[products_.size() - 1]; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product* InstallerState::AddProduct(scoped_ptr<Product>* product) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddProductInDirectory(NULL, product); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a product of type |distribution_type| constructed on the basis of 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |prefs|, setting this object's msi flag if the product is represented in 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |machine_state| and is msi-installed. Returns the product that was added, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or NULL if |state| is incompatible with this object. Ownership is not passed 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the caller. 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product* InstallerState::AddProductFromPreferences( 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type distribution_type, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MasterPreferences& prefs, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Product> product_ptr( 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new Product(BrowserDistribution::GetSpecificDistribution( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) distribution_type))); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_ptr->InitializeFromPreferences(prefs); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Product* product = AddProductInDirectory(NULL, &product_ptr); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product != NULL && !msi_) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* product_state = machine_state.GetProductState( 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_install(), distribution_type); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_state != NULL) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_ = product_state->is_msi(); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return product; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product* InstallerState::AddProductFromState( 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type type, 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState& state) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Product> product_ptr( 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new Product(BrowserDistribution::GetSpecificDistribution(type))); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) product_ptr->InitializeFromUninstallCommand(state.uninstall_command()); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strip off <version>/Installer/setup.exe; see GetInstallerDirectory(). 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath product_dir = 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state.GetSetupPath().DirName().DirName().DirName(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Product* product = AddProductInDirectory(&product_dir, &product_ptr); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product != NULL) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msi_ |= state.is_msi(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return product; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::system_install() const { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(level_ == USER_LEVEL || level_ == SYSTEM_LEVEL); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return level_ == SYSTEM_LEVEL; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::is_multi_install() const { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(package_type_ == SINGLE_PACKAGE || package_type_ == MULTI_PACKAGE); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return package_type_ != SINGLE_PACKAGE; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::RemoveProduct(const Product* product) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<Product>::iterator it = 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(products_.begin(), products_.end(), product); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != products_.end()) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) products_.weak_erase(it); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Product* InstallerState::FindProduct( 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type distribution_type) const { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products_.begin(), end = products_.end(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scan != end; ++scan) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*scan)->is_type(distribution_type)) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *scan; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Version* InstallerState::GetCurrentVersion( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) const { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!products_.empty()); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Version> current_version; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're doing a multi-install, the current version may be either an 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // existing multi or an existing single product that is being migrated 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in place (i.e., Chrome). In the latter case, there is no existing 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CHROME_BINARIES installation so we need to search for the product. 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type prod_type; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (package_type_ == MULTI_PACKAGE) { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type = BrowserDistribution::CHROME_BINARIES; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type) == NULL) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for a product on which we're operating that is installed in our 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target directory. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Products::const_iterator end = products().end(); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products().begin(); scan != end; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++scan) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type product_type = 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*scan)->distribution()->GetType(); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* state = 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, product_type); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state != NULL && target_path_.IsParent(state->GetSetupPath())) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type = product_type; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prod_type = products_[0]->distribution()->GetType(); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProductState* product_state = 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product_state != NULL) { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version* version = NULL; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Be aware that there might be a pending "new_chrome.exe" already in the 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installation path. If so, we use old_version, which holds the version of 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "chrome.exe" itself. 5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (base::PathExists(target_path().Append(kChromeNewExe))) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = product_state->old_version(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version == NULL) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = &product_state->version(); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_version.reset(new Version(*version)); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_version.release(); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Version InstallerState::DetermineCriticalVersion( 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version* current_version, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version& new_version) const { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(current_version == NULL || current_version->IsValid()); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_version.IsValid()); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (critical_update_version_.IsValid() && 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (current_version == NULL || 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (current_version->CompareTo(critical_update_version_) < 0)) && 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_version.CompareTo(critical_update_version_) >= 0) { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return critical_update_version_; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Version(); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::IsChromeFrameRunning( 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const InstallationState& machine_state) const { 5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AnyExistsAndIsInUse(machine_state, CHROME_FRAME_DLL); 5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool InstallerState::AreBinariesInUse( 6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const InstallationState& machine_state) const { 6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AnyExistsAndIsInUse( 6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) machine_state, 603a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (CHROME_FRAME_HELPER_EXE | CHROME_FRAME_HELPER_DLL | 604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHROME_FRAME_DLL | CHROME_DLL)); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath InstallerState::GetInstallerDirectory( 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Version& version) const { 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_path().Append(ASCIIToWide(version.GetString())) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Append(kInstallerDir); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool InstallerState::IsFileInUse(const base::FilePath& file) { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call CreateFile with a share mode of 0 which should cause this to fail 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with ERROR_SHARING_VIOLATION if the file exists and is in-use. 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !base::win::ScopedHandle(CreateFile(file.value().c_str(), 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GENERIC_WRITE, 0, NULL, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OPEN_EXISTING, 0, 0)).IsValid(); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void InstallerState::Clear() { 623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) operation_ = UNINITIALIZED; 624a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) target_path_.clear(); 625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_key_.clear(); 626a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state_type_ = BrowserDistribution::CHROME_BROWSER; 627a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) products_.clear(); 628a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) multi_package_distribution_ = NULL; 629a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) critical_update_version_ = base::Version(); 630a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) level_ = UNKNOWN_LEVEL; 631a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) package_type_ = UNKNOWN_PACKAGE_TYPE; 632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) root_key_ = NULL; 633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) msi_ = false; 634a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) verbose_logging_ = false; 635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ensure_google_update_present_ = false; 636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool InstallerState::AnyExistsAndIsInUse( 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const InstallationState& machine_state, 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 file_bits) const { 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const wchar_t* const kBinaryFileNames[] = { 642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kChromeDll, 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kChromeFrameDll, 644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kChromeFrameHelperDll, 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kChromeFrameHelperExe, 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_NE(file_bits, 0U); 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_LT(file_bits, 1U << NUM_BINARIES); 649a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_DLL == 1, no_youre_out_of_order); 650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_FRAME_DLL == 2, no_youre_out_of_order); 651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_FRAME_HELPER_DLL == 4, no_youre_out_of_order); 652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) COMPILE_ASSERT(CHROME_FRAME_HELPER_EXE == 8, no_youre_out_of_order); 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check only for the current version (i.e., the version we are upgrading 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // _from_). Later versions from pending in-use updates need not be checked 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // since the current version is guaranteed to be in use if any such are. 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool in_use = false; 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<Version> current_version(GetCurrentVersion(machine_state)); 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!current_version) 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::FilePath directory( 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) target_path().AppendASCII(current_version->GetString())); 6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < NUM_BINARIES; ++i) { 6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!(file_bits & (1U << i))) 6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::FilePath file(directory.Append(kBinaryFileNames[i])); 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (base::PathExists(file) && IsFileInUse(file)) 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::GetExistingExeVersions( 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>* existing_versions) const { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const wchar_t* const kChromeFilenames[] = { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::kChromeExe, 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::kChromeNewExe, 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer::kChromeOldExe, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < arraysize(kChromeFilenames); ++i) { 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath chrome_exe(target_path().Append(kChromeFilenames[i])); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FileVersionInfo> file_version_info( 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileVersionInfo::CreateFileVersionInfo(chrome_exe)); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_version_info) { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 version_string = file_version_info->file_version(); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!version_string.empty() && IsStringASCII(version_string)) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_versions->insert(WideToASCII(version_string)); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::RemoveOldVersionDirectories( 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version& new_version, 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version* existing_version, 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& temp_path) const { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Version version; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WorkItem> item; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string> existing_version_strings; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_version_strings.insert(new_version.GetString()); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_version) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_version_strings.insert(existing_version->GetString()); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure not to delete any version dir that is "referenced" by an existing 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome executable. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetExistingExeVersions(&existing_version_strings); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to delete all directories that are not in the set we care to keep. 711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator version_enum(target_path(), false, 712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator::DIRECTORIES); 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::FilePath next_version = version_enum.Next(); !next_version.empty(); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_version = version_enum.Next()) { 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath dir_name(next_version.BaseName()); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = Version(WideToASCII(dir_name.value())); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the version folder if it is less than the new version and not 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // equal to the old version (if we have an old version). 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (version.IsValid() && 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_version_strings.count(version.GetString()) == 0) { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: temporarily log old version deletion at ERROR level to make it 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more likely we see this in the installer log. 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Deleting old version directory: " << next_version.value(); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt to recursively delete the old version dir. 7267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool delete_succeeded = base::DeleteFile(next_version, true); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: temporarily log old version deletion at ERROR level to make it 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more likely we see this in the installer log. 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(ERROR, !delete_succeeded) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Failed to delete old version directory: " << next_version.value(); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallerState::AddComDllList( 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath>* com_dll_list) const { 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::for_each(products_.begin(), products_.end(), 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::bind2nd(std::mem_fun(&Product::AddComDllList), 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) com_dll_list)); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallerState::SetChannelFlags(bool set, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelInfo* channel_info) const { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool modified = false; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products_.begin(), end = products_.end(); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scan != end; ++scan) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified |= (*scan)->SetChannelFlags(set, channel_info); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return modified; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::UpdateStage(installer::InstallerStage stage) const { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallUtil::UpdateInstallerStage(system_install(), state_key_, stage); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::UpdateChannels() const { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (operation_ != MULTI_INSTALL && operation_ != MULTI_UPDATE) { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "InstallerState::UpdateChannels noop: " << operation_; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the "ap" value for the product being installed/updated. We get the 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current value from the registry since the InstallationState instance used 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by the bulk of the installer does not track changes made by UpdateStage. 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the app's ClientState key if it doesn't exist. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelInfo channel_info; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey state_key; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LONG result = state_key.Create(root_key_, state_key_.c_str(), 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERROR_SUCCESS) { 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.Initialize(state_key); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a multi-install product. 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool modified = channel_info.SetMultiInstall(true); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the appropriate modifiers for all products and their options. 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified |= SetChannelFlags(true, &channel_info); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "ap: " << channel_info.value(); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the results if needed. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modified) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.Write(&state_key); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the -stage: modifier since we don't want to propagate that to the 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // other app_guids. 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.SetStage(NULL); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synchronize the other products and the package with this one. 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelInfo other_info; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution::Type type = 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<BrowserDistribution::Type>(i); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip the app_guid we started with. 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == state_type_) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserDistribution* dist = NULL; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always operate on the binaries. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == BrowserDistribution::CHROME_BINARIES) { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dist = multi_package_distribution_; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Product* product = FindProduct(type); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip this one if it's for a product we're not operating on. 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (product == NULL) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dist = product->distribution(); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = state_key.Create(root_key_, dist->GetStateKey().c_str(), 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEY_QUERY_VALUE | KEY_SET_VALUE); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERROR_SUCCESS) { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_info.Initialize(state_key); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!other_info.Equals(channel_info)) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_info.Write(&state_key); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed opening key " << dist->GetStateKey() 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " to update app channels; result: " << result; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed opening key " << state_key_ 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " to update app channels; result: " << result; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallerState::WriteInstallerResult( 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallStatus status, 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int string_resource_id, 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring* const launch_cmd) const { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a no-rollback list since this is a best-effort deal. 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WorkItemList> install_list( 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkItem::CreateNoRollbackWorkItemList()); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool system_install = this->system_install(); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the value for all products upon which we're operating. 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Products::const_iterator end = products().end(); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Products::const_iterator scan = products().begin(); scan != end; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++scan) { 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallUtil::AddInstallerResultItems( 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_install, (*scan)->distribution()->GetStateKey(), status, 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string_resource_id, launch_cmd, install_list.get()); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And for the binaries if this is a multi-install. 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_multi_install()) { 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallUtil::AddInstallerResultItems( 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_install, multi_package_binaries_distribution()->GetStateKey(), 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status, string_resource_id, launch_cmd, install_list.get()); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!install_list->Do()) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to record installer error information in registry."; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool InstallerState::RequiresActiveSetup() const { 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace installer 857