opengl32/tests: Do not pass NULL attrib list to wglCreatePBufferARB.
[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     UINT index;
40 };
41
42 static inline struct enum_class_object *impl_from_IEnumWbemClassObject(
43     IEnumWbemClassObject *iface )
44 {
45     return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface);
46 }
47
48 static ULONG WINAPI enum_class_object_AddRef(
49     IEnumWbemClassObject *iface )
50 {
51     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
52     return InterlockedIncrement( &ec->refs );
53 }
54
55 static ULONG WINAPI enum_class_object_Release(
56     IEnumWbemClassObject *iface )
57 {
58     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
59     LONG refs = InterlockedDecrement( &ec->refs );
60     if (!refs)
61     {
62         TRACE("destroying %p\n", ec);
63         release_query( ec->query );
64         heap_free( ec );
65     }
66     return refs;
67 }
68
69 static HRESULT WINAPI enum_class_object_QueryInterface(
70     IEnumWbemClassObject *iface,
71     REFIID riid,
72     void **ppvObject )
73 {
74     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
75
76     TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject );
77
78     if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) ||
79          IsEqualGUID( riid, &IID_IUnknown ) )
80     {
81         *ppvObject = ec;
82     }
83     else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
84     {
85         *ppvObject = &client_security;
86         return S_OK;
87     }
88     else
89     {
90         FIXME("interface %s not implemented\n", debugstr_guid(riid));
91         return E_NOINTERFACE;
92     }
93     IEnumWbemClassObject_AddRef( iface );
94     return S_OK;
95 }
96
97 static HRESULT WINAPI enum_class_object_Reset(
98     IEnumWbemClassObject *iface )
99 {
100     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
101
102     TRACE("%p\n", iface);
103
104     ec->index = 0;
105     return WBEM_S_NO_ERROR;
106 }
107
108 static HRESULT WINAPI enum_class_object_Next(
109     IEnumWbemClassObject *iface,
110     LONG lTimeout,
111     ULONG uCount,
112     IWbemClassObject **apObjects,
113     ULONG *puReturned )
114 {
115     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
116     struct view *view = ec->query->view;
117     HRESULT hr;
118
119     TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
120
121     if (!uCount) return WBEM_S_FALSE;
122     if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER;
123     if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
124
125     *puReturned = 0;
126     if (ec->index + uCount > view->count) return WBEM_S_FALSE;
127
128     hr = create_class_object( view->table->name, iface, ec->index, apObjects );
129     if (hr != S_OK) return hr;
130
131     ec->index++;
132     *puReturned = 1;
133     if (ec->index == view->count) return WBEM_S_FALSE;
134     if (uCount > 1) return WBEM_S_TIMEDOUT;
135     return WBEM_S_NO_ERROR;
136 }
137
138 static HRESULT WINAPI enum_class_object_NextAsync(
139     IEnumWbemClassObject *iface,
140     ULONG uCount,
141     IWbemObjectSink *pSink )
142 {
143     FIXME("%p, %u, %p\n", iface, uCount, pSink);
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI enum_class_object_Clone(
148     IEnumWbemClassObject *iface,
149     IEnumWbemClassObject **ppEnum )
150 {
151     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
152
153     TRACE("%p, %p\n", iface, ppEnum);
154
155     return EnumWbemClassObject_create( NULL, ec->query, (void **)ppEnum );
156 }
157
158 static HRESULT WINAPI enum_class_object_Skip(
159     IEnumWbemClassObject *iface,
160     LONG lTimeout,
161     ULONG nCount )
162 {
163     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
164     struct view *view = ec->query->view;
165
166     TRACE("%p, %d, %u\n", iface, lTimeout, nCount);
167
168     if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
169
170     if (!view->count) return WBEM_S_FALSE;
171
172     if (nCount > view->count - ec->index)
173     {
174         ec->index = view->count - 1;
175         return WBEM_S_FALSE;
176     }
177     ec->index += nCount;
178     return WBEM_S_NO_ERROR;
179 }
180
181 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
182 {
183     enum_class_object_QueryInterface,
184     enum_class_object_AddRef,
185     enum_class_object_Release,
186     enum_class_object_Reset,
187     enum_class_object_Next,
188     enum_class_object_NextAsync,
189     enum_class_object_Clone,
190     enum_class_object_Skip
191 };
192
193 HRESULT EnumWbemClassObject_create(
194     IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj )
195 {
196     struct enum_class_object *ec;
197
198     TRACE("%p, %p\n", pUnkOuter, ppObj);
199
200     ec = heap_alloc( sizeof(*ec) );
201     if (!ec) return E_OUTOFMEMORY;
202
203     ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl;
204     ec->refs  = 1;
205     ec->query = query;
206     addref_query( query );
207     ec->index = 0;
208
209     *ppObj = &ec->IEnumWbemClassObject_iface;
210
211     TRACE("returning iface %p\n", *ppObj);
212     return S_OK;
213 }
214
215 struct class_object
216 {
217     IWbemClassObject IWbemClassObject_iface;
218     LONG refs;
219     WCHAR *name;
220     IEnumWbemClassObject *iter;
221     UINT index;
222     UINT index_method;
223     UINT index_property;
224 };
225
226 static inline struct class_object *impl_from_IWbemClassObject(
227     IWbemClassObject *iface )
228 {
229     return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
230 }
231
232 static ULONG WINAPI class_object_AddRef(
233     IWbemClassObject *iface )
234 {
235     struct class_object *co = impl_from_IWbemClassObject( iface );
236     return InterlockedIncrement( &co->refs );
237 }
238
239 static ULONG WINAPI class_object_Release(
240     IWbemClassObject *iface )
241 {
242     struct class_object *co = impl_from_IWbemClassObject( iface );
243     LONG refs = InterlockedDecrement( &co->refs );
244     if (!refs)
245     {
246         TRACE("destroying %p\n", co);
247         if (co->iter) IEnumWbemClassObject_Release( co->iter );
248         heap_free( co->name );
249         heap_free( co );
250     }
251     return refs;
252 }
253
254 static HRESULT WINAPI class_object_QueryInterface(
255     IWbemClassObject *iface,
256     REFIID riid,
257     void **ppvObject )
258 {
259     struct class_object *co = impl_from_IWbemClassObject( iface );
260
261     TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
262
263     if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
264          IsEqualGUID( riid, &IID_IUnknown ) )
265     {
266         *ppvObject = co;
267     }
268     else
269     {
270         FIXME("interface %s not implemented\n", debugstr_guid(riid));
271         return E_NOINTERFACE;
272     }
273     IWbemClassObject_AddRef( iface );
274     return S_OK;
275 }
276
277 static HRESULT WINAPI class_object_GetQualifierSet(
278     IWbemClassObject *iface,
279     IWbemQualifierSet **ppQualSet )
280 {
281     FIXME("%p, %p\n", iface, ppQualSet);
282     return E_NOTIMPL;
283 }
284
285 static HRESULT WINAPI class_object_Get(
286     IWbemClassObject *iface,
287     LPCWSTR wszName,
288     LONG lFlags,
289     VARIANT *pVal,
290     CIMTYPE *pType,
291     LONG *plFlavor )
292 {
293     struct class_object *co = impl_from_IWbemClassObject( iface );
294     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
295     struct view *view = ec->query->view;
296
297     TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);
298
299     return get_propval( view, co->index, wszName, pVal, pType, plFlavor );
300 }
301
302 static HRESULT WINAPI class_object_Put(
303     IWbemClassObject *iface,
304     LPCWSTR wszName,
305     LONG lFlags,
306     VARIANT *pVal,
307     CIMTYPE Type )
308 {
309     struct class_object *co = impl_from_IWbemClassObject( iface );
310     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
311     struct view *view = ec->query->view;
312
313     TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
314
315     return put_propval( view, co->index, wszName, pVal, Type );
316 }
317
318 static HRESULT WINAPI class_object_Delete(
319     IWbemClassObject *iface,
320     LPCWSTR wszName )
321 {
322     FIXME("%p, %s\n", iface, debugstr_w(wszName));
323     return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI class_object_GetNames(
327     IWbemClassObject *iface,
328     LPCWSTR wszQualifierName,
329     LONG lFlags,
330     VARIANT *pQualifierVal,
331     SAFEARRAY **pNames )
332 {
333     struct class_object *co = impl_from_IWbemClassObject( iface );
334     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
335
336     TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszQualifierName), lFlags, pQualifierVal, pNames);
337
338     if (wszQualifierName || pQualifierVal)
339     {
340         FIXME("qualifier not supported\n");
341         return E_NOTIMPL;
342     }
343     if (lFlags != WBEM_FLAG_ALWAYS)
344     {
345         FIXME("flags %08x not supported\n", lFlags);
346         return E_NOTIMPL;
347     }
348     return get_properties( ec->query->view, pNames );
349 }
350
351 static HRESULT WINAPI class_object_BeginEnumeration(
352     IWbemClassObject *iface,
353     LONG lEnumFlags )
354 {
355     struct class_object *co = impl_from_IWbemClassObject( iface );
356
357     TRACE("%p, %08x\n", iface, lEnumFlags);
358
359     if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
360
361     co->index_property = 0;
362     return S_OK;
363 }
364
365 static HRESULT WINAPI class_object_Next(
366     IWbemClassObject *iface,
367     LONG lFlags,
368     BSTR *strName,
369     VARIANT *pVal,
370     CIMTYPE *pType,
371     LONG *plFlavor )
372 {
373     struct class_object *co = impl_from_IWbemClassObject( iface );
374     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
375     struct view *view = ec->query->view;
376     const WCHAR *property;
377     HRESULT hr;
378
379     TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
380
381     if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA;
382     if (!(*strName = SysAllocString( property ))) return E_OUTOFMEMORY;
383     if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK))
384     {
385         SysFreeString( *strName );
386         return hr;
387     }
388     co->index_property++;
389     return S_OK;
390 }
391
392 static HRESULT WINAPI class_object_EndEnumeration(
393     IWbemClassObject *iface )
394 {
395     struct class_object *co = impl_from_IWbemClassObject( iface );
396
397     TRACE("%p\n", iface);
398
399     co->index_property = 0;
400     return S_OK;
401 }
402
403 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
404     IWbemClassObject *iface,
405     LPCWSTR wszProperty,
406     IWbemQualifierSet **ppQualSet )
407 {
408     FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
409     return E_NOTIMPL;
410 }
411
412 static HRESULT WINAPI class_object_Clone(
413     IWbemClassObject *iface,
414     IWbemClassObject **ppCopy )
415 {
416     FIXME("%p, %p\n", iface, ppCopy);
417     return E_NOTIMPL;
418 }
419
420 static HRESULT WINAPI class_object_GetObjectText(
421     IWbemClassObject *iface,
422     LONG lFlags,
423     BSTR *pstrObjectText )
424 {
425     FIXME("%p, %08x, %p\n", iface, lFlags, pstrObjectText);
426     return E_NOTIMPL;
427 }
428
429 static HRESULT WINAPI class_object_SpawnDerivedClass(
430     IWbemClassObject *iface,
431     LONG lFlags,
432     IWbemClassObject **ppNewClass )
433 {
434     FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
435     return E_NOTIMPL;
436 }
437
438 static HRESULT WINAPI class_object_SpawnInstance(
439     IWbemClassObject *iface,
440     LONG lFlags,
441     IWbemClassObject **ppNewInstance )
442 {
443     FIXME("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
444     return E_NOTIMPL;
445 }
446
447 static HRESULT WINAPI class_object_CompareTo(
448     IWbemClassObject *iface,
449     LONG lFlags,
450     IWbemClassObject *pCompareTo )
451 {
452     FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
453     return E_NOTIMPL;
454 }
455
456 static HRESULT WINAPI class_object_GetPropertyOrigin(
457     IWbemClassObject *iface,
458     LPCWSTR wszName,
459     BSTR *pstrClassName )
460 {
461     FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
462     return E_NOTIMPL;
463 }
464
465 static HRESULT WINAPI class_object_InheritsFrom(
466     IWbemClassObject *iface,
467     LPCWSTR strAncestor )
468 {
469     FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
470     return E_NOTIMPL;
471 }
472
473 static UINT count_instances( IEnumWbemClassObject *iter )
474 {
475     UINT count = 0;
476     while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++;
477     IEnumWbemClassObject_Reset( iter );
478     return count;
479 }
480
481 static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr )
482 {
483     switch (type)
484     {
485     case CIM_SINT16:
486         *(INT16 *)ptr = val;
487         break;
488     case CIM_UINT16:
489         *(UINT16 *)ptr = val;
490         break;
491     case CIM_SINT32:
492         *(INT32 *)ptr = val;
493         break;
494     case CIM_UINT32:
495         *(UINT32 *)ptr = val;
496         break;
497     default:
498         FIXME("unhandled type %u\n", type);
499         break;
500     }
501 }
502
503 static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols,
504                                            struct column **cols, BYTE **data )
505 {
506     static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
507     static const WCHAR typeW[] = {'T','y','p','e',0};
508     static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
509     struct column *columns;
510     BYTE *row;
511     IWbemClassObject *param;
512     VARIANT val;
513     HRESULT hr = E_OUTOFMEMORY;
514     UINT offset = 0;
515     ULONG count;
516     int i = 0;
517
518     count = count_instances( iter );
519     if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
520     if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
521
522     for (;;)
523     {
524         IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &param, &count );
525         if (!count) break;
526
527         hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL );
528         if (hr != S_OK) goto error;
529         columns[i].name = heap_strdupW( V_BSTR( &val ) );
530         VariantClear( &val );
531
532         hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL );
533         if (hr != S_OK) goto error;
534         columns[i].type    = V_UI4( &val );
535         columns[i].vartype = 0;
536
537         hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
538         if (hr != S_OK) goto error;
539         if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
540         offset += get_type_size( columns[i].type );
541
542         IWbemClassObject_Release( param );
543         i++;
544     }
545     *num_cols = i;
546     *cols = columns;
547     *data = row;
548     return S_OK;
549
550 error:
551     for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
552     heap_free( columns );
553     heap_free( row );
554     return hr;
555 }
556
557 static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
558 {
559     HRESULT hr;
560     struct table *table;
561     struct column *columns;
562     UINT num_cols;
563     BYTE *row;
564
565     hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
566     if (hr != S_OK) return hr;
567
568     if (!(table = create_table( name, num_cols, columns, 1, row, NULL )))
569     {
570         free_columns( columns, num_cols );
571         heap_free( row );
572         return E_OUTOFMEMORY;
573     }
574     if (!add_table( table )) free_table( table ); /* already exists */
575     return S_OK;
576 }
577
578 static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
579 {
580     static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
581     static const WCHAR outW[] = {'O','U','T',0};
582     static const WCHAR inW[] = {'I','N',0};
583     UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method );
584     WCHAR *ret;
585
586     if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
587     sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
588     return struprW( ret );
589 }
590
591 static HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
592                                  IWbemClassObject **sig )
593 {
594     static const WCHAR selectW[] =
595         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
596          '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
597          'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
598          'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
599          'D','i','r','e','c','t','i','o','n','%','s',0};
600     static const WCHAR geW[] = {'>','=','0',0};
601     static const WCHAR leW[] = {'<','=','0',0};
602     UINT len = SIZEOF(selectW) + SIZEOF(geW);
603     IEnumWbemClassObject *iter;
604     WCHAR *query, *name;
605     HRESULT hr;
606
607     len += strlenW( class ) + strlenW( method );
608     if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
609     sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
610
611     hr = exec_query( query, &iter );
612     heap_free( query );
613     if (hr != S_OK) return hr;
614
615     if (!(name = build_signature_table_name( class, method, dir )))
616     {
617         IEnumWbemClassObject_Release( iter );
618         return E_OUTOFMEMORY;
619     }
620     hr = create_signature_table( iter, name );
621     IEnumWbemClassObject_Release( iter );
622     if (hr != S_OK)
623     {
624         heap_free( name );
625         return hr;
626     }
627     return get_object( name, sig );
628 }
629
630 static HRESULT WINAPI class_object_GetMethod(
631     IWbemClassObject *iface,
632     LPCWSTR wszName,
633     LONG lFlags,
634     IWbemClassObject **ppInSignature,
635     IWbemClassObject **ppOutSignature )
636 {
637     struct class_object *co = impl_from_IWbemClassObject( iface );
638     HRESULT hr;
639
640     TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
641
642     hr = create_signature( co->name, wszName, PARAM_IN, ppInSignature );
643     if (hr != S_OK) return hr;
644
645     hr = create_signature( co->name, wszName, PARAM_OUT, ppOutSignature );
646     if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
647     return hr;
648 }
649
650 static HRESULT WINAPI class_object_PutMethod(
651     IWbemClassObject *iface,
652     LPCWSTR wszName,
653     LONG lFlags,
654     IWbemClassObject *pInSignature,
655     IWbemClassObject *pOutSignature )
656 {
657     FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
658     return E_NOTIMPL;
659 }
660
661 static HRESULT WINAPI class_object_DeleteMethod(
662     IWbemClassObject *iface,
663     LPCWSTR wszName )
664 {
665     FIXME("%p, %s\n", iface, debugstr_w(wszName));
666     return E_NOTIMPL;
667 }
668
669 static HRESULT WINAPI class_object_BeginMethodEnumeration(
670     IWbemClassObject *iface,
671     LONG lEnumFlags)
672 {
673     struct class_object *co = impl_from_IWbemClassObject( iface );
674
675     TRACE("%p, %08x\n", iface, lEnumFlags);
676
677     if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
678
679     if (co->iter)
680     {
681         WARN("not allowed on instance\n");
682         return WBEM_E_ILLEGAL_OPERATION;
683     }
684     co->index_method = 0;
685     return S_OK;
686 }
687
688 static HRESULT WINAPI class_object_NextMethod(
689     IWbemClassObject *iface,
690     LONG lFlags,
691     BSTR *pstrName,
692     IWbemClassObject **ppInSignature,
693     IWbemClassObject **ppOutSignature)
694 {
695     struct class_object *co = impl_from_IWbemClassObject( iface );
696     const WCHAR *method;
697     HRESULT hr;
698
699     TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
700
701     if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;
702
703     hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
704     if (hr != S_OK) return hr;
705
706     hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
707     if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
708     else
709     {
710         if (!(*pstrName = SysAllocString( method )))
711         {
712             IWbemClassObject_Release( *ppInSignature );
713             IWbemClassObject_Release( *ppOutSignature );
714             return E_OUTOFMEMORY;
715         }
716         co->index_method++;
717     }
718     return hr;
719 }
720
721 static HRESULT WINAPI class_object_EndMethodEnumeration(
722     IWbemClassObject *iface )
723 {
724     struct class_object *co = impl_from_IWbemClassObject( iface );
725
726     TRACE("%p\n", iface);
727
728     co->index_method = 0;
729     return S_OK;
730 }
731
732 static HRESULT WINAPI class_object_GetMethodQualifierSet(
733     IWbemClassObject *iface,
734     LPCWSTR wszMethod,
735     IWbemQualifierSet **ppQualSet)
736 {
737     FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
738     return E_NOTIMPL;
739 }
740
741 static HRESULT WINAPI class_object_GetMethodOrigin(
742     IWbemClassObject *iface,
743     LPCWSTR wszMethodName,
744     BSTR *pstrClassName)
745 {
746     FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
747     return E_NOTIMPL;
748 }
749
750 static const IWbemClassObjectVtbl class_object_vtbl =
751 {
752     class_object_QueryInterface,
753     class_object_AddRef,
754     class_object_Release,
755     class_object_GetQualifierSet,
756     class_object_Get,
757     class_object_Put,
758     class_object_Delete,
759     class_object_GetNames,
760     class_object_BeginEnumeration,
761     class_object_Next,
762     class_object_EndEnumeration,
763     class_object_GetPropertyQualifierSet,
764     class_object_Clone,
765     class_object_GetObjectText,
766     class_object_SpawnDerivedClass,
767     class_object_SpawnInstance,
768     class_object_CompareTo,
769     class_object_GetPropertyOrigin,
770     class_object_InheritsFrom,
771     class_object_GetMethod,
772     class_object_PutMethod,
773     class_object_DeleteMethod,
774     class_object_BeginMethodEnumeration,
775     class_object_NextMethod,
776     class_object_EndMethodEnumeration,
777     class_object_GetMethodQualifierSet,
778     class_object_GetMethodOrigin
779 };
780
781 HRESULT create_class_object(
782     const WCHAR *name, IEnumWbemClassObject *iter, UINT index, IWbemClassObject **obj )
783 {
784     struct class_object *co;
785
786     TRACE("%s, %p\n", debugstr_w(name), obj);
787
788     co = heap_alloc( sizeof(*co) );
789     if (!co) return E_OUTOFMEMORY;
790
791     co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
792     co->refs  = 1;
793     co->name  = heap_strdupW( name );
794     if (!co->name)
795     {
796         heap_free( co );
797         return E_OUTOFMEMORY;
798     }
799     co->iter           = iter;
800     co->index          = index;
801     co->index_method   = 0;
802     co->index_property = 0;
803     if (iter) IEnumWbemClassObject_AddRef( iter );
804
805     *obj = &co->IWbemClassObject_iface;
806
807     TRACE("returning iface %p\n", *obj);
808     return S_OK;
809 }