Home | History | Annotate | Download | only in base
      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:
     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.
     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 
    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>
    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>
    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>
    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>
    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>
    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>
    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>
    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