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