Chromium Code Reviews| Index: remoting/base/dispatch_win.h |
| diff --git a/remoting/base/dispatch_win.h b/remoting/base/dispatch_win.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c779d558bba25581ebb1f27be8bd78b5c2d5c7ed |
| --- /dev/null |
| +++ b/remoting/base/dispatch_win.h |
| @@ -0,0 +1,534 @@ |
| +// 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 if up to |
|
Wez
2012/06/13 17:55:16
typo: if -> is
alexeypa (please no reviews)
2012/06/13 18:45:11
Done.
|
| +// the caller to free leakable variants (such as VT_DISPATCH). |
|
Wez
2012/06/13 17:55:16
It's also the case that any value in the VARIANT o
alexeypa (please no reviews)
2012/06/13 18:45:11
No, it is not. One should be able to pass a pointe
Wez
2012/06/13 21:02:16
In which case it's important that the supplied VAR
alexeypa (please no reviews)
2012/06/14 16:27:20
The same rule applies to any other C++ function ta
|
| +// - [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 marshaling methods that convert between C++ types and VARIANTs. |
|
Wez
2012/06/13 17:55:16
nit: This implies that you could pass e.g. an int
alexeypa (please no reviews)
2012/06/13 18:45:11
With proper support (i.e. Marshal/Unmarshal method
Wez
2012/06/13 21:02:16
OK; consider adding a line to clarify that current
alexeypa (please no reviews)
2012/06/14 16:27:20
Will do.
|
| +// 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 should be possible to cast a pointer to an array of |ScopedVariantArg| to |
|
Wez
2012/06/13 17:55:16
nit: should -> must?
alexeypa (please no reviews)
2012/06/13 18:45:11
Done.
|
| +// a pointer to an array of |VARIANTARG| structures. |
| +class ScopedVariantArg : public VARIANTARG { |
| + public: |
| + ScopedVariantArg() { |
| + vt = VT_EMPTY; |
| + } |
| + |
| + ~ScopedVariantArg() { |
| + VariantClear(this); |
| + } |
| + |
| + // Marshal() routines pack the input parameters into VARIANTARG structures so |
| + // that they can be passed to IDispatch::Invoke. |
| + HRESULT Marshal(const VARIANT& param) { |
|
Wez
2012/06/13 17:55:16
nit: I would recommend CopyFrom rather than Marsha
alexeypa (please no reviews)
2012/06/13 18:45:11
CopyFrom sounds confusing to me. It also does not
Wez
2012/06/13 21:02:16
CopyFrom() describes the actual action that the ca
alexeypa (please no reviews)
2012/06/14 16:27:20
I still think CopyFrom() is one level too verbose
|
| + return VariantCopy(this, ¶m); |
| + } |
| + |
| + HRESULT Marshal(VARIANT* const & param) { |
| + // Do nothing for an [out] parameter. |
| + return S_OK; |
| + } |
| + |
| + // Unmarshal() routines unpack the output parameter from VARIANTARG structures |
| + // to the locations specified by the caller. |
| + void Unmarshal(const VARIANT& param_out) { |
|
Wez
2012/06/13 17:55:16
nit: Similarly, I'd recommend MoveTo rather then U
|
| + // Do nothing for an [in] parameter. |
| + } |
| + |
| + void Unmarshal(VARIANT* const & param_out) { |
| + *param_out = *this; |
|
Wez
2012/06/13 17:55:16
Do you need to VariantClear() param_out before rep
alexeypa (please no reviews)
2012/06/13 18:45:11
No, *param_out is not initialized at this point.
|
| + 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; |
| + |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[1]; |
| + hr = disp_args[1 - 1].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[1 - 1].Unmarshal(p1); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[2]; |
| + hr = disp_args[2 - 1].Marshal(p1); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[2 - 2].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[2 - 1].Unmarshal(p1); |
| + disp_args[2 - 2].Unmarshal(p2); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[3]; |
| + hr = disp_args[3 - 1].Marshal(p1); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[3 - 2].Marshal(p2); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[3 - 3].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[3 - 1].Unmarshal(p1); |
| + disp_args[3 - 2].Unmarshal(p2); |
| + disp_args[3 - 3].Unmarshal(p3); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[4]; |
| + hr = disp_args[4 - 1].Marshal(p1); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[4 - 2].Marshal(p2); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[4 - 3].Marshal(p3); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[4 - 4].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[4 - 1].Unmarshal(p1); |
| + disp_args[4 - 2].Unmarshal(p2); |
| + disp_args[4 - 3].Unmarshal(p3); |
| + disp_args[4 - 4].Unmarshal(p4); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[5]; |
| + hr = disp_args[5 - 1].Marshal(p1); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[5 - 2].Marshal(p2); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[5 - 3].Marshal(p3); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[5 - 4].Marshal(p4); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[5 - 5].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[5 - 1].Unmarshal(p1); |
| + disp_args[5 - 2].Unmarshal(p2); |
| + disp_args[5 - 3].Unmarshal(p3); |
| + disp_args[5 - 4].Unmarshal(p4); |
| + disp_args[5 - 5].Unmarshal(p5); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[6]; |
| + hr = disp_args[6 - 1].Marshal(p1); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[6 - 2].Marshal(p2); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[6 - 3].Marshal(p3); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[6 - 4].Marshal(p4); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[6 - 5].Marshal(p5); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[6 - 6].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[6 - 1].Unmarshal(p1); |
| + disp_args[6 - 2].Unmarshal(p2); |
| + disp_args[6 - 3].Unmarshal(p3); |
| + disp_args[6 - 4].Unmarshal(p4); |
| + disp_args[6 - 5].Unmarshal(p5); |
| + disp_args[6 - 6].Unmarshal(p6); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(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; |
| + |
| + // Marshal the parameters into an array of VARIANT structures. |
| + internal::ScopedVariantArg disp_args[7]; |
| + hr = disp_args[7 - 1].Marshal(p1); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[7 - 2].Marshal(p2); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[7 - 3].Marshal(p3); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[7 - 4].Marshal(p4); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[7 - 5].Marshal(p5); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[7 - 6].Marshal(p6); |
| + if (FAILED(hr)) |
| + return hr; |
| + hr = disp_args[7 - 7].Marshal(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; |
| + |
| + // Unmarshal the parameters. |
| + disp_args[7 - 1].Unmarshal(p1); |
| + disp_args[7 - 2].Unmarshal(p2); |
| + disp_args[7 - 3].Unmarshal(p3); |
| + disp_args[7 - 4].Unmarshal(p4); |
| + disp_args[7 - 5].Unmarshal(p5); |
| + disp_args[7 - 6].Unmarshal(p6); |
| + disp_args[7 - 7].Unmarshal(p7); |
| + |
| + // Unmarshal the return value. |
| + if (result_out != NULL) |
| + result.Unmarshal(result_out); |
| + |
| + return S_OK; |
| +} |
| + |
| +} // namespace dispatch |
| + |
| +} // namespace remoting |
| + |
| +#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_ |