1 /* 2 * Copyright 2013 Hans Leidekker for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #define COBJMACROS 20 21 #include "config.h" 22 #include <stdarg.h> 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "initguid.h" 27 #include "objbase.h" 28 #include "wmiutils.h" 29 #include "wbemcli.h" 30 #include "wbemdisp.h" 31 32 #include "wine/debug.h" 33 #include "wine/heap.h" 34 #include "wine/unicode.h" 35 #include "wbemdisp_private.h" 36 #include "wbemdisp_classes.h" 37 38 WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp); 39 40 static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** ); 41 static HRESULT ISWbemSecurity_create( ISWbemSecurity ** ); 42 43 enum type_id 44 { 45 ISWbemLocator_tid, 46 ISWbemObject_tid, 47 ISWbemObjectSet_tid, 48 ISWbemProperty_tid, 49 ISWbemPropertySet_tid, 50 ISWbemServices_tid, 51 ISWbemSecurity_tid, 52 last_tid 53 }; 54 55 static ITypeLib *wbemdisp_typelib; 56 static ITypeInfo *wbemdisp_typeinfo[last_tid]; 57 58 static REFIID wbemdisp_tid_id[] = 59 { 60 &IID_ISWbemLocator, 61 &IID_ISWbemObject, 62 &IID_ISWbemObjectSet, 63 &IID_ISWbemProperty, 64 &IID_ISWbemPropertySet, 65 &IID_ISWbemServices, 66 &IID_ISWbemSecurity 67 }; 68 69 static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) 70 { 71 HRESULT hr; 72 73 if (!wbemdisp_typelib) 74 { 75 ITypeLib *typelib; 76 77 hr = LoadRegTypeLib( &LIBID_WbemScripting, 1, 2, LOCALE_SYSTEM_DEFAULT, &typelib ); 78 if (FAILED( hr )) 79 { 80 ERR( "LoadRegTypeLib failed: %08x\n", hr ); 81 return hr; 82 } 83 if (InterlockedCompareExchangePointer( (void **)&wbemdisp_typelib, typelib, NULL )) 84 ITypeLib_Release( typelib ); 85 } 86 if (!wbemdisp_typeinfo[tid]) 87 { 88 ITypeInfo *typeinfo; 89 90 hr = ITypeLib_GetTypeInfoOfGuid( wbemdisp_typelib, wbemdisp_tid_id[tid], &typeinfo ); 91 if (FAILED( hr )) 92 { 93 ERR( "GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(wbemdisp_tid_id[tid]), hr ); 94 return hr; 95 } 96 if (InterlockedCompareExchangePointer( (void **)(wbemdisp_typeinfo + tid), typeinfo, NULL )) 97 ITypeInfo_Release( typeinfo ); 98 } 99 *ret = wbemdisp_typeinfo[tid]; 100 ITypeInfo_AddRef( *ret ); 101 return S_OK; 102 } 103 104 struct property 105 { 106 ISWbemProperty ISWbemProperty_iface; 107 LONG refs; 108 IWbemClassObject *object; 109 BSTR name; 110 }; 111 112 static inline struct property *impl_from_ISWbemProperty( ISWbemProperty *iface ) 113 { 114 return CONTAINING_RECORD( iface, struct property, ISWbemProperty_iface ); 115 } 116 117 static ULONG WINAPI property_AddRef( ISWbemProperty *iface ) 118 { 119 struct property *property = impl_from_ISWbemProperty( iface ); 120 return InterlockedIncrement( &property->refs ); 121 } 122 123 static ULONG WINAPI property_Release( ISWbemProperty *iface ) 124 { 125 struct property *property = impl_from_ISWbemProperty( iface ); 126 LONG refs = InterlockedDecrement( &property->refs ); 127 if (!refs) 128 { 129 TRACE( "destroying %p\n", property ); 130 IWbemClassObject_Release( property->object ); 131 SysFreeString( property->name ); 132 heap_free( property ); 133 } 134 return refs; 135 } 136 137 static HRESULT WINAPI property_QueryInterface( ISWbemProperty *iface, REFIID riid, void **obj ) 138 { 139 struct property *property = impl_from_ISWbemProperty( iface ); 140 141 TRACE( "%p %s %p\n", property, debugstr_guid(riid), obj ); 142 143 if (IsEqualGUID( riid, &IID_ISWbemProperty ) || 144 IsEqualGUID( riid, &IID_IDispatch ) || 145 IsEqualGUID( riid, &IID_IUnknown )) 146 { 147 *obj = iface; 148 } 149 else 150 { 151 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 152 return E_NOINTERFACE; 153 } 154 ISWbemProperty_AddRef( iface ); 155 return S_OK; 156 } 157 158 static HRESULT WINAPI property_GetTypeInfoCount( ISWbemProperty *iface, UINT *count ) 159 { 160 struct property *property = impl_from_ISWbemProperty( iface ); 161 TRACE( "%p, %p\n", property, count ); 162 *count = 1; 163 return S_OK; 164 } 165 166 static HRESULT WINAPI property_GetTypeInfo( ISWbemProperty *iface, UINT index, 167 LCID lcid, ITypeInfo **info ) 168 { 169 struct property *property = impl_from_ISWbemProperty( iface ); 170 TRACE( "%p, %u, %u, %p\n", property, index, lcid, info ); 171 172 return get_typeinfo( ISWbemProperty_tid, info ); 173 } 174 175 static HRESULT WINAPI property_GetIDsOfNames( ISWbemProperty *iface, REFIID riid, LPOLESTR *names, 176 UINT count, LCID lcid, DISPID *dispid ) 177 { 178 struct property *property = impl_from_ISWbemProperty( iface ); 179 ITypeInfo *typeinfo; 180 HRESULT hr; 181 182 TRACE( "%p, %s, %p, %u, %u, %p\n", property, debugstr_guid(riid), names, count, lcid, dispid ); 183 184 if (!names || !count || !dispid) return E_INVALIDARG; 185 186 hr = get_typeinfo( ISWbemProperty_tid, &typeinfo ); 187 if (SUCCEEDED(hr)) 188 { 189 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 190 ITypeInfo_Release( typeinfo ); 191 } 192 return hr; 193 } 194 195 static HRESULT WINAPI property_Invoke( ISWbemProperty *iface, DISPID member, REFIID riid, 196 LCID lcid, WORD flags, DISPPARAMS *params, 197 VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) 198 { 199 struct property *property = impl_from_ISWbemProperty( iface ); 200 ITypeInfo *typeinfo; 201 HRESULT hr; 202 203 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", property, member, debugstr_guid(riid), 204 lcid, flags, params, result, excep_info, arg_err ); 205 206 hr = get_typeinfo( ISWbemProperty_tid, &typeinfo ); 207 if (SUCCEEDED(hr)) 208 { 209 hr = ITypeInfo_Invoke( typeinfo, &property->ISWbemProperty_iface, member, flags, 210 params, result, excep_info, arg_err ); 211 ITypeInfo_Release( typeinfo ); 212 } 213 return hr; 214 } 215 216 static HRESULT WINAPI property_get_Value( ISWbemProperty *iface, VARIANT *value ) 217 { 218 struct property *property = impl_from_ISWbemProperty( iface ); 219 220 TRACE( "%p %p\n", property, value ); 221 222 return IWbemClassObject_Get( property->object, property->name, 0, value, NULL, NULL ); 223 } 224 225 static HRESULT WINAPI property_put_Value( ISWbemProperty *iface, VARIANT *varValue ) 226 { 227 FIXME( "\n" ); 228 return E_NOTIMPL; 229 } 230 231 static HRESULT WINAPI property_get_Name( ISWbemProperty *iface, BSTR *strName ) 232 { 233 FIXME( "\n" ); 234 return E_NOTIMPL; 235 } 236 237 static HRESULT WINAPI property_get_IsLocal( ISWbemProperty *iface, VARIANT_BOOL *bIsLocal ) 238 { 239 FIXME( "\n" ); 240 return E_NOTIMPL; 241 } 242 243 static HRESULT WINAPI property_get_Origin( ISWbemProperty *iface, BSTR *strOrigin ) 244 { 245 FIXME( "\n" ); 246 return E_NOTIMPL; 247 } 248 249 static HRESULT WINAPI property_get_CIMType( ISWbemProperty *iface, WbemCimtypeEnum *iCimType ) 250 { 251 FIXME( "\n" ); 252 return E_NOTIMPL; 253 } 254 255 static HRESULT WINAPI property_get_Qualifiers_( ISWbemProperty *iface, ISWbemQualifierSet **objWbemQualifierSet ) 256 { 257 FIXME( "\n" ); 258 return E_NOTIMPL; 259 } 260 261 static HRESULT WINAPI property_get_IsArray( ISWbemProperty *iface, VARIANT_BOOL *bIsArray ) 262 { 263 FIXME( "\n" ); 264 return E_NOTIMPL; 265 } 266 267 static const ISWbemPropertyVtbl property_vtbl = 268 { 269 property_QueryInterface, 270 property_AddRef, 271 property_Release, 272 property_GetTypeInfoCount, 273 property_GetTypeInfo, 274 property_GetIDsOfNames, 275 property_Invoke, 276 property_get_Value, 277 property_put_Value, 278 property_get_Name, 279 property_get_IsLocal, 280 property_get_Origin, 281 property_get_CIMType, 282 property_get_Qualifiers_, 283 property_get_IsArray 284 }; 285 286 static HRESULT SWbemProperty_create( IWbemClassObject *wbem_object, BSTR name, ISWbemProperty **obj ) 287 { 288 struct property *property; 289 290 TRACE( "%p, %p\n", obj, wbem_object ); 291 292 if (!(property = heap_alloc( sizeof(*property) ))) return E_OUTOFMEMORY; 293 property->ISWbemProperty_iface.lpVtbl = &property_vtbl; 294 property->refs = 1; 295 property->object = wbem_object; 296 IWbemClassObject_AddRef( property->object ); 297 property->name = SysAllocStringLen( name, SysStringLen( name ) ); 298 *obj = &property->ISWbemProperty_iface; 299 TRACE( "returning iface %p\n", *obj ); 300 return S_OK; 301 } 302 303 struct propertyset 304 { 305 ISWbemPropertySet ISWbemPropertySet_iface; 306 LONG refs; 307 IWbemClassObject *object; 308 }; 309 310 static inline struct propertyset *impl_from_ISWbemPropertySet( 311 ISWbemPropertySet *iface ) 312 { 313 return CONTAINING_RECORD( iface, struct propertyset, ISWbemPropertySet_iface ); 314 } 315 316 static ULONG WINAPI propertyset_AddRef( ISWbemPropertySet *iface ) 317 { 318 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 319 return InterlockedIncrement( &propertyset->refs ); 320 } 321 322 static ULONG WINAPI propertyset_Release( ISWbemPropertySet *iface ) 323 { 324 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 325 LONG refs = InterlockedDecrement( &propertyset->refs ); 326 if (!refs) 327 { 328 TRACE( "destroying %p\n", propertyset ); 329 IWbemClassObject_Release( propertyset->object ); 330 heap_free( propertyset ); 331 } 332 return refs; 333 } 334 335 static HRESULT WINAPI propertyset_QueryInterface( ISWbemPropertySet *iface, 336 REFIID riid, void **obj ) 337 { 338 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 339 340 TRACE( "%p %s %p\n", propertyset, debugstr_guid(riid), obj ); 341 342 if (IsEqualGUID( riid, &IID_ISWbemPropertySet ) || 343 IsEqualGUID( riid, &IID_IDispatch ) || 344 IsEqualGUID( riid, &IID_IUnknown )) 345 { 346 *obj = iface; 347 } 348 else 349 { 350 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 351 return E_NOINTERFACE; 352 } 353 ISWbemPropertySet_AddRef( iface ); 354 return S_OK; 355 } 356 357 static HRESULT WINAPI propertyset_GetTypeInfoCount( ISWbemPropertySet *iface, UINT *count ) 358 { 359 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 360 TRACE( "%p, %p\n", propertyset, count ); 361 *count = 1; 362 return S_OK; 363 } 364 365 static HRESULT WINAPI propertyset_GetTypeInfo( ISWbemPropertySet *iface, 366 UINT index, LCID lcid, ITypeInfo **info ) 367 { 368 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 369 TRACE( "%p, %u, %u, %p\n", propertyset, index, lcid, info ); 370 371 return get_typeinfo( ISWbemPropertySet_tid, info ); 372 } 373 374 static HRESULT WINAPI propertyset_GetIDsOfNames( ISWbemPropertySet *iface, REFIID riid, LPOLESTR *names, 375 UINT count, LCID lcid, DISPID *dispid ) 376 { 377 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 378 ITypeInfo *typeinfo; 379 HRESULT hr; 380 381 TRACE( "%p, %s, %p, %u, %u, %p\n", propertyset, debugstr_guid(riid), names, count, lcid, dispid ); 382 383 if (!names || !count || !dispid) return E_INVALIDARG; 384 385 hr = get_typeinfo( ISWbemPropertySet_tid, &typeinfo ); 386 if (SUCCEEDED(hr)) 387 { 388 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 389 ITypeInfo_Release( typeinfo ); 390 } 391 return hr; 392 } 393 394 static HRESULT WINAPI propertyset_Invoke( ISWbemPropertySet *iface, DISPID member, REFIID riid, 395 LCID lcid, WORD flags, DISPPARAMS *params, 396 VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) 397 { 398 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 399 ITypeInfo *typeinfo; 400 HRESULT hr; 401 402 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", propertyset, member, debugstr_guid(riid), 403 lcid, flags, params, result, excep_info, arg_err ); 404 405 hr = get_typeinfo( ISWbemPropertySet_tid, &typeinfo ); 406 if (SUCCEEDED(hr)) 407 { 408 hr = ITypeInfo_Invoke( typeinfo, &propertyset->ISWbemPropertySet_iface, member, flags, 409 params, result, excep_info, arg_err ); 410 ITypeInfo_Release( typeinfo ); 411 } 412 return hr; 413 } 414 415 static HRESULT WINAPI propertyset_get__NewEnum( ISWbemPropertySet *iface, IUnknown **unk ) 416 { 417 FIXME( "\n" ); 418 return E_NOTIMPL; 419 } 420 421 static HRESULT WINAPI propertyset_Item( ISWbemPropertySet *iface, BSTR name, 422 LONG flags, ISWbemProperty **prop ) 423 { 424 struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); 425 HRESULT hr; 426 VARIANT var; 427 428 TRACE( "%p, %s, %08x, %p\n", propertyset, debugstr_w(name), flags, prop ); 429 430 hr = IWbemClassObject_Get( propertyset->object, name, 0, &var, NULL, NULL ); 431 if (SUCCEEDED(hr)) 432 { 433 hr = SWbemProperty_create( propertyset->object, name, prop ); 434 VariantClear( &var ); 435 } 436 return hr; 437 } 438 439 static HRESULT WINAPI propertyset_get_Count( ISWbemPropertySet *iface, LONG *count ) 440 { 441 FIXME( "\n" ); 442 return E_NOTIMPL; 443 } 444 445 static HRESULT WINAPI propertyset_Add( ISWbemPropertySet *iface, BSTR name, WbemCimtypeEnum type, 446 VARIANT_BOOL is_array, LONG flags, ISWbemProperty **prop ) 447 { 448 FIXME( "\n" ); 449 return E_NOTIMPL; 450 } 451 452 static HRESULT WINAPI propertyset_Remove( ISWbemPropertySet *iface, BSTR name, LONG flags ) 453 { 454 FIXME( "\n" ); 455 return E_NOTIMPL; 456 } 457 458 static const ISWbemPropertySetVtbl propertyset_vtbl = 459 { 460 propertyset_QueryInterface, 461 propertyset_AddRef, 462 propertyset_Release, 463 propertyset_GetTypeInfoCount, 464 propertyset_GetTypeInfo, 465 propertyset_GetIDsOfNames, 466 propertyset_Invoke, 467 propertyset_get__NewEnum, 468 propertyset_Item, 469 propertyset_get_Count, 470 propertyset_Add, 471 propertyset_Remove 472 }; 473 474 static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPropertySet **obj ) 475 { 476 struct propertyset *propertyset; 477 478 TRACE( "%p, %p\n", obj, wbem_object ); 479 480 if (!(propertyset = heap_alloc( sizeof(*propertyset) ))) return E_OUTOFMEMORY; 481 propertyset->ISWbemPropertySet_iface.lpVtbl = &propertyset_vtbl; 482 propertyset->refs = 1; 483 propertyset->object = wbem_object; 484 IWbemClassObject_AddRef( propertyset->object ); 485 *obj = &propertyset->ISWbemPropertySet_iface; 486 487 TRACE( "returning iface %p\n", *obj ); 488 return S_OK; 489 } 490 491 #define DISPID_BASE 0x1800000 492 493 struct member 494 { 495 BSTR name; 496 DISPID dispid; 497 }; 498 499 struct object 500 { 501 ISWbemObject ISWbemObject_iface; 502 LONG refs; 503 IWbemClassObject *object; 504 struct member *members; 505 UINT nb_members; 506 DISPID last_dispid; 507 }; 508 509 static inline struct object *impl_from_ISWbemObject( 510 ISWbemObject *iface ) 511 { 512 return CONTAINING_RECORD( iface, struct object, ISWbemObject_iface ); 513 } 514 515 static ULONG WINAPI object_AddRef( 516 ISWbemObject *iface ) 517 { 518 struct object *object = impl_from_ISWbemObject( iface ); 519 return InterlockedIncrement( &object->refs ); 520 } 521 522 static ULONG WINAPI object_Release( 523 ISWbemObject *iface ) 524 { 525 struct object *object = impl_from_ISWbemObject( iface ); 526 LONG refs = InterlockedDecrement( &object->refs ); 527 if (!refs) 528 { 529 UINT i; 530 531 TRACE( "destroying %p\n", object ); 532 IWbemClassObject_Release( object->object ); 533 for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name ); 534 heap_free( object->members ); 535 heap_free( object ); 536 } 537 return refs; 538 } 539 540 static HRESULT WINAPI object_QueryInterface( 541 ISWbemObject *iface, 542 REFIID riid, 543 void **ppvObject ) 544 { 545 struct object *object = impl_from_ISWbemObject( iface ); 546 547 TRACE( "%p %s %p\n", object, debugstr_guid(riid), ppvObject ); 548 549 if (IsEqualGUID( riid, &IID_ISWbemObject ) || 550 IsEqualGUID( riid, &IID_IDispatch ) || 551 IsEqualGUID( riid, &IID_IUnknown )) 552 { 553 *ppvObject = iface; 554 } 555 else 556 { 557 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 558 return E_NOINTERFACE; 559 } 560 ISWbemObject_AddRef( iface ); 561 return S_OK; 562 } 563 564 static HRESULT WINAPI object_GetTypeInfoCount( 565 ISWbemObject *iface, 566 UINT *count ) 567 { 568 struct object *object = impl_from_ISWbemObject( iface ); 569 570 TRACE( "%p, %p\n", object, count ); 571 *count = 1; 572 return S_OK; 573 } 574 575 static HRESULT WINAPI object_GetTypeInfo( 576 ISWbemObject *iface, 577 UINT index, 578 LCID lcid, 579 ITypeInfo **info ) 580 { 581 struct object *object = impl_from_ISWbemObject( iface ); 582 FIXME( "%p, %u, %u, %p\n", object, index, lcid, info ); 583 return E_NOTIMPL; 584 } 585 586 static HRESULT init_members( struct object *object ) 587 { 588 LONG bound, i; 589 SAFEARRAY *sa; 590 HRESULT hr; 591 592 if (object->members) return S_OK; 593 594 hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa ); 595 if (FAILED( hr )) return hr; 596 hr = SafeArrayGetUBound( sa, 1, &bound ); 597 if (FAILED( hr )) 598 { 599 SafeArrayDestroy( sa ); 600 return hr; 601 } 602 if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) ))) 603 { 604 SafeArrayDestroy( sa ); 605 return E_OUTOFMEMORY; 606 } 607 for (i = 0; i <= bound; i++) 608 { 609 hr = SafeArrayGetElement( sa, &i, &object->members[i].name ); 610 if (FAILED( hr )) 611 { 612 for (i--; i >= 0; i--) SysFreeString( object->members[i].name ); 613 SafeArrayDestroy( sa ); 614 heap_free( object->members ); 615 object->members = NULL; 616 return E_OUTOFMEMORY; 617 } 618 object->members[i].dispid = 0; 619 } 620 object->nb_members = bound + 1; 621 SafeArrayDestroy( sa ); 622 return S_OK; 623 } 624 625 static DISPID get_member_dispid( struct object *object, const WCHAR *name ) 626 { 627 UINT i; 628 for (i = 0; i < object->nb_members; i++) 629 { 630 if (!strcmpiW( object->members[i].name, name )) 631 { 632 if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid; 633 return object->members[i].dispid; 634 } 635 } 636 return DISPID_UNKNOWN; 637 } 638 639 static HRESULT WINAPI object_GetIDsOfNames( 640 ISWbemObject *iface, 641 REFIID riid, 642 LPOLESTR *names, 643 UINT count, 644 LCID lcid, 645 DISPID *dispid ) 646 { 647 struct object *object = impl_from_ISWbemObject( iface ); 648 HRESULT hr; 649 UINT i; 650 ITypeInfo *typeinfo; 651 652 TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid ); 653 654 if (!names || !count || !dispid) return E_INVALIDARG; 655 656 hr = init_members( object ); 657 if (FAILED( hr )) return hr; 658 659 hr = get_typeinfo( ISWbemObject_tid, &typeinfo ); 660 if (SUCCEEDED(hr)) 661 { 662 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 663 ITypeInfo_Release( typeinfo ); 664 } 665 if (SUCCEEDED(hr)) return hr; 666 667 for (i = 0; i < count; i++) 668 { 669 if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break; 670 } 671 if (i != count) return DISP_E_UNKNOWNNAME; 672 return S_OK; 673 } 674 675 static BSTR get_member_name( struct object *object, DISPID dispid ) 676 { 677 UINT i; 678 for (i = 0; i < object->nb_members; i++) 679 { 680 if (object->members[i].dispid == dispid) return object->members[i].name; 681 } 682 return NULL; 683 } 684 685 static HRESULT WINAPI object_Invoke( 686 ISWbemObject *iface, 687 DISPID member, 688 REFIID riid, 689 LCID lcid, 690 WORD flags, 691 DISPPARAMS *params, 692 VARIANT *result, 693 EXCEPINFO *excep_info, 694 UINT *arg_err ) 695 { 696 struct object *object = impl_from_ISWbemObject( iface ); 697 BSTR name; 698 ITypeInfo *typeinfo; 699 HRESULT hr; 700 701 TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid), 702 lcid, flags, params, result, excep_info, arg_err ); 703 704 if (member <= DISPID_BASE) 705 { 706 hr = get_typeinfo( ISWbemObject_tid, &typeinfo ); 707 if (SUCCEEDED(hr)) 708 { 709 hr = ITypeInfo_Invoke( typeinfo, &object->ISWbemObject_iface, member, flags, 710 params, result, excep_info, arg_err ); 711 ITypeInfo_Release( typeinfo ); 712 } 713 return hr; 714 } 715 716 if (flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET)) 717 { 718 FIXME( "flags %x not supported\n", flags ); 719 return E_NOTIMPL; 720 } 721 if (!(name = get_member_name( object, member ))) 722 return DISP_E_MEMBERNOTFOUND; 723 724 memset( params, 0, sizeof(*params) ); 725 return IWbemClassObject_Get( object->object, name, 0, result, NULL, NULL ); 726 } 727 728 static HRESULT WINAPI object_Put_( 729 ISWbemObject *iface, 730 LONG iFlags, 731 IDispatch *objWbemNamedValueSet, 732 ISWbemObjectPath **objWbemObjectPath ) 733 { 734 FIXME( "\n" ); 735 return E_NOTIMPL; 736 } 737 738 static HRESULT WINAPI object_PutAsync_( 739 ISWbemObject *iface, 740 IDispatch *objWbemSink, 741 LONG iFlags, 742 IDispatch *objWbemNamedValueSet, 743 IDispatch *objWbemAsyncContext ) 744 { 745 FIXME( "\n" ); 746 return E_NOTIMPL; 747 } 748 749 static HRESULT WINAPI object_Delete_( 750 ISWbemObject *iface, 751 LONG iFlags, 752 IDispatch *objWbemNamedValueSet ) 753 { 754 FIXME( "\n" ); 755 return E_NOTIMPL; 756 } 757 758 static HRESULT WINAPI object_DeleteAsync_( 759 ISWbemObject *iface, 760 IDispatch *objWbemSink, 761 LONG iFlags, 762 IDispatch *objWbemNamedValueSet, 763 IDispatch *objWbemAsyncContext ) 764 { 765 FIXME( "\n" ); 766 return E_NOTIMPL; 767 } 768 769 static HRESULT WINAPI object_Instances_( 770 ISWbemObject *iface, 771 LONG iFlags, 772 IDispatch *objWbemNamedValueSet, 773 ISWbemObjectSet **objWbemObjectSet ) 774 { 775 FIXME( "\n" ); 776 return E_NOTIMPL; 777 } 778 779 static HRESULT WINAPI object_InstancesAsync_( 780 ISWbemObject *iface, 781 IDispatch *objWbemSink, 782 LONG iFlags, 783 IDispatch *objWbemNamedValueSet, 784 IDispatch *objWbemAsyncContext ) 785 { 786 FIXME( "\n" ); 787 return E_NOTIMPL; 788 } 789 790 static HRESULT WINAPI object_Subclasses_( 791 ISWbemObject *iface, 792 LONG iFlags, 793 IDispatch *objWbemNamedValueSet, 794 ISWbemObjectSet **objWbemObjectSet ) 795 { 796 FIXME( "\n" ); 797 return E_NOTIMPL; 798 } 799 800 static HRESULT WINAPI object_SubclassesAsync_( 801 ISWbemObject *iface, 802 IDispatch *objWbemSink, 803 LONG iFlags, 804 IDispatch *objWbemNamedValueSet, 805 IDispatch *objWbemAsyncContext ) 806 { 807 FIXME( "\n" ); 808 return E_NOTIMPL; 809 } 810 811 static HRESULT WINAPI object_Associators_( 812 ISWbemObject *iface, 813 BSTR strAssocClass, 814 BSTR strResultClass, 815 BSTR strResultRole, 816 BSTR strRole, 817 VARIANT_BOOL bClassesOnly, 818 VARIANT_BOOL bSchemaOnly, 819 BSTR strRequiredAssocQualifier, 820 BSTR strRequiredQualifier, 821 LONG iFlags, 822 IDispatch *objWbemNamedValueSet, 823 ISWbemObjectSet **objWbemObjectSet ) 824 { 825 FIXME( "\n" ); 826 return E_NOTIMPL; 827 } 828 829 static HRESULT WINAPI object_AssociatorsAsync_( 830 ISWbemObject *iface, 831 IDispatch *objWbemSink, 832 BSTR strAssocClass, 833 BSTR strResultClass, 834 BSTR strResultRole, 835 BSTR strRole, 836 VARIANT_BOOL bClassesOnly, 837 VARIANT_BOOL bSchemaOnly, 838 BSTR strRequiredAssocQualifier, 839 BSTR strRequiredQualifier, 840 LONG iFlags, 841 IDispatch *objWbemNamedValueSet, 842 IDispatch *objWbemAsyncContext ) 843 { 844 FIXME( "\n" ); 845 return E_NOTIMPL; 846 } 847 848 static HRESULT WINAPI object_References_( 849 ISWbemObject *iface, 850 BSTR strResultClass, 851 BSTR strRole, 852 VARIANT_BOOL bClassesOnly, 853 VARIANT_BOOL bSchemaOnly, 854 BSTR strRequiredQualifier, 855 LONG iFlags, 856 IDispatch *objWbemNamedValueSet, 857 ISWbemObjectSet **objWbemObjectSet ) 858 { 859 FIXME( "\n" ); 860 return E_NOTIMPL; 861 } 862 863 static HRESULT WINAPI object_ReferencesAsync_( 864 ISWbemObject *iface, 865 IDispatch *objWbemSink, 866 BSTR strResultClass, 867 BSTR strRole, 868 VARIANT_BOOL bClassesOnly, 869 VARIANT_BOOL bSchemaOnly, 870 BSTR strRequiredQualifier, 871 LONG iFlags, 872 IDispatch *objWbemNamedValueSet, 873 IDispatch *objWbemAsyncContext ) 874 { 875 FIXME( "\n" ); 876 return E_NOTIMPL; 877 } 878 879 static HRESULT WINAPI object_ExecMethod_( 880 ISWbemObject *iface, 881 BSTR strMethodName, 882 IDispatch *objWbemInParameters, 883 LONG iFlags, 884 IDispatch *objWbemNamedValueSet, 885 ISWbemObject **objWbemOutParameters ) 886 { 887 FIXME( "\n" ); 888 return E_NOTIMPL; 889 } 890 891 static HRESULT WINAPI object_ExecMethodAsync_( 892 ISWbemObject *iface, 893 IDispatch *objWbemSink, 894 BSTR strMethodName, 895 IDispatch *objWbemInParameters, 896 LONG iFlags, 897 IDispatch *objWbemNamedValueSet, 898 IDispatch *objWbemAsyncContext ) 899 { 900 FIXME( "\n" ); 901 return E_NOTIMPL; 902 } 903 904 static HRESULT WINAPI object_Clone_( 905 ISWbemObject *iface, 906 ISWbemObject **objWbemObject ) 907 { 908 FIXME( "\n" ); 909 return E_NOTIMPL; 910 } 911 912 static HRESULT WINAPI object_GetObjectText_( 913 ISWbemObject *iface, 914 LONG iFlags, 915 BSTR *strObjectText ) 916 { 917 FIXME( "\n" ); 918 return E_NOTIMPL; 919 } 920 921 static HRESULT WINAPI object_SpawnDerivedClass_( 922 ISWbemObject *iface, 923 LONG iFlags, 924 ISWbemObject **objWbemObject ) 925 { 926 FIXME( "\n" ); 927 return E_NOTIMPL; 928 } 929 930 static HRESULT WINAPI object_SpawnInstance_( 931 ISWbemObject *iface, 932 LONG iFlags, 933 ISWbemObject **objWbemObject ) 934 { 935 FIXME( "\n" ); 936 return E_NOTIMPL; 937 } 938 939 static HRESULT WINAPI object_CompareTo_( 940 ISWbemObject *iface, 941 IDispatch *objWbemObject, 942 LONG iFlags, 943 VARIANT_BOOL *bResult ) 944 { 945 FIXME( "\n" ); 946 return E_NOTIMPL; 947 } 948 949 static HRESULT WINAPI object_get_Qualifiers_( 950 ISWbemObject *iface, 951 ISWbemQualifierSet **objWbemQualifierSet ) 952 { 953 FIXME( "\n" ); 954 return E_NOTIMPL; 955 } 956 957 static HRESULT WINAPI object_get_Properties_( ISWbemObject *iface, ISWbemPropertySet **prop_set ) 958 { 959 struct object *object = impl_from_ISWbemObject( iface ); 960 961 TRACE( "%p, %p\n", object, prop_set ); 962 return SWbemPropertySet_create( object->object, prop_set ); 963 } 964 965 static HRESULT WINAPI object_get_Methods_( 966 ISWbemObject *iface, 967 ISWbemMethodSet **objWbemMethodSet ) 968 { 969 FIXME( "\n" ); 970 return E_NOTIMPL; 971 } 972 973 static HRESULT WINAPI object_get_Derivation_( 974 ISWbemObject *iface, 975 VARIANT *strClassNameArray ) 976 { 977 FIXME( "\n" ); 978 return E_NOTIMPL; 979 } 980 981 static HRESULT WINAPI object_get_Path_( 982 ISWbemObject *iface, 983 ISWbemObjectPath **objWbemObjectPath ) 984 { 985 FIXME( "\n" ); 986 return E_NOTIMPL; 987 } 988 989 static HRESULT WINAPI object_get_Security_( 990 ISWbemObject *iface, 991 ISWbemSecurity **objWbemSecurity ) 992 { 993 FIXME( "\n" ); 994 return E_NOTIMPL; 995 } 996 997 static const ISWbemObjectVtbl object_vtbl = 998 { 999 object_QueryInterface, 1000 object_AddRef, 1001 object_Release, 1002 object_GetTypeInfoCount, 1003 object_GetTypeInfo, 1004 object_GetIDsOfNames, 1005 object_Invoke, 1006 object_Put_, 1007 object_PutAsync_, 1008 object_Delete_, 1009 object_DeleteAsync_, 1010 object_Instances_, 1011 object_InstancesAsync_, 1012 object_Subclasses_, 1013 object_SubclassesAsync_, 1014 object_Associators_, 1015 object_AssociatorsAsync_, 1016 object_References_, 1017 object_ReferencesAsync_, 1018 object_ExecMethod_, 1019 object_ExecMethodAsync_, 1020 object_Clone_, 1021 object_GetObjectText_, 1022 object_SpawnDerivedClass_, 1023 object_SpawnInstance_, 1024 object_CompareTo_, 1025 object_get_Qualifiers_, 1026 object_get_Properties_, 1027 object_get_Methods_, 1028 object_get_Derivation_, 1029 object_get_Path_, 1030 object_get_Security_ 1031 }; 1032 1033 static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj ) 1034 { 1035 struct object *object; 1036 1037 TRACE( "%p, %p\n", obj, wbem_object ); 1038 1039 if (!(object = heap_alloc( sizeof(*object) ))) return E_OUTOFMEMORY; 1040 object->ISWbemObject_iface.lpVtbl = &object_vtbl; 1041 object->refs = 1; 1042 object->object = wbem_object; 1043 IWbemClassObject_AddRef( object->object ); 1044 object->members = NULL; 1045 object->nb_members = 0; 1046 object->last_dispid = DISPID_BASE; 1047 1048 *obj = &object->ISWbemObject_iface; 1049 TRACE( "returning iface %p\n", *obj ); 1050 return S_OK; 1051 } 1052 1053 struct objectset 1054 { 1055 ISWbemObjectSet ISWbemObjectSet_iface; 1056 LONG refs; 1057 IEnumWbemClassObject *objectenum; 1058 LONG count; 1059 }; 1060 1061 static inline struct objectset *impl_from_ISWbemObjectSet( 1062 ISWbemObjectSet *iface ) 1063 { 1064 return CONTAINING_RECORD( iface, struct objectset, ISWbemObjectSet_iface ); 1065 } 1066 1067 static ULONG WINAPI objectset_AddRef( 1068 ISWbemObjectSet *iface ) 1069 { 1070 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1071 return InterlockedIncrement( &objectset->refs ); 1072 } 1073 1074 static ULONG WINAPI objectset_Release( 1075 ISWbemObjectSet *iface ) 1076 { 1077 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1078 LONG refs = InterlockedDecrement( &objectset->refs ); 1079 if (!refs) 1080 { 1081 TRACE( "destroying %p\n", objectset ); 1082 IEnumWbemClassObject_Release( objectset->objectenum ); 1083 heap_free( objectset ); 1084 } 1085 return refs; 1086 } 1087 1088 static HRESULT WINAPI objectset_QueryInterface( 1089 ISWbemObjectSet *iface, 1090 REFIID riid, 1091 void **ppvObject ) 1092 { 1093 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1094 1095 TRACE( "%p %s %p\n", objectset, debugstr_guid(riid), ppvObject ); 1096 1097 if (IsEqualGUID( riid, &IID_ISWbemObjectSet ) || 1098 IsEqualGUID( riid, &IID_IDispatch ) || 1099 IsEqualGUID( riid, &IID_IUnknown )) 1100 { 1101 *ppvObject = iface; 1102 } 1103 else 1104 { 1105 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 1106 return E_NOINTERFACE; 1107 } 1108 ISWbemObjectSet_AddRef( iface ); 1109 return S_OK; 1110 } 1111 1112 static HRESULT WINAPI objectset_GetTypeInfoCount( 1113 ISWbemObjectSet *iface, 1114 UINT *count ) 1115 { 1116 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1117 TRACE( "%p, %p\n", objectset, count ); 1118 *count = 1; 1119 return S_OK; 1120 } 1121 1122 static HRESULT WINAPI objectset_GetTypeInfo( 1123 ISWbemObjectSet *iface, 1124 UINT index, 1125 LCID lcid, 1126 ITypeInfo **info ) 1127 { 1128 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1129 TRACE( "%p, %u, %u, %p\n", objectset, index, lcid, info ); 1130 1131 return get_typeinfo( ISWbemObjectSet_tid, info ); 1132 } 1133 1134 static HRESULT WINAPI objectset_GetIDsOfNames( 1135 ISWbemObjectSet *iface, 1136 REFIID riid, 1137 LPOLESTR *names, 1138 UINT count, 1139 LCID lcid, 1140 DISPID *dispid ) 1141 { 1142 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1143 ITypeInfo *typeinfo; 1144 HRESULT hr; 1145 1146 TRACE( "%p, %s, %p, %u, %u, %p\n", objectset, debugstr_guid(riid), names, count, lcid, dispid ); 1147 1148 if (!names || !count || !dispid) return E_INVALIDARG; 1149 1150 hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo ); 1151 if (SUCCEEDED(hr)) 1152 { 1153 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 1154 ITypeInfo_Release( typeinfo ); 1155 } 1156 return hr; 1157 } 1158 1159 static HRESULT WINAPI objectset_Invoke( 1160 ISWbemObjectSet *iface, 1161 DISPID member, 1162 REFIID riid, 1163 LCID lcid, 1164 WORD flags, 1165 DISPPARAMS *params, 1166 VARIANT *result, 1167 EXCEPINFO *excep_info, 1168 UINT *arg_err ) 1169 { 1170 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1171 ITypeInfo *typeinfo; 1172 HRESULT hr; 1173 1174 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", objectset, member, debugstr_guid(riid), 1175 lcid, flags, params, result, excep_info, arg_err ); 1176 1177 hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo ); 1178 if (SUCCEEDED(hr)) 1179 { 1180 hr = ITypeInfo_Invoke( typeinfo, &objectset->ISWbemObjectSet_iface, member, flags, 1181 params, result, excep_info, arg_err ); 1182 ITypeInfo_Release( typeinfo ); 1183 } 1184 return hr; 1185 } 1186 1187 static HRESULT WINAPI objectset_get__NewEnum( 1188 ISWbemObjectSet *iface, 1189 IUnknown **pUnk ) 1190 { 1191 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1192 IEnumWbemClassObject *objectenum; 1193 HRESULT hr; 1194 1195 TRACE( "%p, %p\n", objectset, pUnk ); 1196 1197 hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum ); 1198 if (FAILED( hr )) return hr; 1199 1200 hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk ); 1201 IEnumWbemClassObject_Release( objectenum ); 1202 return hr; 1203 } 1204 1205 static HRESULT WINAPI objectset_Item( 1206 ISWbemObjectSet *iface, 1207 BSTR strObjectPath, 1208 LONG iFlags, 1209 ISWbemObject **objWbemObject ) 1210 { 1211 FIXME( "\n" ); 1212 return E_NOTIMPL; 1213 } 1214 1215 static HRESULT WINAPI objectset_get_Count( 1216 ISWbemObjectSet *iface, 1217 LONG *iCount ) 1218 { 1219 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1220 1221 TRACE( "%p, %p\n", objectset, iCount ); 1222 1223 *iCount = objectset->count; 1224 return S_OK; 1225 } 1226 1227 static HRESULT WINAPI objectset_get_Security_( 1228 ISWbemObjectSet *iface, 1229 ISWbemSecurity **objWbemSecurity ) 1230 { 1231 FIXME( "\n" ); 1232 return E_NOTIMPL; 1233 } 1234 1235 static HRESULT WINAPI objectset_ItemIndex( 1236 ISWbemObjectSet *iface, 1237 LONG lIndex, 1238 ISWbemObject **objWbemObject ) 1239 { 1240 struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); 1241 LONG count; 1242 HRESULT hr; 1243 IEnumVARIANT *enum_var; 1244 VARIANT var; 1245 1246 TRACE( "%p, %d, %p\n", objectset, lIndex, objWbemObject ); 1247 1248 *objWbemObject = NULL; 1249 hr = ISWbemObjectSet_get_Count( iface, &count ); 1250 if (FAILED(hr)) return hr; 1251 1252 if (lIndex >= count) return WBEM_E_NOT_FOUND; 1253 1254 hr = ISWbemObjectSet_get__NewEnum( iface, (IUnknown **)&enum_var ); 1255 if (FAILED(hr)) return hr; 1256 1257 IEnumVARIANT_Reset( enum_var ); 1258 hr = IEnumVARIANT_Skip( enum_var, lIndex ); 1259 if (SUCCEEDED(hr)) 1260 hr = IEnumVARIANT_Next( enum_var, 1, &var, NULL ); 1261 IEnumVARIANT_Release( enum_var ); 1262 1263 if (SUCCEEDED(hr)) 1264 { 1265 if (V_VT( &var ) == VT_DISPATCH) 1266 hr = IDispatch_QueryInterface( V_DISPATCH( &var ), &IID_ISWbemObject, (void **)objWbemObject ); 1267 else 1268 hr = WBEM_E_NOT_FOUND; 1269 VariantClear( &var ); 1270 } 1271 1272 return hr; 1273 } 1274 1275 static const ISWbemObjectSetVtbl objectset_vtbl = 1276 { 1277 objectset_QueryInterface, 1278 objectset_AddRef, 1279 objectset_Release, 1280 objectset_GetTypeInfoCount, 1281 objectset_GetTypeInfo, 1282 objectset_GetIDsOfNames, 1283 objectset_Invoke, 1284 objectset_get__NewEnum, 1285 objectset_Item, 1286 objectset_get_Count, 1287 objectset_get_Security_, 1288 objectset_ItemIndex 1289 }; 1290 1291 static LONG get_object_count( IEnumWbemClassObject *iter ) 1292 { 1293 LONG count = 0; 1294 while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) count++; 1295 IEnumWbemClassObject_Reset( iter ); 1296 return count; 1297 } 1298 1299 static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj ) 1300 { 1301 struct objectset *objectset; 1302 1303 TRACE( "%p, %p\n", obj, wbem_objectenum ); 1304 1305 if (!(objectset = heap_alloc( sizeof(*objectset) ))) return E_OUTOFMEMORY; 1306 objectset->ISWbemObjectSet_iface.lpVtbl = &objectset_vtbl; 1307 objectset->refs = 1; 1308 objectset->objectenum = wbem_objectenum; 1309 IEnumWbemClassObject_AddRef( objectset->objectenum ); 1310 objectset->count = get_object_count( objectset->objectenum ); 1311 1312 *obj = &objectset->ISWbemObjectSet_iface; 1313 TRACE( "returning iface %p\n", *obj ); 1314 return S_OK; 1315 } 1316 1317 struct enumvar 1318 { 1319 IEnumVARIANT IEnumVARIANT_iface; 1320 LONG refs; 1321 IEnumWbemClassObject *objectenum; 1322 }; 1323 1324 static inline struct enumvar *impl_from_IEnumVARIANT( 1325 IEnumVARIANT *iface ) 1326 { 1327 return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface ); 1328 } 1329 1330 static ULONG WINAPI enumvar_AddRef( 1331 IEnumVARIANT *iface ) 1332 { 1333 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); 1334 return InterlockedIncrement( &enumvar->refs ); 1335 } 1336 1337 static ULONG WINAPI enumvar_Release( 1338 IEnumVARIANT *iface ) 1339 { 1340 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); 1341 LONG refs = InterlockedDecrement( &enumvar->refs ); 1342 if (!refs) 1343 { 1344 TRACE( "destroying %p\n", enumvar ); 1345 IEnumWbemClassObject_Release( enumvar->objectenum ); 1346 heap_free( enumvar ); 1347 } 1348 return refs; 1349 } 1350 1351 static HRESULT WINAPI enumvar_QueryInterface( 1352 IEnumVARIANT *iface, 1353 REFIID riid, 1354 void **ppvObject ) 1355 { 1356 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); 1357 1358 TRACE( "%p %s %p\n", enumvar, debugstr_guid(riid), ppvObject ); 1359 1360 if (IsEqualGUID( riid, &IID_IEnumVARIANT ) || 1361 IsEqualGUID( riid, &IID_IUnknown )) 1362 { 1363 *ppvObject = iface; 1364 } 1365 else 1366 { 1367 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 1368 return E_NOINTERFACE; 1369 } 1370 IEnumVARIANT_AddRef( iface ); 1371 return S_OK; 1372 } 1373 1374 static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched ) 1375 { 1376 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); 1377 IWbemClassObject *obj; 1378 ULONG count = 0; 1379 1380 TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched ); 1381 1382 if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count ); 1383 if (count) 1384 { 1385 ISWbemObject *sobj; 1386 HRESULT hr; 1387 1388 hr = SWbemObject_create( obj, &sobj ); 1389 IWbemClassObject_Release( obj ); 1390 if (FAILED( hr )) return hr; 1391 1392 V_VT( var ) = VT_DISPATCH; 1393 V_DISPATCH( var ) = (IDispatch *)sobj; 1394 } 1395 if (fetched) *fetched = count; 1396 return (count < celt) ? S_FALSE : S_OK; 1397 } 1398 1399 static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt ) 1400 { 1401 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); 1402 1403 TRACE( "%p, %u\n", iface, celt ); 1404 1405 return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt ); 1406 } 1407 1408 static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface ) 1409 { 1410 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); 1411 1412 TRACE( "%p\n", iface ); 1413 1414 return IEnumWbemClassObject_Reset( enumvar->objectenum ); 1415 } 1416 1417 static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum ) 1418 { 1419 FIXME( "%p, %p\n", iface, penum ); 1420 return E_NOTIMPL; 1421 } 1422 1423 static const struct IEnumVARIANTVtbl enumvar_vtbl = 1424 { 1425 enumvar_QueryInterface, 1426 enumvar_AddRef, 1427 enumvar_Release, 1428 enumvar_Next, 1429 enumvar_Skip, 1430 enumvar_Reset, 1431 enumvar_Clone 1432 }; 1433 1434 static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj ) 1435 { 1436 struct enumvar *enumvar; 1437 1438 if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY; 1439 enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl; 1440 enumvar->refs = 1; 1441 enumvar->objectenum = objectenum; 1442 IEnumWbemClassObject_AddRef( enumvar->objectenum ); 1443 1444 *obj = &enumvar->IEnumVARIANT_iface; 1445 TRACE( "returning iface %p\n", *obj ); 1446 return S_OK; 1447 } 1448 1449 struct services 1450 { 1451 ISWbemServices ISWbemServices_iface; 1452 LONG refs; 1453 IWbemServices *services; 1454 }; 1455 1456 static inline struct services *impl_from_ISWbemServices( 1457 ISWbemServices *iface ) 1458 { 1459 return CONTAINING_RECORD( iface, struct services, ISWbemServices_iface ); 1460 } 1461 1462 static ULONG WINAPI services_AddRef( 1463 ISWbemServices *iface ) 1464 { 1465 struct services *services = impl_from_ISWbemServices( iface ); 1466 return InterlockedIncrement( &services->refs ); 1467 } 1468 1469 static ULONG WINAPI services_Release( 1470 ISWbemServices *iface ) 1471 { 1472 struct services *services = impl_from_ISWbemServices( iface ); 1473 LONG refs = InterlockedDecrement( &services->refs ); 1474 if (!refs) 1475 { 1476 TRACE( "destroying %p\n", services ); 1477 IWbemServices_Release( services->services ); 1478 heap_free( services ); 1479 } 1480 return refs; 1481 } 1482 1483 static HRESULT WINAPI services_QueryInterface( 1484 ISWbemServices *iface, 1485 REFIID riid, 1486 void **ppvObject ) 1487 { 1488 struct services *services = impl_from_ISWbemServices( iface ); 1489 1490 TRACE( "%p %s %p\n", services, debugstr_guid(riid), ppvObject ); 1491 1492 if (IsEqualGUID( riid, &IID_ISWbemServices ) || 1493 IsEqualGUID( riid, &IID_IDispatch ) || 1494 IsEqualGUID( riid, &IID_IUnknown )) 1495 { 1496 *ppvObject = iface; 1497 } 1498 else 1499 { 1500 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 1501 return E_NOINTERFACE; 1502 } 1503 ISWbemServices_AddRef( iface ); 1504 return S_OK; 1505 } 1506 1507 static HRESULT WINAPI services_GetTypeInfoCount( 1508 ISWbemServices *iface, 1509 UINT *count ) 1510 { 1511 struct services *services = impl_from_ISWbemServices( iface ); 1512 TRACE( "%p, %p\n", services, count ); 1513 1514 *count = 1; 1515 return S_OK; 1516 } 1517 1518 static HRESULT WINAPI services_GetTypeInfo( 1519 ISWbemServices *iface, 1520 UINT index, 1521 LCID lcid, 1522 ITypeInfo **info ) 1523 { 1524 struct services *services = impl_from_ISWbemServices( iface ); 1525 TRACE( "%p, %u, %u, %p\n", services, index, lcid, info ); 1526 1527 return get_typeinfo( ISWbemServices_tid, info ); 1528 } 1529 1530 static HRESULT WINAPI services_GetIDsOfNames( 1531 ISWbemServices *iface, 1532 REFIID riid, 1533 LPOLESTR *names, 1534 UINT count, 1535 LCID lcid, 1536 DISPID *dispid ) 1537 { 1538 struct services *services = impl_from_ISWbemServices( iface ); 1539 ITypeInfo *typeinfo; 1540 HRESULT hr; 1541 1542 TRACE( "%p, %s, %p, %u, %u, %p\n", services, debugstr_guid(riid), names, count, lcid, dispid ); 1543 1544 if (!names || !count || !dispid) return E_INVALIDARG; 1545 1546 hr = get_typeinfo( ISWbemServices_tid, &typeinfo ); 1547 if (SUCCEEDED(hr)) 1548 { 1549 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 1550 ITypeInfo_Release( typeinfo ); 1551 } 1552 return hr; 1553 } 1554 1555 static HRESULT WINAPI services_Invoke( 1556 ISWbemServices *iface, 1557 DISPID member, 1558 REFIID riid, 1559 LCID lcid, 1560 WORD flags, 1561 DISPPARAMS *params, 1562 VARIANT *result, 1563 EXCEPINFO *excep_info, 1564 UINT *arg_err ) 1565 { 1566 struct services *services = impl_from_ISWbemServices( iface ); 1567 ITypeInfo *typeinfo; 1568 HRESULT hr; 1569 1570 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", services, member, debugstr_guid(riid), 1571 lcid, flags, params, result, excep_info, arg_err ); 1572 1573 hr = get_typeinfo( ISWbemServices_tid, &typeinfo ); 1574 if (SUCCEEDED(hr)) 1575 { 1576 hr = ITypeInfo_Invoke( typeinfo, &services->ISWbemServices_iface, member, flags, 1577 params, result, excep_info, arg_err ); 1578 ITypeInfo_Release( typeinfo ); 1579 } 1580 return hr; 1581 } 1582 1583 static HRESULT WINAPI services_Get( 1584 ISWbemServices *iface, 1585 BSTR strObjectPath, 1586 LONG iFlags, 1587 IDispatch *objWbemNamedValueSet, 1588 ISWbemObject **objWbemObject ) 1589 { 1590 struct services *services = impl_from_ISWbemServices( iface ); 1591 IWbemClassObject *obj; 1592 HRESULT hr; 1593 1594 TRACE( "%p, %s, %d, %p, %p\n", iface, debugstr_w(strObjectPath), iFlags, objWbemNamedValueSet, 1595 objWbemObject ); 1596 1597 if (objWbemNamedValueSet) FIXME( "ignoring context\n" ); 1598 1599 hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL ); 1600 if (hr != S_OK) return hr; 1601 1602 hr = SWbemObject_create( obj, objWbemObject ); 1603 IWbemClassObject_Release( obj ); 1604 return hr; 1605 } 1606 1607 static HRESULT WINAPI services_GetAsync( 1608 ISWbemServices *iface, 1609 IDispatch *objWbemSink, 1610 BSTR strObjectPath, 1611 LONG iFlags, 1612 IDispatch *objWbemNamedValueSet, 1613 IDispatch *objWbemAsyncContext ) 1614 { 1615 FIXME( "\n" ); 1616 return E_NOTIMPL; 1617 } 1618 1619 static HRESULT WINAPI services_Delete( 1620 ISWbemServices *iface, 1621 BSTR strObjectPath, 1622 LONG iFlags, 1623 IDispatch *objWbemNamedValueSet ) 1624 { 1625 FIXME( "\n" ); 1626 return E_NOTIMPL; 1627 } 1628 1629 static HRESULT WINAPI services_DeleteAsync( 1630 ISWbemServices* This, 1631 IDispatch *objWbemSink, 1632 BSTR strObjectPath, 1633 LONG iFlags, 1634 IDispatch *objWbemNamedValueSet, 1635 IDispatch *objWbemAsyncContext ) 1636 { 1637 FIXME( "\n" ); 1638 return E_NOTIMPL; 1639 } 1640 1641 static BSTR build_query_string( const WCHAR *class ) 1642 { 1643 static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; 1644 UINT len = strlenW(class) + sizeof(selectW) / sizeof(selectW[0]); 1645 BSTR ret; 1646 1647 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; 1648 strcpyW( ret, selectW ); 1649 strcatW( ret, class ); 1650 return ret; 1651 } 1652 1653 static HRESULT WINAPI services_InstancesOf( 1654 ISWbemServices *iface, 1655 BSTR strClass, 1656 LONG iFlags, 1657 IDispatch *objWbemNamedValueSet, 1658 ISWbemObjectSet **objWbemObjectSet ) 1659 { 1660 static const WCHAR wqlW[] = {'W','Q','L',0}; 1661 BSTR query, wql = SysAllocString( wqlW ); 1662 HRESULT hr; 1663 1664 TRACE( "%p, %s, %x, %p, %p\n", iface, debugstr_w(strClass), iFlags, objWbemNamedValueSet, 1665 objWbemObjectSet ); 1666 1667 if (!(query = build_query_string( strClass ))) 1668 { 1669 SysFreeString( wql ); 1670 return E_OUTOFMEMORY; 1671 } 1672 hr = ISWbemServices_ExecQuery( iface, query, wql, iFlags, objWbemNamedValueSet, objWbemObjectSet ); 1673 SysFreeString( wql ); 1674 SysFreeString( query ); 1675 return hr; 1676 } 1677 1678 static HRESULT WINAPI services_InstancesOfAsync( 1679 ISWbemServices *iface, 1680 IDispatch *objWbemSink, 1681 BSTR strClass, 1682 LONG iFlags, 1683 IDispatch *objWbemNamedValueSet, 1684 IDispatch *objWbemAsyncContext ) 1685 { 1686 FIXME( "\n" ); 1687 return E_NOTIMPL; 1688 } 1689 1690 static HRESULT WINAPI services_SubclassesOf( 1691 ISWbemServices *iface, 1692 BSTR strSuperclass, 1693 LONG iFlags, 1694 IDispatch *objWbemNamedValueSet, 1695 ISWbemObjectSet **objWbemObjectSet ) 1696 { 1697 FIXME( "\n" ); 1698 return E_NOTIMPL; 1699 } 1700 1701 static HRESULT WINAPI services_SubclassesOfAsync( 1702 ISWbemServices *iface, 1703 IDispatch *objWbemSink, 1704 BSTR strSuperclass, 1705 LONG iFlags, 1706 IDispatch *objWbemNamedValueSet, 1707 IDispatch *objWbemAsyncContext ) 1708 { 1709 FIXME( "\n" ); 1710 return E_NOTIMPL; 1711 } 1712 1713 static HRESULT WINAPI services_ExecQuery( 1714 ISWbemServices *iface, 1715 BSTR strQuery, 1716 BSTR strQueryLanguage, 1717 LONG iFlags, 1718 IDispatch *objWbemNamedValueSet, 1719 ISWbemObjectSet **objWbemObjectSet ) 1720 { 1721 struct services *services = impl_from_ISWbemServices( iface ); 1722 IEnumWbemClassObject *iter; 1723 HRESULT hr; 1724 1725 TRACE( "%p, %s, %s, %x, %p, %p\n", iface, debugstr_w(strQuery), debugstr_w(strQueryLanguage), 1726 iFlags, objWbemNamedValueSet, objWbemObjectSet ); 1727 1728 if (objWbemNamedValueSet) FIXME( "ignoring context\n" ); 1729 1730 hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter ); 1731 if (hr != S_OK) return hr; 1732 1733 hr = SWbemObjectSet_create( iter, objWbemObjectSet ); 1734 IEnumWbemClassObject_Release( iter ); 1735 return hr; 1736 } 1737 1738 static HRESULT WINAPI services_ExecQueryAsync( 1739 ISWbemServices *iface, 1740 IDispatch *objWbemSink, 1741 BSTR strQuery, 1742 BSTR strQueryLanguage, 1743 LONG lFlags, 1744 IDispatch *objWbemNamedValueSet, 1745 IDispatch *objWbemAsyncContext ) 1746 { 1747 FIXME( "\n" ); 1748 return E_NOTIMPL; 1749 } 1750 1751 static HRESULT WINAPI services_AssociatorsOf( 1752 ISWbemServices *iface, 1753 BSTR strObjectPath, 1754 BSTR strAssocClass, 1755 BSTR strResultClass, 1756 BSTR strResultRole, 1757 BSTR strRole, 1758 VARIANT_BOOL bClassesOnly, 1759 VARIANT_BOOL bSchemaOnly, 1760 BSTR strRequiredAssocQualifier, 1761 BSTR strRequiredQualifier, 1762 LONG iFlags, 1763 IDispatch *objWbemNamedValueSet, 1764 ISWbemObjectSet **objWbemObjectSet ) 1765 { 1766 FIXME( "\n" ); 1767 return E_NOTIMPL; 1768 } 1769 1770 static HRESULT WINAPI services_AssociatorsOfAsync( 1771 ISWbemServices *iface, 1772 IDispatch *objWbemSink, 1773 BSTR strObjectPath, 1774 BSTR strAssocClass, 1775 BSTR strResultClass, 1776 BSTR strResultRole, 1777 BSTR strRole, 1778 VARIANT_BOOL bClassesOnly, 1779 VARIANT_BOOL bSchemaOnly, 1780 BSTR strRequiredAssocQualifier, 1781 BSTR strRequiredQualifier, 1782 LONG iFlags, 1783 IDispatch *objWbemNamedValueSet, 1784 IDispatch *objWbemAsyncContext ) 1785 { 1786 FIXME( "\n" ); 1787 return E_NOTIMPL; 1788 } 1789 1790 static HRESULT WINAPI services_ReferencesTo( 1791 ISWbemServices *iface, 1792 BSTR strObjectPath, 1793 BSTR strResultClass, 1794 BSTR strRole, 1795 VARIANT_BOOL bClassesOnly, 1796 VARIANT_BOOL bSchemaOnly, 1797 BSTR strRequiredQualifier, 1798 LONG iFlags, 1799 IDispatch *objWbemNamedValueSet, 1800 ISWbemObjectSet **objWbemObjectSet ) 1801 { 1802 FIXME( "\n" ); 1803 return E_NOTIMPL; 1804 } 1805 1806 static HRESULT WINAPI services_ReferencesToAsync( 1807 ISWbemServices *iface, 1808 IDispatch *objWbemSink, 1809 BSTR strObjectPath, 1810 BSTR strResultClass, 1811 BSTR strRole, 1812 VARIANT_BOOL bClassesOnly, 1813 VARIANT_BOOL bSchemaOnly, 1814 BSTR strRequiredQualifier, 1815 LONG iFlags, 1816 IDispatch *objWbemNamedValueSet, 1817 IDispatch *objWbemAsyncContext ) 1818 { 1819 FIXME( "\n" ); 1820 return E_NOTIMPL; 1821 } 1822 1823 static HRESULT WINAPI services_ExecNotificationQuery( 1824 ISWbemServices *iface, 1825 BSTR strQuery, 1826 BSTR strQueryLanguage, 1827 LONG iFlags, 1828 IDispatch *objWbemNamedValueSet, 1829 ISWbemEventSource **objWbemEventSource ) 1830 { 1831 FIXME( "\n" ); 1832 return E_NOTIMPL; 1833 } 1834 1835 static HRESULT WINAPI services_ExecNotificationQueryAsync( 1836 ISWbemServices *iface, 1837 IDispatch *objWbemSink, 1838 BSTR strQuery, 1839 BSTR strQueryLanguage, 1840 LONG iFlags, 1841 IDispatch *objWbemNamedValueSet, 1842 IDispatch *objWbemAsyncContext ) 1843 { 1844 FIXME( "\n" ); 1845 return E_NOTIMPL; 1846 } 1847 1848 static HRESULT WINAPI services_ExecMethod( 1849 ISWbemServices *iface, 1850 BSTR strObjectPath, 1851 BSTR strMethodName, 1852 IDispatch *objWbemInParameters, 1853 LONG iFlags, 1854 IDispatch *objWbemNamedValueSet, 1855 ISWbemObject **objWbemOutParameters ) 1856 { 1857 FIXME( "\n" ); 1858 return E_NOTIMPL; 1859 } 1860 1861 static HRESULT WINAPI services_ExecMethodAsync( 1862 ISWbemServices *iface, 1863 IDispatch *objWbemSink, 1864 BSTR strObjectPath, 1865 BSTR strMethodName, 1866 IDispatch *objWbemInParameters, 1867 LONG iFlags, 1868 IDispatch *objWbemNamedValueSet, 1869 IDispatch *objWbemAsyncContext ) 1870 { 1871 FIXME( "\n" ); 1872 return E_NOTIMPL; 1873 } 1874 1875 static HRESULT WINAPI services_get_Security_( 1876 ISWbemServices *iface, 1877 ISWbemSecurity **objWbemSecurity ) 1878 { 1879 TRACE( "%p, %p\n", iface, objWbemSecurity ); 1880 1881 if (!objWbemSecurity) 1882 return E_INVALIDARG; 1883 1884 return ISWbemSecurity_create( objWbemSecurity ); 1885 } 1886 1887 static const ISWbemServicesVtbl services_vtbl = 1888 { 1889 services_QueryInterface, 1890 services_AddRef, 1891 services_Release, 1892 services_GetTypeInfoCount, 1893 services_GetTypeInfo, 1894 services_GetIDsOfNames, 1895 services_Invoke, 1896 services_Get, 1897 services_GetAsync, 1898 services_Delete, 1899 services_DeleteAsync, 1900 services_InstancesOf, 1901 services_InstancesOfAsync, 1902 services_SubclassesOf, 1903 services_SubclassesOfAsync, 1904 services_ExecQuery, 1905 services_ExecQueryAsync, 1906 services_AssociatorsOf, 1907 services_AssociatorsOfAsync, 1908 services_ReferencesTo, 1909 services_ReferencesToAsync, 1910 services_ExecNotificationQuery, 1911 services_ExecNotificationQueryAsync, 1912 services_ExecMethod, 1913 services_ExecMethodAsync, 1914 services_get_Security_ 1915 }; 1916 1917 static HRESULT SWbemServices_create( IWbemServices *wbem_services, ISWbemServices **obj ) 1918 { 1919 struct services *services; 1920 1921 TRACE( "%p, %p\n", obj, wbem_services ); 1922 1923 if (!(services = heap_alloc( sizeof(*services) ))) return E_OUTOFMEMORY; 1924 services->ISWbemServices_iface.lpVtbl = &services_vtbl; 1925 services->refs = 1; 1926 services->services = wbem_services; 1927 IWbemServices_AddRef( services->services ); 1928 1929 *obj = &services->ISWbemServices_iface; 1930 TRACE( "returning iface %p\n", *obj ); 1931 return S_OK; 1932 } 1933 1934 struct locator 1935 { 1936 ISWbemLocator ISWbemLocator_iface; 1937 LONG refs; 1938 IWbemLocator *locator; 1939 }; 1940 1941 static inline struct locator *impl_from_ISWbemLocator( ISWbemLocator *iface ) 1942 { 1943 return CONTAINING_RECORD( iface, struct locator, ISWbemLocator_iface ); 1944 } 1945 1946 static ULONG WINAPI locator_AddRef( 1947 ISWbemLocator *iface ) 1948 { 1949 struct locator *locator = impl_from_ISWbemLocator( iface ); 1950 return InterlockedIncrement( &locator->refs ); 1951 } 1952 1953 static ULONG WINAPI locator_Release( 1954 ISWbemLocator *iface ) 1955 { 1956 struct locator *locator = impl_from_ISWbemLocator( iface ); 1957 LONG refs = InterlockedDecrement( &locator->refs ); 1958 if (!refs) 1959 { 1960 TRACE( "destroying %p\n", locator ); 1961 if (locator->locator) 1962 IWbemLocator_Release( locator->locator ); 1963 heap_free( locator ); 1964 } 1965 return refs; 1966 } 1967 1968 static HRESULT WINAPI locator_QueryInterface( 1969 ISWbemLocator *iface, 1970 REFIID riid, 1971 void **ppvObject ) 1972 { 1973 struct locator *locator = impl_from_ISWbemLocator( iface ); 1974 1975 TRACE( "%p, %s, %p\n", locator, debugstr_guid( riid ), ppvObject ); 1976 1977 if (IsEqualGUID( riid, &IID_ISWbemLocator ) || 1978 IsEqualGUID( riid, &IID_IDispatch ) || 1979 IsEqualGUID( riid, &IID_IUnknown )) 1980 { 1981 *ppvObject = iface; 1982 } 1983 else 1984 { 1985 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 1986 return E_NOINTERFACE; 1987 } 1988 ISWbemLocator_AddRef( iface ); 1989 return S_OK; 1990 } 1991 1992 static HRESULT WINAPI locator_GetTypeInfoCount( 1993 ISWbemLocator *iface, 1994 UINT *count ) 1995 { 1996 struct locator *locator = impl_from_ISWbemLocator( iface ); 1997 1998 TRACE( "%p, %p\n", locator, count ); 1999 *count = 1; 2000 return S_OK; 2001 } 2002 2003 static HRESULT WINAPI locator_GetTypeInfo( 2004 ISWbemLocator *iface, 2005 UINT index, 2006 LCID lcid, 2007 ITypeInfo **info ) 2008 { 2009 struct locator *locator = impl_from_ISWbemLocator( iface ); 2010 TRACE( "%p, %u, %u, %p\n", locator, index, lcid, info ); 2011 2012 return get_typeinfo( ISWbemLocator_tid, info ); 2013 } 2014 2015 static HRESULT WINAPI locator_GetIDsOfNames( 2016 ISWbemLocator *iface, 2017 REFIID riid, 2018 LPOLESTR *names, 2019 UINT count, 2020 LCID lcid, 2021 DISPID *dispid ) 2022 { 2023 struct locator *locator = impl_from_ISWbemLocator( iface ); 2024 ITypeInfo *typeinfo; 2025 HRESULT hr; 2026 2027 TRACE( "%p, %s, %p, %u, %u, %p\n", locator, debugstr_guid(riid), names, count, lcid, dispid ); 2028 2029 if (!names || !count || !dispid) return E_INVALIDARG; 2030 2031 hr = get_typeinfo( ISWbemLocator_tid, &typeinfo ); 2032 if (SUCCEEDED(hr)) 2033 { 2034 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 2035 ITypeInfo_Release( typeinfo ); 2036 } 2037 return hr; 2038 } 2039 2040 static HRESULT WINAPI locator_Invoke( 2041 ISWbemLocator *iface, 2042 DISPID member, 2043 REFIID riid, 2044 LCID lcid, 2045 WORD flags, 2046 DISPPARAMS *params, 2047 VARIANT *result, 2048 EXCEPINFO *excep_info, 2049 UINT *arg_err ) 2050 { 2051 struct locator *locator = impl_from_ISWbemLocator( iface ); 2052 ITypeInfo *typeinfo; 2053 HRESULT hr; 2054 2055 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", locator, member, debugstr_guid(riid), 2056 lcid, flags, params, result, excep_info, arg_err ); 2057 2058 hr = get_typeinfo( ISWbemLocator_tid, &typeinfo ); 2059 if (SUCCEEDED(hr)) 2060 { 2061 hr = ITypeInfo_Invoke( typeinfo, &locator->ISWbemLocator_iface, member, flags, 2062 params, result, excep_info, arg_err ); 2063 ITypeInfo_Release( typeinfo ); 2064 } 2065 return hr; 2066 } 2067 2068 static BSTR build_resource_string( BSTR server, BSTR namespace ) 2069 { 2070 static const WCHAR defaultW[] = {'r','o','o','t','\\','d','e','f','a','u','l','t',0}; 2071 ULONG len, len_server = 0, len_namespace = 0; 2072 BSTR ret; 2073 2074 if (server && *server) len_server = strlenW( server ); 2075 else len_server = 1; 2076 if (namespace && *namespace) len_namespace = strlenW( namespace ); 2077 else len_namespace = sizeof(defaultW) / sizeof(defaultW[0]) - 1; 2078 2079 if (!(ret = SysAllocStringLen( NULL, 2 + len_server + 1 + len_namespace ))) return NULL; 2080 2081 ret[0] = ret[1] = '\\'; 2082 if (server && *server) strcpyW( ret + 2, server ); 2083 else ret[2] = '.'; 2084 2085 len = len_server + 2; 2086 ret[len++] = '\\'; 2087 2088 if (namespace && *namespace) strcpyW( ret + len, namespace ); 2089 else strcpyW( ret + len, defaultW ); 2090 return ret; 2091 } 2092 2093 static HRESULT WINAPI locator_ConnectServer( 2094 ISWbemLocator *iface, 2095 BSTR strServer, 2096 BSTR strNamespace, 2097 BSTR strUser, 2098 BSTR strPassword, 2099 BSTR strLocale, 2100 BSTR strAuthority, 2101 LONG iSecurityFlags, 2102 IDispatch *objWbemNamedValueSet, 2103 ISWbemServices **objWbemServices ) 2104 { 2105 struct locator *locator = impl_from_ISWbemLocator( iface ); 2106 IWbemServices *services; 2107 BSTR resource; 2108 HRESULT hr; 2109 2110 TRACE( "%p, %s, %s, %s, %p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strServer), 2111 debugstr_w(strNamespace), debugstr_w(strUser), strPassword, debugstr_w(strLocale), 2112 debugstr_w(strAuthority), iSecurityFlags, objWbemNamedValueSet, objWbemServices ); 2113 2114 if (objWbemNamedValueSet) FIXME( "context not supported\n" ); 2115 2116 if (!locator->locator) 2117 { 2118 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, 2119 (void **)&locator->locator ); 2120 if (hr != S_OK) return hr; 2121 } 2122 2123 if (!(resource = build_resource_string( strServer, strNamespace ))) return E_OUTOFMEMORY; 2124 hr = IWbemLocator_ConnectServer( locator->locator, resource, strUser, strPassword, strLocale, 2125 iSecurityFlags, strAuthority, NULL, &services ); 2126 SysFreeString( resource ); 2127 if (hr != S_OK) return hr; 2128 2129 hr = SWbemServices_create( services, objWbemServices ); 2130 IWbemServices_Release( services ); 2131 return hr; 2132 } 2133 2134 static HRESULT WINAPI locator_get_Security_( 2135 ISWbemLocator *iface, 2136 ISWbemSecurity **objWbemSecurity ) 2137 { 2138 TRACE( "%p, %p\n", iface, objWbemSecurity ); 2139 2140 if (!objWbemSecurity) 2141 return E_INVALIDARG; 2142 2143 return ISWbemSecurity_create( objWbemSecurity ); 2144 } 2145 2146 static const ISWbemLocatorVtbl locator_vtbl = 2147 { 2148 locator_QueryInterface, 2149 locator_AddRef, 2150 locator_Release, 2151 locator_GetTypeInfoCount, 2152 locator_GetTypeInfo, 2153 locator_GetIDsOfNames, 2154 locator_Invoke, 2155 locator_ConnectServer, 2156 locator_get_Security_ 2157 }; 2158 2159 HRESULT SWbemLocator_create( void **obj ) 2160 { 2161 struct locator *locator; 2162 2163 TRACE( "%p\n", obj ); 2164 2165 if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY; 2166 locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl; 2167 locator->refs = 1; 2168 locator->locator = NULL; 2169 2170 *obj = &locator->ISWbemLocator_iface; 2171 TRACE( "returning iface %p\n", *obj ); 2172 return S_OK; 2173 } 2174 2175 struct security 2176 { 2177 ISWbemSecurity ISWbemSecurity_iface; 2178 LONG refs; 2179 WbemImpersonationLevelEnum implevel; 2180 WbemAuthenticationLevelEnum authlevel; 2181 }; 2182 2183 static inline struct security *impl_from_ISWbemSecurity( ISWbemSecurity *iface ) 2184 { 2185 return CONTAINING_RECORD( iface, struct security, ISWbemSecurity_iface ); 2186 } 2187 2188 static ULONG WINAPI security_AddRef( 2189 ISWbemSecurity *iface ) 2190 { 2191 struct security *security = impl_from_ISWbemSecurity( iface ); 2192 return InterlockedIncrement( &security->refs ); 2193 } 2194 2195 static ULONG WINAPI security_Release( 2196 ISWbemSecurity *iface ) 2197 { 2198 struct security *security = impl_from_ISWbemSecurity( iface ); 2199 LONG refs = InterlockedDecrement( &security->refs ); 2200 if (!refs) 2201 { 2202 TRACE( "destroying %p\n", security ); 2203 heap_free( security ); 2204 } 2205 return refs; 2206 } 2207 2208 static HRESULT WINAPI security_QueryInterface( 2209 ISWbemSecurity *iface, 2210 REFIID riid, 2211 void **ppvObject ) 2212 { 2213 struct security *security = impl_from_ISWbemSecurity( iface ); 2214 TRACE( "%p, %s, %p\n", security, debugstr_guid( riid ), ppvObject ); 2215 2216 if (IsEqualGUID( riid, &IID_ISWbemSecurity ) || 2217 IsEqualGUID( riid, &IID_IDispatch ) || 2218 IsEqualGUID( riid, &IID_IUnknown )) 2219 { 2220 *ppvObject = iface; 2221 } 2222 else 2223 { 2224 FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); 2225 return E_NOINTERFACE; 2226 } 2227 ISWbemSecurity_AddRef( iface ); 2228 return S_OK; 2229 } 2230 2231 static HRESULT WINAPI security_GetTypeInfoCount( 2232 ISWbemSecurity *iface, 2233 UINT *count ) 2234 { 2235 struct security *security = impl_from_ISWbemSecurity( iface ); 2236 TRACE( "%p, %p\n", security, count ); 2237 2238 *count = 1; 2239 return S_OK; 2240 } 2241 2242 static HRESULT WINAPI security_GetTypeInfo( 2243 ISWbemSecurity *iface, 2244 UINT index, 2245 LCID lcid, 2246 ITypeInfo **info ) 2247 { 2248 struct security *security = impl_from_ISWbemSecurity( iface ); 2249 TRACE( "%p, %u, %u, %p\n", security, index, lcid, info ); 2250 2251 return get_typeinfo( ISWbemSecurity_tid, info ); 2252 } 2253 2254 static HRESULT WINAPI security_GetIDsOfNames( 2255 ISWbemSecurity *iface, 2256 REFIID riid, 2257 LPOLESTR *names, 2258 UINT count, 2259 LCID lcid, 2260 DISPID *dispid ) 2261 { 2262 struct security *security = impl_from_ISWbemSecurity( iface ); 2263 ITypeInfo *typeinfo; 2264 HRESULT hr; 2265 2266 TRACE( "%p, %s, %p, %u, %u, %p\n", security, debugstr_guid(riid), names, count, lcid, dispid ); 2267 2268 if (!names || !count || !dispid) return E_INVALIDARG; 2269 2270 hr = get_typeinfo( ISWbemSecurity_tid, &typeinfo ); 2271 if (SUCCEEDED(hr)) 2272 { 2273 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); 2274 ITypeInfo_Release( typeinfo ); 2275 } 2276 return hr; 2277 } 2278 2279 static HRESULT WINAPI security_Invoke( 2280 ISWbemSecurity *iface, 2281 DISPID member, 2282 REFIID riid, 2283 LCID lcid, 2284 WORD flags, 2285 DISPPARAMS *params, 2286 VARIANT *result, 2287 EXCEPINFO *excep_info, 2288 UINT *arg_err ) 2289 { 2290 struct security *security = impl_from_ISWbemSecurity( iface ); 2291 ITypeInfo *typeinfo; 2292 HRESULT hr; 2293 2294 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", security, member, debugstr_guid(riid), 2295 lcid, flags, params, result, excep_info, arg_err ); 2296 2297 hr = get_typeinfo( ISWbemSecurity_tid, &typeinfo ); 2298 if (SUCCEEDED(hr)) 2299 { 2300 hr = ITypeInfo_Invoke( typeinfo, &security->ISWbemSecurity_iface, member, flags, 2301 params, result, excep_info, arg_err ); 2302 ITypeInfo_Release( typeinfo ); 2303 } 2304 return hr; 2305 } 2306 2307 static HRESULT WINAPI security_get_ImpersonationLevel_( 2308 ISWbemSecurity *iface, 2309 WbemImpersonationLevelEnum *impersonation_level ) 2310 { 2311 struct security *security = impl_from_ISWbemSecurity( iface ); 2312 FIXME( "%p, %p: stub\n", security, impersonation_level ); 2313 2314 if (!impersonation_level) 2315 return E_INVALIDARG; 2316 2317 *impersonation_level = security->implevel; 2318 return S_OK; 2319 } 2320 2321 static HRESULT WINAPI security_put_ImpersonationLevel_( 2322 ISWbemSecurity *iface, 2323 WbemImpersonationLevelEnum impersonation_level ) 2324 { 2325 struct security *security = impl_from_ISWbemSecurity( iface ); 2326 FIXME( "%p, %d: stub\n", security, impersonation_level ); 2327 2328 security->implevel = impersonation_level; 2329 return S_OK; 2330 } 2331 2332 static HRESULT WINAPI security_get_AuthenticationLevel_( 2333 ISWbemSecurity *iface, 2334 WbemAuthenticationLevelEnum *authentication_level ) 2335 { 2336 struct security *security = impl_from_ISWbemSecurity( iface ); 2337 FIXME( "%p, %p: stub\n", security, authentication_level ); 2338 2339 if (!authentication_level) 2340 return E_INVALIDARG; 2341 2342 *authentication_level = security->authlevel; 2343 return S_OK; 2344 } 2345 2346 static HRESULT WINAPI security_put_AuthenticationLevel_( 2347 ISWbemSecurity *iface, 2348 WbemAuthenticationLevelEnum authentication_level ) 2349 { 2350 struct security *security = impl_from_ISWbemSecurity( iface ); 2351 FIXME( "%p, %d: stub\n", security, authentication_level ); 2352 2353 security->authlevel = authentication_level; 2354 return S_OK; 2355 } 2356 2357 static HRESULT WINAPI security_get_Privileges_( 2358 ISWbemSecurity *iface, 2359 ISWbemPrivilegeSet **privilege_set ) 2360 { 2361 struct security *security = impl_from_ISWbemSecurity( iface ); 2362 FIXME( "%p, %p: stub\n", security, privilege_set ); 2363 2364 if (!privilege_set) 2365 return E_INVALIDARG; 2366 2367 return E_NOTIMPL; 2368 } 2369 2370 static const ISWbemSecurityVtbl security_vtbl = 2371 { 2372 security_QueryInterface, 2373 security_AddRef, 2374 security_Release, 2375 security_GetTypeInfoCount, 2376 security_GetTypeInfo, 2377 security_GetIDsOfNames, 2378 security_Invoke, 2379 security_get_ImpersonationLevel_, 2380 security_put_ImpersonationLevel_, 2381 security_get_AuthenticationLevel_, 2382 security_put_AuthenticationLevel_, 2383 security_get_Privileges_ 2384 }; 2385 2386 static HRESULT ISWbemSecurity_create( ISWbemSecurity **obj ) 2387 { 2388 struct security *security; 2389 2390 TRACE( "%p\n", obj ); 2391 2392 if (!(security = heap_alloc( sizeof(*security) ))) return E_OUTOFMEMORY; 2393 security->ISWbemSecurity_iface.lpVtbl = &security_vtbl; 2394 security->refs = 1; 2395 security->implevel = wbemImpersonationLevelAnonymous; 2396 security->authlevel = wbemAuthenticationLevelDefault; 2397 2398 *obj = &security->ISWbemSecurity_iface; 2399 TRACE( "returning iface %p\n", *obj ); 2400 return S_OK; 2401 } 2402