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
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
;
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
);
61 TRACE("destroying %p\n", ec
);
62 release_query( ec
->query
);
68 static HRESULT WINAPI
enum_class_object_QueryInterface(
69 IEnumWbemClassObject
*iface
,
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
) )
82 else if ( IsEqualGUID( riid
, &IID_IClientSecurity
) )
84 *ppvObject
= &client_security
;
89 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
92 IEnumWbemClassObject_AddRef( iface
);
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
);
104 return WBEM_S_NO_ERROR
;
107 static HRESULT WINAPI
enum_class_object_Next(
108 IEnumWbemClassObject
*iface
,
111 IWbemClassObject
**apObjects
,
114 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
115 struct view
*view
= ec
->query
->view
;
121 TRACE("%p, %d, %u, %p, %p\n", iface
, lTimeout
, uCount
, apObjects
, puReturned
);
123 if (!apObjects
|| !puReturned
) return WBEM_E_INVALID_PARAMETER
;
124 if (lTimeout
!= WBEM_INFINITE
&& !once
++) FIXME("timeout not supported\n");
128 for (i
= 0; i
< uCount
; i
++)
130 if (ec
->index
>= view
->result_count
) return WBEM_S_FALSE
;
131 table
= get_view_table( view
, ec
->index
);
132 hr
= create_class_object( table
->name
, iface
, ec
->index
, NULL
, &apObjects
[i
] );
135 for (j
= 0; j
< i
; j
++) IWbemClassObject_Release( apObjects
[j
] );
142 return WBEM_S_NO_ERROR
;
145 static HRESULT WINAPI
enum_class_object_NextAsync(
146 IEnumWbemClassObject
*iface
,
148 IWbemObjectSink
*pSink
)
150 FIXME("%p, %u, %p\n", iface
, uCount
, pSink
);
154 static HRESULT WINAPI
enum_class_object_Clone(
155 IEnumWbemClassObject
*iface
,
156 IEnumWbemClassObject
**ppEnum
)
158 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
160 TRACE("%p, %p\n", iface
, ppEnum
);
162 return EnumWbemClassObject_create( ec
->query
, (void **)ppEnum
);
165 static HRESULT WINAPI
enum_class_object_Skip(
166 IEnumWbemClassObject
*iface
,
170 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
171 struct view
*view
= ec
->query
->view
;
174 TRACE("%p, %d, %u\n", iface
, lTimeout
, nCount
);
176 if (lTimeout
!= WBEM_INFINITE
&& !once
++) FIXME("timeout not supported\n");
178 if (!view
->result_count
) return WBEM_S_FALSE
;
180 if (nCount
> view
->result_count
- ec
->index
)
182 ec
->index
= view
->result_count
- 1;
186 return WBEM_S_NO_ERROR
;
189 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl
=
191 enum_class_object_QueryInterface
,
192 enum_class_object_AddRef
,
193 enum_class_object_Release
,
194 enum_class_object_Reset
,
195 enum_class_object_Next
,
196 enum_class_object_NextAsync
,
197 enum_class_object_Clone
,
198 enum_class_object_Skip
201 HRESULT
EnumWbemClassObject_create( struct query
*query
, LPVOID
*ppObj
)
203 struct enum_class_object
*ec
;
205 TRACE("%p\n", ppObj
);
207 ec
= heap_alloc( sizeof(*ec
) );
208 if (!ec
) return E_OUTOFMEMORY
;
210 ec
->IEnumWbemClassObject_iface
.lpVtbl
= &enum_class_object_vtbl
;
212 ec
->query
= addref_query( query
);
215 *ppObj
= &ec
->IEnumWbemClassObject_iface
;
217 TRACE("returning iface %p\n", *ppObj
);
221 static struct record
*create_record( struct table
*table
)
224 struct record
*record
;
226 if (!(record
= heap_alloc( sizeof(struct record
) ))) return NULL
;
227 if (!(record
->fields
= heap_alloc( table
->num_cols
* sizeof(struct field
) )))
232 for (i
= 0; i
< table
->num_cols
; i
++)
234 record
->fields
[i
].type
= table
->columns
[i
].type
;
235 record
->fields
[i
].u
.ival
= 0;
237 record
->count
= table
->num_cols
;
238 record
->table
= addref_table( table
);
242 void destroy_array( struct array
*array
, CIMTYPE type
)
246 if (type
== CIM_STRING
|| type
== CIM_DATETIME
|| type
== CIM_REFERENCE
)
248 for (i
= 0; i
< array
->count
; i
++) heap_free( *(WCHAR
**)((char *)array
->ptr
+ i
* array
->elem_size
) );
250 heap_free( array
->ptr
);
254 static void destroy_record( struct record
*record
)
259 release_table( record
->table
);
260 for (i
= 0; i
< record
->count
; i
++)
262 if (record
->fields
[i
].type
== CIM_STRING
||
263 record
->fields
[i
].type
== CIM_DATETIME
||
264 record
->fields
[i
].type
== CIM_REFERENCE
) heap_free( record
->fields
[i
].u
.sval
);
265 else if (record
->fields
[i
].type
& CIM_FLAG_ARRAY
)
266 destroy_array( record
->fields
[i
].u
.aval
, record
->fields
[i
].type
& CIM_TYPE_MASK
);
268 heap_free( record
->fields
);
274 IWbemClassObject IWbemClassObject_iface
;
277 IEnumWbemClassObject
*iter
;
281 struct record
*record
; /* uncommitted instance */
284 static inline struct class_object
*impl_from_IWbemClassObject(
285 IWbemClassObject
*iface
)
287 return CONTAINING_RECORD(iface
, struct class_object
, IWbemClassObject_iface
);
290 static ULONG WINAPI
class_object_AddRef(
291 IWbemClassObject
*iface
)
293 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
294 return InterlockedIncrement( &co
->refs
);
297 static ULONG WINAPI
class_object_Release(
298 IWbemClassObject
*iface
)
300 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
301 LONG refs
= InterlockedDecrement( &co
->refs
);
304 TRACE("destroying %p\n", co
);
305 if (co
->iter
) IEnumWbemClassObject_Release( co
->iter
);
306 destroy_record( co
->record
);
307 heap_free( co
->name
);
313 static HRESULT WINAPI
class_object_QueryInterface(
314 IWbemClassObject
*iface
,
318 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
320 TRACE("%p, %s, %p\n", co
, debugstr_guid( riid
), ppvObject
);
322 if ( IsEqualGUID( riid
, &IID_IWbemClassObject
) ||
323 IsEqualGUID( riid
, &IID_IUnknown
) )
327 else if (IsEqualGUID( riid
, &IID_IClientSecurity
))
329 *ppvObject
= &client_security
;
334 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
335 return E_NOINTERFACE
;
337 IWbemClassObject_AddRef( iface
);
341 static HRESULT WINAPI
class_object_GetQualifierSet(
342 IWbemClassObject
*iface
,
343 IWbemQualifierSet
**ppQualSet
)
345 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
347 TRACE("%p, %p\n", iface
, ppQualSet
);
349 return WbemQualifierSet_create( co
->name
, NULL
, (void **)ppQualSet
);
352 static HRESULT
record_get_value( const struct record
*record
, UINT index
, VARIANT
*var
, CIMTYPE
*type
)
354 VARTYPE vartype
= to_vartype( record
->fields
[index
].type
& CIM_TYPE_MASK
);
356 if (type
) *type
= record
->fields
[index
].type
;
358 if (record
->fields
[index
].type
& CIM_FLAG_ARRAY
)
360 V_VT( var
) = vartype
| VT_ARRAY
;
361 V_ARRAY( var
) = to_safearray( record
->fields
[index
].u
.aval
, record
->fields
[index
].type
& CIM_TYPE_MASK
);
364 switch (record
->fields
[index
].type
)
369 V_BSTR( var
) = SysAllocString( record
->fields
[index
].u
.sval
);
372 V_I4( var
) = record
->fields
[index
].u
.ival
;
375 V_UI4( var
) = record
->fields
[index
].u
.ival
;
378 FIXME("unhandled type %u\n", record
->fields
[index
].type
);
379 return WBEM_E_INVALID_PARAMETER
;
381 V_VT( var
) = vartype
;
385 static HRESULT WINAPI
class_object_Get(
386 IWbemClassObject
*iface
,
393 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
394 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
396 TRACE("%p, %s, %08x, %p, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, pVal
, pType
, plFlavor
);
403 if ((hr
= get_column_index( co
->record
->table
, wszName
, &index
)) != S_OK
) return hr
;
404 return record_get_value( co
->record
, index
, pVal
, pType
);
406 return get_propval( ec
->query
->view
, co
->index
, wszName
, pVal
, pType
, plFlavor
);
409 static HRESULT
record_set_value( struct record
*record
, UINT index
, VARIANT
*var
)
415 if ((hr
= to_longlong( var
, &val
, &type
)) != S_OK
) return hr
;
416 if (type
!= record
->fields
[index
].type
) return WBEM_E_TYPE_MISMATCH
;
418 if (type
& CIM_FLAG_ARRAY
)
420 record
->fields
[index
].u
.aval
= (struct array
*)(INT_PTR
)val
;
428 record
->fields
[index
].u
.sval
= (WCHAR
*)(INT_PTR
)val
;
434 record
->fields
[index
].u
.ival
= val
;
437 FIXME("unhandled type %u\n", type
);
440 return WBEM_E_INVALID_PARAMETER
;
443 static HRESULT WINAPI
class_object_Put(
444 IWbemClassObject
*iface
,
450 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
451 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
453 TRACE("%p, %s, %08x, %p, %u\n", iface
, debugstr_w(wszName
), lFlags
, pVal
, Type
);
460 if ((hr
= get_column_index( co
->record
->table
, wszName
, &index
)) != S_OK
) return hr
;
461 return record_set_value( co
->record
, index
, pVal
);
464 if (!ec
) return S_OK
;
466 return put_propval( ec
->query
->view
, co
->index
, wszName
, pVal
, Type
);
469 static HRESULT WINAPI
class_object_Delete(
470 IWbemClassObject
*iface
,
473 FIXME("%p, %s\n", iface
, debugstr_w(wszName
));
477 static HRESULT WINAPI
class_object_GetNames(
478 IWbemClassObject
*iface
,
479 LPCWSTR wszQualifierName
,
481 VARIANT
*pQualifierVal
,
484 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
485 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
487 TRACE("%p, %s, %08x, %s, %p\n", iface
, debugstr_w(wszQualifierName
), lFlags
,
488 debugstr_variant(pQualifierVal
), pNames
);
491 return WBEM_E_INVALID_PARAMETER
;
493 /* Combination used in a handful of broken apps */
494 if (lFlags
== (WBEM_FLAG_ALWAYS
| WBEM_MASK_CONDITION_ORIGIN
))
495 lFlags
= WBEM_FLAG_ALWAYS
;
497 if (lFlags
&& (lFlags
!= WBEM_FLAG_ALWAYS
&&
498 lFlags
!= WBEM_FLAG_NONSYSTEM_ONLY
&&
499 lFlags
!= WBEM_FLAG_SYSTEM_ONLY
))
501 FIXME("flags %08x not supported\n", lFlags
);
505 if (wszQualifierName
|| pQualifierVal
)
506 FIXME("qualifier not supported\n");
508 return get_properties( ec
->query
->view
, co
->index
, lFlags
, pNames
);
511 static HRESULT WINAPI
class_object_BeginEnumeration(
512 IWbemClassObject
*iface
,
515 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
517 TRACE("%p, %08x\n", iface
, lEnumFlags
);
519 if (lEnumFlags
) FIXME("flags 0x%08x not supported\n", lEnumFlags
);
521 co
->index_property
= 0;
525 static HRESULT WINAPI
class_object_Next(
526 IWbemClassObject
*iface
,
533 struct class_object
*obj
= impl_from_IWbemClassObject( iface
);
534 struct enum_class_object
*iter
= impl_from_IEnumWbemClassObject( obj
->iter
);
535 struct view
*view
= iter
->query
->view
;
536 struct table
*table
= get_view_table( view
, obj
->index
);
541 TRACE("%p, %08x, %p, %p, %p, %p\n", iface
, lFlags
, strName
, pVal
, pType
, plFlavor
);
543 for (i
= obj
->index_property
; i
< table
->num_cols
; i
++)
545 if (is_method( table
, i
)) continue;
546 if (!is_result_prop( view
, table
->columns
[i
].name
)) continue;
547 if (!(prop
= SysAllocString( table
->columns
[i
].name
))) return E_OUTOFMEMORY
;
548 if ((hr
= get_propval( view
, obj
->index
, prop
, pVal
, pType
, plFlavor
)) != S_OK
)
550 SysFreeString( prop
);
554 obj
->index_property
= i
+ 1;
555 if (strName
) *strName
= prop
;
556 else SysFreeString( prop
);
560 return WBEM_S_NO_MORE_DATA
;
563 static HRESULT WINAPI
class_object_EndEnumeration(
564 IWbemClassObject
*iface
)
566 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
568 TRACE("%p\n", iface
);
570 co
->index_property
= 0;
574 static HRESULT WINAPI
class_object_GetPropertyQualifierSet(
575 IWbemClassObject
*iface
,
577 IWbemQualifierSet
**ppQualSet
)
579 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
581 TRACE("%p, %s, %p\n", iface
, debugstr_w(wszProperty
), ppQualSet
);
583 return WbemQualifierSet_create( co
->name
, wszProperty
, (void **)ppQualSet
);
586 static HRESULT WINAPI
class_object_Clone(
587 IWbemClassObject
*iface
,
588 IWbemClassObject
**ppCopy
)
590 FIXME("%p, %p\n", iface
, ppCopy
);
594 static BSTR
get_body_text( const struct table
*table
, UINT row
, UINT
*len
)
601 for (i
= 0; i
< table
->num_cols
; i
++)
603 if ((value
= get_value_bstr( table
, row
, i
)))
605 *len
+= ARRAY_SIZE( L
"\n\t%s = %s;" );
606 *len
+= lstrlenW( table
->columns
[i
].name
);
607 *len
+= SysStringLen( value
);
608 SysFreeString( value
);
611 if (!(ret
= SysAllocStringLen( NULL
, *len
))) return NULL
;
613 for (i
= 0; i
< table
->num_cols
; i
++)
615 if ((value
= get_value_bstr( table
, row
, i
)))
617 p
+= swprintf( p
, *len
- (p
- ret
), L
"\n\t%s = %s;", table
->columns
[i
].name
, value
);
618 SysFreeString( value
);
624 static BSTR
get_object_text( const struct view
*view
, UINT index
)
626 UINT len
, len_body
, row
= view
->result
[index
];
627 struct table
*table
= get_view_table( view
, index
);
630 len
= ARRAY_SIZE( L
"\ninstance of %s\n{%s\n};" );
631 len
+= lstrlenW( table
->name
);
632 if (!(body
= get_body_text( table
, row
, &len_body
))) return NULL
;
635 if (!(ret
= SysAllocStringLen( NULL
, len
))) return NULL
;
636 swprintf( ret
, len
, L
"\ninstance of %s\n{%s\n};", table
->name
, body
);
637 SysFreeString( body
);
641 static HRESULT WINAPI
class_object_GetObjectText(
642 IWbemClassObject
*iface
,
644 BSTR
*pstrObjectText
)
646 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
647 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
648 struct view
*view
= ec
->query
->view
;
651 TRACE("%p, %08x, %p\n", iface
, lFlags
, pstrObjectText
);
653 if (lFlags
) FIXME("flags %08x not implemented\n", lFlags
);
655 if (!(text
= get_object_text( view
, co
->index
))) return E_OUTOFMEMORY
;
656 *pstrObjectText
= text
;
660 static HRESULT WINAPI
class_object_SpawnDerivedClass(
661 IWbemClassObject
*iface
,
663 IWbemClassObject
**ppNewClass
)
665 FIXME("%p, %08x, %p\n", iface
, lFlags
, ppNewClass
);
669 static HRESULT WINAPI
class_object_SpawnInstance(
670 IWbemClassObject
*iface
,
672 IWbemClassObject
**ppNewInstance
)
674 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
675 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
676 struct table
*table
= get_view_table( ec
->query
->view
, co
->index
);
677 struct record
*record
;
679 TRACE("%p, %08x, %p\n", iface
, lFlags
, ppNewInstance
);
681 if (!(record
= create_record( table
))) return E_OUTOFMEMORY
;
683 return create_class_object( co
->name
, NULL
, 0, record
, ppNewInstance
);
686 static HRESULT WINAPI
class_object_CompareTo(
687 IWbemClassObject
*iface
,
689 IWbemClassObject
*pCompareTo
)
691 FIXME("%p, %08x, %p\n", iface
, lFlags
, pCompareTo
);
695 static HRESULT WINAPI
class_object_GetPropertyOrigin(
696 IWbemClassObject
*iface
,
698 BSTR
*pstrClassName
)
700 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszName
), pstrClassName
);
704 static HRESULT WINAPI
class_object_InheritsFrom(
705 IWbemClassObject
*iface
,
706 LPCWSTR strAncestor
)
708 FIXME("%p, %s\n", iface
, debugstr_w(strAncestor
));
712 static UINT
count_instances( IEnumWbemClassObject
*iter
)
715 while (!IEnumWbemClassObject_Skip( iter
, WBEM_INFINITE
, 1 )) count
++;
716 IEnumWbemClassObject_Reset( iter
);
720 static void set_default_value( CIMTYPE type
, UINT val
, BYTE
*ptr
)
728 *(UINT16
*)ptr
= val
;
734 *(UINT32
*)ptr
= val
;
737 FIXME("unhandled type %u\n", type
);
742 static HRESULT
create_signature_columns_and_data( IEnumWbemClassObject
*iter
, UINT
*num_cols
,
743 struct column
**cols
, BYTE
**data
)
745 struct column
*columns
;
747 IWbemClassObject
*param
;
749 HRESULT hr
= E_OUTOFMEMORY
;
754 count
= count_instances( iter
);
755 if (!(columns
= heap_alloc( count
* sizeof(struct column
) ))) return E_OUTOFMEMORY
;
756 if (!(row
= heap_alloc_zero( count
* sizeof(LONGLONG
) ))) goto error
;
760 IEnumWbemClassObject_Next( iter
, WBEM_INFINITE
, 1, ¶m
, &count
);
763 hr
= IWbemClassObject_Get( param
, L
"Parameter", 0, &val
, NULL
, NULL
);
764 if (hr
!= S_OK
) goto error
;
765 columns
[i
].name
= heap_strdupW( V_BSTR( &val
) );
766 VariantClear( &val
);
768 hr
= IWbemClassObject_Get( param
, L
"Type", 0, &val
, NULL
, NULL
);
769 if (hr
!= S_OK
) goto error
;
770 columns
[i
].type
= V_UI4( &val
);
772 hr
= IWbemClassObject_Get( param
, L
"DefaultValue", 0, &val
, NULL
, NULL
);
773 if (hr
!= S_OK
) goto error
;
774 if (V_UI4( &val
)) set_default_value( columns
[i
].type
, V_UI4( &val
), row
+ offset
);
775 offset
+= get_type_size( columns
[i
].type
);
777 IWbemClassObject_Release( param
);
786 for (; i
>= 0; i
--) heap_free( (WCHAR
*)columns
[i
].name
);
787 heap_free( columns
);
792 static HRESULT
create_signature_table( IEnumWbemClassObject
*iter
, WCHAR
*name
)
796 struct column
*columns
;
800 hr
= create_signature_columns_and_data( iter
, &num_cols
, &columns
, &row
);
801 if (hr
!= S_OK
) return hr
;
803 if (!(table
= create_table( name
, num_cols
, columns
, 1, 1, row
, NULL
)))
805 free_columns( columns
, num_cols
);
807 return E_OUTOFMEMORY
;
809 if (!add_table( table
)) free_table( table
); /* already exists */
813 static WCHAR
*build_signature_table_name( const WCHAR
*class, const WCHAR
*method
, enum param_direction dir
)
815 UINT len
= ARRAY_SIZE(L
"__%s_%s_%s") + ARRAY_SIZE(L
"OUT") + lstrlenW( class ) + lstrlenW( method
);
818 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
819 swprintf( ret
, len
, L
"__%s_%s_%s", class, method
, dir
== PARAM_IN
? L
"IN" : L
"OUT" );
820 return wcsupr( ret
);
823 HRESULT
create_signature( const WCHAR
*class, const WCHAR
*method
, enum param_direction dir
,
824 IWbemClassObject
**sig
)
826 static const WCHAR selectW
[] = L
"SELECT * FROM __PARAMETERS WHERE Class='%s' AND Method='%s' AND Direction%s";
827 UINT len
= ARRAY_SIZE(selectW
) + ARRAY_SIZE(L
">=0");
828 IEnumWbemClassObject
*iter
;
832 len
+= lstrlenW( class ) + lstrlenW( method
);
833 if (!(query
= heap_alloc( len
* sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
834 swprintf( query
, len
, selectW
, class, method
, dir
>= 0 ? L
">=0" : L
"<=0" );
836 hr
= exec_query( query
, &iter
);
838 if (hr
!= S_OK
) return hr
;
840 if (!count_instances( iter
))
843 IEnumWbemClassObject_Release( iter
);
847 if (!(name
= build_signature_table_name( class, method
, dir
)))
849 IEnumWbemClassObject_Release( iter
);
850 return E_OUTOFMEMORY
;
852 hr
= create_signature_table( iter
, name
);
853 IEnumWbemClassObject_Release( iter
);
855 hr
= get_object( name
, sig
);
861 static HRESULT WINAPI
class_object_GetMethod(
862 IWbemClassObject
*iface
,
865 IWbemClassObject
**ppInSignature
,
866 IWbemClassObject
**ppOutSignature
)
868 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
869 IWbemClassObject
*in
, *out
;
872 TRACE("%p, %s, %08x, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, ppInSignature
, ppOutSignature
);
874 hr
= create_signature( co
->name
, wszName
, PARAM_IN
, &in
);
875 if (hr
!= S_OK
) return hr
;
877 hr
= create_signature( co
->name
, wszName
, PARAM_OUT
, &out
);
880 if (ppInSignature
) *ppInSignature
= in
;
881 else if (in
) IWbemClassObject_Release( in
);
882 if (ppOutSignature
) *ppOutSignature
= out
;
883 else if (out
) IWbemClassObject_Release( out
);
885 else IWbemClassObject_Release( in
);
889 static HRESULT WINAPI
class_object_PutMethod(
890 IWbemClassObject
*iface
,
893 IWbemClassObject
*pInSignature
,
894 IWbemClassObject
*pOutSignature
)
896 FIXME("%p, %s, %08x, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, pInSignature
, pOutSignature
);
900 static HRESULT WINAPI
class_object_DeleteMethod(
901 IWbemClassObject
*iface
,
904 FIXME("%p, %s\n", iface
, debugstr_w(wszName
));
908 static HRESULT WINAPI
class_object_BeginMethodEnumeration(
909 IWbemClassObject
*iface
,
912 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
914 TRACE("%p, %08x\n", iface
, lEnumFlags
);
916 if (lEnumFlags
) FIXME("flags 0x%08x not supported\n", lEnumFlags
);
918 co
->index_method
= 0;
922 static HRESULT WINAPI
class_object_NextMethod(
923 IWbemClassObject
*iface
,
926 IWbemClassObject
**ppInSignature
,
927 IWbemClassObject
**ppOutSignature
)
929 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
933 TRACE("%p, %08x, %p, %p, %p\n", iface
, lFlags
, pstrName
, ppInSignature
, ppOutSignature
);
935 if (!(method
= get_method_name( co
->name
, co
->index_method
))) return WBEM_S_NO_MORE_DATA
;
937 hr
= create_signature( co
->name
, method
, PARAM_IN
, ppInSignature
);
940 SysFreeString( method
);
943 hr
= create_signature( co
->name
, method
, PARAM_OUT
, ppOutSignature
);
946 SysFreeString( method
);
948 IWbemClassObject_Release( *ppInSignature
);
958 static HRESULT WINAPI
class_object_EndMethodEnumeration(
959 IWbemClassObject
*iface
)
961 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
963 TRACE("%p\n", iface
);
965 co
->index_method
= 0;
969 static HRESULT WINAPI
class_object_GetMethodQualifierSet(
970 IWbemClassObject
*iface
,
972 IWbemQualifierSet
**ppQualSet
)
974 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
976 TRACE("%p, %s, %p\n", iface
, debugstr_w(wszMethod
), ppQualSet
);
978 return WbemQualifierSet_create( co
->name
, wszMethod
, (void **)ppQualSet
);
981 static HRESULT WINAPI
class_object_GetMethodOrigin(
982 IWbemClassObject
*iface
,
983 LPCWSTR wszMethodName
,
986 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszMethodName
), pstrClassName
);
990 static const IWbemClassObjectVtbl class_object_vtbl
=
992 class_object_QueryInterface
,
994 class_object_Release
,
995 class_object_GetQualifierSet
,
999 class_object_GetNames
,
1000 class_object_BeginEnumeration
,
1002 class_object_EndEnumeration
,
1003 class_object_GetPropertyQualifierSet
,
1005 class_object_GetObjectText
,
1006 class_object_SpawnDerivedClass
,
1007 class_object_SpawnInstance
,
1008 class_object_CompareTo
,
1009 class_object_GetPropertyOrigin
,
1010 class_object_InheritsFrom
,
1011 class_object_GetMethod
,
1012 class_object_PutMethod
,
1013 class_object_DeleteMethod
,
1014 class_object_BeginMethodEnumeration
,
1015 class_object_NextMethod
,
1016 class_object_EndMethodEnumeration
,
1017 class_object_GetMethodQualifierSet
,
1018 class_object_GetMethodOrigin
1021 HRESULT
create_class_object( const WCHAR
*name
, IEnumWbemClassObject
*iter
, UINT index
,
1022 struct record
*record
, IWbemClassObject
**obj
)
1024 struct class_object
*co
;
1026 TRACE("%s, %p\n", debugstr_w(name
), obj
);
1028 co
= heap_alloc( sizeof(*co
) );
1029 if (!co
) return E_OUTOFMEMORY
;
1031 co
->IWbemClassObject_iface
.lpVtbl
= &class_object_vtbl
;
1033 if (!name
) co
->name
= NULL
;
1034 else if (!(co
->name
= heap_strdupW( name
)))
1037 return E_OUTOFMEMORY
;
1041 co
->index_method
= 0;
1042 co
->index_property
= 0;
1043 co
->record
= record
;
1044 if (iter
) IEnumWbemClassObject_AddRef( iter
);
1046 *obj
= &co
->IWbemClassObject_iface
;
1048 TRACE("returning iface %p\n", *obj
);