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