[WBEMDISP] Sync with Wine Staging 1.9.4. CORE-10912
[reactos.git] / reactos / dll / win32 / wbemdisp / locator.c
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 #include "wbemdisp_private.h"
20
21 #include <wbemcli.h>
22
23 static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** );
24 static HRESULT ISWbemSecurity_create( ISWbemSecurity ** );
25
26 enum type_id
27 {
28 ISWbemLocator_tid,
29 ISWbemObject_tid,
30 ISWbemObjectSet_tid,
31 ISWbemServices_tid,
32 ISWbemSecurity_tid,
33 last_tid
34 };
35
36 static ITypeLib *wbemdisp_typelib;
37 static ITypeInfo *wbemdisp_typeinfo[last_tid];
38
39 static REFIID wbemdisp_tid_id[] =
40 {
41 &IID_ISWbemLocator,
42 &IID_ISWbemObject,
43 &IID_ISWbemObjectSet,
44 &IID_ISWbemServices,
45 &IID_ISWbemSecurity
46 };
47
48 static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret )
49 {
50 HRESULT hr;
51
52 if (!wbemdisp_typelib)
53 {
54 ITypeLib *typelib;
55
56 hr = LoadRegTypeLib( &LIBID_WbemScripting, 1, 2, LOCALE_SYSTEM_DEFAULT, &typelib );
57 if (FAILED( hr ))
58 {
59 ERR( "LoadRegTypeLib failed: %08x\n", hr );
60 return hr;
61 }
62 if (InterlockedCompareExchangePointer( (void **)&wbemdisp_typelib, typelib, NULL ))
63 ITypeLib_Release( typelib );
64 }
65 if (!wbemdisp_typeinfo[tid])
66 {
67 ITypeInfo *typeinfo;
68
69 hr = ITypeLib_GetTypeInfoOfGuid( wbemdisp_typelib, wbemdisp_tid_id[tid], &typeinfo );
70 if (FAILED( hr ))
71 {
72 ERR( "GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(wbemdisp_tid_id[tid]), hr );
73 return hr;
74 }
75 if (InterlockedCompareExchangePointer( (void **)(wbemdisp_typeinfo + tid), typeinfo, NULL ))
76 ITypeInfo_Release( typeinfo );
77 }
78 *ret = wbemdisp_typeinfo[tid];
79 ITypeInfo_AddRef( *ret );
80 return S_OK;
81 }
82
83 #define DISPID_BASE 0x1800000
84
85 struct member
86 {
87 BSTR name;
88 DISPID dispid;
89 };
90
91 struct object
92 {
93 ISWbemObject ISWbemObject_iface;
94 LONG refs;
95 IWbemClassObject *object;
96 struct member *members;
97 UINT nb_members;
98 DISPID last_dispid;
99 };
100
101 static inline struct object *impl_from_ISWbemObject(
102 ISWbemObject *iface )
103 {
104 return CONTAINING_RECORD( iface, struct object, ISWbemObject_iface );
105 }
106
107 static ULONG WINAPI object_AddRef(
108 ISWbemObject *iface )
109 {
110 struct object *object = impl_from_ISWbemObject( iface );
111 return InterlockedIncrement( &object->refs );
112 }
113
114 static ULONG WINAPI object_Release(
115 ISWbemObject *iface )
116 {
117 struct object *object = impl_from_ISWbemObject( iface );
118 LONG refs = InterlockedDecrement( &object->refs );
119 if (!refs)
120 {
121 UINT i;
122
123 TRACE( "destroying %p\n", object );
124 IWbemClassObject_Release( object->object );
125 for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name );
126 heap_free( object->members );
127 heap_free( object );
128 }
129 return refs;
130 }
131
132 static HRESULT WINAPI object_QueryInterface(
133 ISWbemObject *iface,
134 REFIID riid,
135 void **ppvObject )
136 {
137 struct object *object = impl_from_ISWbemObject( iface );
138
139 TRACE( "%p %s %p\n", object, debugstr_guid(riid), ppvObject );
140
141 if (IsEqualGUID( riid, &IID_ISWbemObject ) ||
142 IsEqualGUID( riid, &IID_IDispatch ) ||
143 IsEqualGUID( riid, &IID_IUnknown ))
144 {
145 *ppvObject = object;
146 }
147 else
148 {
149 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
150 return E_NOINTERFACE;
151 }
152 ISWbemObject_AddRef( iface );
153 return S_OK;
154 }
155
156 static HRESULT WINAPI object_GetTypeInfoCount(
157 ISWbemObject *iface,
158 UINT *count )
159 {
160 struct object *object = impl_from_ISWbemObject( iface );
161
162 TRACE( "%p, %p\n", object, count );
163 *count = 1;
164 return S_OK;
165 }
166
167 static HRESULT WINAPI object_GetTypeInfo(
168 ISWbemObject *iface,
169 UINT index,
170 LCID lcid,
171 ITypeInfo **info )
172 {
173 struct object *object = impl_from_ISWbemObject( iface );
174 FIXME( "%p, %u, %u, %p\n", object, index, lcid, info );
175 return E_NOTIMPL;
176 }
177
178 #define DISPID_BASE 0x1800000
179
180 static HRESULT init_members( struct object *object )
181 {
182 LONG bound, i;
183 SAFEARRAY *sa;
184 HRESULT hr;
185
186 if (object->members) return S_OK;
187
188 hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa );
189 if (FAILED( hr )) return hr;
190 hr = SafeArrayGetUBound( sa, 1, &bound );
191 if (FAILED( hr ))
192 {
193 SafeArrayDestroy( sa );
194 return hr;
195 }
196 if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) )))
197 {
198 SafeArrayDestroy( sa );
199 return E_OUTOFMEMORY;
200 }
201 for (i = 0; i <= bound; i++)
202 {
203 hr = SafeArrayGetElement( sa, &i, &object->members[i].name );
204 if (FAILED( hr ))
205 {
206 for (i--; i >= 0; i--) SysFreeString( object->members[i].name );
207 SafeArrayDestroy( sa );
208 heap_free( object->members );
209 object->members = NULL;
210 return E_OUTOFMEMORY;
211 }
212 object->members[i].dispid = 0;
213 }
214 object->nb_members = bound + 1;
215 SafeArrayDestroy( sa );
216 return S_OK;
217 }
218
219 static DISPID get_member_dispid( struct object *object, const WCHAR *name )
220 {
221 UINT i;
222 for (i = 0; i < object->nb_members; i++)
223 {
224 if (!strcmpiW( object->members[i].name, name ))
225 {
226 if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid;
227 return object->members[i].dispid;
228 }
229 }
230 return DISPID_UNKNOWN;
231 }
232
233 static HRESULT WINAPI object_GetIDsOfNames(
234 ISWbemObject *iface,
235 REFIID riid,
236 LPOLESTR *names,
237 UINT count,
238 LCID lcid,
239 DISPID *dispid )
240 {
241 struct object *object = impl_from_ISWbemObject( iface );
242 HRESULT hr;
243 UINT i;
244
245 TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid );
246
247 if (!names || !count || !dispid) return E_INVALIDARG;
248
249 hr = init_members( object );
250 if (FAILED( hr )) return hr;
251
252 for (i = 0; i < count; i++)
253 {
254 if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break;
255 }
256 if (i != count) return DISP_E_UNKNOWNNAME;
257 return S_OK;
258 }
259
260 static BSTR get_member_name( struct object *object, DISPID dispid )
261 {
262 UINT i;
263 for (i = 0; i < object->nb_members; i++)
264 {
265 if (object->members[i].dispid == dispid) return object->members[i].name;
266 }
267 return NULL;
268 }
269
270 static HRESULT WINAPI object_Invoke(
271 ISWbemObject *iface,
272 DISPID member,
273 REFIID riid,
274 LCID lcid,
275 WORD flags,
276 DISPPARAMS *params,
277 VARIANT *result,
278 EXCEPINFO *excep_info,
279 UINT *arg_err )
280 {
281 struct object *object = impl_from_ISWbemObject( iface );
282 BSTR name;
283
284 TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid),
285 lcid, flags, params, result, excep_info, arg_err );
286
287 if (flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET))
288 {
289 FIXME( "flags %x not supported\n", flags );
290 return E_NOTIMPL;
291 }
292 if (!(name = get_member_name( object, member )))
293 return DISP_E_MEMBERNOTFOUND;
294
295 memset( params, 0, sizeof(*params) );
296 return IWbemClassObject_Get( object->object, name, 0, result, NULL, NULL );
297 }
298
299 static HRESULT WINAPI object_Put_(
300 ISWbemObject *iface,
301 LONG iFlags,
302 IDispatch *objWbemNamedValueSet,
303 ISWbemObjectPath **objWbemObjectPath )
304 {
305 FIXME( "\n" );
306 return E_NOTIMPL;
307 }
308
309 static const ISWbemObjectVtbl object_vtbl =
310 {
311 object_QueryInterface,
312 object_AddRef,
313 object_Release,
314 object_GetTypeInfoCount,
315 object_GetTypeInfo,
316 object_GetIDsOfNames,
317 object_Invoke,
318 object_Put_
319 };
320
321 static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj )
322 {
323 struct object *object;
324
325 TRACE( "%p, %p\n", obj, wbem_object );
326
327 if (!(object = heap_alloc( sizeof(*object) ))) return E_OUTOFMEMORY;
328 object->ISWbemObject_iface.lpVtbl = &object_vtbl;
329 object->refs = 1;
330 object->object = wbem_object;
331 IWbemClassObject_AddRef( object->object );
332 object->members = NULL;
333 object->nb_members = 0;
334 object->last_dispid = DISPID_BASE;
335
336 *obj = &object->ISWbemObject_iface;
337 TRACE( "returning iface %p\n", *obj );
338 return S_OK;
339 }
340
341 struct objectset
342 {
343 ISWbemObjectSet ISWbemObjectSet_iface;
344 LONG refs;
345 IEnumWbemClassObject *objectenum;
346 LONG count;
347 };
348
349 static inline struct objectset *impl_from_ISWbemObjectSet(
350 ISWbemObjectSet *iface )
351 {
352 return CONTAINING_RECORD( iface, struct objectset, ISWbemObjectSet_iface );
353 }
354
355 static ULONG WINAPI objectset_AddRef(
356 ISWbemObjectSet *iface )
357 {
358 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
359 return InterlockedIncrement( &objectset->refs );
360 }
361
362 static ULONG WINAPI objectset_Release(
363 ISWbemObjectSet *iface )
364 {
365 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
366 LONG refs = InterlockedDecrement( &objectset->refs );
367 if (!refs)
368 {
369 TRACE( "destroying %p\n", objectset );
370 IEnumWbemClassObject_Release( objectset->objectenum );
371 heap_free( objectset );
372 }
373 return refs;
374 }
375
376 static HRESULT WINAPI objectset_QueryInterface(
377 ISWbemObjectSet *iface,
378 REFIID riid,
379 void **ppvObject )
380 {
381 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
382
383 TRACE( "%p %s %p\n", objectset, debugstr_guid(riid), ppvObject );
384
385 if (IsEqualGUID( riid, &IID_ISWbemObjectSet ) ||
386 IsEqualGUID( riid, &IID_IDispatch ) ||
387 IsEqualGUID( riid, &IID_IUnknown ))
388 {
389 *ppvObject = objectset;
390 }
391 else
392 {
393 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
394 return E_NOINTERFACE;
395 }
396 ISWbemObjectSet_AddRef( iface );
397 return S_OK;
398 }
399
400 static HRESULT WINAPI objectset_GetTypeInfoCount(
401 ISWbemObjectSet *iface,
402 UINT *count )
403 {
404 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
405 TRACE( "%p, %p\n", objectset, count );
406 *count = 1;
407 return S_OK;
408 }
409
410 static HRESULT WINAPI objectset_GetTypeInfo(
411 ISWbemObjectSet *iface,
412 UINT index,
413 LCID lcid,
414 ITypeInfo **info )
415 {
416 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
417 TRACE( "%p, %u, %u, %p\n", objectset, index, lcid, info );
418
419 return get_typeinfo( ISWbemObjectSet_tid, info );
420 }
421
422 static HRESULT WINAPI objectset_GetIDsOfNames(
423 ISWbemObjectSet *iface,
424 REFIID riid,
425 LPOLESTR *names,
426 UINT count,
427 LCID lcid,
428 DISPID *dispid )
429 {
430 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
431 ITypeInfo *typeinfo;
432 HRESULT hr;
433
434 TRACE( "%p, %s, %p, %u, %u, %p\n", objectset, debugstr_guid(riid), names, count, lcid, dispid );
435
436 if (!names || !count || !dispid) return E_INVALIDARG;
437
438 hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo );
439 if (SUCCEEDED(hr))
440 {
441 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
442 ITypeInfo_Release( typeinfo );
443 }
444 return hr;
445 }
446
447 static HRESULT WINAPI objectset_Invoke(
448 ISWbemObjectSet *iface,
449 DISPID member,
450 REFIID riid,
451 LCID lcid,
452 WORD flags,
453 DISPPARAMS *params,
454 VARIANT *result,
455 EXCEPINFO *excep_info,
456 UINT *arg_err )
457 {
458 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
459 ITypeInfo *typeinfo;
460 HRESULT hr;
461
462 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", objectset, member, debugstr_guid(riid),
463 lcid, flags, params, result, excep_info, arg_err );
464
465 hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo );
466 if (SUCCEEDED(hr))
467 {
468 hr = ITypeInfo_Invoke( typeinfo, &objectset->ISWbemObjectSet_iface, member, flags,
469 params, result, excep_info, arg_err );
470 ITypeInfo_Release( typeinfo );
471 }
472 return hr;
473 }
474
475 static HRESULT WINAPI objectset_get__NewEnum(
476 ISWbemObjectSet *iface,
477 IUnknown **pUnk )
478 {
479 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
480 IEnumWbemClassObject *objectenum;
481 HRESULT hr;
482
483 TRACE( "%p, %p\n", objectset, pUnk );
484
485 hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum );
486 if (FAILED( hr )) return hr;
487
488 hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk );
489 IEnumWbemClassObject_Release( objectenum );
490 return hr;
491 }
492
493 static HRESULT WINAPI objectset_Item(
494 ISWbemObjectSet *iface,
495 BSTR strObjectPath,
496 LONG iFlags,
497 ISWbemObject **objWbemObject )
498 {
499 FIXME( "\n" );
500 return E_NOTIMPL;
501 }
502
503 static HRESULT WINAPI objectset_get_Count(
504 ISWbemObjectSet *iface,
505 LONG *iCount )
506 {
507 struct objectset *objectset = impl_from_ISWbemObjectSet( iface );
508
509 TRACE( "%p, %p\n", objectset, iCount );
510
511 *iCount = objectset->count;
512 return S_OK;
513 }
514
515 static HRESULT WINAPI objectset_get_Security_(
516 ISWbemObjectSet *iface,
517 ISWbemSecurity **objWbemSecurity )
518 {
519 FIXME( "\n" );
520 return E_NOTIMPL;
521 }
522
523 static HRESULT WINAPI objectset_ItemIndex(
524 ISWbemObjectSet *iface,
525 LONG lIndex,
526 ISWbemObject **objWbemObject )
527 {
528 FIXME( "\n" );
529 return E_NOTIMPL;
530 }
531
532 static const ISWbemObjectSetVtbl objectset_vtbl =
533 {
534 objectset_QueryInterface,
535 objectset_AddRef,
536 objectset_Release,
537 objectset_GetTypeInfoCount,
538 objectset_GetTypeInfo,
539 objectset_GetIDsOfNames,
540 objectset_Invoke,
541 objectset_get__NewEnum,
542 objectset_Item,
543 objectset_get_Count,
544 objectset_get_Security_,
545 objectset_ItemIndex
546 };
547
548 static LONG get_object_count( IEnumWbemClassObject *iter )
549 {
550 LONG count = 0;
551 while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) count++;
552 IEnumWbemClassObject_Reset( iter );
553 return count;
554 }
555
556 static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj )
557 {
558 struct objectset *objectset;
559
560 TRACE( "%p, %p\n", obj, wbem_objectenum );
561
562 if (!(objectset = heap_alloc( sizeof(*objectset) ))) return E_OUTOFMEMORY;
563 objectset->ISWbemObjectSet_iface.lpVtbl = &objectset_vtbl;
564 objectset->refs = 1;
565 objectset->objectenum = wbem_objectenum;
566 IEnumWbemClassObject_AddRef( objectset->objectenum );
567 objectset->count = get_object_count( objectset->objectenum );
568
569 *obj = &objectset->ISWbemObjectSet_iface;
570 TRACE( "returning iface %p\n", *obj );
571 return S_OK;
572 }
573
574 struct enumvar
575 {
576 IEnumVARIANT IEnumVARIANT_iface;
577 LONG refs;
578 IEnumWbemClassObject *objectenum;
579 };
580
581 static inline struct enumvar *impl_from_IEnumVARIANT(
582 IEnumVARIANT *iface )
583 {
584 return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface );
585 }
586
587 static ULONG WINAPI enumvar_AddRef(
588 IEnumVARIANT *iface )
589 {
590 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
591 return InterlockedIncrement( &enumvar->refs );
592 }
593
594 static ULONG WINAPI enumvar_Release(
595 IEnumVARIANT *iface )
596 {
597 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
598 LONG refs = InterlockedDecrement( &enumvar->refs );
599 if (!refs)
600 {
601 TRACE( "destroying %p\n", enumvar );
602 IEnumWbemClassObject_Release( enumvar->objectenum );
603 heap_free( enumvar );
604 }
605 return refs;
606 }
607
608 static HRESULT WINAPI enumvar_QueryInterface(
609 IEnumVARIANT *iface,
610 REFIID riid,
611 void **ppvObject )
612 {
613 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
614
615 TRACE( "%p %s %p\n", enumvar, debugstr_guid(riid), ppvObject );
616
617 if (IsEqualGUID( riid, &IID_IEnumVARIANT ) ||
618 IsEqualGUID( riid, &IID_IUnknown ))
619 {
620 *ppvObject = enumvar;
621 }
622 else
623 {
624 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
625 return E_NOINTERFACE;
626 }
627 IEnumVARIANT_AddRef( iface );
628 return S_OK;
629 }
630
631 static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched )
632 {
633 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
634 IWbemClassObject *obj;
635 ULONG count = 0;
636
637 TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched );
638
639 if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count );
640 if (count)
641 {
642 ISWbemObject *sobj;
643 HRESULT hr;
644
645 hr = SWbemObject_create( obj, &sobj );
646 IWbemClassObject_Release( obj );
647 if (FAILED( hr )) return hr;
648
649 V_VT( var ) = VT_DISPATCH;
650 V_DISPATCH( var ) = (IDispatch *)sobj;
651 }
652 if (fetched) *fetched = count;
653 return (count < celt) ? S_FALSE : S_OK;
654 }
655
656 static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt )
657 {
658 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
659
660 TRACE( "%p, %u\n", iface, celt );
661
662 return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt );
663 }
664
665 static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface )
666 {
667 struct enumvar *enumvar = impl_from_IEnumVARIANT( iface );
668
669 TRACE( "%p\n", iface );
670
671 return IEnumWbemClassObject_Reset( enumvar->objectenum );
672 }
673
674 static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum )
675 {
676 FIXME( "%p, %p\n", iface, penum );
677 return E_NOTIMPL;
678 }
679
680 static const struct IEnumVARIANTVtbl enumvar_vtbl =
681 {
682 enumvar_QueryInterface,
683 enumvar_AddRef,
684 enumvar_Release,
685 enumvar_Next,
686 enumvar_Skip,
687 enumvar_Reset,
688 enumvar_Clone
689 };
690
691 static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj )
692 {
693 struct enumvar *enumvar;
694
695 if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY;
696 enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl;
697 enumvar->refs = 1;
698 enumvar->objectenum = objectenum;
699 IEnumWbemClassObject_AddRef( enumvar->objectenum );
700
701 *obj = &enumvar->IEnumVARIANT_iface;
702 TRACE( "returning iface %p\n", *obj );
703 return S_OK;
704 }
705
706 struct services
707 {
708 ISWbemServices ISWbemServices_iface;
709 LONG refs;
710 IWbemServices *services;
711 };
712
713 static inline struct services *impl_from_ISWbemServices(
714 ISWbemServices *iface )
715 {
716 return CONTAINING_RECORD( iface, struct services, ISWbemServices_iface );
717 }
718
719 static ULONG WINAPI services_AddRef(
720 ISWbemServices *iface )
721 {
722 struct services *services = impl_from_ISWbemServices( iface );
723 return InterlockedIncrement( &services->refs );
724 }
725
726 static ULONG WINAPI services_Release(
727 ISWbemServices *iface )
728 {
729 struct services *services = impl_from_ISWbemServices( iface );
730 LONG refs = InterlockedDecrement( &services->refs );
731 if (!refs)
732 {
733 TRACE( "destroying %p\n", services );
734 IWbemServices_Release( services->services );
735 heap_free( services );
736 }
737 return refs;
738 }
739
740 static HRESULT WINAPI services_QueryInterface(
741 ISWbemServices *iface,
742 REFIID riid,
743 void **ppvObject )
744 {
745 struct services *services = impl_from_ISWbemServices( iface );
746
747 TRACE( "%p %s %p\n", services, debugstr_guid(riid), ppvObject );
748
749 if (IsEqualGUID( riid, &IID_ISWbemServices ) ||
750 IsEqualGUID( riid, &IID_IDispatch ) ||
751 IsEqualGUID( riid, &IID_IUnknown ))
752 {
753 *ppvObject = services;
754 }
755 else
756 {
757 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
758 return E_NOINTERFACE;
759 }
760 ISWbemServices_AddRef( iface );
761 return S_OK;
762 }
763
764 static HRESULT WINAPI services_GetTypeInfoCount(
765 ISWbemServices *iface,
766 UINT *count )
767 {
768 struct services *services = impl_from_ISWbemServices( iface );
769 TRACE( "%p, %p\n", services, count );
770
771 *count = 1;
772 return S_OK;
773 }
774
775 static HRESULT WINAPI services_GetTypeInfo(
776 ISWbemServices *iface,
777 UINT index,
778 LCID lcid,
779 ITypeInfo **info )
780 {
781 struct services *services = impl_from_ISWbemServices( iface );
782 TRACE( "%p, %u, %u, %p\n", services, index, lcid, info );
783
784 return get_typeinfo( ISWbemServices_tid, info );
785 }
786
787 static HRESULT WINAPI services_GetIDsOfNames(
788 ISWbemServices *iface,
789 REFIID riid,
790 LPOLESTR *names,
791 UINT count,
792 LCID lcid,
793 DISPID *dispid )
794 {
795 struct services *services = impl_from_ISWbemServices( iface );
796 ITypeInfo *typeinfo;
797 HRESULT hr;
798
799 TRACE( "%p, %s, %p, %u, %u, %p\n", services, debugstr_guid(riid), names, count, lcid, dispid );
800
801 if (!names || !count || !dispid) return E_INVALIDARG;
802
803 hr = get_typeinfo( ISWbemServices_tid, &typeinfo );
804 if (SUCCEEDED(hr))
805 {
806 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
807 ITypeInfo_Release( typeinfo );
808 }
809 return hr;
810 }
811
812 static HRESULT WINAPI services_Invoke(
813 ISWbemServices *iface,
814 DISPID member,
815 REFIID riid,
816 LCID lcid,
817 WORD flags,
818 DISPPARAMS *params,
819 VARIANT *result,
820 EXCEPINFO *excep_info,
821 UINT *arg_err )
822 {
823 struct services *services = impl_from_ISWbemServices( iface );
824 ITypeInfo *typeinfo;
825 HRESULT hr;
826
827 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", services, member, debugstr_guid(riid),
828 lcid, flags, params, result, excep_info, arg_err );
829
830 hr = get_typeinfo( ISWbemServices_tid, &typeinfo );
831 if (SUCCEEDED(hr))
832 {
833 hr = ITypeInfo_Invoke( typeinfo, &services->ISWbemServices_iface, member, flags,
834 params, result, excep_info, arg_err );
835 ITypeInfo_Release( typeinfo );
836 }
837 return hr;
838 }
839
840 static HRESULT WINAPI services_Get(
841 ISWbemServices *iface,
842 BSTR strObjectPath,
843 LONG iFlags,
844 IDispatch *objWbemNamedValueSet,
845 ISWbemObject **objWbemObject )
846 {
847 struct services *services = impl_from_ISWbemServices( iface );
848 IWbemClassObject *obj;
849 HRESULT hr;
850
851 TRACE( "%p, %s, %d, %p, %p\n", iface, debugstr_w(strObjectPath), iFlags, objWbemNamedValueSet,
852 objWbemObject );
853
854 if (objWbemNamedValueSet) FIXME( "ignoring context\n" );
855
856 hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL );
857 if (hr != S_OK) return hr;
858
859 hr = SWbemObject_create( obj, objWbemObject );
860 IWbemClassObject_Release( obj );
861 return hr;
862 }
863
864 static HRESULT WINAPI services_GetAsync(
865 ISWbemServices *iface,
866 IDispatch *objWbemSink,
867 BSTR strObjectPath,
868 LONG iFlags,
869 IDispatch *objWbemNamedValueSet,
870 IDispatch *objWbemAsyncContext )
871 {
872 FIXME( "\n" );
873 return E_NOTIMPL;
874 }
875
876 static HRESULT WINAPI services_Delete(
877 ISWbemServices *iface,
878 BSTR strObjectPath,
879 LONG iFlags,
880 IDispatch *objWbemNamedValueSet )
881 {
882 FIXME( "\n" );
883 return E_NOTIMPL;
884 }
885
886 static HRESULT WINAPI services_DeleteAsync(
887 ISWbemServices* This,
888 IDispatch *objWbemSink,
889 BSTR strObjectPath,
890 LONG iFlags,
891 IDispatch *objWbemNamedValueSet,
892 IDispatch *objWbemAsyncContext )
893 {
894 FIXME( "\n" );
895 return E_NOTIMPL;
896 }
897
898 static BSTR build_query_string( const WCHAR *class )
899 {
900 static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0};
901 UINT len = strlenW(class) + sizeof(selectW) / sizeof(selectW[0]);
902 BSTR ret;
903
904 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
905 strcpyW( ret, selectW );
906 strcatW( ret, class );
907 return ret;
908 }
909
910 static HRESULT WINAPI services_InstancesOf(
911 ISWbemServices *iface,
912 BSTR strClass,
913 LONG iFlags,
914 IDispatch *objWbemNamedValueSet,
915 ISWbemObjectSet **objWbemObjectSet )
916 {
917 static const WCHAR wqlW[] = {'W','Q','L',0};
918 BSTR query, wql = SysAllocString( wqlW );
919 HRESULT hr;
920
921 TRACE( "%p, %s, %x, %p, %p\n", iface, debugstr_w(strClass), iFlags, objWbemNamedValueSet,
922 objWbemObjectSet );
923
924 if (!(query = build_query_string( strClass )))
925 {
926 SysFreeString( wql );
927 return E_OUTOFMEMORY;
928 }
929 hr = ISWbemServices_ExecQuery( iface, query, wql, iFlags, objWbemNamedValueSet, objWbemObjectSet );
930 SysFreeString( wql );
931 SysFreeString( query );
932 return hr;
933 }
934
935 static HRESULT WINAPI services_InstancesOfAsync(
936 ISWbemServices *iface,
937 IDispatch *objWbemSink,
938 BSTR strClass,
939 LONG iFlags,
940 IDispatch *objWbemNamedValueSet,
941 IDispatch *objWbemAsyncContext )
942 {
943 FIXME( "\n" );
944 return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI services_SubclassesOf(
948 ISWbemServices *iface,
949 BSTR strSuperclass,
950 LONG iFlags,
951 IDispatch *objWbemNamedValueSet,
952 ISWbemObjectSet **objWbemObjectSet )
953 {
954 FIXME( "\n" );
955 return E_NOTIMPL;
956 }
957
958 static HRESULT WINAPI services_SubclassesOfAsync(
959 ISWbemServices *iface,
960 IDispatch *objWbemSink,
961 BSTR strSuperclass,
962 LONG iFlags,
963 IDispatch *objWbemNamedValueSet,
964 IDispatch *objWbemAsyncContext )
965 {
966 FIXME( "\n" );
967 return E_NOTIMPL;
968 }
969
970 static HRESULT WINAPI services_ExecQuery(
971 ISWbemServices *iface,
972 BSTR strQuery,
973 BSTR strQueryLanguage,
974 LONG iFlags,
975 IDispatch *objWbemNamedValueSet,
976 ISWbemObjectSet **objWbemObjectSet )
977 {
978 struct services *services = impl_from_ISWbemServices( iface );
979 IEnumWbemClassObject *iter;
980 HRESULT hr;
981
982 TRACE( "%p, %s, %s, %x, %p, %p\n", iface, debugstr_w(strQuery), debugstr_w(strQueryLanguage),
983 iFlags, objWbemNamedValueSet, objWbemObjectSet );
984
985 if (objWbemNamedValueSet) FIXME( "ignoring context\n" );
986
987 hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter );
988 if (hr != S_OK) return hr;
989
990 hr = SWbemObjectSet_create( iter, objWbemObjectSet );
991 IEnumWbemClassObject_Release( iter );
992 return hr;
993 }
994
995 static HRESULT WINAPI services_ExecQueryAsync(
996 ISWbemServices *iface,
997 IDispatch *objWbemSink,
998 BSTR strQuery,
999 BSTR strQueryLanguage,
1000 LONG lFlags,
1001 IDispatch *objWbemNamedValueSet,
1002 IDispatch *objWbemAsyncContext )
1003 {
1004 FIXME( "\n" );
1005 return E_NOTIMPL;
1006 }
1007
1008 static HRESULT WINAPI services_AssociatorsOf(
1009 ISWbemServices *iface,
1010 BSTR strObjectPath,
1011 BSTR strAssocClass,
1012 BSTR strResultClass,
1013 BSTR strResultRole,
1014 BSTR strRole,
1015 VARIANT_BOOL bClassesOnly,
1016 VARIANT_BOOL bSchemaOnly,
1017 BSTR strRequiredAssocQualifier,
1018 BSTR strRequiredQualifier,
1019 LONG iFlags,
1020 IDispatch *objWbemNamedValueSet,
1021 ISWbemObjectSet **objWbemObjectSet )
1022 {
1023 FIXME( "\n" );
1024 return E_NOTIMPL;
1025 }
1026
1027 static HRESULT WINAPI services_AssociatorsOfAsync(
1028 ISWbemServices *iface,
1029 IDispatch *objWbemSink,
1030 BSTR strObjectPath,
1031 BSTR strAssocClass,
1032 BSTR strResultClass,
1033 BSTR strResultRole,
1034 BSTR strRole,
1035 VARIANT_BOOL bClassesOnly,
1036 VARIANT_BOOL bSchemaOnly,
1037 BSTR strRequiredAssocQualifier,
1038 BSTR strRequiredQualifier,
1039 LONG iFlags,
1040 IDispatch *objWbemNamedValueSet,
1041 IDispatch *objWbemAsyncContext )
1042 {
1043 FIXME( "\n" );
1044 return E_NOTIMPL;
1045 }
1046
1047 static HRESULT WINAPI services_ReferencesTo(
1048 ISWbemServices *iface,
1049 BSTR strObjectPath,
1050 BSTR strResultClass,
1051 BSTR strRole,
1052 VARIANT_BOOL bClassesOnly,
1053 VARIANT_BOOL bSchemaOnly,
1054 BSTR strRequiredQualifier,
1055 LONG iFlags,
1056 IDispatch *objWbemNamedValueSet,
1057 ISWbemObjectSet **objWbemObjectSet )
1058 {
1059 FIXME( "\n" );
1060 return E_NOTIMPL;
1061 }
1062
1063 static HRESULT WINAPI services_ReferencesToAsync(
1064 ISWbemServices *iface,
1065 IDispatch *objWbemSink,
1066 BSTR strObjectPath,
1067 BSTR strResultClass,
1068 BSTR strRole,
1069 VARIANT_BOOL bClassesOnly,
1070 VARIANT_BOOL bSchemaOnly,
1071 BSTR strRequiredQualifier,
1072 LONG iFlags,
1073 IDispatch *objWbemNamedValueSet,
1074 IDispatch *objWbemAsyncContext )
1075 {
1076 FIXME( "\n" );
1077 return E_NOTIMPL;
1078 }
1079
1080 static HRESULT WINAPI services_ExecNotificationQuery(
1081 ISWbemServices *iface,
1082 BSTR strQuery,
1083 BSTR strQueryLanguage,
1084 LONG iFlags,
1085 IDispatch *objWbemNamedValueSet,
1086 ISWbemEventSource **objWbemEventSource )
1087 {
1088 FIXME( "\n" );
1089 return E_NOTIMPL;
1090 }
1091
1092 static HRESULT WINAPI services_ExecNotificationQueryAsync(
1093 ISWbemServices *iface,
1094 IDispatch *objWbemSink,
1095 BSTR strQuery,
1096 BSTR strQueryLanguage,
1097 LONG iFlags,
1098 IDispatch *objWbemNamedValueSet,
1099 IDispatch *objWbemAsyncContext )
1100 {
1101 FIXME( "\n" );
1102 return E_NOTIMPL;
1103 }
1104
1105 static HRESULT WINAPI services_ExecMethod(
1106 ISWbemServices *iface,
1107 BSTR strObjectPath,
1108 BSTR strMethodName,
1109 IDispatch *objWbemInParameters,
1110 LONG iFlags,
1111 IDispatch *objWbemNamedValueSet,
1112 ISWbemObject **objWbemOutParameters )
1113 {
1114 FIXME( "\n" );
1115 return E_NOTIMPL;
1116 }
1117
1118 static HRESULT WINAPI services_ExecMethodAsync(
1119 ISWbemServices *iface,
1120 IDispatch *objWbemSink,
1121 BSTR strObjectPath,
1122 BSTR strMethodName,
1123 IDispatch *objWbemInParameters,
1124 LONG iFlags,
1125 IDispatch *objWbemNamedValueSet,
1126 IDispatch *objWbemAsyncContext )
1127 {
1128 FIXME( "\n" );
1129 return E_NOTIMPL;
1130 }
1131
1132 static HRESULT WINAPI services_get_Security_(
1133 ISWbemServices *iface,
1134 ISWbemSecurity **objWbemSecurity )
1135 {
1136 TRACE( "%p, %p\n", iface, objWbemSecurity );
1137
1138 if (!objWbemSecurity)
1139 return E_INVALIDARG;
1140
1141 return ISWbemSecurity_create( objWbemSecurity );
1142 }
1143
1144 static const ISWbemServicesVtbl services_vtbl =
1145 {
1146 services_QueryInterface,
1147 services_AddRef,
1148 services_Release,
1149 services_GetTypeInfoCount,
1150 services_GetTypeInfo,
1151 services_GetIDsOfNames,
1152 services_Invoke,
1153 services_Get,
1154 services_GetAsync,
1155 services_Delete,
1156 services_DeleteAsync,
1157 services_InstancesOf,
1158 services_InstancesOfAsync,
1159 services_SubclassesOf,
1160 services_SubclassesOfAsync,
1161 services_ExecQuery,
1162 services_ExecQueryAsync,
1163 services_AssociatorsOf,
1164 services_AssociatorsOfAsync,
1165 services_ReferencesTo,
1166 services_ReferencesToAsync,
1167 services_ExecNotificationQuery,
1168 services_ExecNotificationQueryAsync,
1169 services_ExecMethod,
1170 services_ExecMethodAsync,
1171 services_get_Security_
1172 };
1173
1174 static HRESULT SWbemServices_create( IWbemServices *wbem_services, ISWbemServices **obj )
1175 {
1176 struct services *services;
1177
1178 TRACE( "%p, %p\n", obj, wbem_services );
1179
1180 if (!(services = heap_alloc( sizeof(*services) ))) return E_OUTOFMEMORY;
1181 services->ISWbemServices_iface.lpVtbl = &services_vtbl;
1182 services->refs = 1;
1183 services->services = wbem_services;
1184 IWbemServices_AddRef( services->services );
1185
1186 *obj = &services->ISWbemServices_iface;
1187 TRACE( "returning iface %p\n", *obj );
1188 return S_OK;
1189 }
1190
1191 struct locator
1192 {
1193 ISWbemLocator ISWbemLocator_iface;
1194 LONG refs;
1195 IWbemLocator *locator;
1196 };
1197
1198 static inline struct locator *impl_from_ISWbemLocator( ISWbemLocator *iface )
1199 {
1200 return CONTAINING_RECORD( iface, struct locator, ISWbemLocator_iface );
1201 }
1202
1203 static ULONG WINAPI locator_AddRef(
1204 ISWbemLocator *iface )
1205 {
1206 struct locator *locator = impl_from_ISWbemLocator( iface );
1207 return InterlockedIncrement( &locator->refs );
1208 }
1209
1210 static ULONG WINAPI locator_Release(
1211 ISWbemLocator *iface )
1212 {
1213 struct locator *locator = impl_from_ISWbemLocator( iface );
1214 LONG refs = InterlockedDecrement( &locator->refs );
1215 if (!refs)
1216 {
1217 TRACE( "destroying %p\n", locator );
1218 IWbemLocator_Release( locator->locator );
1219 heap_free( locator );
1220 }
1221 return refs;
1222 }
1223
1224 static HRESULT WINAPI locator_QueryInterface(
1225 ISWbemLocator *iface,
1226 REFIID riid,
1227 void **ppvObject )
1228 {
1229 struct locator *locator = impl_from_ISWbemLocator( iface );
1230
1231 TRACE( "%p, %s, %p\n", locator, debugstr_guid( riid ), ppvObject );
1232
1233 if (IsEqualGUID( riid, &IID_ISWbemLocator ) ||
1234 IsEqualGUID( riid, &IID_IDispatch ) ||
1235 IsEqualGUID( riid, &IID_IUnknown ))
1236 {
1237 *ppvObject = iface;
1238 }
1239 else
1240 {
1241 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1242 return E_NOINTERFACE;
1243 }
1244 ISWbemLocator_AddRef( iface );
1245 return S_OK;
1246 }
1247
1248 static HRESULT WINAPI locator_GetTypeInfoCount(
1249 ISWbemLocator *iface,
1250 UINT *count )
1251 {
1252 struct locator *locator = impl_from_ISWbemLocator( iface );
1253
1254 TRACE( "%p, %p\n", locator, count );
1255 *count = 1;
1256 return S_OK;
1257 }
1258
1259 static HRESULT WINAPI locator_GetTypeInfo(
1260 ISWbemLocator *iface,
1261 UINT index,
1262 LCID lcid,
1263 ITypeInfo **info )
1264 {
1265 struct locator *locator = impl_from_ISWbemLocator( iface );
1266 TRACE( "%p, %u, %u, %p\n", locator, index, lcid, info );
1267
1268 return get_typeinfo( ISWbemLocator_tid, info );
1269 }
1270
1271 static HRESULT WINAPI locator_GetIDsOfNames(
1272 ISWbemLocator *iface,
1273 REFIID riid,
1274 LPOLESTR *names,
1275 UINT count,
1276 LCID lcid,
1277 DISPID *dispid )
1278 {
1279 struct locator *locator = impl_from_ISWbemLocator( iface );
1280 ITypeInfo *typeinfo;
1281 HRESULT hr;
1282
1283 TRACE( "%p, %s, %p, %u, %u, %p\n", locator, debugstr_guid(riid), names, count, lcid, dispid );
1284
1285 if (!names || !count || !dispid) return E_INVALIDARG;
1286
1287 hr = get_typeinfo( ISWbemLocator_tid, &typeinfo );
1288 if (SUCCEEDED(hr))
1289 {
1290 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
1291 ITypeInfo_Release( typeinfo );
1292 }
1293 return hr;
1294 }
1295
1296 static HRESULT WINAPI locator_Invoke(
1297 ISWbemLocator *iface,
1298 DISPID member,
1299 REFIID riid,
1300 LCID lcid,
1301 WORD flags,
1302 DISPPARAMS *params,
1303 VARIANT *result,
1304 EXCEPINFO *excep_info,
1305 UINT *arg_err )
1306 {
1307 struct locator *locator = impl_from_ISWbemLocator( iface );
1308 ITypeInfo *typeinfo;
1309 HRESULT hr;
1310
1311 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", locator, member, debugstr_guid(riid),
1312 lcid, flags, params, result, excep_info, arg_err );
1313
1314 hr = get_typeinfo( ISWbemLocator_tid, &typeinfo );
1315 if (SUCCEEDED(hr))
1316 {
1317 hr = ITypeInfo_Invoke( typeinfo, &locator->ISWbemLocator_iface, member, flags,
1318 params, result, excep_info, arg_err );
1319 ITypeInfo_Release( typeinfo );
1320 }
1321 return hr;
1322 }
1323
1324 static BSTR build_resource_string( BSTR server, BSTR namespace )
1325 {
1326 static const WCHAR defaultW[] = {'r','o','o','t','\\','d','e','f','a','u','l','t',0};
1327 ULONG len, len_server = 0, len_namespace = 0;
1328 BSTR ret;
1329
1330 if (server && *server) len_server = strlenW( server );
1331 else len_server = 1;
1332 if (namespace && *namespace) len_namespace = strlenW( namespace );
1333 else len_namespace = sizeof(defaultW) / sizeof(defaultW[0]) - 1;
1334
1335 if (!(ret = SysAllocStringLen( NULL, 2 + len_server + 1 + len_namespace ))) return NULL;
1336
1337 ret[0] = ret[1] = '\\';
1338 if (server && *server) strcpyW( ret + 2, server );
1339 else ret[2] = '.';
1340
1341 len = len_server + 2;
1342 ret[len++] = '\\';
1343
1344 if (namespace && *namespace) strcpyW( ret + len, namespace );
1345 else strcpyW( ret + len, defaultW );
1346 return ret;
1347 }
1348
1349 static HRESULT WINAPI locator_ConnectServer(
1350 ISWbemLocator *iface,
1351 BSTR strServer,
1352 BSTR strNamespace,
1353 BSTR strUser,
1354 BSTR strPassword,
1355 BSTR strLocale,
1356 BSTR strAuthority,
1357 LONG iSecurityFlags,
1358 IDispatch *objWbemNamedValueSet,
1359 ISWbemServices **objWbemServices )
1360 {
1361 struct locator *locator = impl_from_ISWbemLocator( iface );
1362 IWbemServices *services;
1363 BSTR resource;
1364 HRESULT hr;
1365
1366 TRACE( "%p, %s, %s, %s, %p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strServer),
1367 debugstr_w(strNamespace), debugstr_w(strUser), strPassword, debugstr_w(strLocale),
1368 debugstr_w(strAuthority), iSecurityFlags, objWbemNamedValueSet, objWbemServices );
1369
1370 if (objWbemNamedValueSet) FIXME( "context not supported\n" );
1371
1372 if (!locator->locator)
1373 {
1374 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
1375 (void **)&locator->locator );
1376 if (hr != S_OK) return hr;
1377 }
1378
1379 if (!(resource = build_resource_string( strServer, strNamespace ))) return E_OUTOFMEMORY;
1380 hr = IWbemLocator_ConnectServer( locator->locator, resource, strUser, strPassword, strLocale,
1381 iSecurityFlags, strAuthority, NULL, &services );
1382 SysFreeString( resource );
1383 if (hr != S_OK) return hr;
1384
1385 hr = SWbemServices_create( services, objWbemServices );
1386 IWbemServices_Release( services );
1387 return hr;
1388 }
1389
1390 static HRESULT WINAPI locator_get_Security_(
1391 ISWbemLocator *iface,
1392 ISWbemSecurity **objWbemSecurity )
1393 {
1394 TRACE( "%p, %p\n", iface, objWbemSecurity );
1395
1396 if (!objWbemSecurity)
1397 return E_INVALIDARG;
1398
1399 return ISWbemSecurity_create( objWbemSecurity );
1400 }
1401
1402 static const ISWbemLocatorVtbl locator_vtbl =
1403 {
1404 locator_QueryInterface,
1405 locator_AddRef,
1406 locator_Release,
1407 locator_GetTypeInfoCount,
1408 locator_GetTypeInfo,
1409 locator_GetIDsOfNames,
1410 locator_Invoke,
1411 locator_ConnectServer,
1412 locator_get_Security_
1413 };
1414
1415 HRESULT SWbemLocator_create( void **obj )
1416 {
1417 struct locator *locator;
1418
1419 TRACE( "%p\n", obj );
1420
1421 if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY;
1422 locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl;
1423 locator->refs = 1;
1424 locator->locator = NULL;
1425
1426 *obj = &locator->ISWbemLocator_iface;
1427 TRACE( "returning iface %p\n", *obj );
1428 return S_OK;
1429 }
1430
1431 struct security
1432 {
1433 ISWbemSecurity ISWbemSecurity_iface;
1434 LONG refs;
1435 WbemImpersonationLevelEnum implevel;
1436 WbemAuthenticationLevelEnum authlevel;
1437 };
1438
1439 static inline struct security *impl_from_ISWbemSecurity( ISWbemSecurity *iface )
1440 {
1441 return CONTAINING_RECORD( iface, struct security, ISWbemSecurity_iface );
1442 }
1443
1444 static ULONG WINAPI security_AddRef(
1445 ISWbemSecurity *iface )
1446 {
1447 struct security *security = impl_from_ISWbemSecurity( iface );
1448 return InterlockedIncrement( &security->refs );
1449 }
1450
1451 static ULONG WINAPI security_Release(
1452 ISWbemSecurity *iface )
1453 {
1454 struct security *security = impl_from_ISWbemSecurity( iface );
1455 LONG refs = InterlockedDecrement( &security->refs );
1456 if (!refs)
1457 {
1458 TRACE( "destroying %p\n", security );
1459 heap_free( security );
1460 }
1461 return refs;
1462 }
1463
1464 static HRESULT WINAPI security_QueryInterface(
1465 ISWbemSecurity *iface,
1466 REFIID riid,
1467 void **ppvObject )
1468 {
1469 struct security *security = impl_from_ISWbemSecurity( iface );
1470 TRACE( "%p, %s, %p\n", security, debugstr_guid( riid ), ppvObject );
1471
1472 if (IsEqualGUID( riid, &IID_ISWbemSecurity ) ||
1473 IsEqualGUID( riid, &IID_IDispatch ) ||
1474 IsEqualGUID( riid, &IID_IUnknown ))
1475 {
1476 *ppvObject = iface;
1477 }
1478 else
1479 {
1480 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
1481 return E_NOINTERFACE;
1482 }
1483 ISWbemSecurity_AddRef( iface );
1484 return S_OK;
1485 }
1486
1487 static HRESULT WINAPI security_GetTypeInfoCount(
1488 ISWbemSecurity *iface,
1489 UINT *count )
1490 {
1491 struct security *security = impl_from_ISWbemSecurity( iface );
1492 TRACE( "%p, %p\n", security, count );
1493
1494 *count = 1;
1495 return S_OK;
1496 }
1497
1498 static HRESULT WINAPI security_GetTypeInfo(
1499 ISWbemSecurity *iface,
1500 UINT index,
1501 LCID lcid,
1502 ITypeInfo **info )
1503 {
1504 struct security *security = impl_from_ISWbemSecurity( iface );
1505 TRACE( "%p, %u, %u, %p\n", security, index, lcid, info );
1506
1507 return get_typeinfo( ISWbemSecurity_tid, info );
1508 }
1509
1510 static HRESULT WINAPI security_GetIDsOfNames(
1511 ISWbemSecurity *iface,
1512 REFIID riid,
1513 LPOLESTR *names,
1514 UINT count,
1515 LCID lcid,
1516 DISPID *dispid )
1517 {
1518 struct security *security = impl_from_ISWbemSecurity( iface );
1519 ITypeInfo *typeinfo;
1520 HRESULT hr;
1521
1522 TRACE( "%p, %s, %p, %u, %u, %p\n", security, debugstr_guid(riid), names, count, lcid, dispid );
1523
1524 if (!names || !count || !dispid) return E_INVALIDARG;
1525
1526 hr = get_typeinfo( ISWbemSecurity_tid, &typeinfo );
1527 if (SUCCEEDED(hr))
1528 {
1529 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
1530 ITypeInfo_Release( typeinfo );
1531 }
1532 return hr;
1533 }
1534
1535 static HRESULT WINAPI security_Invoke(
1536 ISWbemSecurity *iface,
1537 DISPID member,
1538 REFIID riid,
1539 LCID lcid,
1540 WORD flags,
1541 DISPPARAMS *params,
1542 VARIANT *result,
1543 EXCEPINFO *excep_info,
1544 UINT *arg_err )
1545 {
1546 struct security *security = impl_from_ISWbemSecurity( iface );
1547 ITypeInfo *typeinfo;
1548 HRESULT hr;
1549
1550 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", security, member, debugstr_guid(riid),
1551 lcid, flags, params, result, excep_info, arg_err );
1552
1553 hr = get_typeinfo( ISWbemSecurity_tid, &typeinfo );
1554 if (SUCCEEDED(hr))
1555 {
1556 hr = ITypeInfo_Invoke( typeinfo, &security->ISWbemSecurity_iface, member, flags,
1557 params, result, excep_info, arg_err );
1558 ITypeInfo_Release( typeinfo );
1559 }
1560 return hr;
1561 }
1562
1563 static HRESULT WINAPI security_get_ImpersonationLevel_(
1564 ISWbemSecurity *iface,
1565 WbemImpersonationLevelEnum *impersonation_level )
1566 {
1567 struct security *security = impl_from_ISWbemSecurity( iface );
1568 FIXME( "%p, %p: stub\n", security, impersonation_level );
1569
1570 if (!impersonation_level)
1571 return E_INVALIDARG;
1572
1573 *impersonation_level = security->implevel;
1574 return S_OK;
1575 }
1576
1577 static HRESULT WINAPI security_put_ImpersonationLevel_(
1578 ISWbemSecurity *iface,
1579 WbemImpersonationLevelEnum impersonation_level )
1580 {
1581 struct security *security = impl_from_ISWbemSecurity( iface );
1582 FIXME( "%p, %d: stub\n", security, impersonation_level );
1583
1584 security->implevel = impersonation_level;
1585 return S_OK;
1586 }
1587
1588 static HRESULT WINAPI security_get_AuthenticationLevel_(
1589 ISWbemSecurity *iface,
1590 WbemAuthenticationLevelEnum *authentication_level )
1591 {
1592 struct security *security = impl_from_ISWbemSecurity( iface );
1593 FIXME( "%p, %p: stub\n", security, authentication_level );
1594
1595 if (!authentication_level)
1596 return E_INVALIDARG;
1597
1598 *authentication_level = security->authlevel;
1599 return S_OK;
1600 }
1601
1602 static HRESULT WINAPI security_put_AuthenticationLevel_(
1603 ISWbemSecurity *iface,
1604 WbemAuthenticationLevelEnum authentication_level )
1605 {
1606 struct security *security = impl_from_ISWbemSecurity( iface );
1607 FIXME( "%p, %d: stub\n", security, authentication_level );
1608
1609 security->authlevel = authentication_level;
1610 return S_OK;
1611 }
1612
1613 static HRESULT WINAPI security_get_Privileges_(
1614 ISWbemSecurity *iface,
1615 ISWbemPrivilegeSet **privilege_set )
1616 {
1617 struct security *security = impl_from_ISWbemSecurity( iface );
1618 FIXME( "%p, %p: stub\n", security, privilege_set );
1619
1620 if (!privilege_set)
1621 return E_INVALIDARG;
1622
1623 return E_NOTIMPL;
1624 }
1625
1626 static const ISWbemSecurityVtbl security_vtbl =
1627 {
1628 security_QueryInterface,
1629 security_AddRef,
1630 security_Release,
1631 security_GetTypeInfoCount,
1632 security_GetTypeInfo,
1633 security_GetIDsOfNames,
1634 security_Invoke,
1635 security_get_ImpersonationLevel_,
1636 security_put_ImpersonationLevel_,
1637 security_get_AuthenticationLevel_,
1638 security_put_AuthenticationLevel_,
1639 security_get_Privileges_
1640 };
1641
1642 static HRESULT ISWbemSecurity_create( ISWbemSecurity **obj )
1643 {
1644 struct security *security;
1645
1646 TRACE( "%p\n", obj );
1647
1648 if (!(security = heap_alloc( sizeof(*security) ))) return E_OUTOFMEMORY;
1649 security->ISWbemSecurity_iface.lpVtbl = &security_vtbl;
1650 security->refs = 1;
1651 security->implevel = wbemImpersonationLevelAnonymous;
1652 security->authlevel = wbemAuthenticationLevelDefault;
1653
1654 *obj = &security->ISWbemSecurity_iface;
1655 TRACE( "returning iface %p\n", *obj );
1656 return S_OK;
1657 }