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/installation_state.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/google_update_constants.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/install_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace installer {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProductState::ProductState()
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : uninstall_command_(CommandLine::NO_PROGRAM),
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      eula_accepted_(0),
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      usagestats_(0),
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      msi_(false),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_install_(false),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_eula_accepted_(false),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_oem_install_(false),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_usagestats_(false) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProductState::Initialize(bool system_install,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              BrowserDistribution::Type type) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Initialize(system_install,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    BrowserDistribution::GetSpecificDistribution(type));
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes |commands| from the "Commands" subkey of |version_key|.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns false if there is no "Commands" subkey or on error.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProductState::InitializeCommands(const base::win::RegKey& version_key,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      AppCommands* commands) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const DWORD kAccess = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey commands_key;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (commands_key.Open(version_key.Handle(), google_update::kRegCommandsKey,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        kAccess) == ERROR_SUCCESS)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return commands->Initialize(commands_key);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProductState::Initialize(bool system_install,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              BrowserDistribution* distribution) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::wstring version_key(distribution->GetVersionKey());
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::wstring state_key(distribution->GetStateKey());
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey key;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the runway.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read from the Clients key.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key.Open(root_key, version_key.c_str(),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               KEY_QUERY_VALUE) == ERROR_SUCCESS) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring version_str;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key.ReadValue(google_update::kRegVersionField,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &version_str) == ERROR_SUCCESS) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      version_.reset(new Version(WideToASCII(version_str)));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!version_->IsValid())
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        version_.reset();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Attempt to read the other values even if the "pv" version value was
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // absent. Note that ProductState instances containing these values will
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // only be accessible via InstallationState::GetNonVersionedProductState.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key.ReadValue(google_update::kRegOldVersionField,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &version_str) == ERROR_SUCCESS) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_version_.reset(new Version(WideToASCII(version_str)));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!old_version_->IsValid())
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        old_version_.reset();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd_);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!InitializeCommands(key, &commands_))
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      commands_.Clear();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read from the ClientState key.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key.Open(root_key, state_key.c_str(),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               KEY_QUERY_VALUE) == ERROR_SUCCESS) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring setup_path;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::wstring uninstall_arguments;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "ap" will be absent if not managed by Google Update.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    channel_.Initialize(key);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read in the brand code, it may be absent
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.ReadValue(google_update::kRegBrandField, &brand_);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "UninstallString" will be absent for the multi-installer package.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.ReadValue(kUninstallStringField, &setup_path);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "UninstallArguments" will be absent for the multi-installer package.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.ReadValue(kUninstallArgumentsField, &uninstall_arguments);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallUtil::MakeUninstallCommand(setup_path, uninstall_arguments,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &uninstall_command_);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "usagestats" may be absent, 0 (false), or 1 (true).  On the chance that
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // different values are permitted in the future, we'll simply hold whatever
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we find.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_usagestats_ = (key.ReadValueDW(google_update::kRegUsageStatsField,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &usagestats_) == ERROR_SUCCESS);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "oeminstall" may be present with any value or absent.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_oem_install_ = (key.ReadValue(google_update::kRegOemInstallField,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &oem_install_) == ERROR_SUCCESS);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "eulaaccepted" may be absent, 0 or 1.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_eula_accepted_ = (key.ReadValueDW(google_update::kRegEULAAceptedField,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          &eula_accepted_) == ERROR_SUCCESS);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // "msi" may be absent, 0 or 1
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD dw_value = 0;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    msi_ = (key.ReadValueDW(google_update::kRegMSIField,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            &dw_value) == ERROR_SUCCESS) && (dw_value != 0);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Multi-install is implied or is derived from the command-line.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_install_ = true;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      multi_install_ = uninstall_command_.HasSwitch(switches::kMultiInstall);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read from the ClientStateMedium key.  Values here override those in
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClientState.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (system_install &&
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      key.Open(root_key, distribution->GetStateMediumKey().c_str(),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               KEY_QUERY_VALUE) == ERROR_SUCCESS) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DWORD dword_value = 0;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key.ReadValueDW(google_update::kRegUsageStatsField,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &dword_value) == ERROR_SUCCESS) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_usagestats_ = true;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      usagestats_ = dword_value;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (key.ReadValueDW(google_update::kRegEULAAceptedField,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &dword_value) == ERROR_SUCCESS) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_eula_accepted_ = true;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      eula_accepted_ = dword_value;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return version_.get() != NULL;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath ProductState::GetSetupPath() const {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return uninstall_command_.GetProgram();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Version& ProductState::version() const {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(version_.get() != NULL);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *version_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProductState& ProductState::CopyFrom(const ProductState& other) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_.set_value(other.channel_.value());
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  version_.reset(other.version_.get() ? new Version(*other.version_) : NULL);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_version_.reset(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other.old_version_.get() ? new Version(*other.old_version_) : NULL);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  brand_ = other.brand_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rename_cmd_ = other.rename_cmd_;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uninstall_command_ = other.uninstall_command_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  oem_install_ = other.oem_install_;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commands_.CopyFrom(other.commands_);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  eula_accepted_ = other.eula_accepted_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  usagestats_ = other.usagestats_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msi_ = other.msi_;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multi_install_ = other.multi_install_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_eula_accepted_ = other.has_eula_accepted_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_oem_install_ = other.has_oem_install_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_usagestats_ = other.has_usagestats_;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProductState::Clear() {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_.set_value(std::wstring());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  version_.reset();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_version_.reset();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  brand_.clear();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rename_cmd_.clear();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  oem_install_.clear();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commands_.Clear();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  eula_accepted_ = 0;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  usagestats_ = 0;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msi_ = false;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  multi_install_ = false;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_eula_accepted_ = false;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_oem_install_ = false;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_usagestats_ = false;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProductState::GetEulaAccepted(DWORD* eula_accepted) const {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(eula_accepted);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_eula_accepted_)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *eula_accepted = eula_accepted_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProductState::GetOemInstall(std::wstring* oem_install) const {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(oem_install);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_oem_install_)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *oem_install = oem_install_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProductState::GetUsageStats(DWORD* usagestats) const {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(usagestats);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!has_usagestats_)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *usagestats = usagestats_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstallationState::InstallationState() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int InstallationState::IndexFromDistType(BrowserDistribution::Type type) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(BrowserDistribution::CHROME_BROWSER == CHROME_BROWSER_INDEX,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 unexpected_chrome_browser_distribution_value_);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(BrowserDistribution::CHROME_FRAME == CHROME_FRAME_INDEX,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 unexpected_chrome_frame_distribution_value_);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(BrowserDistribution::CHROME_BINARIES == CHROME_BINARIES_INDEX,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 unexpected_chrome_frame_distribution_value_);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(BrowserDistribution::CHROME_APP_HOST == CHROME_APP_HOST_INDEX,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 unexpected_chrome_frame_distribution_value_);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type == BrowserDistribution::CHROME_BROWSER ||
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         type == BrowserDistribution::CHROME_FRAME ||
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         type == BrowserDistribution::CHROME_BINARIES ||
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         type == BrowserDistribution::CHROME_APP_HOST);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return type;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationState::Initialize() {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* distribution;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  distribution = BrowserDistribution::GetSpecificDistribution(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::CHROME_BROWSER);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_products_[CHROME_BROWSER_INDEX].Initialize(false, distribution);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  system_products_[CHROME_BROWSER_INDEX].Initialize(true, distribution);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  distribution = BrowserDistribution::GetSpecificDistribution(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::CHROME_FRAME);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_products_[CHROME_FRAME_INDEX].Initialize(false, distribution);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  system_products_[CHROME_FRAME_INDEX].Initialize(true, distribution);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  distribution = BrowserDistribution::GetSpecificDistribution(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::CHROME_BINARIES);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_products_[CHROME_BINARIES_INDEX].Initialize(false, distribution);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  system_products_[CHROME_BINARIES_INDEX].Initialize(true, distribution);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  distribution = BrowserDistribution::GetSpecificDistribution(
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::CHROME_APP_HOST);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_products_[CHROME_APP_HOST_INDEX].Initialize(false, distribution);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  system_products_[CHROME_APP_HOST_INDEX].Initialize(true, distribution);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProductState* InstallationState::GetNonVersionedProductState(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool system_install,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserDistribution::Type type) const {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState& product_state = (system_install ? system_products_ :
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      user_products_)[IndexFromDistType(type)];
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &product_state;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ProductState* InstallationState::GetProductState(
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool system_install,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserDistribution::Type type) const {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* product_state =
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetNonVersionedProductState(system_install, type);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return product_state->version_.get() == NULL ? NULL : product_state;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace installer
278