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, ¶m);
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