mshtml: Keep reference in node returned from get_node.
[wine] / dlls / wbemprox / class.c
1 /*
2  * Copyright 2012 Hans Leidekker for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #define COBJMACROS
20
21 #include "config.h"
22 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "objbase.h"
27 #include "wbemcli.h"
28
29 #include "wine/debug.h"
30 #include "wbemprox_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
33
34 struct enum_class_object
35 {
36     IEnumWbemClassObject IEnumWbemClassObject_iface;
37     LONG refs;
38     struct query *query;
39 };
40
41 static inline struct enum_class_object *impl_from_IEnumWbemClassObject(
42     IEnumWbemClassObject *iface )
43 {
44     return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface);
45 }
46
47 static ULONG WINAPI enum_class_object_AddRef(
48     IEnumWbemClassObject *iface )
49 {
50     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
51     return InterlockedIncrement( &ec->refs );
52 }
53
54 static ULONG WINAPI enum_class_object_Release(
55     IEnumWbemClassObject *iface )
56 {
57     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
58     LONG refs = InterlockedDecrement( &ec->refs );
59     if (!refs)
60     {
61         TRACE("destroying %p\n", ec);
62         free_query( ec->query );
63         heap_free( ec );
64     }
65     return refs;
66 }
67
68 static HRESULT WINAPI enum_class_object_QueryInterface(
69     IEnumWbemClassObject *iface,
70     REFIID riid,
71     void **ppvObject )
72 {
73     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
74
75     TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject );
76
77     if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) ||
78          IsEqualGUID( riid, &IID_IUnknown ) )
79     {
80         *ppvObject = ec;
81     }
82     else
83     {
84         FIXME("interface %s not implemented\n", debugstr_guid(riid));
85         return E_NOINTERFACE;
86     }
87     IEnumWbemClassObject_AddRef( iface );
88     return S_OK;
89 }
90
91 static HRESULT WINAPI enum_class_object_Reset(
92     IEnumWbemClassObject *iface )
93 {
94     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
95     struct view *view = ec->query->view;
96
97     TRACE("%p\n", iface);
98
99     view->index = 0;
100     return WBEM_S_NO_ERROR;
101 }
102
103 static HRESULT WINAPI enum_class_object_Next(
104     IEnumWbemClassObject *iface,
105     LONG lTimeout,
106     ULONG uCount,
107     IWbemClassObject **apObjects,
108     ULONG *puReturned )
109 {
110     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
111     struct view *view = ec->query->view;
112     HRESULT hr;
113
114     TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
115
116     if (!uCount) return WBEM_S_FALSE;
117     if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER;
118     if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
119
120     *puReturned = 0;
121     if (view->index + uCount > view->count) return WBEM_S_FALSE;
122
123     hr = WbemClassObject_create( NULL, iface, view->index, (void **)apObjects );
124     if (hr != S_OK) return hr;
125
126     view->index++;
127     *puReturned = 1;
128     if (view->index == view->count) return WBEM_S_FALSE;
129     if (uCount > 1) return WBEM_S_TIMEDOUT;
130     return WBEM_S_NO_ERROR;
131 }
132
133 static HRESULT WINAPI enum_class_object_NextAsync(
134     IEnumWbemClassObject *iface,
135     ULONG uCount,
136     IWbemObjectSink *pSink )
137 {
138     FIXME("%p, %u, %p\n", iface, uCount, pSink);
139     return E_NOTIMPL;
140 }
141
142 static HRESULT WINAPI enum_class_object_Clone(
143     IEnumWbemClassObject *iface,
144     IEnumWbemClassObject **ppEnum )
145 {
146     FIXME("%p, %p\n", iface, ppEnum);
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI enum_class_object_Skip(
151     IEnumWbemClassObject *iface,
152     LONG lTimeout,
153     ULONG nCount )
154 {
155     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
156     struct view *view = ec->query->view;
157
158     TRACE("%p, %d, %u\n", iface, lTimeout, nCount);
159
160     if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
161
162     if (view->index + nCount >= view->count)
163     {
164         view->index = view->count - 1;
165         return WBEM_S_FALSE;
166     }
167     view->index += nCount;
168     return WBEM_S_NO_ERROR;
169 }
170
171 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
172 {
173     enum_class_object_QueryInterface,
174     enum_class_object_AddRef,
175     enum_class_object_Release,
176     enum_class_object_Reset,
177     enum_class_object_Next,
178     enum_class_object_NextAsync,
179     enum_class_object_Clone,
180     enum_class_object_Skip
181 };
182
183 HRESULT EnumWbemClassObject_create(
184     IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj )
185 {
186     struct enum_class_object *ec;
187
188     TRACE("%p, %p\n", pUnkOuter, ppObj);
189
190     ec = heap_alloc( sizeof(*ec) );
191     if (!ec) return E_OUTOFMEMORY;
192
193     ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl;
194     ec->refs  = 1;
195     ec->query = query;
196
197     *ppObj = &ec->IEnumWbemClassObject_iface;
198
199     TRACE("returning iface %p\n", *ppObj);
200     return S_OK;
201 }
202
203 struct class_object
204 {
205     IWbemClassObject IWbemClassObject_iface;
206     LONG refs;
207     IEnumWbemClassObject *iter;
208     UINT index;
209 };
210
211 static inline struct class_object *impl_from_IWbemClassObject(
212     IWbemClassObject *iface )
213 {
214     return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
215 }
216
217 static ULONG WINAPI class_object_AddRef(
218     IWbemClassObject *iface )
219 {
220     struct class_object *co = impl_from_IWbemClassObject( iface );
221     return InterlockedIncrement( &co->refs );
222 }
223
224 static ULONG WINAPI class_object_Release(
225     IWbemClassObject *iface )
226 {
227     struct class_object *co = impl_from_IWbemClassObject( iface );
228     LONG refs = InterlockedDecrement( &co->refs );
229     if (!refs)
230     {
231         TRACE("destroying %p\n", co);
232         if (co->iter) IEnumWbemClassObject_Release( co->iter );
233         heap_free( co );
234     }
235     return refs;
236 }
237
238 static HRESULT WINAPI class_object_QueryInterface(
239     IWbemClassObject *iface,
240     REFIID riid,
241     void **ppvObject )
242 {
243     struct class_object *co = impl_from_IWbemClassObject( iface );
244
245     TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
246
247     if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
248          IsEqualGUID( riid, &IID_IUnknown ) )
249     {
250         *ppvObject = co;
251     }
252     else
253     {
254         FIXME("interface %s not implemented\n", debugstr_guid(riid));
255         return E_NOINTERFACE;
256     }
257     IWbemClassObject_AddRef( iface );
258     return S_OK;
259 }
260
261 static HRESULT WINAPI class_object_GetQualifierSet(
262     IWbemClassObject *iface,
263     IWbemQualifierSet **ppQualSet )
264 {
265     FIXME("%p, %p\n", iface, ppQualSet);
266     return E_NOTIMPL;
267 }
268
269 static HRESULT WINAPI class_object_Get(
270     IWbemClassObject *iface,
271     LPCWSTR wszName,
272     LONG lFlags,
273     VARIANT *pVal,
274     CIMTYPE *pType,
275     LONG *plFlavor )
276 {
277     struct class_object *co = impl_from_IWbemClassObject( iface );
278     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
279     struct view *view = ec->query->view;
280
281     TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);
282
283     if (plFlavor)
284     {
285         FIXME("flavor parameter not supported\n");
286         *plFlavor = 0;
287     }
288     return get_propval( view, co->index, wszName, pVal, pType );
289 }
290
291 static HRESULT WINAPI class_object_Put(
292     IWbemClassObject *iface,
293     LPCWSTR wszName,
294     LONG lFlags,
295     VARIANT *pVal,
296     CIMTYPE Type )
297 {
298     FIXME("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
299     return E_NOTIMPL;
300 }
301
302 static HRESULT WINAPI class_object_Delete(
303     IWbemClassObject *iface,
304     LPCWSTR wszName )
305 {
306     FIXME("%p, %s\n", iface, debugstr_w(wszName));
307     return E_NOTIMPL;
308 }
309
310 static HRESULT WINAPI class_object_GetNames(
311     IWbemClassObject *iface,
312     LPCWSTR wszQualifierName,
313     LONG lFlags,
314     VARIANT *pQualifierVal,
315     SAFEARRAY **pNames )
316 {
317     struct class_object *co = impl_from_IWbemClassObject( iface );
318     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
319
320     TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszQualifierName), lFlags, pQualifierVal, pNames);
321
322     if (wszQualifierName || pQualifierVal)
323     {
324         FIXME("qualifier not supported\n");
325         return E_NOTIMPL;
326     }
327     if (lFlags != WBEM_FLAG_ALWAYS)
328     {
329         FIXME("flags %08x not supported\n", lFlags);
330         return E_NOTIMPL;
331     }
332     return get_properties( ec->query->view, pNames );
333 }
334
335 static HRESULT WINAPI class_object_BeginEnumeration(
336     IWbemClassObject *iface,
337     LONG lEnumFlags )
338 {
339     FIXME("%p, %08x\n", iface, lEnumFlags);
340     return E_NOTIMPL;
341 }
342
343 static HRESULT WINAPI class_object_Next(
344     IWbemClassObject *iface,
345     LONG lFlags,
346     BSTR *strName,
347     VARIANT *pVal,
348     CIMTYPE *pType,
349     LONG *plFlavor )
350 {
351     FIXME("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
352     return E_NOTIMPL;
353 }
354
355 static HRESULT WINAPI class_object_EndEnumeration(
356     IWbemClassObject *iface )
357 {
358     FIXME("%p\n", iface);
359     return E_NOTIMPL;
360 }
361
362 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
363     IWbemClassObject *iface,
364     LPCWSTR wszProperty,
365     IWbemQualifierSet **ppQualSet )
366 {
367     FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
368     return E_NOTIMPL;
369 }
370
371 static HRESULT WINAPI class_object_Clone(
372     IWbemClassObject *iface,
373     IWbemClassObject **ppCopy )
374 {
375     FIXME("%p, %p\n", iface, ppCopy);
376     return E_NOTIMPL;
377 }
378
379 static HRESULT WINAPI class_object_GetObjectText(
380     IWbemClassObject *iface,
381     LONG lFlags,
382     BSTR *pstrObjectText )
383 {
384     FIXME("%p, %08x, %p\n", iface, lFlags, pstrObjectText);
385     return E_NOTIMPL;
386 }
387
388 static HRESULT WINAPI class_object_SpawnDerivedClass(
389     IWbemClassObject *iface,
390     LONG lFlags,
391     IWbemClassObject **ppNewClass )
392 {
393     FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
394     return E_NOTIMPL;
395 }
396
397 static HRESULT WINAPI class_object_SpawnInstance(
398     IWbemClassObject *iface,
399     LONG lFlags,
400     IWbemClassObject **ppNewInstance )
401 {
402     FIXME("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI class_object_CompareTo(
407     IWbemClassObject *iface,
408     LONG lFlags,
409     IWbemClassObject *pCompareTo )
410 {
411     FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
412     return E_NOTIMPL;
413 }
414
415 static HRESULT WINAPI class_object_GetPropertyOrigin(
416     IWbemClassObject *iface,
417     LPCWSTR wszName,
418     BSTR *pstrClassName )
419 {
420     FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
421     return E_NOTIMPL;
422 }
423
424 static HRESULT WINAPI class_object_InheritsFrom(
425     IWbemClassObject *iface,
426     LPCWSTR strAncestor )
427 {
428     FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
429     return E_NOTIMPL;
430 }
431
432 static HRESULT WINAPI class_object_GetMethod(
433     IWbemClassObject *iface,
434     LPCWSTR wszName,
435     LONG lFlags,
436     IWbemClassObject **ppInSignature,
437     IWbemClassObject **ppOutSignature )
438 {
439     FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
440     return E_NOTIMPL;
441 }
442
443 static HRESULT WINAPI class_object_PutMethod(
444     IWbemClassObject *iface,
445     LPCWSTR wszName,
446     LONG lFlags,
447     IWbemClassObject *pInSignature,
448     IWbemClassObject *pOutSignature )
449 {
450     FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
451     return E_NOTIMPL;
452 }
453
454 static HRESULT WINAPI class_object_DeleteMethod(
455     IWbemClassObject *iface,
456     LPCWSTR wszName )
457 {
458     FIXME("%p, %s\n", iface, debugstr_w(wszName));
459     return E_NOTIMPL;
460 }
461
462 static HRESULT WINAPI class_object_BeginMethodEnumeration(
463     IWbemClassObject *iface,
464     LONG lEnumFlags)
465 {
466     FIXME("%p, %08x\n", iface, lEnumFlags);
467     return E_NOTIMPL;
468 }
469
470 static HRESULT WINAPI class_object_NextMethod(
471     IWbemClassObject *iface,
472     LONG lFlags,
473     BSTR *pstrName,
474     IWbemClassObject **ppInSignature,
475     IWbemClassObject **ppOutSignature)
476 {
477     FIXME("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
478     return E_NOTIMPL;
479 }
480
481 static HRESULT WINAPI class_object_EndMethodEnumeration(
482     IWbemClassObject *iface )
483 {
484     FIXME("%p\n", iface);
485     return E_NOTIMPL;
486 }
487
488 static HRESULT WINAPI class_object_GetMethodQualifierSet(
489     IWbemClassObject *iface,
490     LPCWSTR wszMethod,
491     IWbemQualifierSet **ppQualSet)
492 {
493     FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
494     return E_NOTIMPL;
495 }
496
497 static HRESULT WINAPI class_object_GetMethodOrigin(
498     IWbemClassObject *iface,
499     LPCWSTR wszMethodName,
500     BSTR *pstrClassName)
501 {
502     FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
503     return E_NOTIMPL;
504 }
505
506 static const IWbemClassObjectVtbl class_object_vtbl =
507 {
508     class_object_QueryInterface,
509     class_object_AddRef,
510     class_object_Release,
511     class_object_GetQualifierSet,
512     class_object_Get,
513     class_object_Put,
514     class_object_Delete,
515     class_object_GetNames,
516     class_object_BeginEnumeration,
517     class_object_Next,
518     class_object_EndEnumeration,
519     class_object_GetPropertyQualifierSet,
520     class_object_Clone,
521     class_object_GetObjectText,
522     class_object_SpawnDerivedClass,
523     class_object_SpawnInstance,
524     class_object_CompareTo,
525     class_object_GetPropertyOrigin,
526     class_object_InheritsFrom,
527     class_object_GetMethod,
528     class_object_PutMethod,
529     class_object_DeleteMethod,
530     class_object_BeginMethodEnumeration,
531     class_object_NextMethod,
532     class_object_EndMethodEnumeration,
533     class_object_GetMethodQualifierSet,
534     class_object_GetMethodOrigin
535 };
536
537 HRESULT WbemClassObject_create(
538     IUnknown *pUnkOuter, IEnumWbemClassObject *iter, UINT index, LPVOID *ppObj )
539 {
540     struct class_object *co;
541
542     TRACE("%p, %p\n", pUnkOuter, ppObj);
543
544     co = heap_alloc( sizeof(*co) );
545     if (!co) return E_OUTOFMEMORY;
546
547     co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
548     co->refs  = 1;
549     co->iter  = iter;
550     co->index = index;
551     if (iter) IEnumWbemClassObject_AddRef( iter );
552
553     *ppObj = &co->IWbemClassObject_iface;
554
555     TRACE("returning iface %p\n", *ppObj);
556     return S_OK;
557 }