1// 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
14#include "base/basictypes.h"
15#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
26// |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is:
27//   - [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
36// provides wrapping methods that convert between C++ types and VARIANTs.
37// At the moment the only supported parameter type is |VARIANT| (or
38// |VARIANTARG|).
39//
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) {
56    DCHECK(vt == VT_EMPTY);
57    return VariantCopy(this, &param);
58  }
59
60  HRESULT Wrap(VARIANT* const & param) {
61    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);
70    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) {
81    // Return the output value of an [in] [out] parameter to the caller.
82    Swap(param_out);
83  }
84
85 private:
86  // 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
94  DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg);
95};
96
97// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
98COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
99               scoped_variant_arg_should_not_add_data_members);
100
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//
107// 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//
114// Current limitations:
115//   - 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,
120               LPOLESTR name,
121               WORD flags,
122               VARIANT* const & result_out) {
123  // Retrieve the ID of the method to be called.
124  DISPID disp_id;
125  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
126                                     &disp_id);
127  if (FAILED(hr))
128    return hr;
129
130  // Request the return value if asked by the caller.
131  internal::ScopedVariantArg result;
132  VARIANT* disp_result = NULL;
133  if (result_out != NULL)
134    disp_result = &result;
135
136
137  // Invoke the method passing the parameters via the DISPPARAMS structure.
138  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
139  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
140  // structure members should be initialized.
141  DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
142  DISPID dispid_named = DISPID_PROPERTYPUT;
143  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
144    disp_params.cNamedArgs = 1;
145    disp_params.rgdispidNamedArgs = &dispid_named;
146  }
147
148  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
149                      &disp_params, disp_result, NULL, NULL);
150  if (FAILED(hr))
151    return hr;
152
153
154  // Unwrap the return value.
155  if (result_out != NULL) {
156    result.Unwrap(result_out);
157  }
158
159  return S_OK;
160}
161
162template <typename P1>
163HRESULT Invoke(IDispatch* object,
164               LPOLESTR name,
165               WORD flags,
166               const P1& p1,
167               VARIANT* const & result_out) {
168  // Retrieve the ID of the method to be called.
169  DISPID disp_id;
170  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
171                                     &disp_id);
172  if (FAILED(hr))
173    return hr;
174
175  // Request the return value if asked by the caller.
176  internal::ScopedVariantArg result;
177  VARIANT* disp_result = NULL;
178  if (result_out != NULL)
179    disp_result = &result;
180
181  // Wrap the parameters into an array of VARIANT structures.
182  internal::ScopedVariantArg disp_args[1];
183  hr = disp_args[1 - 1].Wrap(p1);
184  if (FAILED(hr))
185    return hr;
186
187  // Invoke the method passing the parameters via the DISPPARAMS structure.
188  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
189  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
190  // structure members should be initialized.
191  DISPPARAMS disp_params = { disp_args, NULL, 1, 0 };
192  DISPID dispid_named = DISPID_PROPERTYPUT;
193  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
194    disp_params.cNamedArgs = 1;
195    disp_params.rgdispidNamedArgs = &dispid_named;
196  }
197
198  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
199                      &disp_params, disp_result, NULL, NULL);
200  if (FAILED(hr))
201    return hr;
202
203  // Unwrap the parameters.
204  disp_args[1 - 1].Unwrap(p1);
205
206  // Unwrap the return value.
207  if (result_out != NULL) {
208    result.Unwrap(result_out);
209  }
210
211  return S_OK;
212}
213
214template <typename P1, typename P2>
215HRESULT Invoke(IDispatch* object,
216               LPOLESTR name,
217               WORD flags,
218               const P1& p1,
219               const P2& p2,
220               VARIANT* const & result_out) {
221  // Retrieve the ID of the method to be called.
222  DISPID disp_id;
223  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
224                                     &disp_id);
225  if (FAILED(hr))
226    return hr;
227
228  // Request the return value if asked by the caller.
229  internal::ScopedVariantArg result;
230  VARIANT* disp_result = NULL;
231  if (result_out != NULL)
232    disp_result = &result;
233
234  // Wrap the parameters into an array of VARIANT structures.
235  internal::ScopedVariantArg disp_args[2];
236  hr = disp_args[2 - 1].Wrap(p1);
237  if (FAILED(hr))
238    return hr;
239  hr = disp_args[2 - 2].Wrap(p2);
240  if (FAILED(hr))
241    return hr;
242
243  // Invoke the method passing the parameters via the DISPPARAMS structure.
244  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
245  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
246  // structure members should be initialized.
247  DISPPARAMS disp_params = { disp_args, NULL, 2, 0 };
248  DISPID dispid_named = DISPID_PROPERTYPUT;
249  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
250    disp_params.cNamedArgs = 1;
251    disp_params.rgdispidNamedArgs = &dispid_named;
252  }
253
254  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
255                      &disp_params, disp_result, NULL, NULL);
256  if (FAILED(hr))
257    return hr;
258
259  // Unwrap the parameters.
260  disp_args[2 - 1].Unwrap(p1);
261  disp_args[2 - 2].Unwrap(p2);
262
263  // Unwrap the return value.
264  if (result_out != NULL) {
265    result.Unwrap(result_out);
266  }
267
268  return S_OK;
269}
270
271template <typename P1, typename P2, typename P3>
272HRESULT Invoke(IDispatch* object,
273               LPOLESTR name,
274               WORD flags,
275               const P1& p1,
276               const P2& p2,
277               const P3& p3,
278               VARIANT* const & result_out) {
279  // Retrieve the ID of the method to be called.
280  DISPID disp_id;
281  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
282                                     &disp_id);
283  if (FAILED(hr))
284    return hr;
285
286  // Request the return value if asked by the caller.
287  internal::ScopedVariantArg result;
288  VARIANT* disp_result = NULL;
289  if (result_out != NULL)
290    disp_result = &result;
291
292  // Wrap the parameters into an array of VARIANT structures.
293  internal::ScopedVariantArg disp_args[3];
294  hr = disp_args[3 - 1].Wrap(p1);
295  if (FAILED(hr))
296    return hr;
297  hr = disp_args[3 - 2].Wrap(p2);
298  if (FAILED(hr))
299    return hr;
300  hr = disp_args[3 - 3].Wrap(p3);
301  if (FAILED(hr))
302    return hr;
303
304  // Invoke the method passing the parameters via the DISPPARAMS structure.
305  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
306  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
307  // structure members should be initialized.
308  DISPPARAMS disp_params = { disp_args, NULL, 3, 0 };
309  DISPID dispid_named = DISPID_PROPERTYPUT;
310  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
311    disp_params.cNamedArgs = 1;
312    disp_params.rgdispidNamedArgs = &dispid_named;
313  }
314
315  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
316                      &disp_params, disp_result, NULL, NULL);
317  if (FAILED(hr))
318    return hr;
319
320  // Unwrap the parameters.
321  disp_args[3 - 1].Unwrap(p1);
322  disp_args[3 - 2].Unwrap(p2);
323  disp_args[3 - 3].Unwrap(p3);
324
325  // Unwrap the return value.
326  if (result_out != NULL) {
327    result.Unwrap(result_out);
328  }
329
330  return S_OK;
331}
332
333template <typename P1, typename P2, typename P3, typename P4>
334HRESULT Invoke(IDispatch* object,
335               LPOLESTR name,
336               WORD flags,
337               const P1& p1,
338               const P2& p2,
339               const P3& p3,
340               const P4& p4,
341               VARIANT* const & result_out) {
342  // Retrieve the ID of the method to be called.
343  DISPID disp_id;
344  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
345                                     &disp_id);
346  if (FAILED(hr))
347    return hr;
348
349  // Request the return value if asked by the caller.
350  internal::ScopedVariantArg result;
351  VARIANT* disp_result = NULL;
352  if (result_out != NULL)
353    disp_result = &result;
354
355  // Wrap the parameters into an array of VARIANT structures.
356  internal::ScopedVariantArg disp_args[4];
357  hr = disp_args[4 - 1].Wrap(p1);
358  if (FAILED(hr))
359    return hr;
360  hr = disp_args[4 - 2].Wrap(p2);
361  if (FAILED(hr))
362    return hr;
363  hr = disp_args[4 - 3].Wrap(p3);
364  if (FAILED(hr))
365    return hr;
366  hr = disp_args[4 - 4].Wrap(p4);
367  if (FAILED(hr))
368    return hr;
369
370  // Invoke the method passing the parameters via the DISPPARAMS structure.
371  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
372  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
373  // structure members should be initialized.
374  DISPPARAMS disp_params = { disp_args, NULL, 4, 0 };
375  DISPID dispid_named = DISPID_PROPERTYPUT;
376  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
377    disp_params.cNamedArgs = 1;
378    disp_params.rgdispidNamedArgs = &dispid_named;
379  }
380
381  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
382                      &disp_params, disp_result, NULL, NULL);
383  if (FAILED(hr))
384    return hr;
385
386  // Unwrap the parameters.
387  disp_args[4 - 1].Unwrap(p1);
388  disp_args[4 - 2].Unwrap(p2);
389  disp_args[4 - 3].Unwrap(p3);
390  disp_args[4 - 4].Unwrap(p4);
391
392  // Unwrap the return value.
393  if (result_out != NULL) {
394    result.Unwrap(result_out);
395  }
396
397  return S_OK;
398}
399
400template <typename P1, typename P2, typename P3, typename P4, typename P5>
401HRESULT Invoke(IDispatch* object,
402               LPOLESTR name,
403               WORD flags,
404               const P1& p1,
405               const P2& p2,
406               const P3& p3,
407               const P4& p4,
408               const P5& p5,
409               VARIANT* const & result_out) {
410  // Retrieve the ID of the method to be called.
411  DISPID disp_id;
412  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
413                                     &disp_id);
414  if (FAILED(hr))
415    return hr;
416
417  // Request the return value if asked by the caller.
418  internal::ScopedVariantArg result;
419  VARIANT* disp_result = NULL;
420  if (result_out != NULL)
421    disp_result = &result;
422
423  // Wrap the parameters into an array of VARIANT structures.
424  internal::ScopedVariantArg disp_args[5];
425  hr = disp_args[5 - 1].Wrap(p1);
426  if (FAILED(hr))
427    return hr;
428  hr = disp_args[5 - 2].Wrap(p2);
429  if (FAILED(hr))
430    return hr;
431  hr = disp_args[5 - 3].Wrap(p3);
432  if (FAILED(hr))
433    return hr;
434  hr = disp_args[5 - 4].Wrap(p4);
435  if (FAILED(hr))
436    return hr;
437  hr = disp_args[5 - 5].Wrap(p5);
438  if (FAILED(hr))
439    return hr;
440
441  // Invoke the method passing the parameters via the DISPPARAMS structure.
442  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
443  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
444  // structure members should be initialized.
445  DISPPARAMS disp_params = { disp_args, NULL, 5, 0 };
446  DISPID dispid_named = DISPID_PROPERTYPUT;
447  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
448    disp_params.cNamedArgs = 1;
449    disp_params.rgdispidNamedArgs = &dispid_named;
450  }
451
452  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
453                      &disp_params, disp_result, NULL, NULL);
454  if (FAILED(hr))
455    return hr;
456
457  // Unwrap the parameters.
458  disp_args[5 - 1].Unwrap(p1);
459  disp_args[5 - 2].Unwrap(p2);
460  disp_args[5 - 3].Unwrap(p3);
461  disp_args[5 - 4].Unwrap(p4);
462  disp_args[5 - 5].Unwrap(p5);
463
464  // Unwrap the return value.
465  if (result_out != NULL) {
466    result.Unwrap(result_out);
467  }
468
469  return S_OK;
470}
471
472template <typename P1, typename P2, typename P3, typename P4, typename P5,
473    typename P6>
474HRESULT Invoke(IDispatch* object,
475               LPOLESTR name,
476               WORD flags,
477               const P1& p1,
478               const P2& p2,
479               const P3& p3,
480               const P4& p4,
481               const P5& p5,
482               const P6& p6,
483               VARIANT* const & result_out) {
484  // Retrieve the ID of the method to be called.
485  DISPID disp_id;
486  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
487                                     &disp_id);
488  if (FAILED(hr))
489    return hr;
490
491  // Request the return value if asked by the caller.
492  internal::ScopedVariantArg result;
493  VARIANT* disp_result = NULL;
494  if (result_out != NULL)
495    disp_result = &result;
496
497  // Wrap the parameters into an array of VARIANT structures.
498  internal::ScopedVariantArg disp_args[6];
499  hr = disp_args[6 - 1].Wrap(p1);
500  if (FAILED(hr))
501    return hr;
502  hr = disp_args[6 - 2].Wrap(p2);
503  if (FAILED(hr))
504    return hr;
505  hr = disp_args[6 - 3].Wrap(p3);
506  if (FAILED(hr))
507    return hr;
508  hr = disp_args[6 - 4].Wrap(p4);
509  if (FAILED(hr))
510    return hr;
511  hr = disp_args[6 - 5].Wrap(p5);
512  if (FAILED(hr))
513    return hr;
514  hr = disp_args[6 - 6].Wrap(p6);
515  if (FAILED(hr))
516    return hr;
517
518  // Invoke the method passing the parameters via the DISPPARAMS structure.
519  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
520  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
521  // structure members should be initialized.
522  DISPPARAMS disp_params = { disp_args, NULL, 6, 0 };
523  DISPID dispid_named = DISPID_PROPERTYPUT;
524  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
525    disp_params.cNamedArgs = 1;
526    disp_params.rgdispidNamedArgs = &dispid_named;
527  }
528
529  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
530                      &disp_params, disp_result, NULL, NULL);
531  if (FAILED(hr))
532    return hr;
533
534  // Unwrap the parameters.
535  disp_args[6 - 1].Unwrap(p1);
536  disp_args[6 - 2].Unwrap(p2);
537  disp_args[6 - 3].Unwrap(p3);
538  disp_args[6 - 4].Unwrap(p4);
539  disp_args[6 - 5].Unwrap(p5);
540  disp_args[6 - 6].Unwrap(p6);
541
542  // Unwrap the return value.
543  if (result_out != NULL) {
544    result.Unwrap(result_out);
545  }
546
547  return S_OK;
548}
549
550template <typename P1, typename P2, typename P3, typename P4, typename P5,
551    typename P6, typename P7>
552HRESULT Invoke(IDispatch* object,
553               LPOLESTR name,
554               WORD flags,
555               const P1& p1,
556               const P2& p2,
557               const P3& p3,
558               const P4& p4,
559               const P5& p5,
560               const P6& p6,
561               const P7& p7,
562               VARIANT* const & result_out) {
563  // Retrieve the ID of the method to be called.
564  DISPID disp_id;
565  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
566                                     &disp_id);
567  if (FAILED(hr))
568    return hr;
569
570  // Request the return value if asked by the caller.
571  internal::ScopedVariantArg result;
572  VARIANT* disp_result = NULL;
573  if (result_out != NULL)
574    disp_result = &result;
575
576  // Wrap the parameters into an array of VARIANT structures.
577  internal::ScopedVariantArg disp_args[7];
578  hr = disp_args[7 - 1].Wrap(p1);
579  if (FAILED(hr))
580    return hr;
581  hr = disp_args[7 - 2].Wrap(p2);
582  if (FAILED(hr))
583    return hr;
584  hr = disp_args[7 - 3].Wrap(p3);
585  if (FAILED(hr))
586    return hr;
587  hr = disp_args[7 - 4].Wrap(p4);
588  if (FAILED(hr))
589    return hr;
590  hr = disp_args[7 - 5].Wrap(p5);
591  if (FAILED(hr))
592    return hr;
593  hr = disp_args[7 - 6].Wrap(p6);
594  if (FAILED(hr))
595    return hr;
596  hr = disp_args[7 - 7].Wrap(p7);
597  if (FAILED(hr))
598    return hr;
599
600  // Invoke the method passing the parameters via the DISPPARAMS structure.
601  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
602  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
603  // structure members should be initialized.
604  DISPPARAMS disp_params = { disp_args, NULL, 7, 0 };
605  DISPID dispid_named = DISPID_PROPERTYPUT;
606  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
607    disp_params.cNamedArgs = 1;
608    disp_params.rgdispidNamedArgs = &dispid_named;
609  }
610
611  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
612                      &disp_params, disp_result, NULL, NULL);
613  if (FAILED(hr))
614    return hr;
615
616  // Unwrap the parameters.
617  disp_args[7 - 1].Unwrap(p1);
618  disp_args[7 - 2].Unwrap(p2);
619  disp_args[7 - 3].Unwrap(p3);
620  disp_args[7 - 4].Unwrap(p4);
621  disp_args[7 - 5].Unwrap(p5);
622  disp_args[7 - 6].Unwrap(p6);
623  disp_args[7 - 7].Unwrap(p7);
624
625  // Unwrap the return value.
626  if (result_out != NULL) {
627    result.Unwrap(result_out);
628  }
629
630  return S_OK;
631}
632
633} // namespace dispatch
634
635} // namespace remoting
636
637#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
638