ntdll: Make sure we don't try to attach the main exe a second time.
[wine/zf.git] / dlls / wbemprox / class.c
blobba7720b098d238822af2df27d9b837990ff0433d
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 <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "objbase.h"
26 #include "wbemcli.h"
28 #include "wine/debug.h"
29 #include "wbemprox_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
33 struct enum_class_object
35 IEnumWbemClassObject IEnumWbemClassObject_iface;
36 LONG refs;
37 struct query *query;
38 UINT index;
41 static inline struct enum_class_object *impl_from_IEnumWbemClassObject(
42 IEnumWbemClassObject *iface )
44 return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface);
47 static ULONG WINAPI enum_class_object_AddRef(
48 IEnumWbemClassObject *iface )
50 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
51 return InterlockedIncrement( &ec->refs );
54 static ULONG WINAPI enum_class_object_Release(
55 IEnumWbemClassObject *iface )
57 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
58 LONG refs = InterlockedDecrement( &ec->refs );
59 if (!refs)
61 TRACE("destroying %p\n", ec);
62 release_query( ec->query );
63 heap_free( ec );
65 return refs;
68 static HRESULT WINAPI enum_class_object_QueryInterface(
69 IEnumWbemClassObject *iface,
70 REFIID riid,
71 void **ppvObject )
73 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
75 TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject );
77 if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) ||
78 IsEqualGUID( riid, &IID_IUnknown ) )
80 *ppvObject = ec;
82 else if ( IsEqualGUID( riid, &IID_IClientSecurity ) )
84 *ppvObject = &client_security;
85 return S_OK;
87 else
89 FIXME("interface %s not implemented\n", debugstr_guid(riid));
90 return E_NOINTERFACE;
92 IEnumWbemClassObject_AddRef( iface );
93 return S_OK;
96 static HRESULT WINAPI enum_class_object_Reset(
97 IEnumWbemClassObject *iface )
99 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
101 TRACE("%p\n", iface);
103 ec->index = 0;
104 return WBEM_S_NO_ERROR;
107 static HRESULT WINAPI enum_class_object_Next(
108 IEnumWbemClassObject *iface,
109 LONG lTimeout,
110 ULONG uCount,
111 IWbemClassObject **apObjects,
112 ULONG *puReturned )
114 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
115 struct view *view = ec->query->view;
116 struct table *table;
117 static int once = 0;
118 HRESULT hr;
120 TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned);
122 if (!uCount) return WBEM_S_FALSE;
123 if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER;
124 if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
126 *puReturned = 0;
127 if (ec->index >= view->result_count) return WBEM_S_FALSE;
129 table = get_view_table( view, ec->index );
130 hr = create_class_object( table->name, iface, ec->index, NULL, apObjects );
131 if (hr != S_OK) return hr;
133 ec->index++;
134 *puReturned = 1;
135 if (ec->index == view->result_count && uCount > 1) return WBEM_S_FALSE;
136 if (uCount > 1) return WBEM_S_TIMEDOUT;
137 return WBEM_S_NO_ERROR;
140 static HRESULT WINAPI enum_class_object_NextAsync(
141 IEnumWbemClassObject *iface,
142 ULONG uCount,
143 IWbemObjectSink *pSink )
145 FIXME("%p, %u, %p\n", iface, uCount, pSink);
146 return E_NOTIMPL;
149 static HRESULT WINAPI enum_class_object_Clone(
150 IEnumWbemClassObject *iface,
151 IEnumWbemClassObject **ppEnum )
153 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
155 TRACE("%p, %p\n", iface, ppEnum);
157 return EnumWbemClassObject_create( ec->query, (void **)ppEnum );
160 static HRESULT WINAPI enum_class_object_Skip(
161 IEnumWbemClassObject *iface,
162 LONG lTimeout,
163 ULONG nCount )
165 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
166 struct view *view = ec->query->view;
167 static int once = 0;
169 TRACE("%p, %d, %u\n", iface, lTimeout, nCount);
171 if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
173 if (!view->result_count) return WBEM_S_FALSE;
175 if (nCount > view->result_count - ec->index)
177 ec->index = view->result_count - 1;
178 return WBEM_S_FALSE;
180 ec->index += nCount;
181 return WBEM_S_NO_ERROR;
184 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
186 enum_class_object_QueryInterface,
187 enum_class_object_AddRef,
188 enum_class_object_Release,
189 enum_class_object_Reset,
190 enum_class_object_Next,
191 enum_class_object_NextAsync,
192 enum_class_object_Clone,
193 enum_class_object_Skip
196 HRESULT EnumWbemClassObject_create( struct query *query, LPVOID *ppObj )
198 struct enum_class_object *ec;
200 TRACE("%p\n", ppObj);
202 ec = heap_alloc( sizeof(*ec) );
203 if (!ec) return E_OUTOFMEMORY;
205 ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl;
206 ec->refs = 1;
207 ec->query = addref_query( query );
208 ec->index = 0;
210 *ppObj = &ec->IEnumWbemClassObject_iface;
212 TRACE("returning iface %p\n", *ppObj);
213 return S_OK;
216 static struct record *create_record( struct table *table )
218 UINT i;
219 struct record *record;
221 if (!(record = heap_alloc( sizeof(struct record) ))) return NULL;
222 if (!(record->fields = heap_alloc( table->num_cols * sizeof(struct field) )))
224 heap_free( record );
225 return NULL;
227 for (i = 0; i < table->num_cols; i++)
229 record->fields[i].type = table->columns[i].type;
230 record->fields[i].u.ival = 0;
232 record->count = table->num_cols;
233 record->table = addref_table( table );
234 return record;
237 void destroy_array( struct array *array, CIMTYPE type )
239 UINT i;
240 if (!array) return;
241 if (type == CIM_STRING || type == CIM_DATETIME || type == CIM_REFERENCE)
243 for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * array->elem_size) );
245 heap_free( array->ptr );
246 heap_free( array );
249 static void destroy_record( struct record *record )
251 UINT i;
253 if (!record) return;
254 release_table( record->table );
255 for (i = 0; i < record->count; i++)
257 if (record->fields[i].type == CIM_STRING ||
258 record->fields[i].type == CIM_DATETIME ||
259 record->fields[i].type == CIM_REFERENCE) heap_free( record->fields[i].u.sval );
260 else if (record->fields[i].type & CIM_FLAG_ARRAY)
261 destroy_array( record->fields[i].u.aval, record->fields[i].type & CIM_TYPE_MASK );
263 heap_free( record->fields );
264 heap_free( record );
267 struct class_object
269 IWbemClassObject IWbemClassObject_iface;
270 LONG refs;
271 WCHAR *name;
272 IEnumWbemClassObject *iter;
273 UINT index;
274 UINT index_method;
275 UINT index_property;
276 struct record *record; /* uncommitted instance */
279 static inline struct class_object *impl_from_IWbemClassObject(
280 IWbemClassObject *iface )
282 return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
285 static ULONG WINAPI class_object_AddRef(
286 IWbemClassObject *iface )
288 struct class_object *co = impl_from_IWbemClassObject( iface );
289 return InterlockedIncrement( &co->refs );
292 static ULONG WINAPI class_object_Release(
293 IWbemClassObject *iface )
295 struct class_object *co = impl_from_IWbemClassObject( iface );
296 LONG refs = InterlockedDecrement( &co->refs );
297 if (!refs)
299 TRACE("destroying %p\n", co);
300 if (co->iter) IEnumWbemClassObject_Release( co->iter );
301 destroy_record( co->record );
302 heap_free( co->name );
303 heap_free( co );
305 return refs;
308 static HRESULT WINAPI class_object_QueryInterface(
309 IWbemClassObject *iface,
310 REFIID riid,
311 void **ppvObject )
313 struct class_object *co = impl_from_IWbemClassObject( iface );
315 TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
317 if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
318 IsEqualGUID( riid, &IID_IUnknown ) )
320 *ppvObject = co;
322 else if (IsEqualGUID( riid, &IID_IClientSecurity ))
324 *ppvObject = &client_security;
325 return S_OK;
327 else
329 FIXME("interface %s not implemented\n", debugstr_guid(riid));
330 return E_NOINTERFACE;
332 IWbemClassObject_AddRef( iface );
333 return S_OK;
336 static HRESULT WINAPI class_object_GetQualifierSet(
337 IWbemClassObject *iface,
338 IWbemQualifierSet **ppQualSet )
340 struct class_object *co = impl_from_IWbemClassObject( iface );
342 TRACE("%p, %p\n", iface, ppQualSet);
344 return WbemQualifierSet_create( co->name, NULL, (void **)ppQualSet );
347 static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type )
349 VARTYPE vartype = to_vartype( record->fields[index].type & CIM_TYPE_MASK );
351 if (type) *type = record->fields[index].type;
353 if (record->fields[index].type & CIM_FLAG_ARRAY)
355 V_VT( var ) = vartype | VT_ARRAY;
356 V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & CIM_TYPE_MASK );
357 return S_OK;
359 switch (record->fields[index].type)
361 case CIM_STRING:
362 case CIM_DATETIME:
363 case CIM_REFERENCE:
364 V_BSTR( var ) = SysAllocString( record->fields[index].u.sval );
365 break;
366 case CIM_SINT32:
367 V_I4( var ) = record->fields[index].u.ival;
368 break;
369 case CIM_UINT32:
370 V_UI4( var ) = record->fields[index].u.ival;
371 break;
372 default:
373 FIXME("unhandled type %u\n", record->fields[index].type);
374 return WBEM_E_INVALID_PARAMETER;
376 V_VT( var ) = vartype;
377 return S_OK;
380 static HRESULT WINAPI class_object_Get(
381 IWbemClassObject *iface,
382 LPCWSTR wszName,
383 LONG lFlags,
384 VARIANT *pVal,
385 CIMTYPE *pType,
386 LONG *plFlavor )
388 struct class_object *co = impl_from_IWbemClassObject( iface );
389 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
391 TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor);
393 if (co->record)
395 UINT index;
396 HRESULT hr;
398 if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr;
399 return record_get_value( co->record, index, pVal, pType );
401 return get_propval( ec->query->view, co->index, wszName, pVal, pType, plFlavor );
404 static HRESULT record_set_value( struct record *record, UINT index, VARIANT *var )
406 LONGLONG val;
407 CIMTYPE type;
408 HRESULT hr;
410 if ((hr = to_longlong( var, &val, &type )) != S_OK) return hr;
411 if (type != record->fields[index].type) return WBEM_E_TYPE_MISMATCH;
413 if (type & CIM_FLAG_ARRAY)
415 record->fields[index].u.aval = (struct array *)(INT_PTR)val;
416 return S_OK;
418 switch (type)
420 case CIM_STRING:
421 case CIM_DATETIME:
422 case CIM_REFERENCE:
423 record->fields[index].u.sval = (WCHAR *)(INT_PTR)val;
424 return S_OK;
425 case CIM_SINT16:
426 case CIM_UINT16:
427 case CIM_SINT32:
428 case CIM_UINT32:
429 record->fields[index].u.ival = val;
430 return S_OK;
431 default:
432 FIXME("unhandled type %u\n", type);
433 break;
435 return WBEM_E_INVALID_PARAMETER;
438 static HRESULT WINAPI class_object_Put(
439 IWbemClassObject *iface,
440 LPCWSTR wszName,
441 LONG lFlags,
442 VARIANT *pVal,
443 CIMTYPE Type )
445 struct class_object *co = impl_from_IWbemClassObject( iface );
446 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
448 TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
450 if (co->record)
452 UINT index;
453 HRESULT hr;
455 if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr;
456 return record_set_value( co->record, index, pVal );
458 return put_propval( ec->query->view, co->index, wszName, pVal, Type );
461 static HRESULT WINAPI class_object_Delete(
462 IWbemClassObject *iface,
463 LPCWSTR wszName )
465 FIXME("%p, %s\n", iface, debugstr_w(wszName));
466 return E_NOTIMPL;
469 static HRESULT WINAPI class_object_GetNames(
470 IWbemClassObject *iface,
471 LPCWSTR wszQualifierName,
472 LONG lFlags,
473 VARIANT *pQualifierVal,
474 SAFEARRAY **pNames )
476 struct class_object *co = impl_from_IWbemClassObject( iface );
477 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
479 TRACE("%p, %s, %08x, %s, %p\n", iface, debugstr_w(wszQualifierName), lFlags,
480 debugstr_variant(pQualifierVal), pNames);
482 if (lFlags != WBEM_FLAG_ALWAYS &&
483 lFlags != WBEM_FLAG_NONSYSTEM_ONLY &&
484 lFlags != WBEM_FLAG_SYSTEM_ONLY)
486 FIXME("flags %08x not supported\n", lFlags);
487 return E_NOTIMPL;
489 if (wszQualifierName || pQualifierVal)
490 FIXME("qualifier not supported\n");
492 return get_properties( ec->query->view, co->index, lFlags, pNames );
495 static HRESULT WINAPI class_object_BeginEnumeration(
496 IWbemClassObject *iface,
497 LONG lEnumFlags )
499 struct class_object *co = impl_from_IWbemClassObject( iface );
501 TRACE("%p, %08x\n", iface, lEnumFlags);
503 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
505 co->index_property = 0;
506 return S_OK;
509 static HRESULT WINAPI class_object_Next(
510 IWbemClassObject *iface,
511 LONG lFlags,
512 BSTR *strName,
513 VARIANT *pVal,
514 CIMTYPE *pType,
515 LONG *plFlavor )
517 struct class_object *obj = impl_from_IWbemClassObject( iface );
518 struct enum_class_object *iter = impl_from_IEnumWbemClassObject( obj->iter );
519 struct view *view = iter->query->view;
520 struct table *table = get_view_table( view, obj->index );
521 BSTR prop;
522 HRESULT hr;
523 UINT i;
525 TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
527 for (i = obj->index_property; i < table->num_cols; i++)
529 if (is_method( table, i )) continue;
530 if (!is_result_prop( view, table->columns[i].name )) continue;
531 if (!(prop = SysAllocString( table->columns[i].name ))) return E_OUTOFMEMORY;
532 if ((hr = get_propval( view, obj->index, prop, pVal, pType, plFlavor )) != S_OK)
534 SysFreeString( prop );
535 return hr;
538 obj->index_property = i + 1;
539 if (strName) *strName = prop;
540 else SysFreeString( prop );
542 return S_OK;
544 return WBEM_S_NO_MORE_DATA;
547 static HRESULT WINAPI class_object_EndEnumeration(
548 IWbemClassObject *iface )
550 struct class_object *co = impl_from_IWbemClassObject( iface );
552 TRACE("%p\n", iface);
554 co->index_property = 0;
555 return S_OK;
558 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
559 IWbemClassObject *iface,
560 LPCWSTR wszProperty,
561 IWbemQualifierSet **ppQualSet )
563 struct class_object *co = impl_from_IWbemClassObject( iface );
565 TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
567 return WbemQualifierSet_create( co->name, wszProperty, (void **)ppQualSet );
570 static HRESULT WINAPI class_object_Clone(
571 IWbemClassObject *iface,
572 IWbemClassObject **ppCopy )
574 FIXME("%p, %p\n", iface, ppCopy);
575 return E_NOTIMPL;
578 static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
580 BSTR value, ret;
581 WCHAR *p;
582 UINT i;
584 *len = 0;
585 for (i = 0; i < table->num_cols; i++)
587 if ((value = get_value_bstr( table, row, i )))
589 *len += ARRAY_SIZE( L"\n\t%s = %s;" );
590 *len += lstrlenW( table->columns[i].name );
591 *len += SysStringLen( value );
592 SysFreeString( value );
595 if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL;
596 p = ret;
597 for (i = 0; i < table->num_cols; i++)
599 if ((value = get_value_bstr( table, row, i )))
601 p += swprintf( p, *len - (p - ret), L"\n\t%s = %s;", table->columns[i].name, value );
602 SysFreeString( value );
605 return ret;
608 static BSTR get_object_text( const struct view *view, UINT index )
610 UINT len, len_body, row = view->result[index];
611 struct table *table = get_view_table( view, index );
612 BSTR ret, body;
614 len = ARRAY_SIZE( L"\ninstance of %s\n{%s\n};" );
615 len += lstrlenW( table->name );
616 if (!(body = get_body_text( table, row, &len_body ))) return NULL;
617 len += len_body;
619 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
620 swprintf( ret, len, L"\ninstance of %s\n{%s\n};", table->name, body );
621 SysFreeString( body );
622 return ret;
625 static HRESULT WINAPI class_object_GetObjectText(
626 IWbemClassObject *iface,
627 LONG lFlags,
628 BSTR *pstrObjectText )
630 struct class_object *co = impl_from_IWbemClassObject( iface );
631 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
632 struct view *view = ec->query->view;
633 BSTR text;
635 TRACE("%p, %08x, %p\n", iface, lFlags, pstrObjectText);
637 if (lFlags) FIXME("flags %08x not implemented\n", lFlags);
639 if (!(text = get_object_text( view, co->index ))) return E_OUTOFMEMORY;
640 *pstrObjectText = text;
641 return S_OK;
644 static HRESULT WINAPI class_object_SpawnDerivedClass(
645 IWbemClassObject *iface,
646 LONG lFlags,
647 IWbemClassObject **ppNewClass )
649 FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass);
650 return E_NOTIMPL;
653 static HRESULT WINAPI class_object_SpawnInstance(
654 IWbemClassObject *iface,
655 LONG lFlags,
656 IWbemClassObject **ppNewInstance )
658 struct class_object *co = impl_from_IWbemClassObject( iface );
659 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
660 struct table *table = get_view_table( ec->query->view, co->index );
661 struct record *record;
663 TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
665 if (!(record = create_record( table ))) return E_OUTOFMEMORY;
667 return create_class_object( co->name, NULL, 0, record, ppNewInstance );
670 static HRESULT WINAPI class_object_CompareTo(
671 IWbemClassObject *iface,
672 LONG lFlags,
673 IWbemClassObject *pCompareTo )
675 FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo);
676 return E_NOTIMPL;
679 static HRESULT WINAPI class_object_GetPropertyOrigin(
680 IWbemClassObject *iface,
681 LPCWSTR wszName,
682 BSTR *pstrClassName )
684 FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName);
685 return E_NOTIMPL;
688 static HRESULT WINAPI class_object_InheritsFrom(
689 IWbemClassObject *iface,
690 LPCWSTR strAncestor )
692 FIXME("%p, %s\n", iface, debugstr_w(strAncestor));
693 return E_NOTIMPL;
696 static UINT count_instances( IEnumWbemClassObject *iter )
698 UINT count = 0;
699 while (!IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 )) count++;
700 IEnumWbemClassObject_Reset( iter );
701 return count;
704 static void set_default_value( CIMTYPE type, UINT val, BYTE *ptr )
706 switch (type)
708 case CIM_SINT16:
709 *(INT16 *)ptr = val;
710 break;
711 case CIM_UINT16:
712 *(UINT16 *)ptr = val;
713 break;
714 case CIM_SINT32:
715 *(INT32 *)ptr = val;
716 break;
717 case CIM_UINT32:
718 *(UINT32 *)ptr = val;
719 break;
720 default:
721 FIXME("unhandled type %u\n", type);
722 break;
726 static HRESULT create_signature_columns_and_data( IEnumWbemClassObject *iter, UINT *num_cols,
727 struct column **cols, BYTE **data )
729 struct column *columns;
730 BYTE *row;
731 IWbemClassObject *param;
732 VARIANT val;
733 HRESULT hr = E_OUTOFMEMORY;
734 UINT offset = 0;
735 ULONG count;
736 int i = 0;
738 count = count_instances( iter );
739 if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
740 if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
742 for (;;)
744 IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &param, &count );
745 if (!count) break;
747 hr = IWbemClassObject_Get( param, L"Parameter", 0, &val, NULL, NULL );
748 if (hr != S_OK) goto error;
749 columns[i].name = heap_strdupW( V_BSTR( &val ) );
750 VariantClear( &val );
752 hr = IWbemClassObject_Get( param, L"Type", 0, &val, NULL, NULL );
753 if (hr != S_OK) goto error;
754 columns[i].type = V_UI4( &val );
756 hr = IWbemClassObject_Get( param, L"DefaultValue", 0, &val, NULL, NULL );
757 if (hr != S_OK) goto error;
758 if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
759 offset += get_type_size( columns[i].type );
761 IWbemClassObject_Release( param );
762 i++;
764 *num_cols = i;
765 *cols = columns;
766 *data = row;
767 return S_OK;
769 error:
770 for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
771 heap_free( columns );
772 heap_free( row );
773 return hr;
776 static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
778 HRESULT hr;
779 struct table *table;
780 struct column *columns;
781 UINT num_cols;
782 BYTE *row;
784 hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
785 if (hr != S_OK) return hr;
787 if (!(table = create_table( name, num_cols, columns, 1, 1, row, NULL )))
789 free_columns( columns, num_cols );
790 heap_free( row );
791 return E_OUTOFMEMORY;
793 if (!add_table( table )) free_table( table ); /* already exists */
794 return S_OK;
797 static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
799 UINT len = ARRAY_SIZE(L"__%s_%s_%s") + ARRAY_SIZE(L"OUT") + lstrlenW( class ) + lstrlenW( method );
800 WCHAR *ret;
802 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
803 swprintf( ret, len, L"__%s_%s_%s", class, method, dir == PARAM_IN ? L"IN" : L"OUT" );
804 return wcsupr( ret );
807 HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
808 IWbemClassObject **sig )
810 static const WCHAR selectW[] = L"SELECT * FROM __PARAMETERS WHERE Class='%s' AND Method='%s' AND Direction%s";
811 UINT len = ARRAY_SIZE(selectW) + ARRAY_SIZE(L">=0");
812 IEnumWbemClassObject *iter;
813 WCHAR *query, *name;
814 HRESULT hr;
816 len += lstrlenW( class ) + lstrlenW( method );
817 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
818 swprintf( query, len, selectW, class, method, dir >= 0 ? L">=0" : L"<=0" );
820 hr = exec_query( query, &iter );
821 heap_free( query );
822 if (hr != S_OK) return hr;
824 if (!count_instances( iter ))
826 *sig = NULL;
827 IEnumWbemClassObject_Release( iter );
828 return S_OK;
831 if (!(name = build_signature_table_name( class, method, dir )))
833 IEnumWbemClassObject_Release( iter );
834 return E_OUTOFMEMORY;
836 hr = create_signature_table( iter, name );
837 IEnumWbemClassObject_Release( iter );
838 if (hr == S_OK)
839 hr = get_object( name, sig );
841 heap_free( name );
842 return hr;
845 static HRESULT WINAPI class_object_GetMethod(
846 IWbemClassObject *iface,
847 LPCWSTR wszName,
848 LONG lFlags,
849 IWbemClassObject **ppInSignature,
850 IWbemClassObject **ppOutSignature )
852 struct class_object *co = impl_from_IWbemClassObject( iface );
853 IWbemClassObject *in, *out;
854 HRESULT hr;
856 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
858 hr = create_signature( co->name, wszName, PARAM_IN, &in );
859 if (hr != S_OK) return hr;
861 hr = create_signature( co->name, wszName, PARAM_OUT, &out );
862 if (hr == S_OK)
864 if (ppInSignature) *ppInSignature = in;
865 else if (in) IWbemClassObject_Release( in );
866 if (ppOutSignature) *ppOutSignature = out;
867 else if (out) IWbemClassObject_Release( out );
869 else IWbemClassObject_Release( in );
870 return hr;
873 static HRESULT WINAPI class_object_PutMethod(
874 IWbemClassObject *iface,
875 LPCWSTR wszName,
876 LONG lFlags,
877 IWbemClassObject *pInSignature,
878 IWbemClassObject *pOutSignature )
880 FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
881 return E_NOTIMPL;
884 static HRESULT WINAPI class_object_DeleteMethod(
885 IWbemClassObject *iface,
886 LPCWSTR wszName )
888 FIXME("%p, %s\n", iface, debugstr_w(wszName));
889 return E_NOTIMPL;
892 static HRESULT WINAPI class_object_BeginMethodEnumeration(
893 IWbemClassObject *iface,
894 LONG lEnumFlags)
896 struct class_object *co = impl_from_IWbemClassObject( iface );
898 TRACE("%p, %08x\n", iface, lEnumFlags);
900 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
902 co->index_method = 0;
903 return S_OK;
906 static HRESULT WINAPI class_object_NextMethod(
907 IWbemClassObject *iface,
908 LONG lFlags,
909 BSTR *pstrName,
910 IWbemClassObject **ppInSignature,
911 IWbemClassObject **ppOutSignature)
913 struct class_object *co = impl_from_IWbemClassObject( iface );
914 BSTR method;
915 HRESULT hr;
917 TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
919 if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;
921 hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
922 if (hr != S_OK)
924 SysFreeString( method );
925 return hr;
927 hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
928 if (hr != S_OK)
930 SysFreeString( method );
931 if (*ppInSignature)
932 IWbemClassObject_Release( *ppInSignature );
934 else
936 *pstrName = method;
937 co->index_method++;
939 return hr;
942 static HRESULT WINAPI class_object_EndMethodEnumeration(
943 IWbemClassObject *iface )
945 struct class_object *co = impl_from_IWbemClassObject( iface );
947 TRACE("%p\n", iface);
949 co->index_method = 0;
950 return S_OK;
953 static HRESULT WINAPI class_object_GetMethodQualifierSet(
954 IWbemClassObject *iface,
955 LPCWSTR wszMethod,
956 IWbemQualifierSet **ppQualSet)
958 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
959 return E_NOTIMPL;
962 static HRESULT WINAPI class_object_GetMethodOrigin(
963 IWbemClassObject *iface,
964 LPCWSTR wszMethodName,
965 BSTR *pstrClassName)
967 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
968 return E_NOTIMPL;
971 static const IWbemClassObjectVtbl class_object_vtbl =
973 class_object_QueryInterface,
974 class_object_AddRef,
975 class_object_Release,
976 class_object_GetQualifierSet,
977 class_object_Get,
978 class_object_Put,
979 class_object_Delete,
980 class_object_GetNames,
981 class_object_BeginEnumeration,
982 class_object_Next,
983 class_object_EndEnumeration,
984 class_object_GetPropertyQualifierSet,
985 class_object_Clone,
986 class_object_GetObjectText,
987 class_object_SpawnDerivedClass,
988 class_object_SpawnInstance,
989 class_object_CompareTo,
990 class_object_GetPropertyOrigin,
991 class_object_InheritsFrom,
992 class_object_GetMethod,
993 class_object_PutMethod,
994 class_object_DeleteMethod,
995 class_object_BeginMethodEnumeration,
996 class_object_NextMethod,
997 class_object_EndMethodEnumeration,
998 class_object_GetMethodQualifierSet,
999 class_object_GetMethodOrigin
1002 HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index,
1003 struct record *record, IWbemClassObject **obj )
1005 struct class_object *co;
1007 TRACE("%s, %p\n", debugstr_w(name), obj);
1009 co = heap_alloc( sizeof(*co) );
1010 if (!co) return E_OUTOFMEMORY;
1012 co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
1013 co->refs = 1;
1014 if (!name) co->name = NULL;
1015 else if (!(co->name = heap_strdupW( name )))
1017 heap_free( co );
1018 return E_OUTOFMEMORY;
1020 co->iter = iter;
1021 co->index = index;
1022 co->index_method = 0;
1023 co->index_property = 0;
1024 co->record = record;
1025 if (iter) IEnumWbemClassObject_AddRef( iter );
1027 *obj = &co->IWbemClassObject_iface;
1029 TRACE("returning iface %p\n", *obj);
1030 return S_OK;