| Index: remoting/host/setup/daemon_installer_win.cc
|
| diff --git a/remoting/host/setup/daemon_installer_win.cc b/remoting/host/setup/daemon_installer_win.cc
|
| deleted file mode 100644
|
| index a125dfeb819b550892b0614dd1b854e6d8919a28..0000000000000000000000000000000000000000
|
| --- a/remoting/host/setup/daemon_installer_win.cc
|
| +++ /dev/null
|
| @@ -1,412 +0,0 @@
|
| -// 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 "remoting/host/setup/daemon_installer_win.h"
|
| -
|
| -#include <windows.h>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/process/launch.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/time/time.h"
|
| -#include "base/timer/timer.h"
|
| -#include "base/win/object_watcher.h"
|
| -#include "base/win/registry.h"
|
| -#include "base/win/scoped_bstr.h"
|
| -#include "base/win/scoped_comptr.h"
|
| -#include "base/win/scoped_handle.h"
|
| -#include "base/win/scoped_variant.h"
|
| -#include "base/win/windows_version.h"
|
| -#include "google_update/google_update_idl.h"
|
| -#include "remoting/base/dispatch_win.h"
|
| -#include "remoting/host/win/omaha.h"
|
| -
|
| -using base::win::ScopedBstr;
|
| -using base::win::ScopedComPtr;
|
| -using base::win::ScopedVariant;
|
| -
|
| -namespace {
|
| -
|
| -// ProgID of the per-machine Omaha COM server.
|
| -const wchar_t kGoogleUpdate[] = L"GoogleUpdate.Update3WebMachine";
|
| -
|
| -// The COM elevation moniker for the per-machine Omaha COM server.
|
| -const wchar_t kGoogleUpdateElevationMoniker[] =
|
| - L"Elevation:Administrator!new:GoogleUpdate.Update3WebMachine";
|
| -
|
| -// The registry key where the configuration of Omaha is stored.
|
| -const wchar_t kOmahaUpdateKeyName[] = L"Software\\Google\\Update";
|
| -
|
| -// The name of the value where the full path to GoogleUpdate.exe is stored.
|
| -const wchar_t kOmahaPathValueName[] = L"path";
|
| -
|
| -// The command line format string for GoogleUpdate.exe
|
| -const wchar_t kGoogleUpdateCommandLineFormat[] =
|
| - L"\"%ls\" /install \"bundlename=Chromoting%%20Host&appguid=%ls&"
|
| - L"appname=Chromoting%%20Host&needsadmin=True&lang=%ls\"";
|
| -
|
| -// TODO(alexeypa): Get the desired laungage from the web app.
|
| -const wchar_t kOmahaLanguage[] = L"en";
|
| -
|
| -// An empty string for optional parameters.
|
| -const wchar_t kOmahaEmpty[] = L"";
|
| -
|
| -// The installation status polling interval.
|
| -const int kOmahaPollIntervalMs = 500;
|
| -
|
| -} // namespace
|
| -
|
| -namespace remoting {
|
| -
|
| -// This class implements on-demand installation of the Chromoting Host via
|
| -// per-machine Omaha instance.
|
| -class DaemonComInstallerWin : public DaemonInstallerWin {
|
| - public:
|
| - DaemonComInstallerWin(const ScopedComPtr<IDispatch>& update3,
|
| - const CompletionCallback& done);
|
| -
|
| - // DaemonInstallerWin implementation.
|
| - virtual void Install() override;
|
| -
|
| - private:
|
| - // Polls the installation status performing state-specific actions (such as
|
| - // starting installation once download has finished).
|
| - void PollInstallationStatus();
|
| -
|
| - // Omaha interfaces.
|
| - ScopedVariant app_;
|
| - ScopedVariant bundle_;
|
| - ScopedComPtr<IDispatch> update3_;
|
| -
|
| - base::Timer polling_timer_;
|
| -};
|
| -
|
| -// This class implements on-demand installation of the Chromoting Host by
|
| -// launching a per-user instance of Omaha and requesting elevation.
|
| -class DaemonCommandLineInstallerWin
|
| - : public DaemonInstallerWin,
|
| - public base::win::ObjectWatcher::Delegate {
|
| - public:
|
| - DaemonCommandLineInstallerWin(const CompletionCallback& done);
|
| - ~DaemonCommandLineInstallerWin();
|
| -
|
| - // DaemonInstallerWin implementation.
|
| - virtual void Install() override;
|
| -
|
| - // base::win::ObjectWatcher::Delegate implementation.
|
| - virtual void OnObjectSignaled(HANDLE object) override;
|
| -
|
| - private:
|
| - // Handle of the launched process.
|
| - base::Process process_;
|
| -
|
| - // Used to determine when the launched process terminates.
|
| - base::win::ObjectWatcher process_watcher_;
|
| -};
|
| -
|
| -DaemonComInstallerWin::DaemonComInstallerWin(
|
| - const ScopedComPtr<IDispatch>& update3,
|
| - const CompletionCallback& done)
|
| - : DaemonInstallerWin(done),
|
| - update3_(update3),
|
| - polling_timer_(
|
| - FROM_HERE,
|
| - base::TimeDelta::FromMilliseconds(kOmahaPollIntervalMs),
|
| - base::Bind(&DaemonComInstallerWin::PollInstallationStatus,
|
| - base::Unretained(this)),
|
| - false) {
|
| -}
|
| -
|
| -void DaemonComInstallerWin::Install() {
|
| - // Create an app bundle.
|
| - HRESULT hr = dispatch::Invoke(update3_.get(), L"createAppBundleWeb",
|
| - DISPATCH_METHOD, bundle_.Receive());
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| - if (bundle_.type() != VT_DISPATCH) {
|
| - Done(DISP_E_TYPEMISMATCH);
|
| - return;
|
| - }
|
| -
|
| - hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"initialize", DISPATCH_METHOD,
|
| - nullptr);
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| -
|
| - // Add Chromoting Host to the bundle.
|
| - ScopedVariant appid(kHostOmahaAppid);
|
| - ScopedVariant empty(kOmahaEmpty);
|
| - ScopedVariant language(kOmahaLanguage);
|
| - hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"createApp", DISPATCH_METHOD,
|
| - appid, empty, language, empty, nullptr);
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| -
|
| - hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"checkForUpdate",
|
| - DISPATCH_METHOD, nullptr);
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| -
|
| - hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"appWeb",
|
| - DISPATCH_PROPERTYGET, ScopedVariant(0), app_.Receive());
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| - if (app_.type() != VT_DISPATCH) {
|
| - Done(DISP_E_TYPEMISMATCH);
|
| - return;
|
| - }
|
| -
|
| - // Now poll for the installation status.
|
| - PollInstallationStatus();
|
| -}
|
| -
|
| -void DaemonComInstallerWin::PollInstallationStatus() {
|
| - // Get the current application installation state.
|
| - // N.B. The object underlying the ICurrentState interface has static data that
|
| - // does not get updated as the server state changes. To get the most "current"
|
| - // state, the currentState property needs to be queried again.
|
| - ScopedVariant current_state;
|
| - HRESULT hr = dispatch::Invoke(V_DISPATCH(&app_), L"currentState",
|
| - DISPATCH_PROPERTYGET, current_state.Receive());
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| - if (current_state.type() != VT_DISPATCH) {
|
| - Done(DISP_E_TYPEMISMATCH);
|
| - return;
|
| - }
|
| -
|
| - ScopedVariant state;
|
| - hr = dispatch::Invoke(V_DISPATCH(¤t_state), L"stateValue",
|
| - DISPATCH_PROPERTYGET, state.Receive());
|
| - if (state.type() != VT_I4) {
|
| - Done(DISP_E_TYPEMISMATCH);
|
| - return;
|
| - }
|
| -
|
| - // Perform state-specific actions.
|
| - switch (V_I4(&state)) {
|
| - case STATE_INIT:
|
| - case STATE_WAITING_TO_CHECK_FOR_UPDATE:
|
| - case STATE_CHECKING_FOR_UPDATE:
|
| - case STATE_WAITING_TO_DOWNLOAD:
|
| - case STATE_RETRYING_DOWNLOAD:
|
| - case STATE_DOWNLOADING:
|
| - case STATE_WAITING_TO_INSTALL:
|
| - case STATE_INSTALLING:
|
| - case STATE_PAUSED:
|
| - break;
|
| -
|
| - case STATE_UPDATE_AVAILABLE:
|
| - hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"download",
|
| - DISPATCH_METHOD, nullptr);
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| - break;
|
| -
|
| - case STATE_DOWNLOAD_COMPLETE:
|
| - case STATE_EXTRACTING:
|
| - case STATE_APPLYING_DIFFERENTIAL_PATCH:
|
| - case STATE_READY_TO_INSTALL:
|
| - hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"install",
|
| - DISPATCH_METHOD, nullptr);
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| - break;
|
| -
|
| - case STATE_INSTALL_COMPLETE:
|
| - case STATE_NO_UPDATE:
|
| - // Installation complete or not required. Report success.
|
| - Done(S_OK);
|
| - return;
|
| -
|
| - case STATE_ERROR: {
|
| - ScopedVariant error_code;
|
| - hr = dispatch::Invoke(V_DISPATCH(¤t_state), L"errorCode",
|
| - DISPATCH_PROPERTYGET, error_code.Receive());
|
| - if (FAILED(hr)) {
|
| - Done(hr);
|
| - return;
|
| - }
|
| - if (error_code.type() != VT_UI4) {
|
| - Done(DISP_E_TYPEMISMATCH);
|
| - return;
|
| - }
|
| - Done(V_UI4(&error_code));
|
| - return;
|
| - }
|
| -
|
| - default:
|
| - LOG(ERROR) << "Unknown bundle state: " << V_I4(&state) << ".";
|
| - Done(E_FAIL);
|
| - return;
|
| - }
|
| -
|
| - // Keep polling.
|
| - polling_timer_.Reset();
|
| -}
|
| -
|
| -DaemonCommandLineInstallerWin::DaemonCommandLineInstallerWin(
|
| - const CompletionCallback& done) : DaemonInstallerWin(done) {
|
| -}
|
| -
|
| -DaemonCommandLineInstallerWin::~DaemonCommandLineInstallerWin() {
|
| - process_watcher_.StopWatching();
|
| -}
|
| -
|
| -void DaemonCommandLineInstallerWin::Install() {
|
| - // Get the full path to GoogleUpdate.exe from the registry.
|
| - base::win::RegKey update_key;
|
| - LONG result = update_key.Open(HKEY_CURRENT_USER,
|
| - kOmahaUpdateKeyName,
|
| - KEY_READ);
|
| - if (result != ERROR_SUCCESS) {
|
| - Done(HRESULT_FROM_WIN32(result));
|
| - return;
|
| - }
|
| -
|
| - // presubmit: allow wstring
|
| - std::wstring google_update;
|
| - result = update_key.ReadValue(kOmahaPathValueName, &google_update);
|
| - if (result != ERROR_SUCCESS) {
|
| - Done(HRESULT_FROM_WIN32(result));
|
| - return;
|
| - }
|
| -
|
| - // Launch the updater process and wait for its termination.
|
| - base::string16 command_line = base::WideToUTF16(
|
| - base::StringPrintf(kGoogleUpdateCommandLineFormat,
|
| - google_update.c_str(),
|
| - kHostOmahaAppid,
|
| - kOmahaLanguage));
|
| -
|
| - base::LaunchOptions options;
|
| - process_ = base::LaunchProcess(command_line, options);
|
| - if (!process_.IsValid()) {
|
| - result = GetLastError();
|
| - Done(HRESULT_FROM_WIN32(result));
|
| - return;
|
| - }
|
| -
|
| - if (!process_watcher_.StartWatching(process_.Handle(), this)) {
|
| - result = GetLastError();
|
| - Done(HRESULT_FROM_WIN32(result));
|
| - return;
|
| - }
|
| -}
|
| -
|
| -void DaemonCommandLineInstallerWin::OnObjectSignaled(HANDLE object) {
|
| - // Check if the updater process returned success.
|
| - DWORD exit_code;
|
| - if (GetExitCodeProcess(process_.Handle(), &exit_code) && exit_code == 0) {
|
| - Done(S_OK);
|
| - } else {
|
| - Done(E_FAIL);
|
| - }
|
| -}
|
| -
|
| -DaemonInstallerWin::DaemonInstallerWin(const CompletionCallback& done)
|
| - : done_(done) {
|
| -}
|
| -
|
| -DaemonInstallerWin::~DaemonInstallerWin() {
|
| -}
|
| -
|
| -void DaemonInstallerWin::Done(HRESULT result) {
|
| - CompletionCallback done = done_;
|
| - done_.Reset();
|
| - done.Run(result);
|
| -}
|
| -
|
| -// static
|
| -scoped_ptr<DaemonInstallerWin> DaemonInstallerWin::Create(
|
| - HWND window_handle,
|
| - CompletionCallback done) {
|
| - HRESULT result = E_FAIL;
|
| - ScopedComPtr<IDispatch> update3;
|
| -
|
| - // Check if the machine instance of Omaha is available. The COM elevation is
|
| - // supported on Vista+, so on XP/W2K3 we assume that we are running under
|
| - // a privileged user and get ACCESS_DENIED later if we are not.
|
| - if (base::win::GetVersion() < base::win::VERSION_VISTA) {
|
| - CLSID class_id;
|
| - result = CLSIDFromProgID(kGoogleUpdate, &class_id);
|
| - if (SUCCEEDED(result)) {
|
| - result = CoCreateInstance(class_id,
|
| - nullptr,
|
| - CLSCTX_LOCAL_SERVER,
|
| - IID_IDispatch,
|
| - update3.ReceiveVoid());
|
| - }
|
| - } else {
|
| - BIND_OPTS3 bind_options;
|
| - memset(&bind_options, 0, sizeof(bind_options));
|
| - bind_options.cbStruct = sizeof(bind_options);
|
| - bind_options.hwnd = GetTopLevelWindow(window_handle);
|
| - bind_options.dwClassContext = CLSCTX_LOCAL_SERVER;
|
| - result = CoGetObject(kGoogleUpdateElevationMoniker,
|
| - &bind_options,
|
| - IID_IDispatch,
|
| - update3.ReceiveVoid());
|
| - }
|
| -
|
| - if (result == CO_E_CLASSSTRING) {
|
| - // The machine instance of Omaha is not available so we will have to run
|
| - // GoogleUpdate.exe manually passing "needsadmin=True". This will cause
|
| - // Omaha to install the machine instance first and then install Chromoting
|
| - // Host.
|
| - return make_scoped_ptr(new DaemonCommandLineInstallerWin(done));
|
| - }
|
| -
|
| - if (!SUCCEEDED(result)) {
|
| - // The user declined the UAC prompt or some other error occured.
|
| - done.Run(result);
|
| - return nullptr;
|
| - }
|
| -
|
| - // The machine instance of Omaha is available and we successfully passed
|
| - // the UAC prompt.
|
| - return make_scoped_ptr(new DaemonComInstallerWin(update3, done));
|
| -}
|
| -
|
| -HWND GetTopLevelWindow(HWND window) {
|
| - if (window == nullptr) {
|
| - return nullptr;
|
| - }
|
| -
|
| - for (;;) {
|
| - LONG style = GetWindowLong(window, GWL_STYLE);
|
| - if ((style & WS_OVERLAPPEDWINDOW) == WS_OVERLAPPEDWINDOW ||
|
| - (style & WS_POPUP) == WS_POPUP) {
|
| - return window;
|
| - }
|
| -
|
| - HWND parent = GetAncestor(window, GA_PARENT);
|
| - if (parent == nullptr) {
|
| - return window;
|
| - }
|
| -
|
| - window = parent;
|
| - }
|
| -}
|
| -
|
| -} // namespace remoting
|
|
|