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