• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 namespace remoting {
19 
20 namespace dispatch {
21 
22 namespace 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.
42 class ScopedVariantArg : public VARIANTARG {
43  public:
ScopedVariantArg()44   ScopedVariantArg() {
45     vt = VT_EMPTY;
46   }
47 
~ScopedVariantArg()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 
Wrap(const VARIANT & param)55   HRESULT Wrap(const VARIANT& param) {
56     DCHECK(vt == VT_EMPTY);
57     return VariantCopy(this, &param);
58   }
59 
Wrap(VARIANT * const & param)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 
Unwrap(const VARIANT & param_out)76   void Unwrap(const VARIANT& param_out) {
77     // Do nothing for an [in] parameter.
78   }
79 
Unwrap(VARIANT * const & param_out)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|.
Swap(VARIANT * other)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.
98 COMPILE_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 
Invoke(IDispatch * object,LPOLESTR name,WORD flags,VARIANT * const & result_out)119 HRESULT 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 
162 template <typename P1>
Invoke(IDispatch * object,LPOLESTR name,WORD flags,const P1 & p1,VARIANT * const & result_out)163 HRESULT 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 
214 template <typename P1, typename P2>
Invoke(IDispatch * object,LPOLESTR name,WORD flags,const P1 & p1,const P2 & p2,VARIANT * const & result_out)215 HRESULT 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 
271 template <typename P1, typename P2, typename P3>
Invoke(IDispatch * object,LPOLESTR name,WORD flags,const P1 & p1,const P2 & p2,const P3 & p3,VARIANT * const & result_out)272 HRESULT 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 
333 template <typename P1, typename P2, typename P3, typename P4>
Invoke(IDispatch * object,LPOLESTR name,WORD flags,const P1 & p1,const P2 & p2,const P3 & p3,const P4 & p4,VARIANT * const & result_out)334 HRESULT 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 
400 template <typename P1, typename P2, typename P3, typename P4, typename P5>
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)401 HRESULT 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 
472 template <typename P1, typename P2, typename P3, typename P4, typename P5,
473     typename P6>
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)474 HRESULT 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 
550 template <typename P1, typename P2, typename P3, typename P4, typename P5,
551     typename P6, typename P7>
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)552 HRESULT 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