quartz: Add tests for IBasicVideo.
[wine.git] / dlls / wbemdisp / locator.c
bloba8b1568965fb96af9661972e0d463d21ff94523e
1 /*
2 * Copyright 2013 Hans Leidekker for CodeWeavers
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.
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.
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
19 #define COBJMACROS
21 #include "config.h"
22 #include <stdarg.h>
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"
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
34 #include "wbemdisp_private.h"
35 #include "wbemdisp_classes.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp);
39 static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** );
41 enum type_id
43 ISWbemLocator_tid,
44 ISWbemObject_tid,
45 ISWbemObjectSet_tid,
46 ISWbemServices_tid,
47 last_tid
50 static ITypeLib *wbemdisp_typelib;
51 static ITypeInfo *wbemdisp_typeinfo[last_tid];
53 static REFIID wbemdisp_tid_id[] =
55 &IID_ISWbemLocator,
56 &IID_ISWbemObject,
57 &IID_ISWbemObjectSet,
58 &IID_ISWbemServices
61 static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret )
63 HRESULT hr;
65 if (!wbemdisp_typelib)
67 ITypeLib *typelib;
69 hr = LoadRegTypeLib( &LIBID_WbemScripting, 1, 2, LOCALE_SYSTEM_DEFAULT, &typelib );
70 if (FAILED( hr ))
72 ERR( "LoadRegTypeLib failed: %08x\n", hr );
73 return hr;
75 if (InterlockedCompareExchangePointer( (void **)&wbemdisp_typelib, typelib, NULL ))
76 ITypeLib_Release( typelib );
78 if (!wbemdisp_typeinfo[tid])
80 ITypeInfo *typeinfo;
82 hr = ITypeLib_GetTypeInfoOfGuid( wbemdisp_typelib, wbemdisp_tid_id[tid], &typeinfo );
83 if (FAILED( hr ))
85 ERR( "GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(wbemdisp_tid_id[tid]), hr );
86 return hr;
88 if (InterlockedCompareExchangePointer( (void **)(wbemdisp_typeinfo + tid), typeinfo, NULL ))
89 ITypeInfo_Release( typeinfo );
91 *ret = wbemdisp_typeinfo[tid];
92 ITypeInfo_AddRef( *ret );
93 return S_OK;
96 #define DISPID_BASE 0x1800000
98 struct member
100 BSTR name;
101 DISPID dispid;
104 struct object
106 ISWbemObject ISWbemObject_iface;
107 LONG refs;
108 IWbemClassObject *object;
109 struct member *members;
110 UINT nb_members;
111 DISPID last_dispid;
114 static inline struct object *impl_from_ISWbemObject(
115 ISWbemObject *iface )
117 return CONTAINING_RECORD( iface, struct object, ISWbemObject_iface );
120 static ULONG WINAPI object_AddRef(
121 ISWbemObject *iface )
123 struct object *object = impl_from_ISWbemObject( iface );
124 return InterlockedIncrement( &object->refs );
127 static ULONG WINAPI object_Release(
128 ISWbemObject *iface )
130 struct object *object = impl_from_ISWbemObject( iface );
131 LONG refs = InterlockedDecrement( &object->refs );
132 if (!refs)
134 UINT i;
136 TRACE( "destroying %p\n", object );
137 IWbemClassObject_Release( object->object );
138 for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name );
139 heap_free( object->members );
140 heap_free( object );
142 return refs;
145 static HRESULT WINAPI object_QueryInterface(
146 ISWbemObject *iface,
147 REFIID riid,
148 void **ppvObject )
150 struct object *object = impl_from_ISWbemObject( iface );
152 TRACE( "%p %s %p\n", object, debugstr_guid(riid), ppvObject );
154 if (IsEqualGUID( riid, &IID_ISWbemObject ) ||
155 IsEqualGUID( riid, &IID_IDispatch ) ||
156 IsEqualGUID( riid, &IID_IUnknown ))
158 *ppvObject = object;
160 else
162 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
163 return E_NOINTERFACE;
165 ISWbemObject_AddRef( iface );
166 return S_OK;
169 static HRESULT WINAPI object_GetTypeInfoCount(
170 ISWbemObject *iface,
171 UINT *count )
173 struct object *object = impl_from_ISWbemObject( iface );
175 TRACE( "%p, %p\n", object, count );
176 *count = 1;
177 return S_OK;
180 static HRESULT WINAPI object_GetTypeInfo(
181 ISWbemObject *iface,
182 UINT index,
183 LCID lcid,
184 ITypeInfo **info )
186 struct object *object = impl_from_ISWbemObject( iface );
187 FIXME( "%p, %u, %u, %p\n", object, index, lcid, info );
188 return E_NOTIMPL;
191 #define DISPID_BASE 0x1800000
193 static HRESULT init_members( struct object *object )
195 LONG bound, i;
196 SAFEARRAY *sa;
197 HRESULT hr;
199 if (object->members) return S_OK;
201 hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa );
202 if (FAILED( hr )) return hr;
203 hr = SafeArrayGetUBound( sa, 1, &bound );
204 if (FAILED( hr ))
206 SafeArrayDestroy( sa );
207 return hr;
209 if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) )))
211 SafeArrayDestroy( sa );
212 return E_OUTOFMEMORY;
214 for (i = 0; i <= bound; i++)
216 hr = SafeArrayGetElement( sa, &i, &object->members[i].name );
217 if (FAILED( hr ))
219 for (i--; i >= 0; i--) SysFreeString( object->members[i].name );
220 SafeArrayDestroy( sa );
221 heap_free( object->members );
222 object->members = NULL;
223 return E_OUTOFMEMORY;
225 object->members[i].dispid = 0;
227 object->nb_members = bound + 1;
228 SafeArrayDestroy( sa );
229 return S_OK;
232 static DISPID get_member_dispid( struct object *object, const WCHAR *name )
234 UINT i;
235 for (i = 0; i < object->nb_members; i++)
237 if (!strcmpiW( object->members[i].name, name ))
239 if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid;
240 return object->members[i].dispid;
243 return DISPID_UNKNOWN;
246 static HRESULT WINAPI object_GetIDsOfNames(
247 ISWbemObject *iface,
248 REFIID riid,
249 LPOLESTR *names,
250 UINT count,
251 LCID lcid,
252 DISPID *dispid )
254 struct object *object = impl_from_ISWbemObject( iface );
255 HRESULT hr;
256 UINT i;
258 TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid );
260 if (!names || !count || !dispid) return E_INVALIDARG;
262 hr = init_members( object );
263 if (FAILED( hr )) return hr;
265 for (i = 0; i < count; i++)
267 if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break;
269 if (i != count) return DISP_E_UNKNOWNNAME;
270 return S_OK;
273 static BSTR get_member_name( struct object *object, DISPID dispid )
275 UINT i;
276 for (i = 0; i < object->nb_members; i++)
278 if (object->members[i].dispid == dispid) return object->members[i].name;
280 return NULL;
283 static HRESULT WINAPI object_Invoke(
284 ISWbemObject *iface,
285 DISPID member,
286 REFIID riid,
287 LCID lcid,
288 WORD flags,
289 DISPPARAMS *params,
290 VARIANT *result,
291 EXCEPINFO *excep_info,
292 UINT *arg_err )
294 struct object *object = impl_from_ISWbemObject( iface );
295 BSTR name;
297 TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid),
298 lcid, flags, params, result, excep_info, arg_err );
300 if (flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET))
302 FIXME( "flags %x not supported\n", flags );
303 return E_NOTIMPL;
305 if (!(name = get_member_name( object, member )))
306 return DISP_E_MEMBERNOTFOUND;
308 memset( params, 0, sizeof(*params) );
309 return IWbemClassObject_Get( object->object, name, 0, result, NULL, NULL );
312 static HRESULT WINAPI object_Put_(
313 ISWbemObject *iface,
314 LONG iFlags,
315 IDispatch *objWbemNamedValueSet,
316 ISWbemObjectPath **objWbemObjectPath )
318 FIXME( "\n" );
319 return E_NOTIMPL;
322 static const ISWbemObjectVtbl object_vtbl =
324 object_QueryInterface,
325 object_AddRef,
326 object_Release,
327 object_GetTypeInfoCount,
328 object_GetTypeInfo,
329 object_GetIDsOfNames,
330 object_Invoke,
331 object_Put_
334 static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj )
336 struct object *object;
338 TRACE( "%p, %p\n", obj, wbem_object );
340 if (!(object = heap_alloc( sizeof(*object) ))) return E_OUTOFMEMORY;
341 object->ISWbemObject_iface.lpVtbl = &object_vtbl;
342 object->refs = 1;
343 object->object = wbem_object;
344 IWbemClassObject_AddRef( object->object );
345 object->members = NULL;
346 object->nb_members = 0;
347 object->last_dispid = DISPID_BASE;
349 *obj = &object->ISWbemObject_iface;
350 TRACE( "returning iface %p\n", *obj );
351 return S_OK;
354 struct objectset
356 ISWbemObjectSet ISWbemObjectSet_iface;
357 LONG refs;
358 IEnumWbemClassObject *objectenum;
359 LONG count;
362 static inline struct objectset *impl_from_ISWbemObjectSet(
363 ISWbemObjectSet *iface )
365 return CONTAINING_RECORD( iface, struct objectset, ISWbemObjectSet_iface );
368 static ULONG WINAPI objectset_AddRef(
369 ISWbemObjectSet *iface )
371 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
372 return InterlockedIncrement( &objectset->refs );
375 static ULONG WINAPI objectset_Release(
376 ISWbemObjectSet *iface )
378 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
379 LONG refs = InterlockedDecrement( &objectset->refs );
380 if (!refs)
382 TRACE( "destroying %p\n", objectset );
383 IEnumWbemClassObject_Release( objectset->objectenum );
384 heap_free( objectset );
386 return refs;
389 static HRESULT WINAPI objectset_QueryInterface(
390 ISWbemObjectSet *iface,
391 REFIID riid,
392 void **ppvObject )
394 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
396 TRACE( "%p %s %p\n", objectset, debugstr_guid(riid), ppvObject );
398 if (IsEqualGUID( riid, &IID_ISWbemObjectSet ) ||
399 IsEqualGUID( riid, &IID_IDispatch ) ||
400 IsEqualGUID( riid, &IID_IUnknown ))
402 *ppvObject = objectset;
404 else
406 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
407 return E_NOINTERFACE;
409 ISWbemObjectSet_AddRef( iface );
410 return S_OK;
413 static HRESULT WINAPI objectset_GetTypeInfoCount(
414 ISWbemObjectSet *iface,
415 UINT *count )
417 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
418 TRACE( "%p, %p\n", objectset, count );
419 *count = 1;
420 return S_OK;
423 static HRESULT WINAPI objectset_GetTypeInfo(
424 ISWbemObjectSet *iface,
425 UINT index,
426 LCID lcid,
427 ITypeInfo **info )
429 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
430 TRACE( "%p, %u, %u, %p\n", objectset, index, lcid, info );
432 return get_typeinfo( ISWbemObjectSet_tid, info );
435 static HRESULT WINAPI objectset_GetIDsOfNames(
436 ISWbemObjectSet *iface,
437 REFIID riid,
438 LPOLESTR *names,
439 UINT count,
440 LCID lcid,
441 DISPID *dispid )
443 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
444 ITypeInfo *typeinfo;
445 HRESULT hr;
447 TRACE( "%p, %s, %p, %u, %u, %p\n", objectset, debugstr_guid(riid), names, count, lcid, dispid );
449 if (!names || !count || !dispid) return E_INVALIDARG;
451 hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo );
452 if (SUCCEEDED(hr))
454 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
455 ITypeInfo_Release( typeinfo );
457 return hr;
460 static HRESULT WINAPI objectset_Invoke(
461 ISWbemObjectSet *iface,
462 DISPID member,
463 REFIID riid,
464 LCID lcid,
465 WORD flags,
466 DISPPARAMS *params,
467 VARIANT *result,
468 EXCEPINFO *excep_info,
469 UINT *arg_err )
471 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
472 ITypeInfo *typeinfo;
473 HRESULT hr;
475 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", objectset, member, debugstr_guid(riid),
476 lcid, flags, params, result, excep_info, arg_err );
478 hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo );
479 if (SUCCEEDED(hr))
481 hr = ITypeInfo_Invoke( typeinfo, &objectset->ISWbemObjectSet_iface, member, flags,
482 params, result, excep_info, arg_err );
483 ITypeInfo_Release( typeinfo );
485 return hr;
488 static HRESULT WINAPI objectset_get__NewEnum(
489 ISWbemObjectSet *iface,
490 IUnknown **pUnk )
492 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
493 IEnumWbemClassObject *objectenum;
494 HRESULT hr;
496 TRACE( "%p, %p\n", objectset, pUnk );
498 hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum );
499 if (FAILED( hr )) return hr;
501 hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk );
502 IEnumWbemClassObject_Release( objectenum );
503 return hr;
506 static HRESULT WINAPI objectset_Item(
507 ISWbemObjectSet *iface,
508 BSTR strObjectPath,
509 LONG iFlags,
510 ISWbemObject **objWbemObject )
512 FIXME( "\n" );
513 return E_NOTIMPL;
516 static HRESULT WINAPI objectset_get_Count(
517 ISWbemObjectSet *iface,
518 LONG *iCount )
520 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
522 TRACE( "%p, %p\n", objectset, iCount );
524 *iCount = objectset->count;
525 return S_OK;
528 static HRESULT WINAPI objectset_get_Security_(
529 ISWbemObjectSet *iface,
530 ISWbemSecurity **objWbemSecurity )
532 FIXME( "\n" );
533 return E_NOTIMPL;
536 static HRESULT WINAPI objectset_ItemIndex(
537 ISWbemObjectSet *iface,
538 LONG lIndex,
539 ISWbemObject **objWbemObject )
541 FIXME( "\n" );
542 return E_NOTIMPL;
545 static const ISWbemObjectSetVtbl objectset_vtbl =
547 objectset_QueryInterface,
548 objectset_AddRef,
549 objectset_Release,
550 objectset_GetTypeInfoCount,
551 objectset_GetTypeInfo,
552 objectset_GetIDsOfNames,
553 objectset_Invoke,
554 objectset_get__NewEnum,
555 objectset_Item,
556 objectset_get_Count,
557 objectset_get_Security_,
558 objectset_ItemIndex
561 static LONG get_object_count( IEnumWbemClassObject *iter )
563 LONG count = 0;
564 while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) count++;
565 IEnumWbemClassObject_Reset( iter );
566 return count;
569 static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj )
571 struct objectset *objectset;
573 TRACE( "%p, %p\n", obj, wbem_objectenum );
575 if (!(objectset = heap_alloc( sizeof(*objectset) ))) return E_OUTOFMEMORY;
576 objectset->ISWbemObjectSet_iface.lpVtbl = &objectset_vtbl;
577 objectset->refs = 1;
578 objectset->objectenum = wbem_objectenum;
579 IEnumWbemClassObject_AddRef( objectset->objectenum );
580 objectset->count = get_object_count( objectset->objectenum );
582 *obj = &objectset->ISWbemObjectSet_iface;
583 TRACE( "returning iface %p\n", *obj );
584 return S_OK;
587 struct enumvar
589 IEnumVARIANT IEnumVARIANT_iface;
590 LONG refs;
591 IEnumWbemClassObject *objectenum;
594 static inline struct enumvar *impl_from_IEnumVARIANT(
595 IEnumVARIANT *iface )
597 return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface );
600 static ULONG WINAPI enumvar_AddRef(
601 IEnumVARIANT *iface )
603 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
604 return InterlockedIncrement( &enumvar->refs );
607 static ULONG WINAPI enumvar_Release(
608 IEnumVARIANT *iface )
610 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
611 LONG refs = InterlockedDecrement( &enumvar->refs );
612 if (!refs)
614 TRACE( "destroying %p\n", enumvar );
615 IEnumWbemClassObject_Release( enumvar->objectenum );
616 heap_free( enumvar );
618 return refs;
621 static HRESULT WINAPI enumvar_QueryInterface(
622 IEnumVARIANT *iface,
623 REFIID riid,
624 void **ppvObject )
626 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
628 TRACE( "%p %s %p\n", enumvar, debugstr_guid(riid), ppvObject );
630 if (IsEqualGUID( riid, &IID_IEnumVARIANT ) ||
631 IsEqualGUID( riid, &IID_IUnknown ))
633 *ppvObject = enumvar;
635 else
637 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
638 return E_NOINTERFACE;
640 IEnumVARIANT_AddRef( iface );
641 return S_OK;
644 static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched )
646 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
647 IWbemClassObject *obj;
648 ULONG count = 0;
650 TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched );
652 if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count );
653 if (count)
655 ISWbemObject *sobj;
656 HRESULT hr;
658 hr = SWbemObject_create( obj, &sobj );
659 IWbemClassObject_Release( obj );
660 if (FAILED( hr )) return hr;
662 V_VT( var ) = VT_DISPATCH;
663 V_DISPATCH( var ) = (IDispatch *)sobj;
665 if (fetched) *fetched = count;
666 return (count < celt) ? S_FALSE : S_OK;
669 static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt )
671 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
673 TRACE( "%p, %u\n", iface, celt );
675 return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt );
678 static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface )
680 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
682 TRACE( "%p\n", iface );
684 return IEnumWbemClassObject_Reset( enumvar->objectenum );
687 static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum )
689 FIXME( "%p, %p\n", iface, penum );
690 return E_NOTIMPL;
693 static const struct IEnumVARIANTVtbl enumvar_vtbl =
695 enumvar_QueryInterface,
696 enumvar_AddRef,
697 enumvar_Release,
698 enumvar_Next,
699 enumvar_Skip,
700 enumvar_Reset,
701 enumvar_Clone
704 static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj )
706 struct enumvar *enumvar;
708 if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY;
709 enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl;
710 enumvar->refs = 1;
711 enumvar->objectenum = objectenum;
712 IEnumWbemClassObject_AddRef( enumvar->objectenum );
714 *obj = &enumvar->IEnumVARIANT_iface;
715 TRACE( "returning iface %p\n", *obj );
716 return S_OK;
719 struct services
721 ISWbemServices ISWbemServices_iface;
722 LONG refs;
723 IWbemServices *services;
726 static inline struct services *impl_from_ISWbemServices(
727 ISWbemServices *iface )
729 return CONTAINING_RECORD( iface, struct services, ISWbemServices_iface );
732 static ULONG WINAPI services_AddRef(
733 ISWbemServices *iface )
735 struct services *services = impl_from_ISWbemServices( iface );
736 return InterlockedIncrement( &services->refs );
739 static ULONG WINAPI services_Release(
740 ISWbemServices *iface )
742 struct services *services = impl_from_ISWbemServices( iface );
743 LONG refs = InterlockedDecrement( &services->refs );
744 if (!refs)
746 TRACE( "destroying %p\n", services );
747 IWbemServices_Release( services->services );
748 heap_free( services );
750 return refs;
753 static HRESULT WINAPI services_QueryInterface(
754 ISWbemServices *iface,
755 REFIID riid,
756 void **ppvObject )
758 struct services *services = impl_from_ISWbemServices( iface );
760 TRACE( "%p %s %p\n", services, debugstr_guid(riid), ppvObject );
762 if (IsEqualGUID( riid, &IID_ISWbemServices ) ||
763 IsEqualGUID( riid, &IID_IDispatch ) ||
764 IsEqualGUID( riid, &IID_IUnknown ))
766 *ppvObject = services;
768 else
770 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
771 return E_NOINTERFACE;
773 ISWbemServices_AddRef( iface );
774 return S_OK;
777 static HRESULT WINAPI services_GetTypeInfoCount(
778 ISWbemServices *iface,
779 UINT *count )
781 struct services *services = impl_from_ISWbemServices( iface );
782 TRACE( "%p, %p\n", services, count );
784 *count = 1;
785 return S_OK;
788 static HRESULT WINAPI services_GetTypeInfo(
789 ISWbemServices *iface,
790 UINT index,
791 LCID lcid,
792 ITypeInfo **info )
794 struct services *services = impl_from_ISWbemServices( iface );
795 TRACE( "%p, %u, %u, %p\n", services, index, lcid, info );
797 return get_typeinfo( ISWbemServices_tid, info );
800 static HRESULT WINAPI services_GetIDsOfNames(
801 ISWbemServices *iface,
802 REFIID riid,
803 LPOLESTR *names,
804 UINT count,
805 LCID lcid,
806 DISPID *dispid )
808 struct services *services = impl_from_ISWbemServices( iface );
809 ITypeInfo *typeinfo;
810 HRESULT hr;
812 TRACE( "%p, %s, %p, %u, %u, %p\n", services, debugstr_guid(riid), names, count, lcid, dispid );
814 if (!names || !count || !dispid) return E_INVALIDARG;
816 hr = get_typeinfo( ISWbemServices_tid, &typeinfo );
817 if (SUCCEEDED(hr))
819 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
820 ITypeInfo_Release( typeinfo );
822 return hr;
825 static HRESULT WINAPI services_Invoke(
826 ISWbemServices *iface,
827 DISPID member,
828 REFIID riid,
829 LCID lcid,
830 WORD flags,
831 DISPPARAMS *params,
832 VARIANT *result,
833 EXCEPINFO *excep_info,
834 UINT *arg_err )
836 struct services *services = impl_from_ISWbemServices( iface );
837 ITypeInfo *typeinfo;
838 HRESULT hr;
840 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", services, member, debugstr_guid(riid),
841 lcid, flags, params, result, excep_info, arg_err );
843 hr = get_typeinfo( ISWbemServices_tid, &typeinfo );
844 if (SUCCEEDED(hr))
846 hr = ITypeInfo_Invoke( typeinfo, &services->ISWbemServices_iface, member, flags,
847 params, result, excep_info, arg_err );
848 ITypeInfo_Release( typeinfo );
850 return hr;
853 static HRESULT WINAPI services_Get(
854 ISWbemServices *iface,
855 BSTR strObjectPath,
856 LONG iFlags,
857 IDispatch *objWbemNamedValueSet,
858 ISWbemObject **objWbemObject )
860 struct services *services = impl_from_ISWbemServices( iface );
861 IWbemClassObject *obj;
862 HRESULT hr;
864 TRACE( "%p, %s, %d, %p, %p\n", iface, debugstr_w(strObjectPath), iFlags, objWbemNamedValueSet,
865 objWbemObject );
867 if (objWbemNamedValueSet) FIXME( "ignoring context\n" );
869 hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL );
870 if (hr != S_OK) return hr;
872 hr = SWbemObject_create( obj, objWbemObject );
873 IWbemClassObject_Release( obj );
874 return hr;
877 static HRESULT WINAPI services_GetAsync(
878 ISWbemServices *iface,
879 IDispatch *objWbemSink,
880 BSTR strObjectPath,
881 LONG iFlags,
882 IDispatch *objWbemNamedValueSet,
883 IDispatch *objWbemAsyncContext )
885 FIXME( "\n" );
886 return E_NOTIMPL;
889 static HRESULT WINAPI services_Delete(
890 ISWbemServices *iface,
891 BSTR strObjectPath,
892 LONG iFlags,
893 IDispatch *objWbemNamedValueSet )
895 FIXME( "\n" );
896 return E_NOTIMPL;
899 static HRESULT WINAPI services_DeleteAsync(
900 ISWbemServices* This,
901 IDispatch *objWbemSink,
902 BSTR strObjectPath,
903 LONG iFlags,
904 IDispatch *objWbemNamedValueSet,
905 IDispatch *objWbemAsyncContext )
907 FIXME( "\n" );
908 return E_NOTIMPL;
911 static BSTR build_query_string( const WCHAR *class )
913 static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
914 UINT len = strlenW(class) + sizeof(selectW) / sizeof(selectW[0]);
915 BSTR ret;
917 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
918 strcpyW( ret, selectW );
919 strcatW( ret, class );
920 return ret;
923 static HRESULT WINAPI services_InstancesOf(
924 ISWbemServices *iface,
925 BSTR strClass,
926 LONG iFlags,
927 IDispatch *objWbemNamedValueSet,
928 ISWbemObjectSet **objWbemObjectSet )
930 static const WCHAR wqlW[] = {'W','Q','L',0};
931 BSTR query, wql = SysAllocString( wqlW );
932 HRESULT hr;
934 TRACE( "%p, %s, %x, %p, %p\n", iface, debugstr_w(strClass), iFlags, objWbemNamedValueSet,
935 objWbemObjectSet );
937 if (!(query = build_query_string( strClass )))
939 SysFreeString( wql );
940 return E_OUTOFMEMORY;
942 hr = ISWbemServices_ExecQuery( iface, query, wql, iFlags, objWbemNamedValueSet, objWbemObjectSet );
943 SysFreeString( wql );
944 SysFreeString( query );
945 return hr;
948 static HRESULT WINAPI services_InstancesOfAsync(
949 ISWbemServices *iface,
950 IDispatch *objWbemSink,
951 BSTR strClass,
952 LONG iFlags,
953 IDispatch *objWbemNamedValueSet,
954 IDispatch *objWbemAsyncContext )
956 FIXME( "\n" );
957 return E_NOTIMPL;
960 static HRESULT WINAPI services_SubclassesOf(
961 ISWbemServices *iface,
962 BSTR strSuperclass,
963 LONG iFlags,
964 IDispatch *objWbemNamedValueSet,
965 ISWbemObjectSet **objWbemObjectSet )
967 FIXME( "\n" );
968 return E_NOTIMPL;
971 static HRESULT WINAPI services_SubclassesOfAsync(
972 ISWbemServices *iface,
973 IDispatch *objWbemSink,
974 BSTR strSuperclass,
975 LONG iFlags,
976 IDispatch *objWbemNamedValueSet,
977 IDispatch *objWbemAsyncContext )
979 FIXME( "\n" );
980 return E_NOTIMPL;
983 static HRESULT WINAPI services_ExecQuery(
984 ISWbemServices *iface,
985 BSTR strQuery,
986 BSTR strQueryLanguage,
987 LONG iFlags,
988 IDispatch *objWbemNamedValueSet,
989 ISWbemObjectSet **objWbemObjectSet )
991 struct services *services = impl_from_ISWbemServices( iface );
992 IEnumWbemClassObject *iter;
993 HRESULT hr;
995 TRACE( "%p, %s, %s, %x, %p, %p\n", iface, debugstr_w(strQuery), debugstr_w(strQueryLanguage),
996 iFlags, objWbemNamedValueSet, objWbemObjectSet );
998 if (objWbemNamedValueSet) FIXME( "ignoring context\n" );
1000 hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter );
1001 if (hr != S_OK) return hr;
1003 hr = SWbemObjectSet_create( iter, objWbemObjectSet );
1004 IEnumWbemClassObject_Release( iter );
1005 return hr;
1008 static HRESULT WINAPI services_ExecQueryAsync(
1009 ISWbemServices *iface,
1010 IDispatch *objWbemSink,
1011 BSTR strQuery,
1012 BSTR strQueryLanguage,
1013 LONG lFlags,
1014 IDispatch *objWbemNamedValueSet,
1015 IDispatch *objWbemAsyncContext )
1017 FIXME( "\n" );
1018 return E_NOTIMPL;
1021 static HRESULT WINAPI services_AssociatorsOf(
1022 ISWbemServices *iface,
1023 BSTR strObjectPath,
1024 BSTR strAssocClass,
1025 BSTR strResultClass,
1026 BSTR strResultRole,
1027 BSTR strRole,
1028 VARIANT_BOOL bClassesOnly,
1029 VARIANT_BOOL bSchemaOnly,
1030 BSTR strRequiredAssocQualifier,
1031 BSTR strRequiredQualifier,
1032 LONG iFlags,
1033 IDispatch *objWbemNamedValueSet,
1034 ISWbemObjectSet **objWbemObjectSet )
1036 FIXME( "\n" );
1037 return E_NOTIMPL;
1040 static HRESULT WINAPI services_AssociatorsOfAsync(
1041 ISWbemServices *iface,
1042 IDispatch *objWbemSink,
1043 BSTR strObjectPath,
1044 BSTR strAssocClass,
1045 BSTR strResultClass,
1046 BSTR strResultRole,
1047 BSTR strRole,
1048 VARIANT_BOOL bClassesOnly,
1049 VARIANT_BOOL bSchemaOnly,
1050 BSTR strRequiredAssocQualifier,
1051 BSTR strRequiredQualifier,
1052 LONG iFlags,
1053 IDispatch *objWbemNamedValueSet,
1054 IDispatch *objWbemAsyncContext )
1056 FIXME( "\n" );
1057 return E_NOTIMPL;
1060 static HRESULT WINAPI services_ReferencesTo(
1061 ISWbemServices *iface,
1062 BSTR strObjectPath,
1063 BSTR strResultClass,
1064 BSTR strRole,
1065 VARIANT_BOOL bClassesOnly,
1066 VARIANT_BOOL bSchemaOnly,
1067 BSTR strRequiredQualifier,
1068 LONG iFlags,
1069 IDispatch *objWbemNamedValueSet,
1070 ISWbemObjectSet **objWbemObjectSet )
1072 FIXME( "\n" );
1073 return E_NOTIMPL;
1076 static HRESULT WINAPI services_ReferencesToAsync(
1077 ISWbemServices *iface,
1078 IDispatch *objWbemSink,
1079 BSTR strObjectPath,
1080 BSTR strResultClass,
1081 BSTR strRole,
1082 VARIANT_BOOL bClassesOnly,
1083 VARIANT_BOOL bSchemaOnly,
1084 BSTR strRequiredQualifier,
1085 LONG iFlags,
1086 IDispatch *objWbemNamedValueSet,
1087 IDispatch *objWbemAsyncContext )
1089 FIXME( "\n" );
1090 return E_NOTIMPL;
1093 static HRESULT WINAPI services_ExecNotificationQuery(
1094 ISWbemServices *iface,
1095 BSTR strQuery,
1096 BSTR strQueryLanguage,
1097 LONG iFlags,
1098 IDispatch *objWbemNamedValueSet,
1099 ISWbemEventSource **objWbemEventSource )
1101 FIXME( "\n" );
1102 return E_NOTIMPL;
1105 static HRESULT WINAPI services_ExecNotificationQueryAsync(
1106 ISWbemServices *iface,
1107 IDispatch *objWbemSink,
1108 BSTR strQuery,
1109 BSTR strQueryLanguage,
1110 LONG iFlags,
1111 IDispatch *objWbemNamedValueSet,
1112 IDispatch *objWbemAsyncContext )
1114 FIXME( "\n" );
1115 return E_NOTIMPL;
1118 static HRESULT WINAPI services_ExecMethod(
1119 ISWbemServices *iface,
1120 BSTR strObjectPath,
1121 BSTR strMethodName,
1122 IDispatch *objWbemInParameters,
1123 LONG iFlags,
1124 IDispatch *objWbemNamedValueSet,
1125 ISWbemObject **objWbemOutParameters )
1127 FIXME( "\n" );
1128 return E_NOTIMPL;
1131 static HRESULT WINAPI services_ExecMethodAsync(
1132 ISWbemServices *iface,
1133 IDispatch *objWbemSink,
1134 BSTR strObjectPath,
1135 BSTR strMethodName,
1136 IDispatch *objWbemInParameters,
1137 LONG iFlags,
1138 IDispatch *objWbemNamedValueSet,
1139 IDispatch *objWbemAsyncContext )
1141 FIXME( "\n" );
1142 return E_NOTIMPL;
1145 static HRESULT WINAPI services_get_Security_(
1146 ISWbemServices *iface,
1147 ISWbemSecurity **objWbemSecurity )
1149 FIXME( "\n" );
1150 return E_NOTIMPL;
1153 static const ISWbemServicesVtbl services_vtbl =
1155 services_QueryInterface,
1156 services_AddRef,
1157 services_Release,
1158 services_GetTypeInfoCount,
1159 services_GetTypeInfo,
1160 services_GetIDsOfNames,
1161 services_Invoke,
1162 services_Get,
1163 services_GetAsync,
1164 services_Delete,
1165 services_DeleteAsync,
1166 services_InstancesOf,
1167 services_InstancesOfAsync,
1168 services_SubclassesOf,
1169 services_SubclassesOfAsync,
1170 services_ExecQuery,
1171 services_ExecQueryAsync,
1172 services_AssociatorsOf,
1173 services_AssociatorsOfAsync,
1174 services_ReferencesTo,
1175 services_ReferencesToAsync,
1176 services_ExecNotificationQuery,
1177 services_ExecNotificationQueryAsync,
1178 services_ExecMethod,
1179 services_ExecMethodAsync,
1180 services_get_Security_
1183 static HRESULT SWbemServices_create( IWbemServices *wbem_services, ISWbemServices **obj )
1185 struct services *services;
1187 TRACE( "%p, %p\n", obj, wbem_services );
1189 if (!(services = heap_alloc( sizeof(*services) ))) return E_OUTOFMEMORY;
1190 services->ISWbemServices_iface.lpVtbl = &services_vtbl;
1191 services->refs = 1;
1192 services->services = wbem_services;
1193 IWbemServices_AddRef( services->services );
1195 *obj = &services->ISWbemServices_iface;
1196 TRACE( "returning iface %p\n", *obj );
1197 return S_OK;
1200 struct locator
1202 ISWbemLocator ISWbemLocator_iface;
1203 LONG refs;
1204 IWbemLocator *locator;
1207 static inline struct locator *impl_from_ISWbemLocator( ISWbemLocator *iface )
1209 return CONTAINING_RECORD( iface, struct locator, ISWbemLocator_iface );
1212 static ULONG WINAPI locator_AddRef(
1213 ISWbemLocator *iface )
1215 struct locator *locator = impl_from_ISWbemLocator( iface );
1216 return InterlockedIncrement( &locator->refs );
1219 static ULONG WINAPI locator_Release(
1220 ISWbemLocator *iface )
1222 struct locator *locator = impl_from_ISWbemLocator( iface );
1223 LONG refs = InterlockedDecrement( &locator->refs );
1224 if (!refs)
1226 TRACE( "destroying %p\n", locator );
1227 if (locator->locator)
1228 IWbemLocator_Release( locator->locator );
1229 heap_free( locator );
1231 return refs;
1234 static HRESULT WINAPI locator_QueryInterface(
1235 ISWbemLocator *iface,
1236 REFIID riid,
1237 void **ppvObject )
1239 struct locator *locator = impl_from_ISWbemLocator( iface );
1241 TRACE( "%p, %s, %p\n", locator, debugstr_guid( riid ), ppvObject );
1243 if (IsEqualGUID( riid, &IID_ISWbemLocator ) ||
1244 IsEqualGUID( riid, &IID_IDispatch ) ||
1245 IsEqualGUID( riid, &IID_IUnknown ))
1247 *ppvObject = iface;
1249 else
1251 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1252 return E_NOINTERFACE;
1254 ISWbemLocator_AddRef( iface );
1255 return S_OK;
1258 static HRESULT WINAPI locator_GetTypeInfoCount(
1259 ISWbemLocator *iface,
1260 UINT *count )
1262 struct locator *locator = impl_from_ISWbemLocator( iface );
1264 TRACE( "%p, %p\n", locator, count );
1265 *count = 1;
1266 return S_OK;
1269 static HRESULT WINAPI locator_GetTypeInfo(
1270 ISWbemLocator *iface,
1271 UINT index,
1272 LCID lcid,
1273 ITypeInfo **info )
1275 struct locator *locator = impl_from_ISWbemLocator( iface );
1276 TRACE( "%p, %u, %u, %p\n", locator, index, lcid, info );
1278 return get_typeinfo( ISWbemLocator_tid, info );
1281 static HRESULT WINAPI locator_GetIDsOfNames(
1282 ISWbemLocator *iface,
1283 REFIID riid,
1284 LPOLESTR *names,
1285 UINT count,
1286 LCID lcid,
1287 DISPID *dispid )
1289 struct locator *locator = impl_from_ISWbemLocator( iface );
1290 ITypeInfo *typeinfo;
1291 HRESULT hr;
1293 TRACE( "%p, %s, %p, %u, %u, %p\n", locator, debugstr_guid(riid), names, count, lcid, dispid );
1295 if (!names || !count || !dispid) return E_INVALIDARG;
1297 hr = get_typeinfo( ISWbemLocator_tid, &typeinfo );
1298 if (SUCCEEDED(hr))
1300 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
1301 ITypeInfo_Release( typeinfo );
1303 return hr;
1306 static HRESULT WINAPI locator_Invoke(
1307 ISWbemLocator *iface,
1308 DISPID member,
1309 REFIID riid,
1310 LCID lcid,
1311 WORD flags,
1312 DISPPARAMS *params,
1313 VARIANT *result,
1314 EXCEPINFO *excep_info,
1315 UINT *arg_err )
1317 struct locator *locator = impl_from_ISWbemLocator( iface );
1318 ITypeInfo *typeinfo;
1319 HRESULT hr;
1321 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", locator, member, debugstr_guid(riid),
1322 lcid, flags, params, result, excep_info, arg_err );
1324 hr = get_typeinfo( ISWbemLocator_tid, &typeinfo );
1325 if (SUCCEEDED(hr))
1327 hr = ITypeInfo_Invoke( typeinfo, &locator->ISWbemLocator_iface, member, flags,
1328 params, result, excep_info, arg_err );
1329 ITypeInfo_Release( typeinfo );
1331 return hr;
1334 static BSTR build_resource_string( BSTR server, BSTR namespace )
1336 static const WCHAR defaultW[] = {'r','o','o','t','\\','d','e','f','a','u','l','t',0};
1337 ULONG len, len_server = 0, len_namespace = 0;
1338 BSTR ret;
1340 if (server && *server) len_server = strlenW( server );
1341 else len_server = 1;
1342 if (namespace && *namespace) len_namespace = strlenW( namespace );
1343 else len_namespace = sizeof(defaultW) / sizeof(defaultW[0]) - 1;
1345 if (!(ret = SysAllocStringLen( NULL, 2 + len_server + 1 + len_namespace ))) return NULL;
1347 ret[0] = ret[1] = '\\';
1348 if (server && *server) strcpyW( ret + 2, server );
1349 else ret[2] = '.';
1351 len = len_server + 2;
1352 ret[len++] = '\\';
1354 if (namespace && *namespace) strcpyW( ret + len, namespace );
1355 else strcpyW( ret + len, defaultW );
1356 return ret;
1359 static HRESULT WINAPI locator_ConnectServer(
1360 ISWbemLocator *iface,
1361 BSTR strServer,
1362 BSTR strNamespace,
1363 BSTR strUser,
1364 BSTR strPassword,
1365 BSTR strLocale,
1366 BSTR strAuthority,
1367 LONG iSecurityFlags,
1368 IDispatch *objWbemNamedValueSet,
1369 ISWbemServices **objWbemServices )
1371 struct locator *locator = impl_from_ISWbemLocator( iface );
1372 IWbemServices *services;
1373 BSTR resource;
1374 HRESULT hr;
1376 TRACE( "%p, %s, %s, %s, %p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strServer),
1377 debugstr_w(strNamespace), debugstr_w(strUser), strPassword, debugstr_w(strLocale),
1378 debugstr_w(strAuthority), iSecurityFlags, objWbemNamedValueSet, objWbemServices );
1380 if (objWbemNamedValueSet) FIXME( "context not supported\n" );
1382 if (!locator->locator)
1384 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
1385 (void **)&locator->locator );
1386 if (hr != S_OK) return hr;
1389 if (!(resource = build_resource_string( strServer, strNamespace ))) return E_OUTOFMEMORY;
1390 hr = IWbemLocator_ConnectServer( locator->locator, resource, strUser, strPassword, strLocale,
1391 iSecurityFlags, strAuthority, NULL, &services );
1392 SysFreeString( resource );
1393 if (hr != S_OK) return hr;
1395 hr = SWbemServices_create( services, objWbemServices );
1396 IWbemServices_Release( services );
1397 return hr;
1400 static HRESULT WINAPI locator_get_Security_(
1401 ISWbemLocator *iface,
1402 ISWbemSecurity **objWbemSecurity )
1404 FIXME( "%p, %p\n", iface, objWbemSecurity );
1405 return E_NOTIMPL;
1408 static const ISWbemLocatorVtbl locator_vtbl =
1410 locator_QueryInterface,
1411 locator_AddRef,
1412 locator_Release,
1413 locator_GetTypeInfoCount,
1414 locator_GetTypeInfo,
1415 locator_GetIDsOfNames,
1416 locator_Invoke,
1417 locator_ConnectServer,
1418 locator_get_Security_
1421 HRESULT SWbemLocator_create( void **obj )
1423 struct locator *locator;
1425 TRACE( "%p\n", obj );
1427 if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY;
1428 locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl;
1429 locator->refs = 1;
1430 locator->locator = NULL;
1432 *obj = &locator->ISWbemLocator_iface;
1433 TRACE( "returning iface %p\n", *obj );
1434 return S_OK;