2 * Copyright 2012 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
30 #include "wbemprox_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox
);
34 struct enum_class_object
36 IEnumWbemClassObject IEnumWbemClassObject_iface
;
42 static inline struct enum_class_object
*impl_from_IEnumWbemClassObject(
43 IEnumWbemClassObject
*iface
)
45 return CONTAINING_RECORD(iface
, struct enum_class_object
, IEnumWbemClassObject_iface
);
48 static ULONG WINAPI
enum_class_object_AddRef(
49 IEnumWbemClassObject
*iface
)
51 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
52 return InterlockedIncrement( &ec
->refs
);
55 static ULONG WINAPI
enum_class_object_Release(
56 IEnumWbemClassObject
*iface
)
58 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
59 LONG refs
= InterlockedDecrement( &ec
->refs
);
62 TRACE("destroying %p\n", ec
);
63 release_query( ec
->query
);
69 static HRESULT WINAPI
enum_class_object_QueryInterface(
70 IEnumWbemClassObject
*iface
,
74 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
76 TRACE("%p, %s, %p\n", ec
, debugstr_guid( riid
), ppvObject
);
78 if ( IsEqualGUID( riid
, &IID_IEnumWbemClassObject
) ||
79 IsEqualGUID( riid
, &IID_IUnknown
) )
83 else if ( IsEqualGUID( riid
, &IID_IClientSecurity
) )
85 *ppvObject
= &client_security
;
90 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
93 IEnumWbemClassObject_AddRef( iface
);
97 static HRESULT WINAPI
enum_class_object_Reset(
98 IEnumWbemClassObject
*iface
)
100 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
102 TRACE("%p\n", iface
);
105 return WBEM_S_NO_ERROR
;
108 static HRESULT WINAPI
enum_class_object_Next(
109 IEnumWbemClassObject
*iface
,
112 IWbemClassObject
**apObjects
,
115 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
116 struct view
*view
= ec
->query
->view
;
119 TRACE("%p, %d, %u, %p, %p\n", iface
, lTimeout
, uCount
, apObjects
, puReturned
);
121 if (!uCount
) return WBEM_S_FALSE
;
122 if (!apObjects
|| !puReturned
) return WBEM_E_INVALID_PARAMETER
;
123 if (lTimeout
!= WBEM_INFINITE
) FIXME("timeout not supported\n");
126 if (ec
->index
+ uCount
> view
->count
) return WBEM_S_FALSE
;
128 hr
= create_class_object( view
->table
->name
, iface
, ec
->index
, apObjects
);
129 if (hr
!= S_OK
) return hr
;
133 if (ec
->index
== view
->count
) return WBEM_S_FALSE
;
134 if (uCount
> 1) return WBEM_S_TIMEDOUT
;
135 return WBEM_S_NO_ERROR
;
138 static HRESULT WINAPI
enum_class_object_NextAsync(
139 IEnumWbemClassObject
*iface
,
141 IWbemObjectSink
*pSink
)
143 FIXME("%p, %u, %p\n", iface
, uCount
, pSink
);
147 static HRESULT WINAPI
enum_class_object_Clone(
148 IEnumWbemClassObject
*iface
,
149 IEnumWbemClassObject
**ppEnum
)
151 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
153 TRACE("%p, %p\n", iface
, ppEnum
);
155 return EnumWbemClassObject_create( NULL
, ec
->query
, (void **)ppEnum
);
158 static HRESULT WINAPI
enum_class_object_Skip(
159 IEnumWbemClassObject
*iface
,
163 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( iface
);
164 struct view
*view
= ec
->query
->view
;
166 TRACE("%p, %d, %u\n", iface
, lTimeout
, nCount
);
168 if (lTimeout
!= WBEM_INFINITE
) FIXME("timeout not supported\n");
170 if (!view
->count
) return WBEM_S_FALSE
;
172 if (nCount
> view
->count
- ec
->index
)
174 ec
->index
= view
->count
- 1;
178 return WBEM_S_NO_ERROR
;
181 static const IEnumWbemClassObjectVtbl enum_class_object_vtbl
=
183 enum_class_object_QueryInterface
,
184 enum_class_object_AddRef
,
185 enum_class_object_Release
,
186 enum_class_object_Reset
,
187 enum_class_object_Next
,
188 enum_class_object_NextAsync
,
189 enum_class_object_Clone
,
190 enum_class_object_Skip
193 HRESULT
EnumWbemClassObject_create(
194 IUnknown
*pUnkOuter
, struct query
*query
, LPVOID
*ppObj
)
196 struct enum_class_object
*ec
;
198 TRACE("%p, %p\n", pUnkOuter
, ppObj
);
200 ec
= heap_alloc( sizeof(*ec
) );
201 if (!ec
) return E_OUTOFMEMORY
;
203 ec
->IEnumWbemClassObject_iface
.lpVtbl
= &enum_class_object_vtbl
;
206 addref_query( query
);
209 *ppObj
= &ec
->IEnumWbemClassObject_iface
;
211 TRACE("returning iface %p\n", *ppObj
);
217 IWbemClassObject IWbemClassObject_iface
;
220 IEnumWbemClassObject
*iter
;
226 static inline struct class_object
*impl_from_IWbemClassObject(
227 IWbemClassObject
*iface
)
229 return CONTAINING_RECORD(iface
, struct class_object
, IWbemClassObject_iface
);
232 static ULONG WINAPI
class_object_AddRef(
233 IWbemClassObject
*iface
)
235 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
236 return InterlockedIncrement( &co
->refs
);
239 static ULONG WINAPI
class_object_Release(
240 IWbemClassObject
*iface
)
242 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
243 LONG refs
= InterlockedDecrement( &co
->refs
);
246 TRACE("destroying %p\n", co
);
247 if (co
->iter
) IEnumWbemClassObject_Release( co
->iter
);
248 heap_free( co
->name
);
254 static HRESULT WINAPI
class_object_QueryInterface(
255 IWbemClassObject
*iface
,
259 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
261 TRACE("%p, %s, %p\n", co
, debugstr_guid( riid
), ppvObject
);
263 if ( IsEqualGUID( riid
, &IID_IWbemClassObject
) ||
264 IsEqualGUID( riid
, &IID_IUnknown
) )
270 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
271 return E_NOINTERFACE
;
273 IWbemClassObject_AddRef( iface
);
277 static HRESULT WINAPI
class_object_GetQualifierSet(
278 IWbemClassObject
*iface
,
279 IWbemQualifierSet
**ppQualSet
)
281 FIXME("%p, %p\n", iface
, ppQualSet
);
285 static HRESULT WINAPI
class_object_Get(
286 IWbemClassObject
*iface
,
293 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
294 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
295 struct view
*view
= ec
->query
->view
;
297 TRACE("%p, %s, %08x, %p, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, pVal
, pType
, plFlavor
);
299 return get_propval( view
, co
->index
, wszName
, pVal
, pType
, plFlavor
);
302 static HRESULT WINAPI
class_object_Put(
303 IWbemClassObject
*iface
,
309 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
310 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
311 struct view
*view
= ec
->query
->view
;
313 TRACE("%p, %s, %08x, %p, %u\n", iface
, debugstr_w(wszName
), lFlags
, pVal
, Type
);
315 return put_propval( view
, co
->index
, wszName
, pVal
, Type
);
318 static HRESULT WINAPI
class_object_Delete(
319 IWbemClassObject
*iface
,
322 FIXME("%p, %s\n", iface
, debugstr_w(wszName
));
326 static HRESULT WINAPI
class_object_GetNames(
327 IWbemClassObject
*iface
,
328 LPCWSTR wszQualifierName
,
330 VARIANT
*pQualifierVal
,
333 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
334 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
336 TRACE("%p, %s, %08x, %p, %p\n", iface
, debugstr_w(wszQualifierName
), lFlags
, pQualifierVal
, pNames
);
338 if (wszQualifierName
|| pQualifierVal
)
340 FIXME("qualifier not supported\n");
343 if (lFlags
!= WBEM_FLAG_ALWAYS
)
345 FIXME("flags %08x not supported\n", lFlags
);
348 return get_properties( ec
->query
->view
, pNames
);
351 static HRESULT WINAPI
class_object_BeginEnumeration(
352 IWbemClassObject
*iface
,
355 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
357 TRACE("%p, %08x\n", iface
, lEnumFlags
);
359 if (lEnumFlags
) FIXME("flags 0x%08x not supported\n", lEnumFlags
);
361 co
->index_property
= 0;
365 static HRESULT WINAPI
class_object_Next(
366 IWbemClassObject
*iface
,
373 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
374 struct enum_class_object
*ec
= impl_from_IEnumWbemClassObject( co
->iter
);
375 struct view
*view
= ec
->query
->view
;
376 const WCHAR
*property
;
379 TRACE("%p, %08x, %p, %p, %p, %p\n", iface
, lFlags
, strName
, pVal
, pType
, plFlavor
);
381 if (!(property
= get_property_name( co
->name
, co
->index_property
))) return WBEM_S_NO_MORE_DATA
;
382 if (!(*strName
= SysAllocString( property
))) return E_OUTOFMEMORY
;
383 if ((hr
= get_propval( view
, co
->index
, property
, pVal
, pType
, plFlavor
) != S_OK
))
385 SysFreeString( *strName
);
388 co
->index_property
++;
392 static HRESULT WINAPI
class_object_EndEnumeration(
393 IWbemClassObject
*iface
)
395 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
397 TRACE("%p\n", iface
);
399 co
->index_property
= 0;
403 static HRESULT WINAPI
class_object_GetPropertyQualifierSet(
404 IWbemClassObject
*iface
,
406 IWbemQualifierSet
**ppQualSet
)
408 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszProperty
), ppQualSet
);
412 static HRESULT WINAPI
class_object_Clone(
413 IWbemClassObject
*iface
,
414 IWbemClassObject
**ppCopy
)
416 FIXME("%p, %p\n", iface
, ppCopy
);
420 static HRESULT WINAPI
class_object_GetObjectText(
421 IWbemClassObject
*iface
,
423 BSTR
*pstrObjectText
)
425 FIXME("%p, %08x, %p\n", iface
, lFlags
, pstrObjectText
);
429 static HRESULT WINAPI
class_object_SpawnDerivedClass(
430 IWbemClassObject
*iface
,
432 IWbemClassObject
**ppNewClass
)
434 FIXME("%p, %08x, %p\n", iface
, lFlags
, ppNewClass
);
438 static HRESULT WINAPI
class_object_SpawnInstance(
439 IWbemClassObject
*iface
,
441 IWbemClassObject
**ppNewInstance
)
443 FIXME("%p, %08x, %p\n", iface
, lFlags
, ppNewInstance
);
447 static HRESULT WINAPI
class_object_CompareTo(
448 IWbemClassObject
*iface
,
450 IWbemClassObject
*pCompareTo
)
452 FIXME("%p, %08x, %p\n", iface
, lFlags
, pCompareTo
);
456 static HRESULT WINAPI
class_object_GetPropertyOrigin(
457 IWbemClassObject
*iface
,
459 BSTR
*pstrClassName
)
461 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszName
), pstrClassName
);
465 static HRESULT WINAPI
class_object_InheritsFrom(
466 IWbemClassObject
*iface
,
467 LPCWSTR strAncestor
)
469 FIXME("%p, %s\n", iface
, debugstr_w(strAncestor
));
473 static UINT
count_instances( IEnumWbemClassObject
*iter
)
476 while (!IEnumWbemClassObject_Skip( iter
, WBEM_INFINITE
, 1 )) count
++;
477 IEnumWbemClassObject_Reset( iter
);
481 static void set_default_value( CIMTYPE type
, UINT val
, BYTE
*ptr
)
489 *(UINT16
*)ptr
= val
;
495 *(UINT32
*)ptr
= val
;
498 FIXME("unhandled type %u\n", type
);
503 static HRESULT
create_signature_columns_and_data( IEnumWbemClassObject
*iter
, UINT
*num_cols
,
504 struct column
**cols
, BYTE
**data
)
506 static const WCHAR parameterW
[] = {'P','a','r','a','m','e','t','e','r',0};
507 static const WCHAR typeW
[] = {'T','y','p','e',0};
508 static const WCHAR defaultvalueW
[] = {'D','e','f','a','u','l','t','V','a','l','u','e',0};
509 struct column
*columns
;
511 IWbemClassObject
*param
;
513 HRESULT hr
= E_OUTOFMEMORY
;
518 count
= count_instances( iter
);
519 if (!(columns
= heap_alloc( count
* sizeof(struct column
) ))) return E_OUTOFMEMORY
;
520 if (!(row
= heap_alloc_zero( count
* sizeof(LONGLONG
) ))) goto error
;
524 IEnumWbemClassObject_Next( iter
, WBEM_INFINITE
, 1, ¶m
, &count
);
527 hr
= IWbemClassObject_Get( param
, parameterW
, 0, &val
, NULL
, NULL
);
528 if (hr
!= S_OK
) goto error
;
529 columns
[i
].name
= heap_strdupW( V_BSTR( &val
) );
530 VariantClear( &val
);
532 hr
= IWbemClassObject_Get( param
, typeW
, 0, &val
, NULL
, NULL
);
533 if (hr
!= S_OK
) goto error
;
534 columns
[i
].type
= V_UI4( &val
);
535 columns
[i
].vartype
= 0;
537 hr
= IWbemClassObject_Get( param
, defaultvalueW
, 0, &val
, NULL
, NULL
);
538 if (hr
!= S_OK
) goto error
;
539 if (V_UI4( &val
)) set_default_value( columns
[i
].type
, V_UI4( &val
), row
+ offset
);
540 offset
+= get_type_size( columns
[i
].type
);
542 IWbemClassObject_Release( param
);
551 for (; i
>= 0; i
--) heap_free( (WCHAR
*)columns
[i
].name
);
552 heap_free( columns
);
557 static HRESULT
create_signature_table( IEnumWbemClassObject
*iter
, WCHAR
*name
)
561 struct column
*columns
;
565 hr
= create_signature_columns_and_data( iter
, &num_cols
, &columns
, &row
);
566 if (hr
!= S_OK
) return hr
;
568 if (!(table
= create_table( name
, num_cols
, columns
, 1, row
, NULL
)))
570 free_columns( columns
, num_cols
);
572 return E_OUTOFMEMORY
;
574 if (!add_table( table
)) free_table( table
); /* already exists */
578 static WCHAR
*build_signature_table_name( const WCHAR
*class, const WCHAR
*method
, enum param_direction dir
)
580 static const WCHAR fmtW
[] = {'_','_','%','s','_','%','s','_','%','s',0};
581 static const WCHAR outW
[] = {'O','U','T',0};
582 static const WCHAR inW
[] = {'I','N',0};
583 UINT len
= SIZEOF(fmtW
) + SIZEOF(outW
) + strlenW( class ) + strlenW( method
);
586 if (!(ret
= heap_alloc( len
* sizeof(WCHAR
) ))) return NULL
;
587 sprintfW( ret
, fmtW
, class, method
, dir
== PARAM_IN
? inW
: outW
);
588 return struprW( ret
);
591 static HRESULT
create_signature( const WCHAR
*class, const WCHAR
*method
, enum param_direction dir
,
592 IWbemClassObject
**sig
)
594 static const WCHAR selectW
[] =
595 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
596 '_','_','P','A','R','A','M','E','T','E','R','S',' ','W','H','E','R','E',' ',
597 'C','l','a','s','s','=','\'','%','s','\'',' ','A','N','D',' ',
598 'M','e','t','h','o','d','=','\'','%','s','\'',' ','A','N','D',' ',
599 'D','i','r','e','c','t','i','o','n','%','s',0};
600 static const WCHAR geW
[] = {'>','=','0',0};
601 static const WCHAR leW
[] = {'<','=','0',0};
602 UINT len
= SIZEOF(selectW
) + SIZEOF(geW
);
603 IEnumWbemClassObject
*iter
;
607 len
+= strlenW( class ) + strlenW( method
);
608 if (!(query
= heap_alloc( len
* sizeof(WCHAR
) ))) return E_OUTOFMEMORY
;
609 sprintfW( query
, selectW
, class, method
, dir
>= 0 ? geW
: leW
);
611 hr
= exec_query( query
, &iter
);
613 if (hr
!= S_OK
) return hr
;
615 if (!(name
= build_signature_table_name( class, method
, dir
)))
617 IEnumWbemClassObject_Release( iter
);
618 return E_OUTOFMEMORY
;
620 hr
= create_signature_table( iter
, name
);
621 IEnumWbemClassObject_Release( iter
);
627 return get_object( name
, sig
);
630 static HRESULT WINAPI
class_object_GetMethod(
631 IWbemClassObject
*iface
,
634 IWbemClassObject
**ppInSignature
,
635 IWbemClassObject
**ppOutSignature
)
637 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
640 TRACE("%p, %s, %08x, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, ppInSignature
, ppOutSignature
);
642 hr
= create_signature( co
->name
, wszName
, PARAM_IN
, ppInSignature
);
643 if (hr
!= S_OK
) return hr
;
645 hr
= create_signature( co
->name
, wszName
, PARAM_OUT
, ppOutSignature
);
646 if (hr
!= S_OK
) IWbemClassObject_Release( *ppInSignature
);
650 static HRESULT WINAPI
class_object_PutMethod(
651 IWbemClassObject
*iface
,
654 IWbemClassObject
*pInSignature
,
655 IWbemClassObject
*pOutSignature
)
657 FIXME("%p, %s, %08x, %p, %p\n", iface
, debugstr_w(wszName
), lFlags
, pInSignature
, pOutSignature
);
661 static HRESULT WINAPI
class_object_DeleteMethod(
662 IWbemClassObject
*iface
,
665 FIXME("%p, %s\n", iface
, debugstr_w(wszName
));
669 static HRESULT WINAPI
class_object_BeginMethodEnumeration(
670 IWbemClassObject
*iface
,
673 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
675 TRACE("%p, %08x\n", iface
, lEnumFlags
);
677 if (lEnumFlags
) FIXME("flags 0x%08x not supported\n", lEnumFlags
);
681 WARN("not allowed on instance\n");
682 return WBEM_E_ILLEGAL_OPERATION
;
684 co
->index_method
= 0;
688 static HRESULT WINAPI
class_object_NextMethod(
689 IWbemClassObject
*iface
,
692 IWbemClassObject
**ppInSignature
,
693 IWbemClassObject
**ppOutSignature
)
695 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
699 TRACE("%p, %08x, %p, %p, %p\n", iface
, lFlags
, pstrName
, ppInSignature
, ppOutSignature
);
701 if (!(method
= get_method_name( co
->name
, co
->index_method
))) return WBEM_S_NO_MORE_DATA
;
703 hr
= create_signature( co
->name
, method
, PARAM_IN
, ppInSignature
);
704 if (hr
!= S_OK
) return hr
;
706 hr
= create_signature( co
->name
, method
, PARAM_OUT
, ppOutSignature
);
707 if (hr
!= S_OK
) IWbemClassObject_Release( *ppInSignature
);
710 if (!(*pstrName
= SysAllocString( method
)))
712 IWbemClassObject_Release( *ppInSignature
);
713 IWbemClassObject_Release( *ppOutSignature
);
714 return E_OUTOFMEMORY
;
721 static HRESULT WINAPI
class_object_EndMethodEnumeration(
722 IWbemClassObject
*iface
)
724 struct class_object
*co
= impl_from_IWbemClassObject( iface
);
726 TRACE("%p\n", iface
);
728 co
->index_method
= 0;
732 static HRESULT WINAPI
class_object_GetMethodQualifierSet(
733 IWbemClassObject
*iface
,
735 IWbemQualifierSet
**ppQualSet
)
737 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszMethod
), ppQualSet
);
741 static HRESULT WINAPI
class_object_GetMethodOrigin(
742 IWbemClassObject
*iface
,
743 LPCWSTR wszMethodName
,
746 FIXME("%p, %s, %p\n", iface
, debugstr_w(wszMethodName
), pstrClassName
);
750 static const IWbemClassObjectVtbl class_object_vtbl
=
752 class_object_QueryInterface
,
754 class_object_Release
,
755 class_object_GetQualifierSet
,
759 class_object_GetNames
,
760 class_object_BeginEnumeration
,
762 class_object_EndEnumeration
,
763 class_object_GetPropertyQualifierSet
,
765 class_object_GetObjectText
,
766 class_object_SpawnDerivedClass
,
767 class_object_SpawnInstance
,
768 class_object_CompareTo
,
769 class_object_GetPropertyOrigin
,
770 class_object_InheritsFrom
,
771 class_object_GetMethod
,
772 class_object_PutMethod
,
773 class_object_DeleteMethod
,
774 class_object_BeginMethodEnumeration
,
775 class_object_NextMethod
,
776 class_object_EndMethodEnumeration
,
777 class_object_GetMethodQualifierSet
,
778 class_object_GetMethodOrigin
781 HRESULT
create_class_object(
782 const WCHAR
*name
, IEnumWbemClassObject
*iter
, UINT index
, IWbemClassObject
**obj
)
784 struct class_object
*co
;
786 TRACE("%s, %p\n", debugstr_w(name
), obj
);
788 co
= heap_alloc( sizeof(*co
) );
789 if (!co
) return E_OUTOFMEMORY
;
791 co
->IWbemClassObject_iface
.lpVtbl
= &class_object_vtbl
;
793 co
->name
= heap_strdupW( name
);
797 return E_OUTOFMEMORY
;
801 co
->index_method
= 0;
802 co
->index_property
= 0;
803 if (iter
) IEnumWbemClassObject_AddRef( iter
);
805 *obj
= &co
->IWbemClassObject_iface
;
807 TRACE("returning iface %p\n", *obj
);