C++程序  |  638行  |  19.56 KB

// This file was GENERATED by command:
//     pump.py dispatch_win.h.pump
// DO NOT EDIT BY HAND!!!

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
#define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_

#include <oaidl.h>

#include "base/basictypes.h"
#include "base/template_util.h"
#include "base/win/scoped_variant.h"

namespace remoting {

namespace dispatch {

namespace internal {

// A helper wrapper for |VARIANTARG| that is used to pass parameters to and from
// IDispatch::Invoke(). The latter accepts parameters as an array of
// |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is:
//   - [in] parameters are initialized and freed if needed by the caller.
//   - [out] parameters are initialized by IDispatch::Invoke(). It is up to
//         the caller to free leakable variants (such as VT_DISPATCH).
//   - [in] [out] parameters are combination of both: the caller initializes
//         them before the call and the callee assigns new values correctly
//         freeing leakable variants.
//
// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
// the resources allocated during the call will be properly freed. It also
// provides wrapping methods that convert between C++ types and VARIANTs.
// At the moment the only supported parameter type is |VARIANT| (or
// |VARIANTARG|).
//
// It must be possible to cast a pointer to an array of |ScopedVariantArg| to
// a pointer to an array of |VARIANTARG| structures.
class ScopedVariantArg : public VARIANTARG {
 public:
  ScopedVariantArg() {
    vt = VT_EMPTY;
  }

  ~ScopedVariantArg() {
    VariantClear(this);
  }

  // Wrap() routines pack the input parameters into VARIANTARG structures so
  // that they can be passed to IDispatch::Invoke.

  HRESULT Wrap(const VARIANT& param) {
    DCHECK(vt == VT_EMPTY);
    return VariantCopy(this, &param);
  }

  HRESULT Wrap(VARIANT* const & param) {
    DCHECK(vt == VT_EMPTY);

    // Make the input value of an [in] [out] parameter visible to
    // IDispatch::Invoke().
    //
    // N.B. We treat both [out] and [in] [out] parameters as [in] [out]. In
    // other words the caller is always responsible for initializing and freeing
    // [out] and [in] [out] parameters.
    Swap(param);
    return S_OK;
  }

  // Unwrap() routines unpack the output parameters from VARIANTARG structures
  // to the locations specified by the caller.

  void Unwrap(const VARIANT& param_out) {
    // Do nothing for an [in] parameter.
  }

  void Unwrap(VARIANT* const & param_out) {
    // Return the output value of an [in] [out] parameter to the caller.
    Swap(param_out);
  }

 private:
  // Exchanges the value (and ownership) of the passed VARIANT with the one
  // wrapped by |ScopedVariantArg|.
  void Swap(VARIANT* other) {
    VARIANT temp = *other;
    *other = *this;
    *static_cast<VARIANTARG*>(this) = temp;
  }

  DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg);
};

// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
               scoped_variant_arg_should_not_add_data_members);

}  // namespace internal

// Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of
// calling the desired method by its ID and implements logic for passing
// a variable number of in/out parameters to the called method.
//
// The calling convention is:
//   - [in] parameters are passsed as a constant reference or by value.
//   - [out] and [in] [out] parameters are passed by pointer. The pointed value
//         is overwritten when the function returns. The pointed-to value must
//         be initialized before the call, and will be replaced when it returns.
//         [out] parameters may be initialized to VT_EMPTY.
//
// Current limitations:
//   - more than 7 parameters are not supported.
//   - the method ID cannot be cached and reused.
//   - VARIANT is the only supported parameter type at the moment.

HRESULT Invoke(IDispatch* object,
               LPOLESTR name,
               WORD flags,
               VARIANT* const & result_out) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;


  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;


  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1>
