windowscodecs: Add support for color table sort flag to the GIF decoder.
[wine.git] / dlls / wbemprox / class.c
blob5a70e9d62669ff109019a8433d2a13a3e4ff360e
1 /*
2 * Copyright 2012 Hans Leidekker for CodeWeavers
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.
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.
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
19 #define COBJMACROS
21 #include "config.h"
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "objbase.h"
27 #include "wbemcli.h"
29 #include "wine/debug.h"
30 #include "wbemprox_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
34 struct enum_class_object
36 IEnumWbemClassObject IEnumWbemClassObject_iface;
37 LONG refs;
38 struct query *query;
39 UINT index;
42 static inline struct enum_class_object *impl_from_IEnumWbemClassObject(
43 IEnumWbemClassObject *iface )
45 return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface);
48 static ULONG WINAPI enum_class_object_AddRef(
49 IEnumWbemClassObject *iface )
51 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
52 return InterlockedIncrement( &ec->refs );
55 static ULONG WINAPI enum_class_object_Release(
56 IEnumWbemClassObject *iface )
58 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
59 LONG refs = InterlockedDecrement( &ec->refs );
60 if (!refs)
62 TRACE("destroying %p\n", ec);
63 release_query( ec->query );
64 heap_free( ec );
66 return refs;
69 static HRESULT WINAPI enum_class_object_QueryInterface(
70 IEnumWbemClassObject *iface,
71 REFIID riid,
72 void **ppvObject )
74 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
76 TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject );
78 if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) ||
79 IsEqualGUID( riid, &IID_IUnknown ) )
81 *ppvObject = ec;
83 else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
85 *ppvObject = &client_security;
86 return S_OK;
88 else
90 FIXME("interface %s not implemented\n", debugstr_guid(riid));
91 return E_NOINTERFACE;
93 IEnumWbemClassObject_AddRef( iface );
94 return S_OK;
97 static HRESULT WINAPI enum_class_object_Reset(
98 IEnumWbemClassObject *iface )
100 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
102 TRACE("%p\n", iface);
104 ec->index = 0;
105 return WBEM_S_NO_ERROR;
108 static HRESULT WINAPI enum_class_object_Next(
109 IEnumWbemClassObject *iface,
110 LONG lTimeout,
111 ULONG uCount,
112 IWbemClassObject **apObjects,
113 ULONG *puReturned )
115 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
116 struct view *view = ec->query->view;
117 HRESULT hr;
119 TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
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");
125 *puReturned = 0;
126 if (ec->index + uCount > view->count) return WBEM_S_FALSE;
128 hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects );
129 if (hr != S_OK) return hr;
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;
138 static HRESULT WINAPI enum_class_object_NextAsync(
139 IEnumWbemClassObject *iface,
140 ULONG uCount,
141 IWbemObjectSink *pSink )
143 FIXME("%p, %u, %p\n", iface, uCount, pSink);
144 return E_NOTIMPL;
147 static HRESULT WINAPI enum_class_object_Clone(
148 IEnumWbemClassObject *iface,
149 IEnumWbemClassObject **ppEnum )
151 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
153 TRACE("%p, %p\n", iface, ppEnum);
155 return EnumWbemClassObject_create( NULL, ec->query, (void **)ppEnum );
158 static HRESULT WINAPI enum_class_object_Skip(
159 IEnumWbemClassObject *iface,
160 LONG lTimeout,
161 ULONG nCount )
163 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
164 struct view *view = ec->query->view;
166 TRACE("%p, %d, %u\n", iface, lTimeout, nCount);
168 if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n");
170 if (!view->count) return WBEM_S_FALSE;
172 if (nCount > view->count - ec->index)
174 ec->index = view->count - 1;
175 return WBEM_S_FALSE;
177 ec->index += nCount;
178 return WBEM_S_NO_ERROR;
181 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
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
193 HRESULT EnumWbemClassObject_create(
194 IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj )
196 struct enum_class_object *ec;
198 TRACE("%p, %p\n", pUnkOuter, ppObj);
200 ec = heap_alloc( sizeof(*ec) );
201 if (!ec) return E_OUTOFMEMORY;
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;
209 *ppObj = &ec->IEnumWbemClassObject_iface;
211 TRACE("returning iface %p\n", *ppObj);
212 return S_OK;
215 static struct record *create_record( const struct column *columns, UINT num_cols )
217 UINT i;
218 struct record *record;
220 if (!(record = heap_alloc( sizeof(struct record) ))) return NULL;
221 if (!(record->fields = heap_alloc( num_cols * sizeof(struct field) )))
223 heap_free( record );
224 return NULL;
226 for (i = 0; i < num_cols; i++)
228 record->fields[i].type = columns[i].type;
229 record->fields[i].u.ival = 0;
231 record->count = num_cols;
232 return record;
235 static void destroy_record( struct record *record )
237 UINT i;
239 if (!record) return;
240 for (i = 0; i < record->count; i++)
242 if (record->fields[i].type == CIM_STRING || record->fields[i].type == CIM_DATETIME)
243 heap_free( record->fields[i].u.sval );
245 heap_free( record->fields );
246 heap_free( record );
249 struct class_object
251 IWbemClassObject IWbemClassObject_iface;
252 LONG refs;
253 WCHAR *name;
254 IEnumWbemClassObject *iter;
255 UINT index;
256 UINT index_method;
257 UINT index_property;
258 struct record *record; /* uncommitted instance */
261 static inline struct class_object *impl_from_IWbemClassObject(
262 IWbemClassObject *iface )
264 return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
267 static ULONG WINAPI class_object_AddRef(
268 IWbemClassObject *iface )
270 struct class_object *co = impl_from_IWbemClassObject( iface );
271 return InterlockedIncrement( &co->refs );
274 static ULONG WINAPI class_object_Release(
275 IWbemClassObject *iface )
277 struct class_object *co = impl_from_IWbemClassObject( iface );
278 LONG refs = InterlockedDecrement( &co->refs );
279 if (!refs)
281 TRACE("destroying %p\n", co);
282 if (co->iter) IEnumWbemClassObject_Release( co->iter );
283 destroy_record( co->record );
284 heap_free( co->name );
285 heap_free( co );
287 return refs;
290 static HRESULT WINAPI class_object_QueryInterface(
291 IWbemClassObject *iface,
292 REFIID riid,
293 void **ppvObject )
295 struct class_object *co = impl_from_IWbemClassObject( iface );
297 TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
299 if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
300 IsEqualGUID( riid, &IID_IUnknown ) )
302 *ppvObject = co;
304 else if (IsEqualGUID( riid, &IID_IClientSecurity ))
306 *ppvObject = &client_security;
307 return S_OK;
309 else
311 FIXME("interface %s not implemented\n", debugstr_guid(riid));
312 return E_NOINTERFACE;
314 IWbemClassObject_AddRef( iface );
315 return S_OK;
318 static HRESULT WINAPI class_object_GetQualifierSet(
319 IWbemClassObject *iface,
320 IWbemQualifierSet **ppQualSet )
322 FIXME("%p, %p\n", iface, ppQualSet);
323 return E_NOTIMPL;
326 static HRESULT WINAPI class_object_Get(
327 IWbemClassObject *iface,
328 LPCWSTR wszName,
329 LONG lFlags,
330 VARIANT *pVal,
331 CIMTYPE *pType,
332 LONG *plFlavor )
334 struct class_object *co = impl_from_IWbemClassObject( iface );
335 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
336 struct view *view = ec->query->view;
338 TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);
340 return get_propval( view, co->index, wszName, pVal, pType, plFlavor );
343 static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var )
345 LONGLONG val;
346 CIMTYPE type;
347 HRESULT hr;
349 if ((hr = variant_to_longlong( var, &val, &type )) != S_OK) return hr;
350 if (type != record->fields[index].type) return WBEM_E_TYPE_MISMATCH;
352 switch (type)
354 case CIM_STRING:
355 case CIM_DATETIME:
356 record->fields[index].u.sval = (WCHAR *)(INT_PTR)val;
357 return S_OK;
358 case CIM_SINT16:
359 case CIM_UINT16:
360 case CIM_SINT32:
361 case CIM_UINT32:
362 record->fields[index].u.ival = val;
363 return S_OK;
364 default:
365 FIXME("unhandled type %u\n", type);
366 break;
368 return WBEM_E_INVALID_PARAMETER;
371 static HRESULT WINAPI class_object_Put(
372 IWbemClassObject *iface,
373 LPCWSTR wszName,
374 LONG lFlags,
375 VARIANT *pVal,
376 CIMTYPE Type )
378 struct class_object *co = impl_from_IWbemClassObject( iface );
379 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
381 TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
383 if (co->record)
385 struct table *table = get_table( co->name );
386 UINT index;
387 HRESULT hr;
389 if ((hr = get_column_index( table, wszName, &index )) != S_OK) return hr;
390 return record_set_value( co->record, index, pVal );
392 return put_propval( ec->query->view, co->index, wszName, pVal, Type );
395 static HRESULT WINAPI class_object_Delete(
396 IWbemClassObject *iface,
397 LPCWSTR wszName )
399 FIXME("%p, %s\n", iface, debugstr_w(wszName));
400 return E_NOTIMPL;
403 static HRESULT WINAPI class_object_GetNames(
404 IWbemClassObject *iface,
405 LPCWSTR wszQualifierName,
406 LONG lFlags,
407 VARIANT *pQualifierVal,
408 SAFEARRAY **pNames )
410 struct class_object *co = impl_from_IWbemClassObject( iface );
411 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
413 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszQualifierName), lFlags, pQualifierVal, pNames);
415 if (wszQualifierName || pQualifierVal)
417 FIXME("qualifier not supported\n");
418 return E_NOTIMPL;
420 if (lFlags != WBEM_FLAG_ALWAYS)
422 FIXME("flags %08x not supported\n", lFlags);
423 return E_NOTIMPL;
425 return get_properties( ec->query->view, pNames );
428 static HRESULT WINAPI class_object_BeginEnumeration(
429 IWbemClassObject *iface,
430 LONG lEnumFlags )
432 struct class_object *co = impl_from_IWbemClassObject( iface );
434 TRACE("%p, %08x\n", iface, lEnumFlags);
436 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
438 co->index_property = 0;
439 return S_OK;
442 static HRESULT WINAPI class_object_Next(
443 IWbemClassObject *iface,
444 LONG lFlags,
445 BSTR *strName,
446 VARIANT *pVal,
447 CIMTYPE *pType,
448 LONG *plFlavor )
450 struct class_object *co = impl_from_IWbemClassObject( iface );
451 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
452 struct view *view = ec->query->view;
453 const WCHAR *property;
454 HRESULT hr;
456 TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
458 if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA;
459 if (!(*strName = SysAllocString( property ))) return E_OUTOFMEMORY;
460 if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK))
462 SysFreeString( *strName );
463 return hr;
465 co->index_property++;
466 return S_OK;
469 static HRESULT WINAPI class_object_EndEnumeration(
470 IWbemClassObject *iface )
472 struct class_object *co = impl_from_IWbemClassObject( iface );
474 TRACE("%p\n", iface);
476 co->index_property = 0;
477 return S_OK;
480 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
481 IWbemClassObject *iface,
482 LPCWSTR wszProperty,
483 IWbemQualifierSet **ppQualSet )
485 FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
486 return E_NOTIMPL;
489 static HRESULT WINAPI class_object_Clone(
490 IWbemClassObject *iface,
491 IWbemClassObject **ppCopy )
493 FIXME("%p, %p\n", iface, ppCopy);
494 return E_NOTIMPL;
497 static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
499 static const WCHAR fmtW[] = {'\n','\t','%','s',' ','=',' ','%','s',';',0};
500 BSTR value, ret;
501 WCHAR *p;
502 UINT i;
504 *len = 0;
505 for (i = 0; i < table->num_cols; i++)
507 *len += sizeof(fmtW) / sizeof(fmtW[0]);
508 *len += strlenW( table->columns[i].name );
509 value = get_value_bstr( table, row, i );
510 *len += SysStringLen( value );
511 SysFreeString( value );
513 if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL;
514 p = ret;
515 for (i = 0; i < table->num_cols; i++)
517 value = get_value_bstr( table, row, i );
518 p += sprintfW( p, fmtW, table->columns[i].name, value );
519 SysFreeString( value );
521 return ret;
524 static BSTR get_object_text( const struct view *view, UINT index )
526 static const WCHAR fmtW[] =
527 {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0};
528 UINT len, len_body, row = view->result[index];
529 BSTR ret, body;
531 len = sizeof(fmtW) / sizeof(fmtW[0]);
532 len += strlenW( view->table->name );
533 if (!(body = get_body_text( view->table, row, &len_body ))) return NULL;
534 len += len_body;
536 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
537 sprintfW( ret, fmtW, view->table->name, body );
538 SysFreeString( body );
539 return ret;
542 static HRESULT WINAPI class_object_GetObjectText(
543 IWbemClassObject *iface,
544 LONG lFlags,
545 BSTR *pstrObjectText )
547 struct class_object *co = impl_from_IWbemClassObject( iface );
548 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
549 struct view *view = ec->query->view;
550 BSTR text;
552 TRACE("%p, %08x, %p\n", iface, lFlags, pstrObjectText);
554 if (lFlags) FIXME("flags %08x not implemented\n", lFlags);
556 if (!(text = get_object_text( view, co->index ))) return E_OUTOFMEMORY;
557 *pstrObjectText = text;
558 return S_OK;
561 static HRESULT WINAPI class_object_SpawnDerivedClass(
562 IWbemClassObject *iface,
563 LONG lFlags,
564 IWbemClassObject **ppNewClass )
566 FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
567 return E_NOTIMPL;
570 static HRESULT WINAPI class_object_SpawnInstance(
571 IWbemClassObject *iface,
572 LONG lFlags,
573 IWbemClassObject **ppNewInstance )
575 struct class_object *co = impl_from_IWbemClassObject( iface );
576 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
577 struct view *view = ec->query->view;
578 struct record *record;
580 TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
582 if (!(record = create_record( view->table->columns, view->table->num_cols )))
583 return E_OUTOFMEMORY;
585 return create_class_object( co->name, NULL, 0, record, ppNewInstance );
588 static HRESULT WINAPI class_object_CompareTo(
589 IWbemClassObject *iface,
590 LONG lFlags,
591 IWbemClassObject *pCompareTo )
593 FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
594 return E_NOTIMPL;
597 static HRESULT WINAPI class_object_GetPropertyOrigin(
598 IWbemClassObject *iface,
599 LPCWSTR wszName,
600 BSTR *pstrClassName )
602 FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
603 return E_NOTIMPL;
606 static HRESULT WINAPI class_object_InheritsFrom(
607 IWbemClassObject *iface,
608 LPCWSTR strAncestor )
610 FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
611 return E_NOTIMPL;
614 static UINT count_instances( IEnumWbemClassObject *iter )
616 UINT count = 0;
617 while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++;
618 IEnumWbemClassObject_Reset( iter );
619 return count;
622 static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr )
624 switch (type)
626 case CIM_SINT16:
627 *(INT16 *)ptr = val;
628 break;
629 case CIM_UINT16:
630 *(UINT16 *)ptr = val;
631 break;
632 case CIM_SINT32:
633 *(INT32 *)ptr = val;
634 break;
635 case CIM_UINT32:
636 *(UINT32 *)ptr = val;
637 break;
638 default:
639 FIXME("unhandled type %u\n", type);
640 break;
644 static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols,
645 struct column **cols, BYTE **data )
647 static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
648 static const WCHAR typeW[] = {'T','y','p','e',0};
649 static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
650 struct column *columns;
651 BYTE *row;
652 IWbemClassObject *param;
653 VARIANT val;
654 HRESULT hr = E_OUTOFMEMORY;
655 UINT offset = 0;
656 ULONG count;
657 int i = 0;
659 count = count_instances( iter );
660 if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
661 if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
663 for (;;)
665 IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &param, &count );
666 if (!count) break;
668 hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL );
669 if (hr != S_OK) goto error;
670 columns[i].name = heap_strdupW( V_BSTR( &val ) );
671 VariantClear( &val );
673 hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL );
674 if (hr != S_OK) goto error;
675 columns[i].type = V_UI4( &val );
676 columns[i].vartype = 0;
678 hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
679 if (hr != S_OK) goto error;
680 if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
681 offset += get_type_size( columns[i].type );
683 IWbemClassObject_Release( param );
684 i++;
686 *num_cols = i;
687 *cols = columns;
688 *data = row;
689 return S_OK;
691 error:
692 for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
693 heap_free( columns );
694 heap_free( row );
695 return hr;
698 static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
700 HRESULT hr;
701 struct table *table;
702 struct column *columns;
703 UINT num_cols;
704 BYTE *row;
706 hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
707 if (hr != S_OK) return hr;
709 if (!(table = create_table( name, num_cols, columns, 1, row, NULL )))
711 free_columns( columns, num_cols );
712 heap_free( row );
713 return E_OUTOFMEMORY;
715 if (!add_table( table )) free_table( table ); /* already exists */
716 return S_OK;
719 static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
721 static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
722 static const WCHAR outW[] = {'O','U','T',0};
723 static const WCHAR inW[] = {'I','N',0};
724 UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method );
725 WCHAR *ret;
727 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
728 sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
729 return struprW( ret );
732 static HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
733 IWbemClassObject **sig )
735 static const WCHAR selectW[] =
736 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
737 '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
738 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
739 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
740 'D','i','r','e','c','t','i','o','n','%','s',0};
741 static const WCHAR geW[] = {'>','=','0',0};
742 static const WCHAR leW[] = {'<','=','0',0};
743 UINT len = SIZEOF(selectW) + SIZEOF(geW);
744 IEnumWbemClassObject *iter;
745 WCHAR *query, *name;
746 HRESULT hr;
748 len += strlenW( class ) + strlenW( method );
749 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
750 sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
752 hr = exec_query( query, &iter );
753 heap_free( query );
754 if (hr != S_OK) return hr;
756 if (!(name = build_signature_table_name( class, method, dir )))
758 IEnumWbemClassObject_Release( iter );
759 return E_OUTOFMEMORY;
761 hr = create_signature_table( iter, name );
762 IEnumWbemClassObject_Release( iter );
763 if (hr != S_OK)
765 heap_free( name );
766 return hr;
768 return get_object( name, sig );
771 static HRESULT WINAPI class_object_GetMethod(
772 IWbemClassObject *iface,
773 LPCWSTR wszName,
774 LONG lFlags,
775 IWbemClassObject **ppInSignature,
776 IWbemClassObject **ppOutSignature )
778 struct class_object *co = impl_from_IWbemClassObject( iface );
779 HRESULT hr;
781 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
783 hr = create_signature( co->name, wszName, PARAM_IN, ppInSignature );
784 if (hr != S_OK) return hr;
786 hr = create_signature( co->name, wszName, PARAM_OUT, ppOutSignature );
787 if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
788 return hr;
791 static HRESULT WINAPI class_object_PutMethod(
792 IWbemClassObject *iface,
793 LPCWSTR wszName,
794 LONG lFlags,
795 IWbemClassObject *pInSignature,
796 IWbemClassObject *pOutSignature )
798 FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
799 return E_NOTIMPL;
802 static HRESULT WINAPI class_object_DeleteMethod(
803 IWbemClassObject *iface,
804 LPCWSTR wszName )
806 FIXME("%p, %s\n", iface, debugstr_w(wszName));
807 return E_NOTIMPL;
810 static HRESULT WINAPI class_object_BeginMethodEnumeration(
811 IWbemClassObject *iface,
812 LONG lEnumFlags)
814 struct class_object *co = impl_from_IWbemClassObject( iface );
816 TRACE("%p, %08x\n", iface, lEnumFlags);
818 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
820 if (co->iter)
822 WARN("not allowed on instance\n");
823 return WBEM_E_ILLEGAL_OPERATION;
825 co->index_method = 0;
826 return S_OK;
829 static HRESULT WINAPI class_object_NextMethod(
830 IWbemClassObject *iface,
831 LONG lFlags,
832 BSTR *pstrName,
833 IWbemClassObject **ppInSignature,
834 IWbemClassObject **ppOutSignature)
836 struct class_object *co = impl_from_IWbemClassObject( iface );
837 const WCHAR *method;
838 HRESULT hr;
840 TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
842 if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;
844 hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
845 if (hr != S_OK) return hr;
847 hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
848 if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
849 else
851 if (!(*pstrName = SysAllocString( method )))
853 IWbemClassObject_Release( *ppInSignature );
854 IWbemClassObject_Release( *ppOutSignature );
855 return E_OUTOFMEMORY;
857 co->index_method++;
859 return hr;
862 static HRESULT WINAPI class_object_EndMethodEnumeration(
863 IWbemClassObject *iface )
865 struct class_object *co = impl_from_IWbemClassObject( iface );
867 TRACE("%p\n", iface);
869 co->index_method = 0;
870 return S_OK;
873 static HRESULT WINAPI class_object_GetMethodQualifierSet(
874 IWbemClassObject *iface,
875 LPCWSTR wszMethod,
876 IWbemQualifierSet **ppQualSet)
878 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
879 return E_NOTIMPL;
882 static HRESULT WINAPI class_object_GetMethodOrigin(
883 IWbemClassObject *iface,
884 LPCWSTR wszMethodName,
885 BSTR *pstrClassName)
887 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
888 return E_NOTIMPL;
891 static const IWbemClassObjectVtbl class_object_vtbl =
893 class_object_QueryInterface,
894 class_object_AddRef,
895 class_object_Release,
896 class_object_GetQualifierSet,
897 class_object_Get,
898 class_object_Put,
899 class_object_Delete,
900 class_object_GetNames,
901 class_object_BeginEnumeration,
902 class_object_Next,
903 class_object_EndEnumeration,
904 class_object_GetPropertyQualifierSet,
905 class_object_Clone,
906 class_object_GetObjectText,
907 class_object_SpawnDerivedClass,
908 class_object_SpawnInstance,
909 class_object_CompareTo,
910 class_object_GetPropertyOrigin,
911 class_object_InheritsFrom,
912 class_object_GetMethod,
913 class_object_PutMethod,
914 class_object_DeleteMethod,
915 class_object_BeginMethodEnumeration,
916 class_object_NextMethod,
917 class_object_EndMethodEnumeration,
918 class_object_GetMethodQualifierSet,
919 class_object_GetMethodOrigin
922 HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index,
923 struct record *record, IWbemClassObject **obj )
925 struct class_object *co;
927 TRACE("%s, %p\n", debugstr_w(name), obj);
929 co = heap_alloc( sizeof(*co) );
930 if (!co) return E_OUTOFMEMORY;
932 co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
933 co->refs = 1;
934 co->name = heap_strdupW( name );
935 if (!co->name)
937 heap_free( co );
938 return E_OUTOFMEMORY;
940 co->iter = iter;
941 co->index = index;
942 co->index_method = 0;
943 co->index_property = 0;
944 co->record = record;
945 if (iter) IEnumWbemClassObject_AddRef( iter );
947 *obj = &co->IWbemClassObject_iface;
949 TRACE("returning iface %p\n", *obj);
950 return S_OK;