blob: 8f00561520a9340546ae8927d472823af4367fff [file] [log] [blame]
[email protected]3a1a51a22012-06-13 20:45:241// This file was GENERATED by command:
2// pump.py dispatch_win.h.pump
3// DO NOT EDIT BY HAND!!!
4
5// Copyright (c) 2012 The Chromium Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style license that can be
7// found in the LICENSE file.
8
9#ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
10#define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
11
12#include <oaidl.h>
13
avi5a080f012015-12-22 23:15:4314#include "base/macros.h"
[email protected]3a1a51a22012-06-13 20:45:2415#include "base/template_util.h"
16#include "base/win/scoped_variant.h"
17
18namespace remoting {
19
20namespace dispatch {
21
22namespace internal {
23
24// A helper wrapper for |VARIANTARG| that is used to pass parameters to and from
25// IDispatch::Invoke(). The latter accepts parameters as an array of
[email protected]56a510782012-06-21 20:42:2526// |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is:
[email protected]3a1a51a22012-06-13 20:45:2427// - [in] parameters are initialized and freed if needed by the caller.
28// - [out] parameters are initialized by IDispatch::Invoke(). It is up to
29// the caller to free leakable variants (such as VT_DISPATCH).
30// - [in] [out] parameters are combination of both: the caller initializes
31// them before the call and the callee assigns new values correctly
32// freeing leakable variants.
33//
34// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
35// the resources allocated during the call will be properly freed. It also
[email protected]56a510782012-06-21 20:42:2536// provides wrapping methods that convert between C++ types and VARIANTs.
37// At the moment the only supported parameter type is |VARIANT| (or
38// |VARIANTARG|).
[email protected]3a1a51a22012-06-13 20:45:2439//
40// It must be possible to cast a pointer to an array of |ScopedVariantArg| to
41// a pointer to an array of |VARIANTARG| structures.
42class ScopedVariantArg : public VARIANTARG {
43 public:
44 ScopedVariantArg() {
45 vt = VT_EMPTY;
46 }
47
48 ~ScopedVariantArg() {
49 VariantClear(this);
50 }
51
52 // Wrap() routines pack the input parameters into VARIANTARG structures so
53 // that they can be passed to IDispatch::Invoke.
54
55 HRESULT Wrap(const VARIANT& param) {
[email protected]56a510782012-06-21 20:42:2556 DCHECK(vt == VT_EMPTY);
[email protected]3a1a51a22012-06-13 20:45:2457 return VariantCopy(this, &param);
58 }
59
60 HRESULT Wrap(VARIANT* const & param) {
[email protected]56a510782012-06-21 20:42:2561 DCHECK(vt == VT_EMPTY);
62
63 // Make the input value of an [in] [out] parameter visible to
64 // IDispatch::Invoke().
65 //
66 // N.B. We treat both [out] and [in] [out] parameters as [in] [out]. In
67 // other words the caller is always responsible for initializing and freeing
68 // [out] and [in] [out] parameters.
69 Swap(param);
[email protected]3a1a51a22012-06-13 20:45:2470 return S_OK;
71 }
72
73 // Unwrap() routines unpack the output parameters from VARIANTARG structures
74 // to the locations specified by the caller.
75
76 void Unwrap(const VARIANT& param_out) {
77 // Do nothing for an [in] parameter.
78 }
79
80 void Unwrap(VARIANT* const & param_out) {
[email protected]56a510782012-06-21 20:42:2581 // Return the output value of an [in] [out] parameter to the caller.
82 Swap(param_out);
[email protected]3a1a51a22012-06-13 20:45:2483 }
84
85 private:
[email protected]56a510782012-06-21 20:42:2586 // Exchanges the value (and ownership) of the passed VARIANT with the one
87 // wrapped by |ScopedVariantArg|.
88 void Swap(VARIANT* other) {
89 VARIANT temp = *other;
90 *other = *this;
91 *static_cast<VARIANTARG*>(this) = temp;
92 }
93
[email protected]3a1a51a22012-06-13 20:45:2494 DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg);
95};
96
97// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
mostynbf62b08923a2015-01-05 22:58:1598static_assert(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
99 "scoped variant arg should not add data members");
[email protected]3a1a51a22012-06-13 20:45:24100
101} // namespace internal
102
103// Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of
104// calling the desired method by its ID and implements logic for passing
105// a variable number of in/out parameters to the called method.
106//
[email protected]56a510782012-06-21 20:42:25107// The calling convention is:
108// - [in] parameters are passsed as a constant reference or by value.
109// - [out] and [in] [out] parameters are passed by pointer. The pointed value
110// is overwritten when the function returns. The pointed-to value must
111// be initialized before the call, and will be replaced when it returns.
112// [out] parameters may be initialized to VT_EMPTY.
113//
[email protected]3a1a51a22012-06-13 20:45:24114// Current limitations:
[email protected]3a1a51a22012-06-13 20:45:24115// - more than 7 parameters are not supported.
116// - the method ID cannot be cached and reused.
117// - VARIANT is the only supported parameter type at the moment.
118
119HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53120 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24121 WORD flags,
122 VARIANT* const & result_out) {
123 // Retrieve the ID of the method to be called.
124 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53125 LPOLESTR name = const_cast<LPOLESTR>(const_name);
126 HRESULT hr = object->GetIDsOfNames(
127 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24128 if (FAILED(hr))
129 return hr;
130
131 // Request the return value if asked by the caller.
132 internal::ScopedVariantArg result;
133 VARIANT* disp_result = NULL;
134 if (result_out != NULL)
135 disp_result = &result;
136
137
[email protected]e39e80e2012-07-17 22:24:48138 // Invoke the method passing the parameters via the DISPPARAMS structure.
139 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
140 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
141 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24142 DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
[email protected]e39e80e2012-07-17 22:24:48143 DISPID dispid_named = DISPID_PROPERTYPUT;
144 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
145 disp_params.cNamedArgs = 1;
146 disp_params.rgdispidNamedArgs = &dispid_named;
147 }
148
[email protected]3a1a51a22012-06-13 20:45:24149 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
150 &disp_params, disp_result, NULL, NULL);
151 if (FAILED(hr))
152 return hr;
153
154
155 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25156 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24157 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25158 }
[email protected]3a1a51a22012-06-13 20:45:24159
160 return S_OK;
161}
162
163template <typename P1>
164HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53165 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24166 WORD flags,
167 const P1& p1,
168 VARIANT* const & result_out) {
169 // Retrieve the ID of the method to be called.
170 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53171 LPOLESTR name = const_cast<LPOLESTR>(const_name);
172 HRESULT hr = object->GetIDsOfNames(
173 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24174 if (FAILED(hr))
175 return hr;
176
177 // Request the return value if asked by the caller.
178 internal::ScopedVariantArg result;
179 VARIANT* disp_result = NULL;
180 if (result_out != NULL)
181 disp_result = &result;
182
183 // Wrap the parameters into an array of VARIANT structures.
184 internal::ScopedVariantArg disp_args[1];
185 hr = disp_args[1 - 1].Wrap(p1);
186 if (FAILED(hr))
187 return hr;
188
[email protected]e39e80e2012-07-17 22:24:48189 // Invoke the method passing the parameters via the DISPPARAMS structure.
190 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
191 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
192 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24193 DISPPARAMS disp_params = { disp_args, NULL, 1, 0 };
[email protected]e39e80e2012-07-17 22:24:48194 DISPID dispid_named = DISPID_PROPERTYPUT;
195 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
196 disp_params.cNamedArgs = 1;
197 disp_params.rgdispidNamedArgs = &dispid_named;
198 }
199
[email protected]3a1a51a22012-06-13 20:45:24200 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
201 &disp_params, disp_result, NULL, NULL);
202 if (FAILED(hr))
203 return hr;
204
205 // Unwrap the parameters.
206 disp_args[1 - 1].Unwrap(p1);
207
208 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25209 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24210 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25211 }
[email protected]3a1a51a22012-06-13 20:45:24212
213 return S_OK;
214}
215
216template <typename P1, typename P2>
217HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53218 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24219 WORD flags,
220 const P1& p1,
221 const P2& p2,
222 VARIANT* const & result_out) {
223 // Retrieve the ID of the method to be called.
224 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53225 LPOLESTR name = const_cast<LPOLESTR>(const_name);
226 HRESULT hr = object->GetIDsOfNames(
227 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24228 if (FAILED(hr))
229 return hr;
230
231 // Request the return value if asked by the caller.
232 internal::ScopedVariantArg result;
233 VARIANT* disp_result = NULL;
234 if (result_out != NULL)
235 disp_result = &result;
236
237 // Wrap the parameters into an array of VARIANT structures.
238 internal::ScopedVariantArg disp_args[2];
239 hr = disp_args[2 - 1].Wrap(p1);
240 if (FAILED(hr))
241 return hr;
242 hr = disp_args[2 - 2].Wrap(p2);
243 if (FAILED(hr))
244 return hr;
245
[email protected]e39e80e2012-07-17 22:24:48246 // Invoke the method passing the parameters via the DISPPARAMS structure.
247 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
248 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
249 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24250 DISPPARAMS disp_params = { disp_args, NULL, 2, 0 };
[email protected]e39e80e2012-07-17 22:24:48251 DISPID dispid_named = DISPID_PROPERTYPUT;
252 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
253 disp_params.cNamedArgs = 1;
254 disp_params.rgdispidNamedArgs = &dispid_named;
255 }
256
[email protected]3a1a51a22012-06-13 20:45:24257 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
258 &disp_params, disp_result, NULL, NULL);
259 if (FAILED(hr))
260 return hr;
261
262 // Unwrap the parameters.
263 disp_args[2 - 1].Unwrap(p1);
264 disp_args[2 - 2].Unwrap(p2);
265
266 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25267 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24268 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25269 }
[email protected]3a1a51a22012-06-13 20:45:24270
271 return S_OK;
272}
273
274template <typename P1, typename P2, typename P3>
275HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53276 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24277 WORD flags,
278 const P1& p1,
279 const P2& p2,
280 const P3& p3,
281 VARIANT* const & result_out) {
282 // Retrieve the ID of the method to be called.
283 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53284 LPOLESTR name = const_cast<LPOLESTR>(const_name);
285 HRESULT hr = object->GetIDsOfNames(
286 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24287 if (FAILED(hr))
288 return hr;
289
290 // Request the return value if asked by the caller.
291 internal::ScopedVariantArg result;
292 VARIANT* disp_result = NULL;
293 if (result_out != NULL)
294 disp_result = &result;
295
296 // Wrap the parameters into an array of VARIANT structures.
297 internal::ScopedVariantArg disp_args[3];
298 hr = disp_args[3 - 1].Wrap(p1);
299 if (FAILED(hr))
300 return hr;
301 hr = disp_args[3 - 2].Wrap(p2);
302 if (FAILED(hr))
303 return hr;
304 hr = disp_args[3 - 3].Wrap(p3);
305 if (FAILED(hr))
306 return hr;
307
[email protected]e39e80e2012-07-17 22:24:48308 // Invoke the method passing the parameters via the DISPPARAMS structure.
309 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
310 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
311 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24312 DISPPARAMS disp_params = { disp_args, NULL, 3, 0 };
[email protected]e39e80e2012-07-17 22:24:48313 DISPID dispid_named = DISPID_PROPERTYPUT;
314 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
315 disp_params.cNamedArgs = 1;
316 disp_params.rgdispidNamedArgs = &dispid_named;
317 }
318
[email protected]3a1a51a22012-06-13 20:45:24319 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
320 &disp_params, disp_result, NULL, NULL);
321 if (FAILED(hr))
322 return hr;
323
324 // Unwrap the parameters.
325 disp_args[3 - 1].Unwrap(p1);
326 disp_args[3 - 2].Unwrap(p2);
327 disp_args[3 - 3].Unwrap(p3);
328
329 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25330 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24331 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25332 }
[email protected]3a1a51a22012-06-13 20:45:24333
334 return S_OK;
335}
336
337template <typename P1, typename P2, typename P3, typename P4>
338HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53339 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24340 WORD flags,
341 const P1& p1,
342 const P2& p2,
343 const P3& p3,
344 const P4& p4,
345 VARIANT* const & result_out) {
346 // Retrieve the ID of the method to be called.
347 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53348 LPOLESTR name = const_cast<LPOLESTR>(const_name);
349 HRESULT hr = object->GetIDsOfNames(
350 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24351 if (FAILED(hr))
352 return hr;
353
354 // Request the return value if asked by the caller.
355 internal::ScopedVariantArg result;
356 VARIANT* disp_result = NULL;
357 if (result_out != NULL)
358 disp_result = &result;
359
360 // Wrap the parameters into an array of VARIANT structures.
361 internal::ScopedVariantArg disp_args[4];
362 hr = disp_args[4 - 1].Wrap(p1);
363 if (FAILED(hr))
364 return hr;
365 hr = disp_args[4 - 2].Wrap(p2);
366 if (FAILED(hr))
367 return hr;
368 hr = disp_args[4 - 3].Wrap(p3);
369 if (FAILED(hr))
370 return hr;
371 hr = disp_args[4 - 4].Wrap(p4);
372 if (FAILED(hr))
373 return hr;
374
[email protected]e39e80e2012-07-17 22:24:48375 // Invoke the method passing the parameters via the DISPPARAMS structure.
376 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
377 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
378 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24379 DISPPARAMS disp_params = { disp_args, NULL, 4, 0 };
[email protected]e39e80e2012-07-17 22:24:48380 DISPID dispid_named = DISPID_PROPERTYPUT;
381 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
382 disp_params.cNamedArgs = 1;
383 disp_params.rgdispidNamedArgs = &dispid_named;
384 }
385
[email protected]3a1a51a22012-06-13 20:45:24386 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
387 &disp_params, disp_result, NULL, NULL);
388 if (FAILED(hr))
389 return hr;
390
391 // Unwrap the parameters.
392 disp_args[4 - 1].Unwrap(p1);
393 disp_args[4 - 2].Unwrap(p2);
394 disp_args[4 - 3].Unwrap(p3);
395 disp_args[4 - 4].Unwrap(p4);
396
397 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25398 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24399 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25400 }
[email protected]3a1a51a22012-06-13 20:45:24401
402 return S_OK;
403}
404
405template <typename P1, typename P2, typename P3, typename P4, typename P5>
406HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53407 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24408 WORD flags,
409 const P1& p1,
410 const P2& p2,
411 const P3& p3,
412 const P4& p4,
413 const P5& p5,
414 VARIANT* const & result_out) {
415 // Retrieve the ID of the method to be called.
416 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53417 LPOLESTR name = const_cast<LPOLESTR>(const_name);
418 HRESULT hr = object->GetIDsOfNames(
419 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24420 if (FAILED(hr))
421 return hr;
422
423 // Request the return value if asked by the caller.
424 internal::ScopedVariantArg result;
425 VARIANT* disp_result = NULL;
426 if (result_out != NULL)
427 disp_result = &result;
428
429 // Wrap the parameters into an array of VARIANT structures.
430 internal::ScopedVariantArg disp_args[5];
431 hr = disp_args[5 - 1].Wrap(p1);
432 if (FAILED(hr))
433 return hr;
434 hr = disp_args[5 - 2].Wrap(p2);
435 if (FAILED(hr))
436 return hr;
437 hr = disp_args[5 - 3].Wrap(p3);
438 if (FAILED(hr))
439 return hr;
440 hr = disp_args[5 - 4].Wrap(p4);
441 if (FAILED(hr))
442 return hr;
443 hr = disp_args[5 - 5].Wrap(p5);
444 if (FAILED(hr))
445 return hr;
446
[email protected]e39e80e2012-07-17 22:24:48447 // Invoke the method passing the parameters via the DISPPARAMS structure.
448 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
449 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
450 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24451 DISPPARAMS disp_params = { disp_args, NULL, 5, 0 };
[email protected]e39e80e2012-07-17 22:24:48452 DISPID dispid_named = DISPID_PROPERTYPUT;
453 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
454 disp_params.cNamedArgs = 1;
455 disp_params.rgdispidNamedArgs = &dispid_named;
456 }
457
[email protected]3a1a51a22012-06-13 20:45:24458 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
459 &disp_params, disp_result, NULL, NULL);
460 if (FAILED(hr))
461 return hr;
462
463 // Unwrap the parameters.
464 disp_args[5 - 1].Unwrap(p1);
465 disp_args[5 - 2].Unwrap(p2);
466 disp_args[5 - 3].Unwrap(p3);
467 disp_args[5 - 4].Unwrap(p4);
468 disp_args[5 - 5].Unwrap(p5);
469
470 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25471 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24472 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25473 }
[email protected]3a1a51a22012-06-13 20:45:24474
475 return S_OK;
476}
477
478template <typename P1, typename P2, typename P3, typename P4, typename P5,
479 typename P6>
480HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53481 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24482 WORD flags,
483 const P1& p1,
484 const P2& p2,
485 const P3& p3,
486 const P4& p4,
487 const P5& p5,
488 const P6& p6,
489 VARIANT* const & result_out) {
490 // Retrieve the ID of the method to be called.
491 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53492 LPOLESTR name = const_cast<LPOLESTR>(const_name);
493 HRESULT hr = object->GetIDsOfNames(
494 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24495 if (FAILED(hr))
496 return hr;
497
498 // Request the return value if asked by the caller.
499 internal::ScopedVariantArg result;
500 VARIANT* disp_result = NULL;
501 if (result_out != NULL)
502 disp_result = &result;
503
504 // Wrap the parameters into an array of VARIANT structures.
505 internal::ScopedVariantArg disp_args[6];
506 hr = disp_args[6 - 1].Wrap(p1);
507 if (FAILED(hr))
508 return hr;
509 hr = disp_args[6 - 2].Wrap(p2);
510 if (FAILED(hr))
511 return hr;
512 hr = disp_args[6 - 3].Wrap(p3);
513 if (FAILED(hr))
514 return hr;
515 hr = disp_args[6 - 4].Wrap(p4);
516 if (FAILED(hr))
517 return hr;
518 hr = disp_args[6 - 5].Wrap(p5);
519 if (FAILED(hr))
520 return hr;
521 hr = disp_args[6 - 6].Wrap(p6);
522 if (FAILED(hr))
523 return hr;
524
[email protected]e39e80e2012-07-17 22:24:48525 // Invoke the method passing the parameters via the DISPPARAMS structure.
526 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
527 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
528 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24529 DISPPARAMS disp_params = { disp_args, NULL, 6, 0 };
[email protected]e39e80e2012-07-17 22:24:48530 DISPID dispid_named = DISPID_PROPERTYPUT;
531 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
532 disp_params.cNamedArgs = 1;
533 disp_params.rgdispidNamedArgs = &dispid_named;
534 }
535
[email protected]3a1a51a22012-06-13 20:45:24536 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
537 &disp_params, disp_result, NULL, NULL);
538 if (FAILED(hr))
539 return hr;
540
541 // Unwrap the parameters.
542 disp_args[6 - 1].Unwrap(p1);
543 disp_args[6 - 2].Unwrap(p2);
544 disp_args[6 - 3].Unwrap(p3);
545 disp_args[6 - 4].Unwrap(p4);
546 disp_args[6 - 5].Unwrap(p5);
547 disp_args[6 - 6].Unwrap(p6);
548
549 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25550 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24551 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25552 }
[email protected]3a1a51a22012-06-13 20:45:24553
554 return S_OK;
555}
556
557template <typename P1, typename P2, typename P3, typename P4, typename P5,
558 typename P6, typename P7>
559HRESULT Invoke(IDispatch* object,
[email protected]900634e02014-07-23 22:04:53560 LPCOLESTR const_name,
[email protected]3a1a51a22012-06-13 20:45:24561 WORD flags,
562 const P1& p1,
563 const P2& p2,
564 const P3& p3,
565 const P4& p4,
566 const P5& p5,
567 const P6& p6,
568 const P7& p7,
569 VARIANT* const & result_out) {
570 // Retrieve the ID of the method to be called.
571 DISPID disp_id;
[email protected]900634e02014-07-23 22:04:53572 LPOLESTR name = const_cast<LPOLESTR>(const_name);
573 HRESULT hr = object->GetIDsOfNames(
574 IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
[email protected]3a1a51a22012-06-13 20:45:24575 if (FAILED(hr))
576 return hr;
577
578 // Request the return value if asked by the caller.
579 internal::ScopedVariantArg result;
580 VARIANT* disp_result = NULL;
581 if (result_out != NULL)
582 disp_result = &result;
583
584 // Wrap the parameters into an array of VARIANT structures.
585 internal::ScopedVariantArg disp_args[7];
586 hr = disp_args[7 - 1].Wrap(p1);
587 if (FAILED(hr))
588 return hr;
589 hr = disp_args[7 - 2].Wrap(p2);
590 if (FAILED(hr))
591 return hr;
592 hr = disp_args[7 - 3].Wrap(p3);
593 if (FAILED(hr))
594 return hr;
595 hr = disp_args[7 - 4].Wrap(p4);
596 if (FAILED(hr))
597 return hr;
598 hr = disp_args[7 - 5].Wrap(p5);
599 if (FAILED(hr))
600 return hr;
601 hr = disp_args[7 - 6].Wrap(p6);
602 if (FAILED(hr))
603 return hr;
604 hr = disp_args[7 - 7].Wrap(p7);
605 if (FAILED(hr))
606 return hr;
607
[email protected]e39e80e2012-07-17 22:24:48608 // Invoke the method passing the parameters via the DISPPARAMS structure.
609 // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
610 // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
611 // structure members should be initialized.
[email protected]3a1a51a22012-06-13 20:45:24612 DISPPARAMS disp_params = { disp_args, NULL, 7, 0 };
[email protected]e39e80e2012-07-17 22:24:48613 DISPID dispid_named = DISPID_PROPERTYPUT;
614 if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
615 disp_params.cNamedArgs = 1;
616 disp_params.rgdispidNamedArgs = &dispid_named;
617 }
618
[email protected]3a1a51a22012-06-13 20:45:24619 hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
620 &disp_params, disp_result, NULL, NULL);
621 if (FAILED(hr))
622 return hr;
623
624 // Unwrap the parameters.
625 disp_args[7 - 1].Unwrap(p1);
626 disp_args[7 - 2].Unwrap(p2);
627 disp_args[7 - 3].Unwrap(p3);
628 disp_args[7 - 4].Unwrap(p4);
629 disp_args[7 - 5].Unwrap(p5);
630 disp_args[7 - 6].Unwrap(p6);
631 disp_args[7 - 7].Unwrap(p7);
632
633 // Unwrap the return value.
[email protected]56a510782012-06-21 20:42:25634 if (result_out != NULL) {
[email protected]3a1a51a22012-06-13 20:45:24635 result.Unwrap(result_out);
[email protected]56a510782012-06-21 20:42:25636 }
[email protected]3a1a51a22012-06-13 20:45:24637
638 return S_OK;
639}
640
641} // namespace dispatch
642
643} // namespace remoting
644
645#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_