HRESULT Invoke(IDispatch* object,
               LPOLESTR name,
               WORD flags,
               const P1& p1,
               VARIANT* const & result_out) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[1];
  hr = disp_args[1 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 1, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[1 - 1].Unwrap(p1);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1, typename P2>
HRESULT Invoke(IDispatch* object,
               LPOLESTR name,
               WORD flags,
               const P1& p1,
               const P2& p2,
               VARIANT* const & result_out) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[2];
  hr = disp_args[2 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;
  hr = disp_args[2 - 2].Wrap(p2);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 2, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[2 - 1].Unwrap(p1);
  disp_args[2 - 2].Unwrap(p2);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1, typename P2, typename P3>
HRESULT Invoke(IDispatch* object,
               LPOLESTR name,
               WORD flags,
               const P1& p1,
               const P2& p2,
               const P3& p3,
               VARIANT* const & result_out) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[3];
  hr = disp_args[3 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;
  hr = disp_args[3 - 2].Wrap(p2);
  if (FAILED(hr))
    return hr;
  hr = disp_args[3 - 3].Wrap(p3);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 3, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[3 - 1].Unwrap(p1);
  disp_args[3 - 2].Unwrap(p2);
  disp_args[3 - 3].Unwrap(p3);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1, typename P2, typename P3, typename P4>
HRESULT Invoke(IDispatch* object,
               LPOLESTR name,
               WORD flags,
               const P1& p1,
               const P2& p2,
               const P3& p3,
               const P4& p4,
               VARIANT* const & result_out) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[4];
  hr = disp_args[4 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;
  hr = disp_args[4 - 2].Wrap(p2);
  if (FAILED(hr))
    return hr;
  hr = disp_args[4 - 3].Wrap(p3);
  if (FAILED(hr))
    return hr;
  hr = disp_args[4 - 4].Wrap(p4);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 4, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[4 - 1].Unwrap(p1);
  disp_args[4 - 2].Unwrap(p2);
  disp_args[4 - 3].Unwrap(p3);
  disp_args[4 - 4].Unwrap(p4);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1, typename P2, typename P3, typename P4, typename P5>
HRESULT 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) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[5];
  hr = disp_args[5 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;
  hr = disp_args[5 - 2].Wrap(p2);
  if (FAILED(hr))
    return hr;
  hr = disp_args[5 - 3].Wrap(p3);
  if (FAILED(hr))
    return hr;
  hr = disp_args[5 - 4].Wrap(p4);
  if (FAILED(hr))
    return hr;
  hr = disp_args[5 - 5].Wrap(p5);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 5, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[5 - 1].Unwrap(p1);
  disp_args[5 - 2].Unwrap(p2);
  disp_args[5 - 3].Unwrap(p3);
  disp_args[5 - 4].Unwrap(p4);
  disp_args[5 - 5].Unwrap(p5);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1, typename P2, typename P3, typename P4, typename P5,
    typename P6>
HRESULT 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) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[6];
  hr = disp_args[6 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;
  hr = disp_args[6 - 2].Wrap(p2);
  if (FAILED(hr))
    return hr;
  hr = disp_args[6 - 3].Wrap(p3);
  if (FAILED(hr))
    return hr;
  hr = disp_args[6 - 4].Wrap(p4);
  if (FAILED(hr))
    return hr;
  hr = disp_args[6 - 5].Wrap(p5);
  if (FAILED(hr))
    return hr;
  hr = disp_args[6 - 6].Wrap(p6);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 6, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[6 - 1].Unwrap(p1);
  disp_args[6 - 2].Unwrap(p2);
  disp_args[6 - 3].Unwrap(p3);
  disp_args[6 - 4].Unwrap(p4);
  disp_args[6 - 5].Unwrap(p5);
  disp_args[6 - 6].Unwrap(p6);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

template <typename P1, typename P2, typename P3, typename P4, typename P5,
    typename P6, typename P7>
HRESULT 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) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  HRESULT hr = object->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT,
                                     &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[7];
  hr = disp_args[7 - 1].Wrap(p1);
  if (FAILED(hr))
    return hr;
  hr = disp_args[7 - 2].Wrap(p2);
  if (FAILED(hr))
    return hr;
  hr = disp_args[7 - 3].Wrap(p3);
  if (FAILED(hr))
    return hr;
  hr = disp_args[7 - 4].Wrap(p4);
  if (FAILED(hr))
    return hr;
  hr = disp_args[7 - 5].Wrap(p5);
  if (FAILED(hr))
    return hr;
  hr = disp_args[7 - 6].Wrap(p6);
  if (FAILED(hr))
    return hr;
  hr = disp_args[7 - 7].Wrap(p7);
  if (FAILED(hr))
    return hr;

  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.
  DISPPARAMS disp_params = { disp_args, NULL, 7, 0 };
  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

  // Unwrap the parameters.
  disp_args[7 - 1].Unwrap(p1);
  disp_args[7 - 2].Unwrap(p2);
  disp_args[7 - 3].Unwrap(p3);
  disp_args[7 - 4].Unwrap(p4);
  disp_args[7 - 5].Unwrap(p5);
  disp_args[7 - 6].Unwrap(p6);
  disp_args[7 - 7].Unwrap(p7);

  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

} // namespace dispatch

} // namespace remoting

#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_