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
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;
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 );
62 TRACE("destroying %p\n", ec);
63 release_query( ec->query );
69 static HRESULT WINAPI enum_class_object_QueryInterface(
70 IEnumWbemClassObject *iface,
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 ) )
83 else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
85 *ppvObject = &client_security;
90 FIXME("interface %s not implemented\n", debugstr_guid(riid));
93 IEnumWbemClassObject_AddRef( iface );
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);
105 return WBEM_S_NO_ERROR;
108 static HRESULT WINAPI enum_class_object_Next(
109 IEnumWbemClassObject *iface,
112 IWbemClassObject **apObjects,
115 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
116 struct view *view = ec->query->view;
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");
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;
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,
141 IWbemObjectSink *pSink )
143 FIXME("%p, %u, %p\n", iface, uCount, pSink);
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,
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;
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;
206 addref_query( query );
209 *ppObj = &ec->IEnumWbemClassObject_iface;
211 TRACE("returning iface %p\n", *ppObj);
215 static struct record *create_record( const struct column *columns, UINT num_cols )
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) )))
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;
235 static void destroy_record( struct record *record )
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 );
244 else if ((record->fields[i].type & CIM_FLAG_ARRAY) && record->fields[i].u.aval)
246 heap_free( record->fields[i].u.aval->ptr );
247 heap_free( record->fields[i].u.aval );
250 heap_free( record->fields );
256 IWbemClassObject IWbemClassObject_iface;
259 IEnumWbemClassObject *iter;
263 struct record *record; /* uncommitted instance */
266 static inline struct class_object *impl_from_IWbemClassObject(
267 IWbemClassObject *iface )
269 return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
272 static ULONG WINAPI class_object_AddRef(
273 IWbemClassObject *iface )
275 struct class_object *co = impl_from_IWbemClassObject( iface );
276 return InterlockedIncrement( &co->refs );
279 static ULONG WINAPI class_object_Release(
280 IWbemClassObject *iface )
282 struct class_object *co = impl_from_IWbemClassObject( iface );
283 LONG refs = InterlockedDecrement( &co->refs );
286 TRACE("destroying %p\n", co);
287 if (co->iter) IEnumWbemClassObject_Release( co->iter );
288 destroy_record( co->record );
289 heap_free( co->name );
295 static HRESULT WINAPI class_object_QueryInterface(
296 IWbemClassObject *iface,
300 struct class_object *co = impl_from_IWbemClassObject( iface );
302 TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
304 if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
305 IsEqualGUID( riid, &IID_IUnknown ) )
309 else if (IsEqualGUID( riid, &IID_IClientSecurity ))
311 *ppvObject = &client_security;
316 FIXME("interface %s not implemented\n", debugstr_guid(riid));
317 return E_NOINTERFACE;
319 IWbemClassObject_AddRef( iface );
323 static HRESULT WINAPI class_object_GetQualifierSet(
324 IWbemClassObject *iface,
325 IWbemQualifierSet **ppQualSet )
327 FIXME("%p, %p\n", iface, ppQualSet);
331 static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type )
333 if (type) *type = record->fields[index].type;
335 if (record->fields[index].type & CIM_FLAG_ARRAY)
337 V_VT( var ) = VT_ARRAY;
338 V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & COL_TYPE_MASK );
341 switch (record->fields[index].type)
345 V_VT( var ) = VT_BSTR;
346 V_BSTR( var ) = SysAllocString( record->fields[index].u.sval );
350 V_I4( var ) = record->fields[index].u.ival;
353 V_VT( var ) = VT_UI4;
354 V_UI4( var ) = record->fields[index].u.ival;
357 FIXME("unhandled type %u\n", record->fields[index].type);
360 return WBEM_E_INVALID_PARAMETER;
363 static HRESULT WINAPI class_object_Get(
364 IWbemClassObject *iface,
371 struct class_object *co = impl_from_IWbemClassObject( iface );
372 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
374 TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);
378 struct table *table = grab_table( co->name );
382 if (!table) return WBEM_E_FAILED;
383 hr = get_column_index( table, wszName, &index );
384 release_table( table );
385 if (hr != S_OK) return hr;
386 return record_get_value( co->record, index, pVal, pType );
388 return get_propval( ec->query->view, co->index, wszName, pVal, pType, plFlavor );
391 static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var )
397 if ((hr = to_longlong( var, &val, &type )) != S_OK) return hr;
398 if (type != record->fields[index].type) return WBEM_E_TYPE_MISMATCH;
400 if (type & CIM_FLAG_ARRAY)
402 record->fields[index].u.aval = (struct array *)(INT_PTR)val;
409 record->fields[index].u.sval = (WCHAR *)(INT_PTR)val;
415 record->fields[index].u.ival = val;
418 FIXME("unhandled type %u\n", type);
421 return WBEM_E_INVALID_PARAMETER;
424 static HRESULT WINAPI class_object_Put(
425 IWbemClassObject *iface,
431 struct class_object *co = impl_from_IWbemClassObject( iface );
432 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
434 TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
438 struct table *table = grab_table( co->name );
442 if (!table) return WBEM_E_FAILED;
443 hr = get_column_index( table, wszName, &index );
444 release_table( table );
445 if (hr != S_OK) return hr;
446 return record_set_value( co->record, index, pVal );
448 return put_propval( ec->query->view, co->index, wszName, pVal, Type );
451 static HRESULT WINAPI class_object_Delete(
452 IWbemClassObject *iface,
455 FIXME("%p, %s\n", iface, debugstr_w(wszName));
459 static HRESULT WINAPI class_object_GetNames(
460 IWbemClassObject *iface,
461 LPCWSTR wszQualifierName,
463 VARIANT *pQualifierVal,
466 struct class_object *co = impl_from_IWbemClassObject( iface );
467 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
469 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszQualifierName), lFlags, pQualifierVal, pNames);
471 if (wszQualifierName || pQualifierVal)
473 FIXME("qualifier not supported\n");
476 if (lFlags != WBEM_FLAG_ALWAYS)
478 FIXME("flags %08x not supported\n", lFlags);
481 return get_properties( ec->query->view, pNames );
484 static HRESULT WINAPI class_object_BeginEnumeration(
485 IWbemClassObject *iface,
488 struct class_object *co = impl_from_IWbemClassObject( iface );
490 TRACE("%p, %08x\n", iface, lEnumFlags);
492 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
494 co->index_property = 0;
498 static HRESULT WINAPI class_object_Next(
499 IWbemClassObject *iface,
506 struct class_object *co = impl_from_IWbemClassObject( iface );
507 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
508 struct view *view = ec->query->view;
512 TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
514 if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA;
515 if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK))
517 SysFreeString( property );
521 co->index_property++;
525 static HRESULT WINAPI class_object_EndEnumeration(
526 IWbemClassObject *iface )
528 struct class_object *co = impl_from_IWbemClassObject( iface );
530 TRACE("%p\n", iface);
532 co->index_property = 0;
536 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
537 IWbemClassObject *iface,
539 IWbemQualifierSet **ppQualSet )
541 FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
545 static HRESULT WINAPI class_object_Clone(
546 IWbemClassObject *iface,
547 IWbemClassObject **ppCopy )
549 FIXME("%p, %p\n", iface, ppCopy);
553 static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
555 static const WCHAR fmtW[] = {'\n','\t','%','s',' ','=',' ','%','s',';',0};
561 for (i = 0; i < table->num_cols; i++)
563 *len += sizeof(fmtW) / sizeof(fmtW[0]);
564 *len += strlenW( table->columns[i].name );
565 value = get_value_bstr( table, row, i );
566 *len += SysStringLen( value );
567 SysFreeString( value );
569 if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL;
571 for (i = 0; i < table->num_cols; i++)
573 value = get_value_bstr( table, row, i );
574 p += sprintfW( p, fmtW, table->columns[i].name, value );
575 SysFreeString( value );
580 static BSTR get_object_text( const struct view *view, UINT index )
582 static const WCHAR fmtW[] =
583 {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0};
584 UINT len, len_body, row = view->result[index];
587 len = sizeof(fmtW) / sizeof(fmtW[0]);
588 len += strlenW( view->table->name );
589 if (!(body = get_body_text( view->table, row, &len_body ))) return NULL;
592 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
593 sprintfW( ret, fmtW, view->table->name, body );
594 SysFreeString( body );
598 static HRESULT WINAPI class_object_GetObjectText(
599 IWbemClassObject *iface,
601 BSTR *pstrObjectText )
603 struct class_object *co = impl_from_IWbemClassObject( iface );
604 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
605 struct view *view = ec->query->view;
608 TRACE("%p, %08x, %p\n", iface, lFlags, pstrObjectText);
610 if (lFlags) FIXME("flags %08x not implemented\n", lFlags);
612 if (!(text = get_object_text( view, co->index ))) return E_OUTOFMEMORY;
613 *pstrObjectText = text;
617 static HRESULT WINAPI class_object_SpawnDerivedClass(
618 IWbemClassObject *iface,
620 IWbemClassObject **ppNewClass )
622 FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
626 static HRESULT WINAPI class_object_SpawnInstance(
627 IWbemClassObject *iface,
629 IWbemClassObject **ppNewInstance )
631 struct class_object *co = impl_from_IWbemClassObject( iface );
632 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
633 struct view *view = ec->query->view;
634 struct record *record;
636 TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
638 if (!(record = create_record( view->table->columns, view->table->num_cols )))
639 return E_OUTOFMEMORY;
641 return create_class_object( co->name, NULL, 0, record, ppNewInstance );
644 static HRESULT WINAPI class_object_CompareTo(
645 IWbemClassObject *iface,
647 IWbemClassObject *pCompareTo )
649 FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
653 static HRESULT WINAPI class_object_GetPropertyOrigin(
654 IWbemClassObject *iface,
656 BSTR *pstrClassName )
658 FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
662 static HRESULT WINAPI class_object_InheritsFrom(
663 IWbemClassObject *iface,
664 LPCWSTR strAncestor )
666 FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
670 static UINT count_instances( IEnumWbemClassObject *iter )
673 while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++;
674 IEnumWbemClassObject_Reset( iter );
678 static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr )
686 *(UINT16 *)ptr = val;
692 *(UINT32 *)ptr = val;
695 FIXME("unhandled type %u\n", type);
700 static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols,
701 struct column **cols, BYTE **data )
703 static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
704 static const WCHAR typeW[] = {'T','y','p','e',0};
705 static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
706 struct column *columns;
708 IWbemClassObject *param;
710 HRESULT hr = E_OUTOFMEMORY;
715 count = count_instances( iter );
716 if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
717 if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
721 IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, ¶m, &count );
724 hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL );
725 if (hr != S_OK) goto error;
726 columns[i].name = heap_strdupW( V_BSTR( &val ) );
727 VariantClear( &val );
729 hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL );
730 if (hr != S_OK) goto error;
731 columns[i].type = V_UI4( &val );
732 columns[i].vartype = 0;
734 hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
735 if (hr != S_OK) goto error;
736 if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
737 offset += get_type_size( columns[i].type );
739 IWbemClassObject_Release( param );
748 for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
749 heap_free( columns );
754 static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
758 struct column *columns;
762 hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
763 if (hr != S_OK) return hr;
765 if (!(table = create_table( name, num_cols, columns, 1, row, NULL )))
767 free_columns( columns, num_cols );
769 return E_OUTOFMEMORY;
771 if (!add_table( table )) free_table( table ); /* already exists */
775 static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
777 static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
778 static const WCHAR outW[] = {'O','U','T',0};
779 static const WCHAR inW[] = {'I','N',0};
780 UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method );
783 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
784 sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
785 return struprW( ret );
788 static HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
789 IWbemClassObject **sig )
791 static const WCHAR selectW[] =
792 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
793 '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
794 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
795 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
796 'D','i','r','e','c','t','i','o','n','%','s',0};
797 static const WCHAR geW[] = {'>','=','0',0};
798 static const WCHAR leW[] = {'<','=','0',0};
799 UINT len = SIZEOF(selectW) + SIZEOF(geW);
800 IEnumWbemClassObject *iter;
804 len += strlenW( class ) + strlenW( method );
805 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
806 sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
808 hr = exec_query( query, &iter );
810 if (hr != S_OK) return hr;
812 if (!(name = build_signature_table_name( class, method, dir )))
814 IEnumWbemClassObject_Release( iter );
815 return E_OUTOFMEMORY;
817 hr = create_signature_table( iter, name );
818 IEnumWbemClassObject_Release( iter );
824 return get_object( name, sig );
827 static HRESULT WINAPI class_object_GetMethod(
828 IWbemClassObject *iface,
831 IWbemClassObject **ppInSignature,
832 IWbemClassObject **ppOutSignature )
834 struct class_object *co = impl_from_IWbemClassObject( iface );
837 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
839 hr = create_signature( co->name, wszName, PARAM_IN, ppInSignature );
840 if (hr != S_OK) return hr;
842 hr = create_signature( co->name, wszName, PARAM_OUT, ppOutSignature );
843 if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
847 static HRESULT WINAPI class_object_PutMethod(
848 IWbemClassObject *iface,
851 IWbemClassObject *pInSignature,
852 IWbemClassObject *pOutSignature )
854 FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
858 static HRESULT WINAPI class_object_DeleteMethod(
859 IWbemClassObject *iface,
862 FIXME("%p, %s\n", iface, debugstr_w(wszName));
866 static HRESULT WINAPI class_object_BeginMethodEnumeration(
867 IWbemClassObject *iface,
870 struct class_object *co = impl_from_IWbemClassObject( iface );
872 TRACE("%p, %08x\n", iface, lEnumFlags);
874 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
878 WARN("not allowed on instance\n");
879 return WBEM_E_ILLEGAL_OPERATION;
881 co->index_method = 0;
885 static HRESULT WINAPI class_object_NextMethod(
886 IWbemClassObject *iface,
889 IWbemClassObject **ppInSignature,
890 IWbemClassObject **ppOutSignature)
892 struct class_object *co = impl_from_IWbemClassObject( iface );
896 TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
898 if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;
900 hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
903 SysFreeString( method );
906 hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
909 SysFreeString( method );
910 IWbemClassObject_Release( *ppInSignature );
920 static HRESULT WINAPI class_object_EndMethodEnumeration(
921 IWbemClassObject *iface )
923 struct class_object *co = impl_from_IWbemClassObject( iface );
925 TRACE("%p\n", iface);
927 co->index_method = 0;
931 static HRESULT WINAPI class_object_GetMethodQualifierSet(
932 IWbemClassObject *iface,
934 IWbemQualifierSet **ppQualSet)
936 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
940 static HRESULT WINAPI class_object_GetMethodOrigin(
941 IWbemClassObject *iface,
942 LPCWSTR wszMethodName,
945 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
949 static const IWbemClassObjectVtbl class_object_vtbl =
951 class_object_QueryInterface,
953 class_object_Release,
954 class_object_GetQualifierSet,
958 class_object_GetNames,
959 class_object_BeginEnumeration,
961 class_object_EndEnumeration,
962 class_object_GetPropertyQualifierSet,
964 class_object_GetObjectText,
965 class_object_SpawnDerivedClass,
966 class_object_SpawnInstance,
967 class_object_CompareTo,
968 class_object_GetPropertyOrigin,
969 class_object_InheritsFrom,
970 class_object_GetMethod,
971 class_object_PutMethod,
972 class_object_DeleteMethod,
973 class_object_BeginMethodEnumeration,
974 class_object_NextMethod,
975 class_object_EndMethodEnumeration,
976 class_object_GetMethodQualifierSet,
977 class_object_GetMethodOrigin
980 HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index,
981 struct record *record, IWbemClassObject **obj )
983 struct class_object *co;
985 TRACE("%s, %p\n", debugstr_w(name), obj);
987 co = heap_alloc( sizeof(*co) );
988 if (!co) return E_OUTOFMEMORY;
990 co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
992 co->name = heap_strdupW( name );
996 return E_OUTOFMEMORY;
1000 co->index_method = 0;
1001 co->index_property = 0;
1002 co->record = record;
1003 if (iter) IEnumWbemClassObject_AddRef( iter );
1005 *obj = &co->IWbemClassObject_iface;
1007 TRACE("returning iface %p\n", *obj);