| Index: chrome/installer/util/google_update_util.cc
|
| diff --git a/chrome/installer/util/google_update_util.cc b/chrome/installer/util/google_update_util.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0f48a477226ef5d5e0f1bdb6771eaa13f5adbfaf
|
| --- /dev/null
|
| +++ b/chrome/installer/util/google_update_util.cc
|
| @@ -0,0 +1,134 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/installer/util/google_update_util.h"
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/file_path.h"
|
| +#include "base/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "base/process_util.h"
|
| +#include "base/string16.h"
|
| +#include "base/time.h"
|
| +#include "base/win/registry.h"
|
| +#include "base/win/scoped_handle.h"
|
| +#include "chrome/installer/launcher_support/chrome_launcher_support.h"
|
| +#include "chrome/installer/util/google_update_constants.h"
|
| +#include "chrome/installer/util/google_update_settings.h"
|
| +
|
| +using base::win::RegKey;
|
| +
|
| +namespace google_update {
|
| +
|
| +namespace {
|
| +
|
| +const int kGoogleUpdateTimeoutMs = 20 * 1000;
|
| +
|
| +// Returns true if Google Update is present at the given level.
|
| +bool IsGoogleUpdatePresent(bool system_install) {
|
| + // Using the existence of version key in the registry to decide.
|
| + return GoogleUpdateSettings::GetGoogleUpdateVersion(system_install).IsValid();
|
| +}
|
| +
|
| +// Returns GoogleUpdateSetup.exe's executable path at specified level.
|
| +// or an empty path if none is found.
|
| +FilePath GetGoogleUpdateSetupExe(bool system_install) {
|
| + const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
|
| + RegKey update_key;
|
| +
|
| + if (update_key.Open(root_key, kRegPathGoogleUpdate, KEY_QUERY_VALUE) ==
|
| + ERROR_SUCCESS) {
|
| + string16 path_str;
|
| + string16 version_str;
|
| + if ((update_key.ReadValue(kRegPathField, &path_str) == ERROR_SUCCESS) &&
|
| + (update_key.ReadValue(kRegGoogleUpdateVersion, &version_str) ==
|
| + ERROR_SUCCESS)) {
|
| + return FilePath(path_str).DirName().Append(version_str).
|
| + Append(kGoogleUpdateSetupExe);
|
| + }
|
| + }
|
| + return FilePath();
|
| +}
|
| +
|
| +// If Google Update is present at system-level, sets |cmd_string| to the command
|
| +// line to install Google Update at user-level and returns true.
|
| +// Otherwise, clears |cmd_string| and returns false.
|
| +bool GetUserLevelGoogleUpdateInstallCommandLine(string16* cmd_string) {
|
| + cmd_string->clear();
|
| + FilePath google_update_setup(GetGoogleUpdateSetupExe(true)); // system-level.
|
| + if (!google_update_setup.empty()) {
|
| + CommandLine cmd(google_update_setup);
|
| + // Appends parameter "/install runtime=true&needsadmin=false /silent"
|
| + // Constants are found in code.google.com/p/omaha/common/const_cmd_line.h.
|
| + cmd.AppendArg("/install");
|
| + // The "&" can be used in base::LaunchProcess() without quotation
|
| + // (this is problematic only if run from command prompt).
|
| + cmd.AppendArg("runtime=true&needsadmin=false");
|
| + cmd.AppendArg("/silent");
|
| + *cmd_string = cmd.GetCommandLineString();
|
| + }
|
| + return !cmd_string->empty();
|
| +}
|
| +
|
| +// Launches command |cmd_string|, and waits for |timeout| milliseconds before
|
| +// timing out. To wait indefinitely, one can set
|
| +// |timeout| to be base::TimeDelta::FromMilliseconds(INFINITE).
|
| +// Returns true if this executes successfully.
|
| +// Returns false if command execution fails to execute, or times out.
|
| +bool LaunchProcessAndWaitWithTimeout(const string16& cmd_string,
|
| + base::TimeDelta timeout) {
|
| + bool success = false;
|
| + base::win::ScopedHandle process;
|
| + int exit_code = 0;
|
| + LOG(INFO) << "Launching: " << cmd_string;
|
| + if (!base::LaunchProcess(cmd_string, base::LaunchOptions(),
|
| + process.Receive())) {
|
| + PLOG(ERROR) << "Failed to launch (" << cmd_string << ")";
|
| + } else if (!base::WaitForExitCodeWithTimeout(process, &exit_code, timeout)) {
|
| + // The GetExitCodeProcess failed or timed-out.
|
| + LOG(ERROR) <<"Command (" << cmd_string << ") is taking more than "
|
| + << timeout.InMilliseconds() << " milliseconds to complete.";
|
| + } else if (exit_code != 0) {
|
| + LOG(ERROR) << "Command (" << cmd_string << ") exited with code "
|
| + << exit_code;
|
| + } else {
|
| + success = true;
|
| + }
|
| + return success;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +bool EnsureUserLevelGoogleUpdatePresent() {
|
| + LOG(INFO) << "Ensuring Google Update is present at user-level.";
|
| +
|
| + bool success = false;
|
| + if (IsGoogleUpdatePresent(false)) {
|
| + success = true;
|
| + } else {
|
| + string16 cmd_string;
|
| + if (!GetUserLevelGoogleUpdateInstallCommandLine(&cmd_string)) {
|
| + LOG(ERROR) << "Cannot find Google Update at system-level.";
|
| + } else {
|
| + success = LaunchProcessAndWaitWithTimeout(cmd_string,
|
| + base::TimeDelta::FromMilliseconds(INFINITE));
|
| + }
|
| + }
|
| + return success;
|
| +}
|
| +
|
| +bool UninstallGoogleUpdate(bool system_install) {
|
| + bool success = false;
|
| + string16 cmd_string(
|
| + GoogleUpdateSettings::GetUninstallCommandLine(system_install));
|
| + if (cmd_string.empty()) {
|
| + success = true; // Nothing to; vacuous success.
|
| + } else {
|
| + success = LaunchProcessAndWaitWithTimeout(cmd_string,
|
| + base::TimeDelta::FromMilliseconds(kGoogleUpdateTimeoutMs));
|
| + }
|
| + return success;
|
| +}
|
| +
|
| +} // namespace google_update
|
|
|