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