ntdll: Convert PE header to 64-bit when loading a 32-bit IL-only module.
[wine.git] / dlls / wbemprox / class.c
blob983834d316409619c077075416a9eacaa74b95ee
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 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->count) return WBEM_S_FALSE;
129 hr = create_class_object( view->table->name, iface, ec->index, NULL, apObjects );
130 if (hr != S_OK) return hr;
132 ec->index++;
133 *puReturned = 1;
134 if (ec->index == view->count && uCount > 1) return WBEM_S_FALSE;
135 if (uCount > 1) return WBEM_S_TIMEDOUT;
136 return WBEM_S_NO_ERROR;
139 static HRESULT WINAPI enum_class_object_NextAsync(
140 IEnumWbemClassObject *iface,
141 ULONG uCount,
142 IWbemObjectSink *pSink )
144 FIXME("%p, %u, %p\n", iface, uCount, pSink);
145 return E_NOTIMPL;
148 static HRESULT WINAPI enum_class_object_Clone(
149 IEnumWbemClassObject *iface,
150 IEnumWbemClassObject **ppEnum )
152 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
154 TRACE("%p, %p\n", iface, ppEnum);
156 return EnumWbemClassObject_create( ec->query, (void **)ppEnum );
159 static HRESULT WINAPI enum_class_object_Skip(
160 IEnumWbemClassObject *iface,
161 LONG lTimeout,
162 ULONG nCount )
164 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface );
165 struct view *view = ec->query->view;
166 static int once = 0;
168 TRACE("%p, %d, %u\n", iface, lTimeout, nCount);
170 if (lTimeout != WBEM_INFINITE && !once++) FIXME("timeout not supported\n");
172 if (!view->count) return WBEM_S_FALSE;
174 if (nCount > view->count - ec->index)
176 ec->index = view->count - 1;
177 return WBEM_S_FALSE;
179 ec->index += nCount;
180 return WBEM_S_NO_ERROR;
183 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl =
185 enum_class_object_QueryInterface,
186 enum_class_object_AddRef,
187 enum_class_object_Release,
188 enum_class_object_Reset,
189 enum_class_object_Next,
190 enum_class_object_NextAsync,
191 enum_class_object_Clone,
192 enum_class_object_Skip
195 HRESULT EnumWbemClassObject_create( struct query *query, LPVOID *ppObj )
197 struct enum_class_object *ec;
199 TRACE("%p\n", ppObj);
201 ec = heap_alloc( sizeof(*ec) );
202 if (!ec) return E_OUTOFMEMORY;
204 ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl;
205 ec->refs = 1;
206 ec->query = 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( struct table *table )
217 UINT i;
218 struct record *record;
220 if (!(record = heap_alloc( sizeof(struct record) ))) return NULL;
221 if (!(record->fields = heap_alloc( table->num_cols * sizeof(struct field) )))
223 heap_free( record );
224 return NULL;
226 for (i = 0; i < table->num_cols; i++)
228 record->fields[i].type = table->columns[i].type;
229 record->fields[i].vartype = table->columns[i].vartype;
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, size;
241 if (!array) return;
242 if (type == CIM_STRING || type == CIM_DATETIME)
244 size = get_type_size( type );
245 for (i = 0; i < array->count; i++) heap_free( *(WCHAR **)((char *)array->ptr + i * size) );
247 heap_free( array->ptr );
248 heap_free( array );
251 static void destroy_record( struct record *record )
253 UINT i;
255 if (!record) return;
256 release_table( record->table );
257 for (i = 0; i < record->count; i++)
259 if (record->fields[i].type == CIM_STRING || record->fields[i].type == CIM_DATETIME)
260 heap_free( record->fields[i].u.sval );
261 else if (record->fields[i].type & CIM_FLAG_ARRAY)
262 destroy_array( record->fields[i].u.aval, record->fields[i].type & CIM_TYPE_MASK );
264 heap_free( record->fields );
265 heap_free( record );
268 struct class_object
270 IWbemClassObject IWbemClassObject_iface;
271 LONG refs;
272 WCHAR *name;
273 IEnumWbemClassObject *iter;
274 UINT index;
275 UINT index_method;
276 UINT index_property;
277 struct record *record; /* uncommitted instance */
280 static inline struct class_object *impl_from_IWbemClassObject(
281 IWbemClassObject *iface )
283 return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface);
286 static ULONG WINAPI class_object_AddRef(
287 IWbemClassObject *iface )
289 struct class_object *co = impl_from_IWbemClassObject( iface );
290 return InterlockedIncrement( &co->refs );
293 static ULONG WINAPI class_object_Release(
294 IWbemClassObject *iface )
296 struct class_object *co = impl_from_IWbemClassObject( iface );
297 LONG refs = InterlockedDecrement( &co->refs );
298 if (!refs)
300 TRACE("destroying %p\n", co);
301 if (co->iter) IEnumWbemClassObject_Release( co->iter );
302 destroy_record( co->record );
303 heap_free( co->name );
304 heap_free( co );
306 return refs;
309 static HRESULT WINAPI class_object_QueryInterface(
310 IWbemClassObject *iface,
311 REFIID riid,
312 void **ppvObject )
314 struct class_object *co = impl_from_IWbemClassObject( iface );
316 TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject );
318 if ( IsEqualGUID( riid, &IID_IWbemClassObject ) ||
319 IsEqualGUID( riid, &IID_IUnknown ) )
321 *ppvObject = co;
323 else if (IsEqualGUID( riid, &IID_IClientSecurity ))
325 *ppvObject = &client_security;
326 return S_OK;
328 else
330 FIXME("interface %s not implemented\n", debugstr_guid(riid));
331 return E_NOINTERFACE;
333 IWbemClassObject_AddRef( iface );
334 return S_OK;
337 static HRESULT WINAPI class_object_GetQualifierSet(
338 IWbemClassObject *iface,
339 IWbemQualifierSet **ppQualSet )
341 FIXME("%p, %p\n", iface, ppQualSet);
342 return E_NOTIMPL;
345 static HRESULT record_get_value( const struct record *record, UINT index, VARIANT *var, CIMTYPE *type )
347 VARTYPE vartype = record->fields[index].vartype;
349 if (type) *type = record->fields[index].type;
351 if (record->fields[index].type & CIM_FLAG_ARRAY)
353 V_VT( var ) = vartype ? vartype : to_vartype( record->fields[index].type & CIM_TYPE_MASK ) | VT_ARRAY;
354 V_ARRAY( var ) = to_safearray( record->fields[index].u.aval, record->fields[index].type & CIM_TYPE_MASK );
355 return S_OK;
357 switch (record->fields[index].type)
359 case CIM_STRING:
360 case CIM_DATETIME:
361 if (!vartype) vartype = VT_BSTR;
362 V_BSTR( var ) = SysAllocString( record->fields[index].u.sval );
363 break;
364 case CIM_SINT32:
365 if (!vartype) vartype = VT_I4;
366 V_I4( var ) = record->fields[index].u.ival;
367 break;
368 case CIM_UINT32:
369 if (!vartype) vartype = VT_UI4;
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 record->fields[index].u.sval = (WCHAR *)(INT_PTR)val;
423 return S_OK;
424 case CIM_SINT16:
425 case CIM_UINT16:
426 case CIM_SINT32:
427 case CIM_UINT32:
428 record->fields[index].u.ival = val;
429 return S_OK;
430 default:
431 FIXME("unhandled type %u\n", type);
432 break;
434 return WBEM_E_INVALID_PARAMETER;
437 static HRESULT WINAPI class_object_Put(
438 IWbemClassObject *iface,
439 LPCWSTR wszName,
440 LONG lFlags,
441 VARIANT *pVal,
442 CIMTYPE Type )
444 struct class_object *co = impl_from_IWbemClassObject( iface );
445 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
447 TRACE("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type);
449 if (co->record)
451 UINT index;
452 HRESULT hr;
454 if ((hr = get_column_index( co->record->table, wszName, &index )) != S_OK) return hr;
455 return record_set_value( co->record, index, pVal );
457 return put_propval( ec->query->view, co->index, wszName, pVal, Type );
460 static HRESULT WINAPI class_object_Delete(
461 IWbemClassObject *iface,
462 LPCWSTR wszName )
464 FIXME("%p, %s\n", iface, debugstr_w(wszName));
465 return E_NOTIMPL;
468 static HRESULT WINAPI class_object_GetNames(
469 IWbemClassObject *iface,
470 LPCWSTR wszQualifierName,
471 LONG lFlags,
472 VARIANT *pQualifierVal,
473 SAFEARRAY **pNames )
475 struct class_object *co = impl_from_IWbemClassObject( iface );
476 struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
478 TRACE("%p, %s, %08x, %s, %p\n", iface, debugstr_w(wszQualifierName), lFlags,
479 debugstr_variant(pQualifierVal), pNames);
481 if (lFlags != WBEM_FLAG_ALWAYS &&
482 lFlags != WBEM_FLAG_NONSYSTEM_ONLY &&
483 lFlags != WBEM_FLAG_SYSTEM_ONLY)
485 FIXME("flags %08x not supported\n", lFlags);
486 return E_NOTIMPL;
488 if (wszQualifierName || pQualifierVal)
489 FIXME("qualifier not supported\n");
491 return get_properties( ec->query->view, lFlags, pNames );
494 static HRESULT WINAPI class_object_BeginEnumeration(
495 IWbemClassObject *iface,
496 LONG lEnumFlags )
498 struct class_object *co = impl_from_IWbemClassObject( iface );
500 TRACE("%p, %08x\n", iface, lEnumFlags);
502 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
504 co->index_property = 0;
505 return S_OK;
508 static HRESULT WINAPI class_object_Next(
509 IWbemClassObject *iface,
510 LONG lFlags,
511 BSTR *strName,
512 VARIANT *pVal,
513 CIMTYPE *pType,
514 LONG *plFlavor )
516 struct class_object *obj = impl_from_IWbemClassObject( iface );
517 struct enum_class_object *iter = impl_from_IEnumWbemClassObject( obj->iter );
518 struct view *view = iter->query->view;
519 BSTR prop;
520 HRESULT hr;
521 UINT i;
523 TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
525 for (i = obj->index_property; i < view->table->num_cols; i++)
527 if (is_method( view->table, i )) continue;
528 if (!is_selected_prop( view, view->table->columns[i].name )) continue;
529 if (!(prop = SysAllocString( view->table->columns[i].name ))) return E_OUTOFMEMORY;
530 if ((hr = get_propval( view, obj->index, prop, pVal, pType, plFlavor )) != S_OK)
532 SysFreeString( prop );
533 return hr;
536 obj->index_property = i + 1;
537 if (strName) *strName = prop;
538 else SysFreeString( prop );
540 return S_OK;
542 return WBEM_S_NO_MORE_DATA;
545 static HRESULT WINAPI class_object_EndEnumeration(
546 IWbemClassObject *iface )
548 struct class_object *co = impl_from_IWbemClassObject( iface );
550 TRACE("%p\n", iface);
552 co->index_property = 0;
553 return S_OK;
556 static HRESULT WINAPI class_object_GetPropertyQualifierSet(
557 IWbemClassObject *iface,
558 LPCWSTR wszProperty,
559 IWbemQualifierSet **ppQualSet )
561 struct class_object *co = impl_from_IWbemClassObject( iface );
563 TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet);
565 return WbemQualifierSet_create( co->name, wszProperty, (void **)ppQualSet );
568 static HRESULT WINAPI class_object_Clone(
569 IWbemClassObject *iface,
570 IWbemClassObject **ppCopy )
572 FIXME("%p, %p\n", iface, ppCopy);
573 return E_NOTIMPL;
576 static BSTR get_body_text( const struct table *table, UINT row, UINT *len )
578 static const WCHAR fmtW[] = {'\n','\t','%','s',' ','=',' ','%','s',';',0};
579 BSTR value, ret;
580 WCHAR *p;
581 UINT i;
583 *len = 0;
584 for (i = 0; i < table->num_cols; i++)
586 if ((value = get_value_bstr( table, row, i )))
588 *len += ARRAY_SIZE( fmtW );
589 *len += strlenW( table->columns[i].name );
590 *len += SysStringLen( value );
591 SysFreeString( value );
594 if (!(ret = SysAllocStringLen( NULL, *len ))) return NULL;
595 p = ret;
596 for (i = 0; i < table->num_cols; i++)
598 if ((value = get_value_bstr( table, row, i )))
600 p += sprintfW( p, fmtW, table->columns[i].name, value );
601 SysFreeString( value );
604 return ret;
607 static BSTR get_object_text( const struct view *view, UINT index )
609 static const WCHAR fmtW[] =
610 {'\n','i','n','s','t','a','n','c','e',' ','o','f',' ','%','s','\n','{','%','s','\n','}',';',0};
611 UINT len, len_body, row = view->result[index];
612 BSTR ret, body;
614 len = ARRAY_SIZE( fmtW );
615 len += strlenW( view->table->name );
616 if (!(body = get_body_text( view->table, row, &len_body ))) return NULL;
617 len += len_body;
619 if (!(ret = SysAllocStringLen( NULL, len ))) return NULL;
620 sprintfW( ret, fmtW, view->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 view *view = ec->query->view;
661 struct record *record;
663 TRACE("%p, %08x, %p\n", iface, lFlags, ppNewInstance);
665 if (!(record = create_record( view->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 static const WCHAR parameterW[] = {'P','a','r','a','m','e','t','e','r',0};
730 static const WCHAR typeW[] = {'T','y','p','e',0};
731 static const WCHAR varianttypeW[] = {'V','a','r','i','a','n','t','T','y','p','e',0};
732 static const WCHAR defaultvalueW[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
733 struct column *columns;
734 BYTE *row;
735 IWbemClassObject *param;
736 VARIANT val;
737 HRESULT hr = E_OUTOFMEMORY;
738 UINT offset = 0;
739 ULONG count;
740 int i = 0;
742 count = count_instances( iter );
743 if (!(columns = heap_alloc( count * sizeof(struct column) ))) return E_OUTOFMEMORY;
744 if (!(row = heap_alloc_zero( count * sizeof(LONGLONG) ))) goto error;
746 for (;;)
748 IEnumWbemClassObject_Next( iter, WBEM_INFINITE, 1, &param, &count );
749 if (!count) break;
751 hr = IWbemClassObject_Get( param, parameterW, 0, &val, NULL, NULL );
752 if (hr != S_OK) goto error;
753 columns[i].name = heap_strdupW( V_BSTR( &val ) );
754 VariantClear( &val );
756 hr = IWbemClassObject_Get( param, typeW, 0, &val, NULL, NULL );
757 if (hr != S_OK) goto error;
758 columns[i].type = V_UI4( &val );
760 hr = IWbemClassObject_Get( param, varianttypeW, 0, &val, NULL, NULL );
761 if (hr != S_OK) goto error;
762 columns[i].vartype = V_UI4( &val );
764 hr = IWbemClassObject_Get( param, defaultvalueW, 0, &val, NULL, NULL );
765 if (hr != S_OK) goto error;
766 if (V_UI4( &val )) set_default_value( columns[i].type, V_UI4( &val ), row + offset );
767 offset += get_type_size( columns[i].type );
769 IWbemClassObject_Release( param );
770 i++;
772 *num_cols = i;
773 *cols = columns;
774 *data = row;
775 return S_OK;
777 error:
778 for (; i >= 0; i--) heap_free( (WCHAR *)columns[i].name );
779 heap_free( columns );
780 heap_free( row );
781 return hr;
784 static HRESULT create_signature_table( IEnumWbemClassObject *iter, WCHAR *name )
786 HRESULT hr;
787 struct table *table;
788 struct column *columns;
789 UINT num_cols;
790 BYTE *row;
792 hr = create_signature_columns_and_data( iter, &num_cols, &columns, &row );
793 if (hr != S_OK) return hr;
795 if (!(table = create_table( name, num_cols, columns, 1, 1, row, NULL )))
797 free_columns( columns, num_cols );
798 heap_free( row );
799 return E_OUTOFMEMORY;
801 if (!add_table( table )) free_table( table ); /* already exists */
802 return S_OK;
805 static WCHAR *build_signature_table_name( const WCHAR *class, const WCHAR *method, enum param_direction dir )
807 static const WCHAR fmtW[] = {'_','_','%','s','_','%','s','_','%','s',0};
808 static const WCHAR outW[] = {'O','U','T',0};
809 static const WCHAR inW[] = {'I','N',0};
810 UINT len = SIZEOF(fmtW) + SIZEOF(outW) + strlenW( class ) + strlenW( method );
811 WCHAR *ret;
813 if (!(ret = heap_alloc( len * sizeof(WCHAR) ))) return NULL;
814 sprintfW( ret, fmtW, class, method, dir == PARAM_IN ? inW : outW );
815 return struprW( ret );
818 HRESULT create_signature( const WCHAR *class, const WCHAR *method, enum param_direction dir,
819 IWbemClassObject **sig )
821 static const WCHAR selectW[] =
822 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
823 '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
824 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
825 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
826 'D','i','r','e','c','t','i','o','n','%','s',0};
827 static const WCHAR geW[] = {'>','=','0',0};
828 static const WCHAR leW[] = {'<','=','0',0};
829 UINT len = SIZEOF(selectW) + SIZEOF(geW);
830 IEnumWbemClassObject *iter;
831 WCHAR *query, *name;
832 HRESULT hr;
834 len += strlenW( class ) + strlenW( method );
835 if (!(query = heap_alloc( len * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
836 sprintfW( query, selectW, class, method, dir >= 0 ? geW : leW );
838 hr = exec_query( query, &iter );
839 heap_free( query );
840 if (hr != S_OK) return hr;
842 if (!count_instances( iter ))
844 *sig = NULL;
845 IEnumWbemClassObject_Release( iter );
846 return S_OK;
849 if (!(name = build_signature_table_name( class, method, dir )))
851 IEnumWbemClassObject_Release( iter );
852 return E_OUTOFMEMORY;
854 hr = create_signature_table( iter, name );
855 IEnumWbemClassObject_Release( iter );
856 if (hr == S_OK)
857 hr = get_object( name, sig );
859 heap_free( name );
860 return hr;
863 static HRESULT WINAPI class_object_GetMethod(
864 IWbemClassObject *iface,
865 LPCWSTR wszName,
866 LONG lFlags,
867 IWbemClassObject **ppInSignature,
868 IWbemClassObject **ppOutSignature )
870 struct class_object *co = impl_from_IWbemClassObject( iface );
871 IWbemClassObject *in, *out;
872 HRESULT hr;
874 TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature);
876 hr = create_signature( co->name, wszName, PARAM_IN, &in );
877 if (hr != S_OK) return hr;
879 hr = create_signature( co->name, wszName, PARAM_OUT, &out );
880 if (hr == S_OK)
882 if (ppInSignature) *ppInSignature = in;
883 else if (in) IWbemClassObject_Release( in );
884 if (ppOutSignature) *ppOutSignature = out;
885 else if (out) IWbemClassObject_Release( out );
887 else IWbemClassObject_Release( in );
888 return hr;
891 static HRESULT WINAPI class_object_PutMethod(
892 IWbemClassObject *iface,
893 LPCWSTR wszName,
894 LONG lFlags,
895 IWbemClassObject *pInSignature,
896 IWbemClassObject *pOutSignature )
898 FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature);
899 return E_NOTIMPL;
902 static HRESULT WINAPI class_object_DeleteMethod(
903 IWbemClassObject *iface,
904 LPCWSTR wszName )
906 FIXME("%p, %s\n", iface, debugstr_w(wszName));
907 return E_NOTIMPL;
910 static HRESULT WINAPI class_object_BeginMethodEnumeration(
911 IWbemClassObject *iface,
912 LONG lEnumFlags)
914 struct class_object *co = impl_from_IWbemClassObject( iface );
916 TRACE("%p, %08x\n", iface, lEnumFlags);
918 if (lEnumFlags) FIXME("flags 0x%08x not supported\n", lEnumFlags);
920 co->index_method = 0;
921 return S_OK;
924 static HRESULT WINAPI class_object_NextMethod(
925 IWbemClassObject *iface,
926 LONG lFlags,
927 BSTR *pstrName,
928 IWbemClassObject **ppInSignature,
929 IWbemClassObject **ppOutSignature)
931 struct class_object *co = impl_from_IWbemClassObject( iface );
932 BSTR method;
933 HRESULT hr;
935 TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
937 if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;
939 hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
940 if (hr != S_OK)
942 SysFreeString( method );
943 return hr;
945 hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
946 if (hr != S_OK)
948 SysFreeString( method );
949 if (*ppInSignature)
950 IWbemClassObject_Release( *ppInSignature );
952 else
954 *pstrName = method;
955 co->index_method++;
957 return hr;
960 static HRESULT WINAPI class_object_EndMethodEnumeration(
961 IWbemClassObject *iface )
963 struct class_object *co = impl_from_IWbemClassObject( iface );
965 TRACE("%p\n", iface);
967 co->index_method = 0;
968 return S_OK;
971 static HRESULT WINAPI class_object_GetMethodQualifierSet(
972 IWbemClassObject *iface,
973 LPCWSTR wszMethod,
974 IWbemQualifierSet **ppQualSet)
976 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet);
977 return E_NOTIMPL;
980 static HRESULT WINAPI class_object_GetMethodOrigin(
981 IWbemClassObject *iface,
982 LPCWSTR wszMethodName,
983 BSTR *pstrClassName)
985 FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName);
986 return E_NOTIMPL;
989 static const IWbemClassObjectVtbl class_object_vtbl =
991 class_object_QueryInterface,
992 class_object_AddRef,
993 class_object_Release,
994 class_object_GetQualifierSet,
995 class_object_Get,
996 class_object_Put,
997 class_object_Delete,
998 class_object_GetNames,
999 class_object_BeginEnumeration,
1000 class_object_Next,
1001 class_object_EndEnumeration,
1002 class_object_GetPropertyQualifierSet,
1003 class_object_Clone,
1004 class_object_GetObjectText,
1005 class_object_SpawnDerivedClass,
1006 class_object_SpawnInstance,
1007 class_object_CompareTo,
1008 class_object_GetPropertyOrigin,
1009 class_object_InheritsFrom,
1010 class_object_GetMethod,
1011 class_object_PutMethod,
1012 class_object_DeleteMethod,
1013 class_object_BeginMethodEnumeration,
1014 class_object_NextMethod,
1015 class_object_EndMethodEnumeration,
1016 class_object_GetMethodQualifierSet,
1017 class_object_GetMethodOrigin
1020 HRESULT create_class_object( const WCHAR *name, IEnumWbemClassObject *iter, UINT index,
1021 struct record *record, IWbemClassObject **obj )
1023 struct class_object *co;
1025 TRACE("%s, %p\n", debugstr_w(name), obj);
1027 co = heap_alloc( sizeof(*co) );
1028 if (!co) return E_OUTOFMEMORY;
1030 co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl;
1031 co->refs = 1;
1032 if (!name) co->name = NULL;
1033 else if (!(co->name = heap_strdupW( name )))
1035 heap_free( co );
1036 return E_OUTOFMEMORY;
1038 co->iter = iter;
1039 co->index = index;
1040 co->index_method = 0;
1041 co->index_property = 0;
1042 co->record = record;
1043 if (iter) IEnumWbemClassObject_AddRef( iter );
1045 *obj = &co->IWbemClassObject_iface;
1047 TRACE("returning iface %p\n", *obj);
1048 return S_OK;