product.cc revision a3f7b4e666c476898878fa745f637129375cd889
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/product.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/process/launch.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/chrome_app_host_operations.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/chrome_binaries_operations.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/chrome_browser_operations.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/chrome_browser_sxs_operations.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/chrome_frame_operations.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/google_update_constants.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/helper.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/install_util.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/master_preferences.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/master_preferences_constants.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/product_operations.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::RegKey; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using installer::MasterPreferences; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace installer { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product::Product(BrowserDistribution* distribution) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : distribution_(distribution) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (distribution->GetType()) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BrowserDistribution::CHROME_BROWSER: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_.reset(InstallUtil::IsChromeSxSProcess() ? 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ChromeBrowserSxSOperations() : 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ChromeBrowserOperations()); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BrowserDistribution::CHROME_FRAME: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_.reset(new ChromeFrameOperations()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BrowserDistribution::CHROME_APP_HOST: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_.reset(new ChromeAppHostOperations()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BrowserDistribution::CHROME_BINARIES: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_.reset(new ChromeBinariesOperations()); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unsupported BrowserDistribution::Type: " 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << distribution->GetType(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Product::~Product() { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::InitializeFromPreferences(const MasterPreferences& prefs) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->ReadOptions(prefs, &options_); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::InitializeFromUninstallCommand( 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& uninstall_command) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->ReadOptions(uninstall_command, &options_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::GetUserDataPaths(std::vector<base::FilePath>* paths) const { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetChromeUserDataPaths(distribution_, paths); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Product::LaunchChrome(const base::FilePath& application_path) const { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = !application_path.empty(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine cmd(application_path.Append(installer::kChromeExe)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = base::LaunchProcess(cmd, base::LaunchOptions(), NULL); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Product::LaunchChromeAndWait(const base::FilePath& application_path, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine& options, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32* exit_code) const { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (application_path.empty()) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine cmd(application_path.Append(installer::kChromeExe)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AppendArguments(options, false); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = false; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STARTUPINFOW si = { sizeof(si) }; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PROCESS_INFORMATION pi = {0}; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a writable copy of the command line string, since CreateProcess may 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // modify the string (insert \0 to separate the program from the arguments). 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring writable_command_line_string(cmd.GetCommandLineString()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::CreateProcess(cmd.GetProgram().value().c_str(), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &writable_command_line_string[0], 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &si, &pi)) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "Failed to launch: " << cmd.GetCommandLineString(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(pi.hThread); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ret = ::WaitForSingleObject(pi.hProcess, INFINITE); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_IF(ERROR, ret != WAIT_OBJECT_0) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Unexpected return value from WaitForSingleObject: " << ret; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetExitCodeProcess(pi.hProcess, &ret)) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ret != STILL_ACTIVE); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = true; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exit_code) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *exit_code = ret; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(ERROR) << "GetExitCodeProcess failed"; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(pi.hProcess); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Product::SetMsiMarker(bool system_install, bool set) const { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HKEY reg_root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegKey client_state_key; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LONG result = client_state_key.Open(reg_root, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) distribution_->GetStateKey().c_str(), KEY_READ | KEY_WRITE); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERROR_SUCCESS) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = client_state_key.WriteValue(google_update::kRegMSIField, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ? 1 : 0); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG_IF(ERROR, result != ERROR_SUCCESS) << "Failed to Open or Write MSI value" 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "to client state key. error: " << result; 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return (result == ERROR_SUCCESS); 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Product::ShouldCreateUninstallEntry() const { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return operations_->ShouldCreateUninstallEntry(options_); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::AddKeyFiles(std::vector<base::FilePath>* key_files) const { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->AddKeyFiles(options_, key_files); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::AddComDllList(std::vector<base::FilePath>* com_dll_list) const { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->AddComDllList(options_, com_dll_list); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::AppendProductFlags(CommandLine* command_line) const { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->AppendProductFlags(options_, command_line); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Product::AppendRenameFlags(CommandLine* command_line) const { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->AppendRenameFlags(options_, command_line); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Product::SetChannelFlags(bool set, ChannelInfo* channel_info) const { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return operations_->SetChannelFlags(options_, set, channel_info); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::AddDefaultShortcutProperties( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::FilePath& target_exe, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShellUtil::ShortcutProperties* properties) const { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return operations_->AddDefaultShortcutProperties( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) distribution_, target_exe, properties); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Product::LaunchUserExperiment(const base::FilePath& setup_path, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallStatus status, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool system_level) const { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (distribution_->HasUserExperiments()) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "LaunchUserExperiment status: " << status << " product: " 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << distribution_->GetAppShortCutName() 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << " system_level: " << system_level; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operations_->LaunchUserExperiment( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setup_path, options_, status, system_level); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace installer 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci