diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-13 20:45:24 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-13 20:45:24 +0000 |
commit | 3a1a51a241fd429f2c63d4dbc5c04613c8a03291 (patch) | |
tree | 5358924f55d5b231436150a38a721f4c1af1f0a4 /remoting | |
parent | 3099a67b91c35a7ba32aeabdf881064fa852733c (diff) | |
download | chromium_src-3a1a51a241fd429f2c63d4dbc5c04613c8a03291.zip chromium_src-3a1a51a241fd429f2c63d4dbc5c04613c8a03291.tar.gz chromium_src-3a1a51a241fd429f2c63d4dbc5c04613c8a03291.tar.bz2 |
[Chromoting] Using IDispatch::Invoke() to call Omaha inetrfaces.
Omaha uses non-standard scheme for versioning its COM interfaces. Instead of letting the callers to know a fixed UUID and prototype of an interface, Omaha relies on the callers to use late binding via IDispatch::Invoke. This way it can extend an interface after it has been released by adding new members and changing its UUID. The limitation is that vtable can no longer be used.
BUG=131498
Review URL: https://chromiumcodereview.appspot.com/10532099
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141960 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/base/dispatch_win.h | 536 | ||||
-rw-r--r-- | remoting/base/dispatch_win.h.pump | 180 | ||||
-rw-r--r-- | remoting/host/plugin/daemon_installer_win.cc | 99 | ||||
-rw-r--r-- | remoting/remoting.gyp | 1 |
4 files changed, 772 insertions, 44 deletions
diff --git a/remoting/base/dispatch_win.h b/remoting/base/dispatch_win.h new file mode 100644 index 0000000..1d12a70 --- /dev/null +++ b/remoting/base/dispatch_win.h @@ -0,0 +1,536 @@ +// This file was GENERATED by command: +// pump.py dispatch_win.h.pump +// DO NOT EDIT BY HAND!!! + +// 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. + +#ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ +#define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ + +#include <oaidl.h> + +#include "base/basictypes.h" +#include "base/template_util.h" +#include "base/win/scoped_variant.h" + +namespace remoting { + +namespace dispatch { + +namespace internal { + +// A helper wrapper for |VARIANTARG| that is used to pass parameters to and from +// IDispatch::Invoke(). The latter accepts parameters as an array of +// |VARIANTARG| structures. The calling convention is: +// - [in] parameters are initialized and freed if needed by the caller. +// - [out] parameters are initialized by IDispatch::Invoke(). It is up to +// the caller to free leakable variants (such as VT_DISPATCH). +// - [in] [out] parameters are combination of both: the caller initializes +// them before the call and the callee assigns new values correctly +// freeing leakable variants. +// +// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that +// the resources allocated during the call will be properly freed. It also +// provides wraping methods that convert between C++ types and VARIANTs. +// The current convention is: +// - constant references are considered input parameters. +// - pointers to non-constant objects are considered output parameters. +// - [in] [out] parameters are not supported. +// +// It must be possible to cast a pointer to an array of |ScopedVariantArg| to +// a pointer to an array of |VARIANTARG| structures. +class ScopedVariantArg : public VARIANTARG { + public: + ScopedVariantArg() { + vt = VT_EMPTY; + } + + ~ScopedVariantArg() { + VariantClear(this); + } + + // Wrap() routines pack the input parameters into VARIANTARG structures so + // that they can be passed to IDispatch::Invoke. + + HRESULT Wrap(const VARIANT& param) { + return VariantCopy(this, ¶m); + } + + HRESULT Wrap(VARIANT* const & param) { + // Do nothing for an [out] parameter. + return S_OK; + } + + // Unwrap() routines unpack the output parameters from VARIANTARG structures + // to the locations specified by the caller. + + void Unwrap(const VARIANT& param_out) { + // Do nothing for an [in] parameter. + } + + void Unwrap(VARIANT* const & param_out) { + *param_out = *this; + vt = VT_EMPTY; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg); +}; + +// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical. +COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG), + scoped_variant_arg_should_not_add_data_members); + +} // namespace internal + +// Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of +// calling the desired method by its ID and implements logic for passing +// a variable number of in/out parameters to the called method. +// +// Current limitations: +// - in_out parameters are not supported. +// - more than 7 parameters are not supported. +// - the method ID cannot be cached and reused. +// - VARIANT is the only supported parameter type at the moment. + +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + + // Invoke the method. + DISPPARAMS disp_params = { NULL, NULL, 0, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[1]; + hr = disp_args[1 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 1, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[1 - 1].Unwrap(p1); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1, typename P2> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + const P2& p2, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[2]; + hr = disp_args[2 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + hr = disp_args[2 - 2].Wrap(p2); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 2, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[2 - 1].Unwrap(p1); + disp_args[2 - 2].Unwrap(p2); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1, typename P2, typename P3> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + const P2& p2, + const P3& p3, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[3]; + hr = disp_args[3 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + hr = disp_args[3 - 2].Wrap(p2); + if (FAILED(hr)) + return hr; + hr = disp_args[3 - 3].Wrap(p3); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 3, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[3 - 1].Unwrap(p1); + disp_args[3 - 2].Unwrap(p2); + disp_args[3 - 3].Unwrap(p3); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1, typename P2, typename P3, typename P4> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + const P2& p2, + const P3& p3, + const P4& p4, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[4]; + hr = disp_args[4 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + hr = disp_args[4 - 2].Wrap(p2); + if (FAILED(hr)) + return hr; + hr = disp_args[4 - 3].Wrap(p3); + if (FAILED(hr)) + return hr; + hr = disp_args[4 - 4].Wrap(p4); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 4, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[4 - 1].Unwrap(p1); + disp_args[4 - 2].Unwrap(p2); + disp_args[4 - 3].Unwrap(p3); + disp_args[4 - 4].Unwrap(p4); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1, typename P2, typename P3, typename P4, typename P5> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + const P2& p2, + const P3& p3, + const P4& p4, + const P5& p5, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[5]; + hr = disp_args[5 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + hr = disp_args[5 - 2].Wrap(p2); + if (FAILED(hr)) + return hr; + hr = disp_args[5 - 3].Wrap(p3); + if (FAILED(hr)) + return hr; + hr = disp_args[5 - 4].Wrap(p4); + if (FAILED(hr)) + return hr; + hr = disp_args[5 - 5].Wrap(p5); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 5, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[5 - 1].Unwrap(p1); + disp_args[5 - 2].Unwrap(p2); + disp_args[5 - 3].Unwrap(p3); + disp_args[5 - 4].Unwrap(p4); + disp_args[5 - 5].Unwrap(p5); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1, typename P2, typename P3, typename P4, typename P5, + typename P6> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + const P2& p2, + const P3& p3, + const P4& p4, + const P5& p5, + const P6& p6, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[6]; + hr = disp_args[6 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + hr = disp_args[6 - 2].Wrap(p2); + if (FAILED(hr)) + return hr; + hr = disp_args[6 - 3].Wrap(p3); + if (FAILED(hr)) + return hr; + hr = disp_args[6 - 4].Wrap(p4); + if (FAILED(hr)) + return hr; + hr = disp_args[6 - 5].Wrap(p5); + if (FAILED(hr)) + return hr; + hr = disp_args[6 - 6].Wrap(p6); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 6, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[6 - 1].Unwrap(p1); + disp_args[6 - 2].Unwrap(p2); + disp_args[6 - 3].Unwrap(p3); + disp_args[6 - 4].Unwrap(p4); + disp_args[6 - 5].Unwrap(p5); + disp_args[6 - 6].Unwrap(p6); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +template <typename P1, typename P2, typename P3, typename P4, typename P5, + typename P6, typename P7> +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, + const P1& p1, + const P2& p2, + const P3& p3, + const P4& p4, + const P5& p5, + const P6& p6, + const P7& p7, + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[7]; + hr = disp_args[7 - 1].Wrap(p1); + if (FAILED(hr)) + return hr; + hr = disp_args[7 - 2].Wrap(p2); + if (FAILED(hr)) + return hr; + hr = disp_args[7 - 3].Wrap(p3); + if (FAILED(hr)) + return hr; + hr = disp_args[7 - 4].Wrap(p4); + if (FAILED(hr)) + return hr; + hr = disp_args[7 - 5].Wrap(p5); + if (FAILED(hr)) + return hr; + hr = disp_args[7 - 6].Wrap(p6); + if (FAILED(hr)) + return hr; + hr = disp_args[7 - 7].Wrap(p7); + if (FAILED(hr)) + return hr; + + // Invoke the method. + DISPPARAMS disp_params = { disp_args, NULL, 7, 0 }; + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + + // Unwrap the parameters. + disp_args[7 - 1].Unwrap(p1); + disp_args[7 - 2].Unwrap(p2); + disp_args[7 - 3].Unwrap(p3); + disp_args[7 - 4].Unwrap(p4); + disp_args[7 - 5].Unwrap(p5); + disp_args[7 - 6].Unwrap(p6); + disp_args[7 - 7].Unwrap(p7); + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +} // namespace dispatch + +} // namespace remoting + +#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ diff --git a/remoting/base/dispatch_win.h.pump b/remoting/base/dispatch_win.h.pump new file mode 100644 index 0000000..fd9ad1d --- /dev/null +++ b/remoting/base/dispatch_win.h.pump @@ -0,0 +1,180 @@ +$$ This is a pump file for generating file templates. Pump is a python +$$ script that is part of the Google Test suite of utilities. Description +$$ can be found here: +$$ +$$ http://code.google.com/p/googletest/wiki/PumpManual + +$$ MAX_ARITY controls the number of arguments that dispatch::Invoke() supports. +$$ It is choosen to match the number of arguments base::Bind() supports. +$var MAX_ARITY = 7 +// 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. + +#ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ +#define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ + +#include <oaidl.h> + +#include "base/basictypes.h" +#include "base/template_util.h" +#include "base/win/scoped_variant.h" + +namespace remoting { + +namespace dispatch { + +namespace internal { + +// A helper wrapper for |VARIANTARG| that is used to pass parameters to and from +// IDispatch::Invoke(). The latter accepts parameters as an array of +// |VARIANTARG| structures. The calling convention is: +// - [in] parameters are initialized and freed if needed by the caller. +// - [out] parameters are initialized by IDispatch::Invoke(). It is up to +// the caller to free leakable variants (such as VT_DISPATCH). +// - [in] [out] parameters are combination of both: the caller initializes +// them before the call and the callee assigns new values correctly +// freeing leakable variants. +// +// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that +// the resources allocated during the call will be properly freed. It also +// provides wraping methods that convert between C++ types and VARIANTs. +// The current convention is: +// - constant references are considered input parameters. +// - pointers to non-constant objects are considered output parameters. +// - [in] [out] parameters are not supported. +// +// It must be possible to cast a pointer to an array of |ScopedVariantArg| to +// a pointer to an array of |VARIANTARG| structures. +class ScopedVariantArg : public VARIANTARG { + public: + ScopedVariantArg() { + vt = VT_EMPTY; + } + + ~ScopedVariantArg() { + VariantClear(this); + } + + // Wrap() routines pack the input parameters into VARIANTARG structures so + // that they can be passed to IDispatch::Invoke. + + HRESULT Wrap(const VARIANT& param) { + return VariantCopy(this, ¶m); + } + + HRESULT Wrap(VARIANT* const & param) { + // Do nothing for an [out] parameter. + return S_OK; + } + + // Unwrap() routines unpack the output parameters from VARIANTARG structures + // to the locations specified by the caller. + + void Unwrap(const VARIANT& param_out) { + // Do nothing for an [in] parameter. + } + + void Unwrap(VARIANT* const & param_out) { + *param_out = *this; + vt = VT_EMPTY; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg); +}; + +// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical. +COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG), + scoped_variant_arg_should_not_add_data_members); + +} // namespace internal + +// Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of +// calling the desired method by its ID and implements logic for passing +// a variable number of in/out parameters to the called method. +// +// Current limitations: +// - in_out parameters are not supported. +// - more than $(MAX_ARITY) parameters are not supported. +// - the method ID cannot be cached and reused. +// - VARIANT is the only supported parameter type at the moment. +$range ARITY 0..MAX_ARITY +$for ARITY [[ +$range ARG 1..ARITY + + +$if ARITY > 0 [[template <$for ARG , [[typename P$(ARG)]]>]] + +HRESULT Invoke(IDispatch* object, + LPOLESTR name, + WORD flags, +$for ARG [[ + + const P$(ARG)& p$(ARG), +]] + + VARIANT* const & result_out) { + // Retrieve the ID of the method to be called. + DISPID disp_id; + HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &disp_id); + if (FAILED(hr)) + return hr; + + // Request the return value if asked by the caller. + internal::ScopedVariantArg result; + VARIANT* disp_result = NULL; + if (result_out != NULL) + disp_result = &result; + +$if ARITY > 0 [[ + + // Wrap the parameters into an array of VARIANT structures. + internal::ScopedVariantArg disp_args[$(ARITY)]; +$for ARG [[ + + hr = disp_args[$(ARITY) - $(ARG)].Wrap(p$(ARG)); + if (FAILED(hr)) + return hr; +]] +]] + + + // Invoke the method. + +$if ARITY > 0 [[ + DISPPARAMS disp_params = { disp_args, NULL, $(ARITY), 0 }; +]] $else [[ + DISPPARAMS disp_params = { NULL, NULL, 0, 0 }; +]] + + hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags, + &disp_params, disp_result, NULL, NULL); + if (FAILED(hr)) + return hr; + +$if ARITY > 0 [[ + + // Unwrap the parameters. +$for ARG [[ + + disp_args[$(ARITY) - $(ARG)].Unwrap(p$(ARG)); +]] +]] + + + // Unwrap the return value. + if (result_out != NULL) + result.Unwrap(result_out); + + return S_OK; +} + +]] + +} // namespace dispatch + +} // namespace remoting + +#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ diff --git a/remoting/host/plugin/daemon_installer_win.cc b/remoting/host/plugin/daemon_installer_win.cc index b502314..a78420b 100644 --- a/remoting/host/plugin/daemon_installer_win.cc +++ b/remoting/host/plugin/daemon_installer_win.cc @@ -19,6 +19,8 @@ #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 "remoting/base/dispatch_win.h" namespace omaha { #include "google_update/google_update_idl.h" @@ -28,6 +30,7 @@ namespace omaha { using base::win::ScopedBstr; using base::win::ScopedComPtr; +using base::win::ScopedVariant; namespace { @@ -63,7 +66,7 @@ namespace remoting { // per-machine Omaha instance. class DaemonComInstallerWin : public DaemonInstallerWin { public: - DaemonComInstallerWin(const ScopedComPtr<omaha::IGoogleUpdate3Web>& update3, + DaemonComInstallerWin(const ScopedComPtr<IDispatch>& update3, const CompletionCallback& done); // DaemonInstallerWin implementation. @@ -75,9 +78,9 @@ class DaemonComInstallerWin : public DaemonInstallerWin { void PollInstallationStatus(); // Omaha interfaces. - ScopedComPtr<omaha::IAppWeb> app_; - ScopedComPtr<omaha::IAppBundleWeb> bundle_; - ScopedComPtr<omaha::IGoogleUpdate3Web> update3_; + ScopedVariant app_; + ScopedVariant bundle_; + ScopedComPtr<IDispatch> update3_; base::Timer polling_timer_; }; @@ -106,7 +109,7 @@ class DaemonCommandLineInstallerWin }; DaemonComInstallerWin::DaemonComInstallerWin( - const ScopedComPtr<omaha::IGoogleUpdate3Web>& update3, + const ScopedComPtr<IDispatch>& update3, const CompletionCallback& done) : DaemonInstallerWin(done), update3_(update3), @@ -121,52 +124,50 @@ DaemonComInstallerWin::DaemonComInstallerWin( void DaemonComInstallerWin::Install() { // Create an app bundle. - ScopedComPtr<IDispatch> dispatch; - HRESULT hr = update3_->createAppBundleWeb(dispatch.Receive()); + HRESULT hr = dispatch::Invoke(update3_.get(), L"createAppBundleWeb", + DISPATCH_METHOD, bundle_.Receive()); if (FAILED(hr)) { Done(hr); return; } - - hr = dispatch.QueryInterface(omaha::IID_IAppBundleWeb, bundle_.ReceiveVoid()); - if (FAILED(hr)) { - Done(hr); + if (bundle_.type() != VT_DISPATCH) { + Done(DISP_E_TYPEMISMATCH); return; } - hr = bundle_->initialize(); + hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"initialize", DISPATCH_METHOD, + NULL); if (FAILED(hr)) { Done(hr); return; } // Add Chromoting Host to the bundle. - ScopedBstr appid(kHostOmahaAppid); - ScopedBstr empty(kOmahaEmpty); - ScopedBstr language(kOmahaLanguage); - hr = bundle_->createApp(appid, empty, language, empty); + ScopedVariant appid(kHostOmahaAppid); + ScopedVariant empty(kOmahaEmpty); + ScopedVariant language(kOmahaLanguage); + hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"createApp", DISPATCH_METHOD, + appid, empty, language, empty, NULL); if (FAILED(hr)) { Done(hr); return; } - hr = bundle_->checkForUpdate(); + hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"checkForUpdate", + DISPATCH_METHOD, NULL); if (FAILED(hr)) { Done(hr); return; } - dispatch.Release(); - hr = bundle_->get_appWeb(0, dispatch.Receive()); + hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"appWeb", + DISPATCH_PROPERTYGET, ScopedVariant(0), app_.Receive()); if (FAILED(hr)) { Done(hr); return; } - - hr = dispatch.QueryInterface(omaha::IID_IAppWeb, - app_.ReceiveVoid()); - if (FAILED(hr)) { - Done(hr); + if (app_.type() != VT_DISPATCH) { + Done(DISP_E_TYPEMISMATCH); return; } @@ -179,30 +180,32 @@ void DaemonComInstallerWin::PollInstallationStatus() { // 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. - ScopedComPtr<IDispatch> dispatch; - HRESULT hr = app_->get_currentState(dispatch.Receive()); + ScopedVariant current_state; + HRESULT hr = dispatch::Invoke(V_DISPATCH(&app_), L"currentState", + DISPATCH_PROPERTYGET, current_state.Receive()); if (FAILED(hr)) { Done(hr); return; } - - ScopedComPtr<omaha::ICurrentState> current_state; - hr = dispatch.QueryInterface(omaha::IID_ICurrentState, - current_state.ReceiveVoid()); - if (FAILED(hr)) { - Done(hr); + if (current_state.type() != VT_DISPATCH) { + Done(DISP_E_TYPEMISMATCH); return; } - LONG state; - hr = current_state->get_stateValue(&state); + ScopedVariant state; + hr = dispatch::Invoke(V_DISPATCH(¤t_state), L"stateValue", + DISPATCH_PROPERTYGET, state.Receive()); if (FAILED(hr)) { Done(hr); return; } + if (state.type() != VT_I4) { + Done(DISP_E_TYPEMISMATCH); + return; + } // Perform state-specific actions. - switch (state) { + switch (V_I4(&state)) { case omaha::STATE_INIT: case omaha::STATE_WAITING_TO_CHECK_FOR_UPDATE: case omaha::STATE_CHECKING_FOR_UPDATE: @@ -215,7 +218,8 @@ void DaemonComInstallerWin::PollInstallationStatus() { break; case omaha::STATE_UPDATE_AVAILABLE: - hr = bundle_->download(); + hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"download", + DISPATCH_METHOD, NULL); if (FAILED(hr)) { Done(hr); return; @@ -226,7 +230,8 @@ void DaemonComInstallerWin::PollInstallationStatus() { case omaha::STATE_EXTRACTING: case omaha::STATE_APPLYING_DIFFERENTIAL_PATCH: case omaha::STATE_READY_TO_INSTALL: - hr = bundle_->install(); + hr = dispatch::Invoke(V_DISPATCH(&bundle_), L"install", + DISPATCH_METHOD, NULL); if (FAILED(hr)) { Done(hr); return; @@ -240,17 +245,23 @@ void DaemonComInstallerWin::PollInstallationStatus() { return; case omaha::STATE_ERROR: { - HRESULT error_code; - hr = current_state->get_errorCode(&error_code); + ScopedVariant error_code; + hr = dispatch::Invoke(V_DISPATCH(¤t_state), L"errorCode", + DISPATCH_PROPERTYGET, error_code.Receive()); if (FAILED(hr)) { - error_code = hr; + Done(hr); + return; + } + if (error_code.type() != VT_UI4) { + Done(DISP_E_TYPEMISMATCH); + return; } - Done(error_code); + Done(V_UI4(&error_code)); return; } default: - LOG(ERROR) << "Unknown bundle state: " << state << "."; + LOG(ERROR) << "Unknown bundle state: " << V_I4(&state) << "."; Done(E_FAIL); return; } @@ -339,11 +350,11 @@ scoped_ptr<DaemonInstallerWin> DaemonInstallerWin::Create( bind_options.hwnd = GetTopLevelWindow(window_handle); bind_options.dwClassContext = CLSCTX_LOCAL_SERVER; - ScopedComPtr<omaha::IGoogleUpdate3Web> update3; + ScopedComPtr<IDispatch> update3; HRESULT result = ::CoGetObject( kOmahaElevationMoniker, &bind_options, - omaha::IID_IGoogleUpdate3Web, + IID_IDispatch, update3.ReceiveVoid()); if (SUCCEEDED(result)) { // The machine instance of Omaha is available and we successfully passed diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index f6afd62..d5fa23b 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -855,6 +855,7 @@ '../third_party/npapi/npapi.gyp:npapi', ], 'sources': [ + 'base/dispatch_win.h', 'host/branding.cc', 'host/branding.h', 'host/host_ui_resource.h', |