dispatch_win.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. // This file was GENERATED by command:
  2. // pump.py dispatch_win.h.pump
  3. // DO NOT EDIT BY HAND!!!
  4. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  5. // Use of this source code is governed by a BSD-style license that can be
  6. // found in the LICENSE file.
  7. #ifndef REMOTING_BASE_DISPATCH_WIN_H_
  8. #define REMOTING_BASE_DISPATCH_WIN_H_
  9. #include <oaidl.h>
  10. #include "base/template_util.h"
  11. #include "base/win/scoped_variant.h"
  12. namespace remoting {
  13. namespace dispatch {
  14. namespace internal {
  15. // A helper wrapper for |VARIANTARG| that is used to pass parameters to and from
  16. // IDispatch::Invoke(). The latter accepts parameters as an array of
  17. // |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is:
  18. // - [in] parameters are initialized and freed if needed by the caller.
  19. // - [out] parameters are initialized by IDispatch::Invoke(). It is up to
  20. // the caller to free leakable variants (such as VT_DISPATCH).
  21. // - [in] [out] parameters are combination of both: the caller initializes
  22. // them before the call and the callee assigns new values correctly
  23. // freeing leakable variants.
  24. //
  25. // Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
  26. // the resources allocated during the call will be properly freed. It also
  27. // provides wrapping methods that convert between C++ types and VARIANTs.
  28. // At the moment the only supported parameter type is |VARIANT| (or
  29. // |VARIANTARG|).
  30. //
  31. // It must be possible to cast a pointer to an array of |ScopedVariantArg| to
  32. // a pointer to an array of |VARIANTARG| structures.
  33. class ScopedVariantArg : public VARIANTARG {
  34. public:
  35. ScopedVariantArg() {
  36. vt = VT_EMPTY;
  37. }
  38. ScopedVariantArg(const ScopedVariantArg&) = delete;
  39. ScopedVariantArg& operator=(const ScopedVariantArg&) = delete;
  40. ~ScopedVariantArg() {
  41. VariantClear(this);
  42. }
  43. // Wrap() routines pack the input parameters into VARIANTARG structures so
  44. // that they can be passed to IDispatch::Invoke.
  45. HRESULT Wrap(const VARIANT& param) {
  46. DCHECK(vt == VT_EMPTY);
  47. return VariantCopy(this, &param);
  48. }
  49. HRESULT Wrap(VARIANT* const & param) {
  50. DCHECK(vt == VT_EMPTY);
  51. // Make the input value of an [in] [out] parameter visible to
  52. // IDispatch::Invoke().
  53. //
  54. // N.B. We treat both [out] and [in] [out] parameters as [in] [out]. In
  55. // other words the caller is always responsible for initializing and freeing
  56. // [out] and [in] [out] parameters.
  57. Swap(param);
  58. return S_OK;
  59. }
  60. // Unwrap() routines unpack the output parameters from VARIANTARG structures
  61. // to the locations specified by the caller.
  62. void Unwrap(const VARIANT& param_out) {
  63. // Do nothing for an [in] parameter.
  64. }
  65. void Unwrap(VARIANT* const & param_out) {
  66. // Return the output value of an [in] [out] parameter to the caller.
  67. Swap(param_out);
  68. }
  69. private:
  70. // Exchanges the value (and ownership) of the passed VARIANT with the one
  71. // wrapped by |ScopedVariantArg|.
  72. void Swap(VARIANT* other) {
  73. VARIANT temp = *other;
  74. *other = *this;
  75. *static_cast<VARIANTARG*>(this) = temp;
  76. }
  77. };
  78. // Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
  79. static_assert(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
  80. "scoped variant arg should not add data members");
  81. } // namespace internal
  82. // Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of
  83. // calling the desired method by its ID and implements logic for passing
  84. // a variable number of in/out parameters to the called method.
  85. //
  86. // The calling convention is:
  87. // - [in] parameters are passsed as a constant reference or by value.
  88. // - [out] and [in] [out] parameters are passed by pointer. The pointed value
  89. // is overwritten when the function returns. The pointed-to value must
  90. // be initialized before the call, and will be replaced when it returns.
  91. // [out] parameters may be initialized to VT_EMPTY.
  92. //
  93. // Current limitations:
  94. // - more than 7 parameters are not supported.
  95. // - the method ID cannot be cached and reused.
  96. // - VARIANT is the only supported parameter type at the moment.
  97. HRESULT Invoke(IDispatch* object,
  98. LPCOLESTR const_name,
  99. WORD flags,
  100. VARIANT* const & result_out) {
  101. // Retrieve the ID of the method to be called.
  102. DISPID disp_id;
  103. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  104. HRESULT hr = object->GetIDsOfNames(
  105. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  106. if (FAILED(hr))
  107. return hr;
  108. // Request the return value if asked by the caller.
  109. internal::ScopedVariantArg result;
  110. VARIANT* disp_result = NULL;
  111. if (result_out != NULL)
  112. disp_result = &result;
  113. // Invoke the method passing the parameters via the DISPPARAMS structure.
  114. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  115. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  116. // structure members should be initialized.
  117. DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
  118. DISPID dispid_named = DISPID_PROPERTYPUT;
  119. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  120. disp_params.cNamedArgs = 1;
  121. disp_params.rgdispidNamedArgs = &dispid_named;
  122. }
  123. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  124. &disp_params, disp_result, NULL, NULL);
  125. if (FAILED(hr))
  126. return hr;
  127. // Unwrap the return value.
  128. if (result_out != NULL) {
  129. result.Unwrap(result_out);
  130. }
  131. return S_OK;
  132. }
  133. template <typename P1>
  134. HRESULT Invoke(IDispatch* object,
  135. LPCOLESTR const_name,
  136. WORD flags,
  137. const P1& p1,
  138. VARIANT* const & result_out) {
  139. // Retrieve the ID of the method to be called.
  140. DISPID disp_id;
  141. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  142. HRESULT hr = object->GetIDsOfNames(
  143. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  144. if (FAILED(hr))
  145. return hr;
  146. // Request the return value if asked by the caller.
  147. internal::ScopedVariantArg result;
  148. VARIANT* disp_result = NULL;
  149. if (result_out != NULL)
  150. disp_result = &result;
  151. // Wrap the parameters into an array of VARIANT structures.
  152. internal::ScopedVariantArg disp_args[1];
  153. hr = disp_args[1 - 1].Wrap(p1);
  154. if (FAILED(hr))
  155. return hr;
  156. // Invoke the method passing the parameters via the DISPPARAMS structure.
  157. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  158. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  159. // structure members should be initialized.
  160. DISPPARAMS disp_params = { disp_args, NULL, 1, 0 };
  161. DISPID dispid_named = DISPID_PROPERTYPUT;
  162. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  163. disp_params.cNamedArgs = 1;
  164. disp_params.rgdispidNamedArgs = &dispid_named;
  165. }
  166. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  167. &disp_params, disp_result, NULL, NULL);
  168. if (FAILED(hr))
  169. return hr;
  170. // Unwrap the parameters.
  171. disp_args[1 - 1].Unwrap(p1);
  172. // Unwrap the return value.
  173. if (result_out != NULL) {
  174. result.Unwrap(result_out);
  175. }
  176. return S_OK;
  177. }
  178. template <typename P1, typename P2>
  179. HRESULT Invoke(IDispatch* object,
  180. LPCOLESTR const_name,
  181. WORD flags,
  182. const P1& p1,
  183. const P2& p2,
  184. VARIANT* const & result_out) {
  185. // Retrieve the ID of the method to be called.
  186. DISPID disp_id;
  187. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  188. HRESULT hr = object->GetIDsOfNames(
  189. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  190. if (FAILED(hr))
  191. return hr;
  192. // Request the return value if asked by the caller.
  193. internal::ScopedVariantArg result;
  194. VARIANT* disp_result = NULL;
  195. if (result_out != NULL)
  196. disp_result = &result;
  197. // Wrap the parameters into an array of VARIANT structures.
  198. internal::ScopedVariantArg disp_args[2];
  199. hr = disp_args[2 - 1].Wrap(p1);
  200. if (FAILED(hr))
  201. return hr;
  202. hr = disp_args[2 - 2].Wrap(p2);
  203. if (FAILED(hr))
  204. return hr;
  205. // Invoke the method passing the parameters via the DISPPARAMS structure.
  206. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  207. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  208. // structure members should be initialized.
  209. DISPPARAMS disp_params = { disp_args, NULL, 2, 0 };
  210. DISPID dispid_named = DISPID_PROPERTYPUT;
  211. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  212. disp_params.cNamedArgs = 1;
  213. disp_params.rgdispidNamedArgs = &dispid_named;
  214. }
  215. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  216. &disp_params, disp_result, NULL, NULL);
  217. if (FAILED(hr))
  218. return hr;
  219. // Unwrap the parameters.
  220. disp_args[2 - 1].Unwrap(p1);
  221. disp_args[2 - 2].Unwrap(p2);
  222. // Unwrap the return value.
  223. if (result_out != NULL) {
  224. result.Unwrap(result_out);
  225. }
  226. return S_OK;
  227. }
  228. template <typename P1, typename P2, typename P3>
  229. HRESULT Invoke(IDispatch* object,
  230. LPCOLESTR const_name,
  231. WORD flags,
  232. const P1& p1,
  233. const P2& p2,
  234. const P3& p3,
  235. VARIANT* const & result_out) {
  236. // Retrieve the ID of the method to be called.
  237. DISPID disp_id;
  238. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  239. HRESULT hr = object->GetIDsOfNames(
  240. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  241. if (FAILED(hr))
  242. return hr;
  243. // Request the return value if asked by the caller.
  244. internal::ScopedVariantArg result;
  245. VARIANT* disp_result = NULL;
  246. if (result_out != NULL)
  247. disp_result = &result;
  248. // Wrap the parameters into an array of VARIANT structures.
  249. internal::ScopedVariantArg disp_args[3];
  250. hr = disp_args[3 - 1].Wrap(p1);
  251. if (FAILED(hr))
  252. return hr;
  253. hr = disp_args[3 - 2].Wrap(p2);
  254. if (FAILED(hr))
  255. return hr;
  256. hr = disp_args[3 - 3].Wrap(p3);
  257. if (FAILED(hr))
  258. return hr;
  259. // Invoke the method passing the parameters via the DISPPARAMS structure.
  260. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  261. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  262. // structure members should be initialized.
  263. DISPPARAMS disp_params = { disp_args, NULL, 3, 0 };
  264. DISPID dispid_named = DISPID_PROPERTYPUT;
  265. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  266. disp_params.cNamedArgs = 1;
  267. disp_params.rgdispidNamedArgs = &dispid_named;
  268. }
  269. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  270. &disp_params, disp_result, NULL, NULL);
  271. if (FAILED(hr))
  272. return hr;
  273. // Unwrap the parameters.
  274. disp_args[3 - 1].Unwrap(p1);
  275. disp_args[3 - 2].Unwrap(p2);
  276. disp_args[3 - 3].Unwrap(p3);
  277. // Unwrap the return value.
  278. if (result_out != NULL) {
  279. result.Unwrap(result_out);
  280. }
  281. return S_OK;
  282. }
  283. template <typename P1, typename P2, typename P3, typename P4>
  284. HRESULT Invoke(IDispatch* object,
  285. LPCOLESTR const_name,
  286. WORD flags,
  287. const P1& p1,
  288. const P2& p2,
  289. const P3& p3,
  290. const P4& p4,
  291. VARIANT* const & result_out) {
  292. // Retrieve the ID of the method to be called.
  293. DISPID disp_id;
  294. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  295. HRESULT hr = object->GetIDsOfNames(
  296. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  297. if (FAILED(hr))
  298. return hr;
  299. // Request the return value if asked by the caller.
  300. internal::ScopedVariantArg result;
  301. VARIANT* disp_result = NULL;
  302. if (result_out != NULL)
  303. disp_result = &result;
  304. // Wrap the parameters into an array of VARIANT structures.
  305. internal::ScopedVariantArg disp_args[4];
  306. hr = disp_args[4 - 1].Wrap(p1);
  307. if (FAILED(hr))
  308. return hr;
  309. hr = disp_args[4 - 2].Wrap(p2);
  310. if (FAILED(hr))
  311. return hr;
  312. hr = disp_args[4 - 3].Wrap(p3);
  313. if (FAILED(hr))
  314. return hr;
  315. hr = disp_args[4 - 4].Wrap(p4);
  316. if (FAILED(hr))
  317. return hr;
  318. // Invoke the method passing the parameters via the DISPPARAMS structure.
  319. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  320. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  321. // structure members should be initialized.
  322. DISPPARAMS disp_params = { disp_args, NULL, 4, 0 };
  323. DISPID dispid_named = DISPID_PROPERTYPUT;
  324. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  325. disp_params.cNamedArgs = 1;
  326. disp_params.rgdispidNamedArgs = &dispid_named;
  327. }
  328. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  329. &disp_params, disp_result, NULL, NULL);
  330. if (FAILED(hr))
  331. return hr;
  332. // Unwrap the parameters.
  333. disp_args[4 - 1].Unwrap(p1);
  334. disp_args[4 - 2].Unwrap(p2);
  335. disp_args[4 - 3].Unwrap(p3);
  336. disp_args[4 - 4].Unwrap(p4);
  337. // Unwrap the return value.
  338. if (result_out != NULL) {
  339. result.Unwrap(result_out);
  340. }
  341. return S_OK;
  342. }
  343. template <typename P1, typename P2, typename P3, typename P4, typename P5>
  344. HRESULT Invoke(IDispatch* object,
  345. LPCOLESTR const_name,
  346. WORD flags,
  347. const P1& p1,
  348. const P2& p2,
  349. const P3& p3,
  350. const P4& p4,
  351. const P5& p5,
  352. VARIANT* const & result_out) {
  353. // Retrieve the ID of the method to be called.
  354. DISPID disp_id;
  355. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  356. HRESULT hr = object->GetIDsOfNames(
  357. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  358. if (FAILED(hr))
  359. return hr;
  360. // Request the return value if asked by the caller.
  361. internal::ScopedVariantArg result;
  362. VARIANT* disp_result = NULL;
  363. if (result_out != NULL)
  364. disp_result = &result;
  365. // Wrap the parameters into an array of VARIANT structures.
  366. internal::ScopedVariantArg disp_args[5];
  367. hr = disp_args[5 - 1].Wrap(p1);
  368. if (FAILED(hr))
  369. return hr;
  370. hr = disp_args[5 - 2].Wrap(p2);
  371. if (FAILED(hr))
  372. return hr;
  373. hr = disp_args[5 - 3].Wrap(p3);
  374. if (FAILED(hr))
  375. return hr;
  376. hr = disp_args[5 - 4].Wrap(p4);
  377. if (FAILED(hr))
  378. return hr;
  379. hr = disp_args[5 - 5].Wrap(p5);
  380. if (FAILED(hr))
  381. return hr;
  382. // Invoke the method passing the parameters via the DISPPARAMS structure.
  383. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  384. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  385. // structure members should be initialized.
  386. DISPPARAMS disp_params = { disp_args, NULL, 5, 0 };
  387. DISPID dispid_named = DISPID_PROPERTYPUT;
  388. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  389. disp_params.cNamedArgs = 1;
  390. disp_params.rgdispidNamedArgs = &dispid_named;
  391. }
  392. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  393. &disp_params, disp_result, NULL, NULL);
  394. if (FAILED(hr))
  395. return hr;
  396. // Unwrap the parameters.
  397. disp_args[5 - 1].Unwrap(p1);
  398. disp_args[5 - 2].Unwrap(p2);
  399. disp_args[5 - 3].Unwrap(p3);
  400. disp_args[5 - 4].Unwrap(p4);
  401. disp_args[5 - 5].Unwrap(p5);
  402. // Unwrap the return value.
  403. if (result_out != NULL) {
  404. result.Unwrap(result_out);
  405. }
  406. return S_OK;
  407. }
  408. template <typename P1, typename P2, typename P3, typename P4, typename P5,
  409. typename P6>
  410. HRESULT Invoke(IDispatch* object,
  411. LPCOLESTR const_name,
  412. WORD flags,
  413. const P1& p1,
  414. const P2& p2,
  415. const P3& p3,
  416. const P4& p4,
  417. const P5& p5,
  418. const P6& p6,
  419. VARIANT* const & result_out) {
  420. // Retrieve the ID of the method to be called.
  421. DISPID disp_id;
  422. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  423. HRESULT hr = object->GetIDsOfNames(
  424. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  425. if (FAILED(hr))
  426. return hr;
  427. // Request the return value if asked by the caller.
  428. internal::ScopedVariantArg result;
  429. VARIANT* disp_result = NULL;
  430. if (result_out != NULL)
  431. disp_result = &result;
  432. // Wrap the parameters into an array of VARIANT structures.
  433. internal::ScopedVariantArg disp_args[6];
  434. hr = disp_args[6 - 1].Wrap(p1);
  435. if (FAILED(hr))
  436. return hr;
  437. hr = disp_args[6 - 2].Wrap(p2);
  438. if (FAILED(hr))
  439. return hr;
  440. hr = disp_args[6 - 3].Wrap(p3);
  441. if (FAILED(hr))
  442. return hr;
  443. hr = disp_args[6 - 4].Wrap(p4);
  444. if (FAILED(hr))
  445. return hr;
  446. hr = disp_args[6 - 5].Wrap(p5);
  447. if (FAILED(hr))
  448. return hr;
  449. hr = disp_args[6 - 6].Wrap(p6);
  450. if (FAILED(hr))
  451. return hr;
  452. // Invoke the method passing the parameters via the DISPPARAMS structure.
  453. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  454. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  455. // structure members should be initialized.
  456. DISPPARAMS disp_params = { disp_args, NULL, 6, 0 };
  457. DISPID dispid_named = DISPID_PROPERTYPUT;
  458. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  459. disp_params.cNamedArgs = 1;
  460. disp_params.rgdispidNamedArgs = &dispid_named;
  461. }
  462. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  463. &disp_params, disp_result, NULL, NULL);
  464. if (FAILED(hr))
  465. return hr;
  466. // Unwrap the parameters.
  467. disp_args[6 - 1].Unwrap(p1);
  468. disp_args[6 - 2].Unwrap(p2);
  469. disp_args[6 - 3].Unwrap(p3);
  470. disp_args[6 - 4].Unwrap(p4);
  471. disp_args[6 - 5].Unwrap(p5);
  472. disp_args[6 - 6].Unwrap(p6);
  473. // Unwrap the return value.
  474. if (result_out != NULL) {
  475. result.Unwrap(result_out);
  476. }
  477. return S_OK;
  478. }
  479. template <typename P1, typename P2, typename P3, typename P4, typename P5,
  480. typename P6, typename P7>
  481. HRESULT Invoke(IDispatch* object,
  482. LPCOLESTR const_name,
  483. WORD flags,
  484. const P1& p1,
  485. const P2& p2,
  486. const P3& p3,
  487. const P4& p4,
  488. const P5& p5,
  489. const P6& p6,
  490. const P7& p7,
  491. VARIANT* const & result_out) {
  492. // Retrieve the ID of the method to be called.
  493. DISPID disp_id;
  494. LPOLESTR name = const_cast<LPOLESTR>(const_name);
  495. HRESULT hr = object->GetIDsOfNames(
  496. IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  497. if (FAILED(hr))
  498. return hr;
  499. // Request the return value if asked by the caller.
  500. internal::ScopedVariantArg result;
  501. VARIANT* disp_result = NULL;
  502. if (result_out != NULL)
  503. disp_result = &result;
  504. // Wrap the parameters into an array of VARIANT structures.
  505. internal::ScopedVariantArg disp_args[7];
  506. hr = disp_args[7 - 1].Wrap(p1);
  507. if (FAILED(hr))
  508. return hr;
  509. hr = disp_args[7 - 2].Wrap(p2);
  510. if (FAILED(hr))
  511. return hr;
  512. hr = disp_args[7 - 3].Wrap(p3);
  513. if (FAILED(hr))
  514. return hr;
  515. hr = disp_args[7 - 4].Wrap(p4);
  516. if (FAILED(hr))
  517. return hr;
  518. hr = disp_args[7 - 5].Wrap(p5);
  519. if (FAILED(hr))
  520. return hr;
  521. hr = disp_args[7 - 6].Wrap(p6);
  522. if (FAILED(hr))
  523. return hr;
  524. hr = disp_args[7 - 7].Wrap(p7);
  525. if (FAILED(hr))
  526. return hr;
  527. // Invoke the method passing the parameters via the DISPPARAMS structure.
  528. // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  529. // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  530. // structure members should be initialized.
  531. DISPPARAMS disp_params = { disp_args, NULL, 7, 0 };
  532. DISPID dispid_named = DISPID_PROPERTYPUT;
  533. if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
  534. disp_params.cNamedArgs = 1;
  535. disp_params.rgdispidNamedArgs = &dispid_named;
  536. }
  537. hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
  538. &disp_params, disp_result, NULL, NULL);
  539. if (FAILED(hr))
  540. return hr;
  541. // Unwrap the parameters.
  542. disp_args[7 - 1].Unwrap(p1);
  543. disp_args[7 - 2].Unwrap(p2);
  544. disp_args[7 - 3].Unwrap(p3);
  545. disp_args[7 - 4].Unwrap(p4);
  546. disp_args[7 - 5].Unwrap(p5);
  547. disp_args[7 - 6].Unwrap(p6);
  548. disp_args[7 - 7].Unwrap(p7);
  549. // Unwrap the return value.
  550. if (result_out != NULL) {
  551. result.Unwrap(result_out);
  552. }
  553. return S_OK;
  554. }
  555. } // namespace dispatch
  556. } // namespace remoting
  557. #endif // REMOTING_BASE_DISPATCH_WIN_H_