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
;
39 enum wbm_namespace ns
;
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
;
122 TRACE( "%p, %ld, %lu, %p, %p\n", iface
, lTimeout
, uCount
, apObjects
, puReturned
);
124 if (!apObjects
|| !puReturned
) return WBEM_E_INVALID_PARAMETER
;
125 if (lTimeout
!= WBEM_INFINITE
&& !once
++) FIXME("timeout not supported\n");
129 for (i
= 0; i
< uCount
; i
++)
131 if (ec
->index
>= view
->result_count
) return WBEM_S_FALSE
;
132 table
= get_view_table( view
, ec
->index
);
133 hr
= create_class_object( ec
->ns
, table
->name
, iface
, ec
->index
, NULL
, &apObjects
[i
] );
136 for (j
= 0; j
< i
; j
++) IWbemClassObject_Release( apObjects
[j
] );
143 return WBEM_S_NO_ERROR
;
146 static HRESULT WINAPI
enum_class_object_NextAsync(
147 IEnumWbemClassObject
*iface
,
149 IWbemObjectSink
*pSink
)
151 FIXME( "%p, %lu, %p\n", iface
, uCount
, pSink
);
155 static HRESULT WINAPI
enum_class_object_Clone(
156 IEnumWbemClassObject
*iface
,
157 IEnumWbemClassObject
**ppEnum
)
159 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
161 TRACE("%p, %p\n", iface
, ppEnum
);
163 return EnumWbemClassObject_create( ec
->query
, (void **)ppEnum
);
166 static HRESULT WINAPI
enum_class_object_Skip(
167 IEnumWbemClassObject
*iface
,
171 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
172 struct view
*view
= ec
->query
->view
;
175 TRACE( "%p, %ld, %lu\n", iface
, lTimeout
, nCount
);
177 if (lTimeout
!= WBEM_INFINITE
&& !once
++) FIXME("timeout not supported\n");
179 if (!view
->result_count
) return WBEM_S_FALSE
;
181 if (nCount
> view
->result_count
- ec
->index
)
183 ec
->index
= view
->result_count
- 1;
187 return WBEM_S_NO_ERROR
;
190 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl
=
192 enum_class_object_QueryInterface
,
193 enum_class_object_AddRef
,
194 enum_class_object_Release
,
195 enum_class_object_Reset
,
196 enum_class_object_Next
,
197 enum_class_object_NextAsync
,
198 enum_class_object_Clone
,
199 enum_class_object_Skip
202 HRESULT
EnumWbemClassObject_create( struct query
*query
, LPVOID
*ppObj
)
204 struct enum_class_object
*ec
;
206 TRACE("%p\n", ppObj
);
208 if (!(ec
= malloc( sizeof(*ec
) ))) return E_OUTOFMEMORY
;
210 ec
->IEnumWbemClassObject_iface
.lpVtbl
= &enum_class_object_vtbl
;
212 ec
->query
= addref_query( query
);
216 *ppObj
= &ec
->IEnumWbemClassObject_iface
;
218 TRACE("returning iface %p\n", *ppObj
);
222 static struct record
*create_record( struct table
*table
)
225 struct record
*record
;
227 if (!(record
= malloc( sizeof(struct record
) ))) return NULL
;
228 if (!(record
->fields
= malloc( table
->num_cols
* sizeof(struct field
) )))
233 for (i
= 0; i
< table
->num_cols
; i
++)
235 record
->fields
[i
].type
= table
->columns
[i
].type
;
236 record
->fields
[i
].u
.ival
= 0;
238 record
->count
= table
->num_cols
;
239 record
->table
= addref_table( table
);
243 void destroy_array( struct array
*array
, CIMTYPE type
)
247 if (type
== CIM_STRING
|| type
== CIM_DATETIME
|| type
== CIM_REFERENCE
)
249 for (i
= 0; i
< array
->count
; i
++) free( *(WCHAR
**)((char *)array
->ptr
+ i
* array
->elem_size
) );
255 static void destroy_record( struct record
*record
)
260 release_table( record
->table
);
261 for (i
= 0; i
< record
->count
; i
++)
263 if (record
->fields
[i
].type
== CIM_STRING
||
264 record
->fields
[i
].type
== CIM_DATETIME
||
265 record
->fields
[i
].type
== CIM_REFERENCE
) free( record
->fields
[i
].u
.sval
);
266 else if (record
->fields
[i
].type
& CIM_FLAG_ARRAY
)
267 destroy_array( record
->fields
[i
].u
.aval
, record
->fields
[i
].type
& CIM_TYPE_MASK
);
269 free( record
->fields
);
275 IWbemClassObject IWbemClassObject_iface
;
278 IEnumWbemClassObject
*iter
;
282 enum wbm_namespace ns
;
283 struct record
*record
; /* uncommitted instance */
286 static inline struct class_object
*impl_from_IWbemClassObject(
287 IWbemClassObject
*iface
)
289 return CONTAINING_RECORD(iface
, struct class_object
, IWbemClassObject_iface
);
292 static ULONG WINAPI
class_object_AddRef(
293 IWbemClassObject
*iface
)
295 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
296 return InterlockedIncrement( &co
->refs
);
299 static ULONG WINAPI
class_object_Release(
300 IWbemClassObject
*iface
)
302 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
303 LONG refs
= InterlockedDecrement( &co
->refs
);
306 TRACE("destroying %p\n", co
);
307 if (co
->iter
) IEnumWbemClassObject_Release( co
->iter
);
308 destroy_record( co
->record
);
315 static HRESULT WINAPI
class_object_QueryInterface(
316 IWbemClassObject
*iface
,
320 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
322 TRACE("%p, %s, %p\n", co
, debugstr_guid( riid
), ppvObject
);
324 if ( IsEqualGUID( riid
, &IID_IWbemClassObject
) ||
325 IsEqualGUID( riid
, &IID_IUnknown
) )
329 else if (IsEqualGUID( riid
, &IID_IClientSecurity
))
331 *ppvObject
= &client_security
;
336 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
337 return E_NOINTERFACE
;
339 IWbemClassObject_AddRef( iface
);
343 static HRESULT WINAPI
class_object_GetQualifierSet(
344 IWbemClassObject
*iface
,
345 IWbemQualifierSet
**ppQualSet
)
347 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
349 TRACE("%p, %p\n", iface
, ppQualSet
);
351 return WbemQualifierSet_create( co
->ns
, co
->name
, NULL
, (void **)ppQualSet
);
354 static HRESULT
record_get_value( const struct record
*record
, UINT index
, VARIANT
*var
, CIMTYPE
*type
)
356 VARTYPE vartype
= to_vartype( record
->fields
[index
].type
& CIM_TYPE_MASK
);
358 if (type
) *type
= record
->fields
[index
].type
;
359 if (!var
) return S_OK
;
361 if (record
->fields
[index
].type
& CIM_FLAG_ARRAY
)
363 V_VT( var
) = vartype
| VT_ARRAY
;
364 V_ARRAY( var
) = to_safearray( record
->fields
[index
].u
.aval
, record
->fields
[index
].type
& CIM_TYPE_MASK
);
367 switch (record
->fields
[index
].type
)
372 V_BSTR( var
) = SysAllocString( record
->fields
[index
].u
.sval
);
375 V_I4( var
) = record
->fields
[index
].u
.ival
;
378 V_UI4( var
) = record
->fields
[index
].u
.ival
;
381 FIXME("unhandled type %u\n", record
->fields
[index
].type
);
382 return WBEM_E_INVALID_PARAMETER
;
384 V_VT( var
) = vartype
;
388 static HRESULT WINAPI
class_object_Get(
389 IWbemClassObject
*iface
,
396 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
397 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
399 TRACE( "%p, %s, %#lx, %p, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, pVal
, pType
, plFlavor
);
406 if ((hr
= get_column_index( co
->record
->table
, wszName
, &index
)) != S_OK
) return hr
;
407 return record_get_value( co
->record
, index
, pVal
, pType
);
409 return get_propval( ec
->query
->view
, co
->index
, wszName
, pVal
, pType
, plFlavor
);
412 static HRESULT
record_set_value( struct record
*record
, UINT index
, VARIANT
*var
)
418 if ((hr
= to_longlong( var
, &val
, &type
)) != S_OK
) return hr
;
419 if (type
!= record
->fields
[index
].type
) return WBEM_E_TYPE_MISMATCH
;
421 if (type
& CIM_FLAG_ARRAY
)
423 record
->fields
[index
].u
.aval
= (struct array
*)(INT_PTR
)val
;
431 record
->fields
[index
].u
.sval
= (WCHAR
*)(INT_PTR
)val
;
437 record
->fields
[index
].u
.ival
= val
;
440 FIXME( "unhandled type %lu\n", type
);
443 return WBEM_E_INVALID_PARAMETER
;
446 static HRESULT WINAPI
class_object_Put(
447 IWbemClassObject
*iface
,
453 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
454 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
456 TRACE( "%p, %s, %#lx, %p, %lu\n", iface
, debugstr_w(wszName
), lFlags
, pVal
, Type
);
463 if ((hr
= get_column_index( co
->record
->table
, wszName
, &index
)) != S_OK
) return hr
;
464 return record_set_value( co
->record
, index
, pVal
);
467 if (!ec
) return S_OK
;
469 return put_propval( ec
->query
->view
, co
->index
, wszName
, pVal
, Type
);
472 static HRESULT WINAPI
class_object_Delete(
473 IWbemClassObject
*iface
,
476 FIXME("%p, %s\n", iface
, debugstr_w(wszName
));
480 static HRESULT WINAPI
class_object_GetNames(
481 IWbemClassObject
*iface
,
482 LPCWSTR wszQualifierName
,
484 VARIANT
*pQualifierVal
,
487 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
488 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
490 TRACE( "%p, %s, %#lx, %s, %p\n", iface
, debugstr_w(wszQualifierName
), lFlags
,
491 debugstr_variant(pQualifierVal
), pNames
);
494 return WBEM_E_INVALID_PARAMETER
;
496 /* Combination used in a handful of broken apps */
497 if (lFlags
== (WBEM_FLAG_ALWAYS
| WBEM_MASK_CONDITION_ORIGIN
))
498 lFlags
= WBEM_FLAG_ALWAYS
;
500 if (lFlags
&& (lFlags
!= WBEM_FLAG_ALWAYS
&&
501 lFlags
!= WBEM_FLAG_NONSYSTEM_ONLY
&&
502 lFlags
!= WBEM_FLAG_SYSTEM_ONLY
))
504 FIXME( "flags %#lx not supported\n", lFlags
);
508 if (wszQualifierName
|| pQualifierVal
)
509 FIXME("qualifier not supported\n");
511 return get_properties( ec
->query
->view
, co
->index
, lFlags
, pNames
);
514 static HRESULT WINAPI
class_object_BeginEnumeration(
515 IWbemClassObject
*iface
,
518 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
520 TRACE( "%p, %#lx\n", iface
, lEnumFlags
);
522 if (lEnumFlags
) FIXME( "flags %#lx not supported\n", lEnumFlags
);
524 co
->index_property
= 0;
528 static HRESULT WINAPI
class_object_Next(
529 IWbemClassObject
*iface
,
536 struct class_object
*obj
= impl_from_IWbemClassObject( iface
);
537 struct enum_class_object
*iter
= impl_from_IEnumWbemClassObject( obj
->iter
);
538 struct view
*view
= iter
->query
->view
;
539 struct table
*table
= get_view_table( view
, obj
->index
);
544 TRACE( "%p, %#lx, %p, %p, %p, %p\n", iface
, lFlags
, strName
, pVal
, pType
, plFlavor
);
546 for (i
= obj
->index_property
; i
< table
->num_cols
; i
++)
548 if (is_method( table
, i
)) continue;
549 if (!is_result_prop( view
, table
->columns
[i
].name
)) continue;
550 if (!(prop
= SysAllocString( table
->columns
[i
].name
))) return E_OUTOFMEMORY
;
555 if ((hr
= get_column_index( table
, table
->columns
[i
].name
, &index
)) == S_OK
)
556 hr
= record_get_value( obj
->record
, index
, pVal
, pType
);
559 hr
= get_propval( view
, obj
->index
, prop
, pVal
, pType
, plFlavor
);
563 SysFreeString( prop
);
567 obj
->index_property
= i
+ 1;
568 if (strName
) *strName
= prop
;
569 else SysFreeString( prop
);
573 return WBEM_S_NO_MORE_DATA
;
576 static HRESULT WINAPI
class_object_EndEnumeration(
577 IWbemClassObject
*iface
)
579 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
581 TRACE("%p\n", iface
);
583 co
->index_property
= 0;
587 static HRESULT WINAPI
class_object_GetPropertyQualifierSet(
588 IWbemClassObject
*iface
,
590 IWbemQualifierSet
**ppQualSet
)
592 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
594 TRACE("%p, %s, %p\n", iface
, debugstr_w(wszProperty
), ppQualSet
);
596 return WbemQualifierSet_create( co
->ns
, co
->name
, wszProperty
, (void **)ppQualSet
);
599 static HRESULT WINAPI
class_object_Clone(
600 IWbemClassObject
*iface
,
601 IWbemClassObject
**ppCopy
)
603 FIXME("%p, %p\n", iface
, ppCopy
);
607 static BSTR
get_body_text( const struct table
*table
, UINT row
, UINT
*len
)
614 for (i
= 0; i
< table
->num_cols
; i
++)
616 if ((value
= get_value_bstr( table
, row
, i
)))
618 *len
+= ARRAY_SIZE( L
"\n\t%s = %s;" );
619 *len
+= lstrlenW( table
->columns
[i
].name
);
620 *len
+= SysStringLen( value
);
621 SysFreeString( value
);
624 if (!(ret
= SysAllocStringLen( NULL
, *len
))) return NULL
;
626 for (i
= 0; i
< table
->num_cols
; i
++)
628 if ((value
= get_value_bstr( table
, row
, i
)))
630 p
+= swprintf( p
, *len
- (p
- ret
), L
"\n\t%s = %s;", table
->columns
[i
].name
, value
);
631 SysFreeString( value
);
637 static BSTR
get_object_text( const struct view
*view
, UINT index
)
639 UINT len
, len_body
, row
= view
->result
[index
];
640 struct table
*table
= get_view_table( view
, index
);
643 len
= ARRAY_SIZE( L
"\ninstance of %s\n{%s\n};" );
644 len
+= lstrlenW( table
->name
);
645 if (!(body
= get_body_text( table
, row
, &len_body
))) return NULL
;
648 if (!(ret
= SysAllocStringLen( NULL
, len
))) return NULL
;
649 swprintf( ret
, len
, L
"\ninstance of %s\n{%s\n};", table
->name
, body
);
650 SysFreeString( body
);
654 static HRESULT WINAPI
class_object_GetObjectText(
655 IWbemClassObject
*iface
,
657 BSTR
*pstrObjectText
)
659 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
660 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
661 struct view
*view
= ec
->query
->view
;
664 TRACE( "%p, %#lx, %p\n", iface
, lFlags
, pstrObjectText
);
666 if (lFlags
) FIXME( "flags %#lx not implemented\n", lFlags
);
668 if (!(text
= get_object_text( view
, co
->index
))) return E_OUTOFMEMORY
;
669 *pstrObjectText
= text
;
673 static HRESULT WINAPI
class_object_SpawnDerivedClass(
674 IWbemClassObject
*iface
,
676 IWbemClassObject
**ppNewClass
)
678 FIXME( "%p, %#lx, %p\n", iface
, lFlags
, ppNewClass
);
682 static HRESULT WINAPI
class_object_SpawnInstance(
683 IWbemClassObject
*iface
,
685 IWbemClassObject
**ppNewInstance
)
687 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
688 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
689 struct table
*table
= get_view_table( ec
->query
->view
, co
->index
);
690 IEnumWbemClassObject
*iter
;
691 struct record
*record
;
694 TRACE( "%p, %#lx, %p\n", iface
, lFlags
, ppNewInstance
);
696 if (!(record
= create_record( table
))) return E_OUTOFMEMORY
;
697 if (FAILED(hr
= IEnumWbemClassObject_Clone( co
->iter
, &iter
)))
699 destroy_record( record
);
702 hr
= create_class_object( co
->ns
, co
->name
, iter
, 0, record
, ppNewInstance
);
703 IEnumWbemClassObject_Release( iter
);
707 static HRESULT WINAPI
class_object_CompareTo(
708 IWbemClassObject
*iface
,
710 IWbemClassObject
*pCompareTo
)
712 FIXME( "%p, %#lx, %p\n", iface
, lFlags
, pCompareTo
);
716 static HRESULT WINAPI
class_object_GetPropertyOrigin(
717 IWbemClassObject
*iface
,
719 BSTR
*pstrClassName
)
721 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszName
), pstrClassName
);
725 static HRESULT WINAPI
class_object_InheritsFrom(
726 IWbemClassObject
*iface
,
727 LPCWSTR strAncestor
)
729 FIXME("%p, %s\n", iface
, debugstr_w(strAncestor
));
733 static UINT
count_instances( IEnumWbemClassObject
*iter
)
736 while (!IEnumWbemClassObject_Skip( iter
, WBEM_INFINITE
, 1 )) count
++;
737 IEnumWbemClassObject_Reset( iter
);
741 static void set_default_value( CIMTYPE type
, UINT val
, BYTE
*ptr
)
749 *(UINT16
*)ptr
= val
;
755 *(UINT32
*)ptr
= val
;
758 FIXME( "unhandled type %lu\n", type
);
763 static HRESULT
create_signature_columns_and_data( IEnumWbemClassObject
*iter
, UINT
*num_cols
,
764 struct column
**cols
, BYTE
**data
)
766 struct column
*columns
;
768 IWbemClassObject
*param
;
770 HRESULT hr
= E_OUTOFMEMORY
;
775 count
= count_instances( iter
);
776 if (!(columns
= malloc( count
* sizeof(struct column
) ))) return E_OUTOFMEMORY
;
777 if (!(row
= calloc( count
, sizeof(LONGLONG
) ))) goto error
;
781 IEnumWbemClassObject_Next( iter
, WBEM_INFINITE
, 1, ¶m
, &count
);
784 hr
= IWbemClassObject_Get( param
, L
"Parameter", 0, &val
, NULL
, NULL
);
785 if (hr
!= S_OK
) goto error
;
786 columns
[i
].name
= heap_strdupW( V_BSTR( &val
) );
787 VariantClear( &val
);
789 hr
= IWbemClassObject_Get( param
, L
"Type", 0, &val
, NULL
, NULL
);
790 if (hr
!= S_OK
) goto error
;
791 columns
[i
].type
= V_UI4( &val
);
793 hr
= IWbemClassObject_Get( param
, L
"DefaultValue", 0, &val
, NULL
, NULL
);
794 if (hr
!= S_OK
) goto error
;
795 if (V_UI4( &val
)) set_default_value( columns
[i
].type
, V_UI4( &val
), row
+ offset
);
796 offset
+= get_type_size( columns
[i
].type
);
798 IWbemClassObject_Release( param
);
807 for (; i
>= 0; i
--) free( (WCHAR
*)columns
[i
].name
);
813 static HRESULT
create_signature_table( IEnumWbemClassObject
*iter
, enum wbm_namespace ns
, WCHAR
*name
)
817 struct column
*columns
;
821 hr
= create_signature_columns_and_data( iter
, &num_cols
, &columns
, &row
);
822 if (hr
!= S_OK
) return hr
;
824 if (!(table
= create_table( name
, num_cols
, columns
, 1, 1, row
, NULL
)))
826 free_columns( columns
, num_cols
);
828 return E_OUTOFMEMORY
;
830 if (!add_table( ns
, table
)) free_table( table
); /* already exists */
834 static WCHAR
*build_signature_table_name( const WCHAR
*class, const WCHAR
*method
, enum param_direction dir
)
836 UINT len
= ARRAY_SIZE(L
"__%s_%s_%s") + ARRAY_SIZE(L
"OUT") + lstrlenW( class ) + lstrlenW( method
);
839 if (!(ret
= malloc( len
* sizeof(WCHAR
) ))) return NULL
;
840 swprintf( ret
, len
, L
"__%s_%s_%s", class, method
, dir
== PARAM_IN
? L
"IN" : L
"OUT" );
841 return wcsupr( ret
);
844 HRESULT
create_signature( enum wbm_namespace ns
, const WCHAR
*class, const WCHAR
*method
, enum param_direction dir
,
845 IWbemClassObject
**sig
)
847 static const WCHAR selectW
[] = L
"SELECT * FROM __PARAMETERS WHERE Class='%s' AND Method='%s' AND Direction%s";
848 UINT len
= ARRAY_SIZE(selectW
) + ARRAY_SIZE(L
">=0");
849 IEnumWbemClassObject
*iter
;
853 len
+= lstrlenW( class ) + lstrlenW( method
);
854 if (!(query
= malloc( len
* sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
855 swprintf( query
, len
, selectW
, class, method
, dir
>= 0 ? L
">=0" : L
"<=0" );
857 hr
= exec_query( ns
, query
, &iter
);
859 if (hr
!= S_OK
) return hr
;
861 if (!count_instances( iter
))
864 IEnumWbemClassObject_Release( iter
);
868 if (!(name
= build_signature_table_name( class, method
, dir
)))
870 IEnumWbemClassObject_Release( iter
);
871 return E_OUTOFMEMORY
;
873 hr
= create_signature_table( iter
, ns
, name
);
874 IEnumWbemClassObject_Release( iter
);
876 hr
= get_object( ns
, name
, sig
);
882 static HRESULT WINAPI
class_object_GetMethod(
883 IWbemClassObject
*iface
,
886 IWbemClassObject
**ppInSignature
,
887 IWbemClassObject
**ppOutSignature
)
889 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
890 IWbemClassObject
*in
, *out
;
895 TRACE( "%p, %s, %#lx, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, ppInSignature
, ppOutSignature
);
897 if (ppInSignature
) *ppInSignature
= NULL
;
898 if (ppOutSignature
) *ppOutSignature
= NULL
;
900 table
= get_view_table( impl_from_IEnumWbemClassObject( co
->iter
)->query
->view
, co
->index
);
902 for (i
= 0; i
< table
->num_cols
; ++i
)
904 if (is_method( table
, i
) && !lstrcmpiW( table
->columns
[i
].name
, wszName
)) break;
906 if (i
== table
->num_cols
)
908 FIXME("Method %s not found in class %s.\n", debugstr_w(wszName
), debugstr_w(co
->name
));
909 return WBEM_E_NOT_FOUND
;
912 hr
= create_signature( co
->ns
, co
->name
, wszName
, PARAM_IN
, &in
);
913 if (hr
!= S_OK
) return hr
;
915 hr
= create_signature( co
->ns
, co
->name
, wszName
, PARAM_OUT
, &out
);
918 if (ppInSignature
) *ppInSignature
= in
;
919 else if (in
) IWbemClassObject_Release( in
);
920 if (ppOutSignature
) *ppOutSignature
= out
;
921 else if (out
) IWbemClassObject_Release( out
);
923 else IWbemClassObject_Release( in
);
927 static HRESULT WINAPI
class_object_PutMethod(
928 IWbemClassObject
*iface
,
931 IWbemClassObject
*pInSignature
,
932 IWbemClassObject
*pOutSignature
)
934 FIXME( "%p, %s, %#lx, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, pInSignature
, pOutSignature
);
938 static HRESULT WINAPI
class_object_DeleteMethod(
939 IWbemClassObject
*iface
,
942 FIXME("%p, %s\n", iface
, debugstr_w(wszName
));
946 static HRESULT WINAPI
class_object_BeginMethodEnumeration(
947 IWbemClassObject
*iface
,
950 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
952 TRACE( "%p, %#lx\n", iface
, lEnumFlags
);
954 if (lEnumFlags
) FIXME( "flags %#lx not supported\n", lEnumFlags
);
956 co
->index_method
= 0;
960 static HRESULT WINAPI
class_object_NextMethod(
961 IWbemClassObject
*iface
,
964 IWbemClassObject
**ppInSignature
,
965 IWbemClassObject
**ppOutSignature
)
967 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
971 TRACE( "%p, %#lx, %p, %p, %p\n", iface
, lFlags
, pstrName
, ppInSignature
, ppOutSignature
);
973 if (!(method
= get_method_name( co
->ns
, co
->name
, co
->index_method
))) return WBEM_S_NO_MORE_DATA
;
975 hr
= create_signature( co
->ns
, co
->name
, method
, PARAM_IN
, ppInSignature
);
978 SysFreeString( method
);
981 hr
= create_signature( co
->ns
, co
->name
, method
, PARAM_OUT
, ppOutSignature
);
984 SysFreeString( method
);
986 IWbemClassObject_Release( *ppInSignature
);
996 static HRESULT WINAPI
class_object_EndMethodEnumeration(
997 IWbemClassObject
*iface
)
999 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
1001 TRACE("%p\n", iface
);
1003 co
->index_method
= 0;
1007 static HRESULT WINAPI
class_object_GetMethodQualifierSet(
1008 IWbemClassObject
*iface
,
1010 IWbemQualifierSet
**ppQualSet
)
1012 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
1014 TRACE("%p, %s, %p\n", iface
, debugstr_w(wszMethod
), ppQualSet
);
1016 return WbemQualifierSet_create( co
->ns
, co
->name
, wszMethod
, (void **)ppQualSet
);
1019 static HRESULT WINAPI
class_object_GetMethodOrigin(
1020 IWbemClassObject
*iface
,
1021 LPCWSTR wszMethodName
,
1022 BSTR
*pstrClassName
)
1024 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszMethodName
), pstrClassName
);
1028 static const IWbemClassObjectVtbl class_object_vtbl
=
1030 class_object_QueryInterface
,
1031 class_object_AddRef
,
1032 class_object_Release
,
1033 class_object_GetQualifierSet
,
1036 class_object_Delete
,
1037 class_object_GetNames
,
1038 class_object_BeginEnumeration
,
1040 class_object_EndEnumeration
,
1041 class_object_GetPropertyQualifierSet
,
1043 class_object_GetObjectText
,
1044 class_object_SpawnDerivedClass
,
1045 class_object_SpawnInstance
,
1046 class_object_CompareTo
,
1047 class_object_GetPropertyOrigin
,
1048 class_object_InheritsFrom
,
1049 class_object_GetMethod
,
1050 class_object_PutMethod
,
1051 class_object_DeleteMethod
,
1052 class_object_BeginMethodEnumeration
,
1053 class_object_NextMethod
,
1054 class_object_EndMethodEnumeration
,
1055 class_object_GetMethodQualifierSet
,
1056 class_object_GetMethodOrigin
1059 HRESULT
create_class_object( enum wbm_namespace ns
, const WCHAR
*name
, IEnumWbemClassObject
*iter
, UINT index
,
1060 struct record
*record
, IWbemClassObject
**obj
)
1062 struct class_object
*co
;
1064 TRACE("%s, %p\n", debugstr_w(name
), obj
);
1066 if (!(co
= malloc( sizeof(*co
) ))) return E_OUTOFMEMORY
;
1068 co
->IWbemClassObject_iface
.lpVtbl
= &class_object_vtbl
;
1070 if (!name
) co
->name
= NULL
;
1071 else if (!(co
->name
= heap_strdupW( name
)))
1074 return E_OUTOFMEMORY
;
1078 co
->index_method
= 0;
1079 co
->index_property
= 0;
1080 co
->record
= record
;
1082 if (iter
) IEnumWbemClassObject_AddRef( iter
);
1084 *obj
= &co
->IWbemClassObject_iface
;
1086 TRACE("returning iface %p\n", *obj
);