Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: remoting/base/dispatch_win.h.pump

Issue 10532099: Switching to IDispatch::Invoke when calling Omaha interfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback. Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 $$ This is a pump file for generating file templates. Pump is a python
2 $$ script that is part of the Google Test suite of utilities. Description
3 $$ can be found here:
4 $$
5 $$ http://code.google.com/p/googletest/wiki/PumpManual
6
7 $$ MAX_ARITY controls the number of arguments that dispatch::Invoke() supports.
8 $$ It is choosen to match the number of arguments base::Bind() supports.
9 $var MAX_ARITY = 7
10 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
11 // Use of this source code is governed by a BSD-style license that can be
12 // found in the LICENSE file.
13
14 #ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
15 #define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
16
17 #include <oaidl.h>
18
19 #include "base/basictypes.h"
20 #include "base/template_util.h"
21 #include "base/win/scoped_variant.h"
22
23 namespace remoting {
24
25 namespace dispatch {
26
27 namespace internal {
28
29 // A helper wrapper for |VARIANTARG| that is used to pass parameters to and from
30 // IDispatch::Invoke(). The latter accepts parameters as an array of
31 // |VARIANTARG| structures. The calling convention is:
32 // - [in] parameters are initialized and freed if needed by the caller.
33 // - [out] parameters are initialized by IDispatch::Invoke(). It if up to
34 // the caller to free leakable variants (such as VT_DISPATCH).
35 // - [in] [out] parameters are combination of both: the caller initializes
36 // them before the call and the callee assigns new values correctly
37 // freeing leakable variants.
38 //
39 // Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
40 // the resources allocated during the call will be properly freed. It also
41 // provides marshaling methods that convert between C++ types and VARIANTs.
42 // The current convention is:
43 // - constant references are considered input parameters.
44 // - pointers to non-constant objects are considered output parameters.
45 // - [in] [out] parameters are not supported.
46 //
47 // It should be possible to cast a pointer to an array of |ScopedVariantArg| to
48 // a pointer to an array of |VARIANTARG| structures.
49 class ScopedVariantArg : public VARIANTARG {
50 public:
51 ScopedVariantArg() {
52 vt = VT_EMPTY;
53 }
54
55 ~ScopedVariantArg() {
56 VariantClear(this);
57 }
58
59 // Marshal() routines pack the input parameters into VARIANTARG structures so
60 // that they can be passed to IDispatch::Invoke.
61 HRESULT Marshal(const VARIANT& param) {
62 return VariantCopy(this, &param);
63 }
64
65 HRESULT Marshal(VARIANT* const & param) {
66 // Do nothing for an [out] parameter.
67 return S_OK;
68 }
69
70 // Unmarshal() routines unpack the output parameter from VARIANTARG structures
71 // to the locations specified by the caller.
72 void Unmarshal(const VARIANT& param_out) {
73 // Do nothing for an [in] parameter.
74 }
75
76 void Unmarshal(VARIANT* const & param_out) {
77 *param_out = *this;
78 vt = VT_EMPTY;
79 }
80
81 private:
82 DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg);
83 };
84
85 // Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
86 COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
87 scoped_variant_arg_should_not_add_data_members);
88
89 } // namespace internal
90
91 // Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of
92 // calling the desired method by its ID and implements logic for passing
93 // a variable number of in/out parameters to the called method.
94 //
95 // Current limitations:
96 // - in_out parameters are not supported.
97 // - more than $(MAX_ARITY) parameters are not supported.
98 // - the method ID cannot be cached and reused.
99 // - VARIANT is the only supported parameter type at the moment.
100 $range ARITY 0..MAX_ARITY
101 $for ARITY [[
102 $range ARG 1..ARITY
103
104
105 $if ARITY > 0 [[template <$for ARG , [[typename P$(ARG)]]>]]
106
107 HRESULT Invoke(IDispatch* object,
108 LPOLESTR name,
109 WORD flags,
110 $for ARG [[
111
112 const P$(ARG)& p$(ARG),
113 ]]
114
115 VARIANT* const & result_out) {
116 // Retrieve the ID of the method to be called.
117 DISPID disp_id;
118 HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
119 &disp_id);
120 if (FAILED(hr))
121 return hr;
122
123 // Request the return value if asked by the caller.
124 internal::ScopedVariantArg result;
125 VARIANT* disp_result = NULL;
126 if (result_out != NULL)
127 disp_result = &result;
128
129 $if ARITY > 0 [[
130
131 // Marshal the parameters into an array of VARIANT structures.
132 internal::ScopedVariantArg disp_args[$(ARITY)];
133 $for ARG [[
134
135 hr = disp_args[$(ARITY) - $(ARG)].Marshal(p$(ARG));
136 if (FAILED(hr))
137 return hr;
138 ]]
139 ]]
140
141
142 // Invoke the method.
143
144 $if ARITY > 0 [[
145 DISPPARAMS disp_params = { disp_args, NULL, $(ARITY), 0 };
146 ]] $else [[
147 DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
148 ]]
149
150 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
151 &disp_params, disp_result, NULL, NULL);
152 if (FAILED(hr))
153 return hr;
154
155 $if ARITY > 0 [[
156
157 // Unmarshal the parameters.
158 $for ARG [[
159
160 disp_args[$(ARITY) - $(ARG)].Unmarshal(p$(ARG));
161 ]]
162 ]]
163
164
165 // Unmarshal the return value.
166 if (result_out != NULL)
167 result.Unmarshal(result_out);
168
169 return S_OK;
170 }
171
172 ]]
173
174 } // namespace dispatch
175
176 } // namespace remoting
177
178 #endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698