15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was GENERATED by command:
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     pump.py dispatch_win.h.pump
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DO NOT EDIT BY HAND!!!
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <oaidl.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/template_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_variant.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace dispatch {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A helper wrapper for |VARIANTARG| that is used to pass parameters to and from
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IDispatch::Invoke(). The latter accepts parameters as an array of
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - [in] parameters are initialized and freed if needed by the caller.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - [out] parameters are initialized by IDispatch::Invoke(). It is up to
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         the caller to free leakable variants (such as VT_DISPATCH).
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - [in] [out] parameters are combination of both: the caller initializes
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         them before the call and the callee assigns new values correctly
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         freeing leakable variants.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the resources allocated during the call will be properly freed. It also
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provides wrapping methods that convert between C++ types and VARIANTs.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// At the moment the only supported parameter type is |VARIANT| (or
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |VARIANTARG|).
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It must be possible to cast a pointer to an array of |ScopedVariantArg| to
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a pointer to an array of |VARIANTARG| structures.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedVariantArg : public VARIANTARG {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVariantArg() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vt = VT_EMPTY;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedVariantArg() {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VariantClear(this);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap() routines pack the input parameters into VARIANTARG structures so
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that they can be passed to IDispatch::Invoke.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT Wrap(const VARIANT& param) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(vt == VT_EMPTY);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return VariantCopy(this, &param);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT Wrap(VARIANT* const & param) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(vt == VT_EMPTY);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make the input value of an [in] [out] parameter visible to
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // IDispatch::Invoke().
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // N.B. We treat both [out] and [in] [out] parameters as [in] [out]. In
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // other words the caller is always responsible for initializing and freeing
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // [out] and [in] [out] parameters.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Swap(param);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return S_OK;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap() routines unpack the output parameters from VARIANTARG structures
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the locations specified by the caller.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Unwrap(const VARIANT& param_out) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do nothing for an [in] parameter.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Unwrap(VARIANT* const & param_out) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return the output value of an [in] [out] parameter to the caller.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Swap(param_out);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Exchanges the value (and ownership) of the passed VARIANT with the one
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wrapped by |ScopedVariantArg|.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Swap(VARIANT* other) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VARIANT temp = *other;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *other = *this;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *static_cast<VARIANTARG*>(this) = temp;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               scoped_variant_arg_should_not_add_data_members);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calling the desired method by its ID and implements logic for passing
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a variable number of in/out parameters to the called method.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The calling convention is:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - [in] parameters are passsed as a constant reference or by value.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - [out] and [in] [out] parameters are passed by pointer. The pointed value
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         is overwritten when the function returns. The pointed-to value must
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         be initialized before the call, and will be replaced when it returns.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         [out] parameters may be initialized to VT_EMPTY.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Current limitations:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - more than 7 parameters are not supported.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - the method ID cannot be cached and reused.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - VARIANT is the only supported parameter type at the moment.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1>
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[1];
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[1 - 1].Wrap(p1);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 1, 0 };
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[1 - 1].Unwrap(p1);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1, typename P2>
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P2& p2,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[2];
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[2 - 1].Wrap(p1);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[2 - 2].Wrap(p2);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 2, 0 };
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[2 - 1].Unwrap(p1);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[2 - 2].Unwrap(p2);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1, typename P2, typename P3>
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P2& p2,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P3& p3,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[3];
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[3 - 1].Wrap(p1);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[3 - 2].Wrap(p2);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[3 - 3].Wrap(p3);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 3, 0 };
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[3 - 1].Unwrap(p1);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[3 - 2].Unwrap(p2);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[3 - 3].Unwrap(p3);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1, typename P2, typename P3, typename P4>
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P2& p2,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P3& p3,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P4& p4,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[4];
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[4 - 1].Wrap(p1);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[4 - 2].Wrap(p2);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[4 - 3].Wrap(p3);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[4 - 4].Wrap(p4);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 4, 0 };
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[4 - 1].Unwrap(p1);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[4 - 2].Unwrap(p2);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[4 - 3].Unwrap(p3);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[4 - 4].Unwrap(p4);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1, typename P2, typename P3, typename P4, typename P5>
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P2& p2,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P3& p3,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P4& p4,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P5& p5,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[5];
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[5 - 1].Wrap(p1);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[5 - 2].Wrap(p2);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[5 - 3].Wrap(p3);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[5 - 4].Wrap(p4);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[5 - 5].Wrap(p5);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 5, 0 };
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[5 - 1].Unwrap(p1);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[5 - 2].Unwrap(p2);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[5 - 3].Unwrap(p3);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[5 - 4].Unwrap(p4);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[5 - 5].Unwrap(p5);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1, typename P2, typename P3, typename P4, typename P5,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename P6>
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P2& p2,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P3& p3,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P4& p4,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P5& p5,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P6& p6,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[6];
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[6 - 1].Wrap(p1);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[6 - 2].Wrap(p2);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[6 - 3].Wrap(p3);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[6 - 4].Wrap(p4);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[6 - 5].Wrap(p5);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[6 - 6].Wrap(p6);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 6, 0 };
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[6 - 1].Unwrap(p1);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[6 - 2].Unwrap(p2);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[6 - 3].Unwrap(p3);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[6 - 4].Unwrap(p4);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[6 - 5].Unwrap(p5);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[6 - 6].Unwrap(p6);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename P1, typename P2, typename P3, typename P4, typename P5,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename P6, typename P7>
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT Invoke(IDispatch* object,
5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               LPCOLESTR const_name,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               WORD flags,
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P1& p1,
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P2& p2,
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P3& p3,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P4& p4,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P5& p5,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P6& p6,
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const P7& p7,
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               VARIANT* const & result_out) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Retrieve the ID of the method to be called.
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID disp_id;
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LPOLESTR name = const_cast<LPOLESTR>(const_name);
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  HRESULT hr = object->GetIDsOfNames(
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Request the return value if asked by the caller.
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg result;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VARIANT* disp_result = NULL;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_result = &result;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrap the parameters into an array of VARIANT structures.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ScopedVariantArg disp_args[7];
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 1].Wrap(p1);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 2].Wrap(p2);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 3].Wrap(p3);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 4].Wrap(p4);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 5].Wrap(p5);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 6].Wrap(p6);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = disp_args[7 - 7].Wrap(p7);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke the method passing the parameters via the DISPPARAMS structure.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure members should be initialized.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPPARAMS disp_params = { disp_args, NULL, 7, 0 };
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISPID dispid_named = DISPID_PROPERTYPUT;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.cNamedArgs = 1;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    disp_params.rgdispidNamedArgs = &dispid_named;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &disp_params, disp_result, NULL, NULL);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (FAILED(hr))
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return hr;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the parameters.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 1].Unwrap(p1);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 2].Unwrap(p2);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 3].Unwrap(p3);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 4].Unwrap(p4);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 5].Unwrap(p5);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 6].Unwrap(p6);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disp_args[7 - 7].Unwrap(p7);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unwrap the return value.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_out != NULL) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.Unwrap(result_out);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return S_OK;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace dispatch
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
646