| /* |
| * Copyright 2013 Hans Leidekker for CodeWeavers |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #define COBJMACROS |
| |
| #include "config.h" |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "initguid.h" |
| #include "objbase.h" |
| #include "wmiutils.h" |
| #include "wbemcli.h" |
| #include "wbemdisp.h" |
| |
| #include "wine/debug.h" |
| #include "wine/unicode.h" |
| #include "wbemdisp_private.h" |
| #include "wbemdisp_classes.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp); |
| |
| static HRESULT EnumVARIANT_create( IEnumWbemClassObject *, IEnumVARIANT ** ); |
| |
| enum type_id |
| { |
| ISWbemLocator_tid, |
| ISWbemObject_tid, |
| ISWbemObjectSet_tid, |
| ISWbemProperty_tid, |
| ISWbemPropertySet_tid, |
| ISWbemServices_tid, |
| last_tid |
| }; |
| |
| static ITypeLib *wbemdisp_typelib; |
| static ITypeInfo *wbemdisp_typeinfo[last_tid]; |
| |
| static REFIID wbemdisp_tid_id[] = |
| { |
| &IID_ISWbemLocator, |
| &IID_ISWbemObject, |
| &IID_ISWbemObjectSet, |
| &IID_ISWbemProperty, |
| &IID_ISWbemPropertySet, |
| &IID_ISWbemServices |
| }; |
| |
| static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) |
| { |
| HRESULT hr; |
| |
| if (!wbemdisp_typelib) |
| { |
| ITypeLib *typelib; |
| |
| hr = LoadRegTypeLib( &LIBID_WbemScripting, 1, 2, LOCALE_SYSTEM_DEFAULT, &typelib ); |
| if (FAILED( hr )) |
| { |
| ERR( "LoadRegTypeLib failed: %08x\n", hr ); |
| return hr; |
| } |
| if (InterlockedCompareExchangePointer( (void **)&wbemdisp_typelib, typelib, NULL )) |
| ITypeLib_Release( typelib ); |
| } |
| if (!wbemdisp_typeinfo[tid]) |
| { |
| ITypeInfo *typeinfo; |
| |
| hr = ITypeLib_GetTypeInfoOfGuid( wbemdisp_typelib, wbemdisp_tid_id[tid], &typeinfo ); |
| if (FAILED( hr )) |
| { |
| ERR( "GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(wbemdisp_tid_id[tid]), hr ); |
| return hr; |
| } |
| if (InterlockedCompareExchangePointer( (void **)(wbemdisp_typeinfo + tid), typeinfo, NULL )) |
| ITypeInfo_Release( typeinfo ); |
| } |
| *ret = wbemdisp_typeinfo[tid]; |
| ITypeInfo_AddRef( *ret ); |
| return S_OK; |
| } |
| |
| struct property |
| { |
| ISWbemProperty ISWbemProperty_iface; |
| LONG refs; |
| IWbemClassObject *object; |
| BSTR name; |
| }; |
| |
| static inline struct property *impl_from_ISWbemProperty( ISWbemProperty *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct property, ISWbemProperty_iface ); |
| } |
| |
| static ULONG WINAPI property_AddRef( ISWbemProperty *iface ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| return InterlockedIncrement( &property->refs ); |
| } |
| |
| static ULONG WINAPI property_Release( ISWbemProperty *iface ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| LONG refs = InterlockedDecrement( &property->refs ); |
| if (!refs) |
| { |
| TRACE( "destroying %p\n", property ); |
| IWbemClassObject_Release( property->object ); |
| SysFreeString( property->name ); |
| heap_free( property ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI property_QueryInterface( ISWbemProperty *iface, REFIID riid, void **obj ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| |
| TRACE( "%p %s %p\n", property, debugstr_guid(riid), obj ); |
| |
| if (IsEqualGUID( riid, &IID_ISWbemProperty ) || |
| IsEqualGUID( riid, &IID_IDispatch ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *obj = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| ISWbemProperty_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI property_GetTypeInfoCount( ISWbemProperty *iface, UINT *count ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| TRACE( "%p, %p\n", property, count ); |
| *count = 1; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI property_GetTypeInfo( ISWbemProperty *iface, UINT index, |
| LCID lcid, ITypeInfo **info ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| TRACE( "%p, %u, %u, %p\n", property, index, lcid, info ); |
| |
| return get_typeinfo( ISWbemProperty_tid, info ); |
| } |
| |
| static HRESULT WINAPI property_GetIDsOfNames( ISWbemProperty *iface, REFIID riid, LPOLESTR *names, |
| UINT count, LCID lcid, DISPID *dispid ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %p, %u, %u, %p\n", property, debugstr_guid(riid), names, count, lcid, dispid ); |
| |
| if (!names || !count || !dispid) return E_INVALIDARG; |
| |
| hr = get_typeinfo( ISWbemProperty_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI property_Invoke( ISWbemProperty *iface, DISPID member, REFIID riid, |
| LCID lcid, WORD flags, DISPPARAMS *params, |
| VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", property, member, debugstr_guid(riid), |
| lcid, flags, params, result, excep_info, arg_err ); |
| |
| hr = get_typeinfo( ISWbemProperty_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_Invoke( typeinfo, &property->ISWbemProperty_iface, member, flags, |
| params, result, excep_info, arg_err ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI property_get_Value( ISWbemProperty *iface, VARIANT *value ) |
| { |
| struct property *property = impl_from_ISWbemProperty( iface ); |
| |
| TRACE( "%p %p\n", property, value ); |
| |
| return IWbemClassObject_Get( property->object, property->name, 0, value, NULL, NULL ); |
| } |
| |
| static HRESULT WINAPI property_put_Value( ISWbemProperty *iface, VARIANT *varValue ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI property_get_Name( ISWbemProperty *iface, BSTR *strName ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI property_get_IsLocal( ISWbemProperty *iface, VARIANT_BOOL *bIsLocal ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI property_get_Origin( ISWbemProperty *iface, BSTR *strOrigin ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI property_get_CIMType( ISWbemProperty *iface, WbemCimtypeEnum *iCimType ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI property_get_Qualifiers_( ISWbemProperty *iface, ISWbemQualifierSet **objWbemQualifierSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI property_get_IsArray( ISWbemProperty *iface, VARIANT_BOOL *bIsArray ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static const ISWbemPropertyVtbl property_vtbl = |
| { |
| property_QueryInterface, |
| property_AddRef, |
| property_Release, |
| property_GetTypeInfoCount, |
| property_GetTypeInfo, |
| property_GetIDsOfNames, |
| property_Invoke, |
| property_get_Value, |
| property_put_Value, |
| property_get_Name, |
| property_get_IsLocal, |
| property_get_Origin, |
| property_get_CIMType, |
| property_get_Qualifiers_, |
| property_get_IsArray |
| }; |
| |
| static HRESULT SWbemProperty_create( IWbemClassObject *wbem_object, BSTR name, ISWbemProperty **obj ) |
| { |
| struct property *property; |
| |
| TRACE( "%p, %p\n", obj, wbem_object ); |
| |
| if (!(property = heap_alloc( sizeof(*property) ))) return E_OUTOFMEMORY; |
| property->ISWbemProperty_iface.lpVtbl = &property_vtbl; |
| property->refs = 1; |
| property->object = wbem_object; |
| IWbemClassObject_AddRef( property->object ); |
| property->name = SysAllocStringLen( name, SysStringLen( name ) ); |
| *obj = &property->ISWbemProperty_iface; |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |
| |
| struct propertyset |
| { |
| ISWbemPropertySet ISWbemPropertySet_iface; |
| LONG refs; |
| IWbemClassObject *object; |
| }; |
| |
| static inline struct propertyset *impl_from_ISWbemPropertySet( |
| ISWbemPropertySet *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct propertyset, ISWbemPropertySet_iface ); |
| } |
| |
| static ULONG WINAPI propertyset_AddRef( ISWbemPropertySet *iface ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| return InterlockedIncrement( &propertyset->refs ); |
| } |
| |
| static ULONG WINAPI propertyset_Release( ISWbemPropertySet *iface ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| LONG refs = InterlockedDecrement( &propertyset->refs ); |
| if (!refs) |
| { |
| TRACE( "destroying %p\n", propertyset ); |
| IWbemClassObject_Release( propertyset->object ); |
| heap_free( propertyset ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI propertyset_QueryInterface( ISWbemPropertySet *iface, |
| REFIID riid, void **obj ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| |
| TRACE( "%p %s %p\n", propertyset, debugstr_guid(riid), obj ); |
| |
| if (IsEqualGUID( riid, &IID_ISWbemPropertySet ) || |
| IsEqualGUID( riid, &IID_IDispatch ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *obj = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| ISWbemPropertySet_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI propertyset_GetTypeInfoCount( ISWbemPropertySet *iface, UINT *count ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| TRACE( "%p, %p\n", propertyset, count ); |
| *count = 1; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI propertyset_GetTypeInfo( ISWbemPropertySet *iface, |
| UINT index, LCID lcid, ITypeInfo **info ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| TRACE( "%p, %u, %u, %p\n", propertyset, index, lcid, info ); |
| |
| return get_typeinfo( ISWbemPropertySet_tid, info ); |
| } |
| |
| static HRESULT WINAPI propertyset_GetIDsOfNames( ISWbemPropertySet *iface, REFIID riid, LPOLESTR *names, |
| UINT count, LCID lcid, DISPID *dispid ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %p, %u, %u, %p\n", propertyset, debugstr_guid(riid), names, count, lcid, dispid ); |
| |
| if (!names || !count || !dispid) return E_INVALIDARG; |
| |
| hr = get_typeinfo( ISWbemPropertySet_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI propertyset_Invoke( ISWbemPropertySet *iface, DISPID member, REFIID riid, |
| LCID lcid, WORD flags, DISPPARAMS *params, |
| VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", propertyset, member, debugstr_guid(riid), |
| lcid, flags, params, result, excep_info, arg_err ); |
| |
| hr = get_typeinfo( ISWbemPropertySet_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_Invoke( typeinfo, &propertyset->ISWbemPropertySet_iface, member, flags, |
| params, result, excep_info, arg_err ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI propertyset_get__NewEnum( ISWbemPropertySet *iface, IUnknown **unk ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI propertyset_Item( ISWbemPropertySet *iface, BSTR name, |
| LONG flags, ISWbemProperty **prop ) |
| { |
| struct propertyset *propertyset = impl_from_ISWbemPropertySet( iface ); |
| HRESULT hr; |
| VARIANT var; |
| |
| TRACE( "%p, %s, %08x, %p\n", propertyset, debugstr_w(name), flags, prop ); |
| |
| hr = IWbemClassObject_Get( propertyset->object, name, 0, &var, NULL, NULL ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = SWbemProperty_create( propertyset->object, name, prop ); |
| VariantClear( &var ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI propertyset_get_Count( ISWbemPropertySet *iface, LONG *count ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI propertyset_Add( ISWbemPropertySet *iface, BSTR name, WbemCimtypeEnum type, |
| VARIANT_BOOL is_array, LONG flags, ISWbemProperty **prop ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI propertyset_Remove( ISWbemPropertySet *iface, BSTR name, LONG flags ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static const ISWbemPropertySetVtbl propertyset_vtbl = |
| { |
| propertyset_QueryInterface, |
| propertyset_AddRef, |
| propertyset_Release, |
| propertyset_GetTypeInfoCount, |
| propertyset_GetTypeInfo, |
| propertyset_GetIDsOfNames, |
| propertyset_Invoke, |
| propertyset_get__NewEnum, |
| propertyset_Item, |
| propertyset_get_Count, |
| propertyset_Add, |
| propertyset_Remove |
| }; |
| |
| static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPropertySet **obj ) |
| { |
| struct propertyset *propertyset; |
| |
| TRACE( "%p, %p\n", obj, wbem_object ); |
| |
| if (!(propertyset = heap_alloc( sizeof(*propertyset) ))) return E_OUTOFMEMORY; |
| propertyset->ISWbemPropertySet_iface.lpVtbl = &propertyset_vtbl; |
| propertyset->refs = 1; |
| propertyset->object = wbem_object; |
| IWbemClassObject_AddRef( propertyset->object ); |
| *obj = &propertyset->ISWbemPropertySet_iface; |
| |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |
| |
| #define DISPID_BASE 0x1800000 |
| |
| struct member |
| { |
| BSTR name; |
| DISPID dispid; |
| }; |
| |
| struct object |
| { |
| ISWbemObject ISWbemObject_iface; |
| LONG refs; |
| IWbemClassObject *object; |
| struct member *members; |
| UINT nb_members; |
| DISPID last_dispid; |
| }; |
| |
| static inline struct object *impl_from_ISWbemObject( |
| ISWbemObject *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct object, ISWbemObject_iface ); |
| } |
| |
| static ULONG WINAPI object_AddRef( |
| ISWbemObject *iface ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| return InterlockedIncrement( &object->refs ); |
| } |
| |
| static ULONG WINAPI object_Release( |
| ISWbemObject *iface ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| LONG refs = InterlockedDecrement( &object->refs ); |
| if (!refs) |
| { |
| UINT i; |
| |
| TRACE( "destroying %p\n", object ); |
| IWbemClassObject_Release( object->object ); |
| for (i = 0; i < object->nb_members; i++) SysFreeString( object->members[i].name ); |
| heap_free( object->members ); |
| heap_free( object ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI object_QueryInterface( |
| ISWbemObject *iface, |
| REFIID riid, |
| void **ppvObject ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| |
| TRACE( "%p %s %p\n", object, debugstr_guid(riid), ppvObject ); |
| |
| if (IsEqualGUID( riid, &IID_ISWbemObject ) || |
| IsEqualGUID( riid, &IID_IDispatch ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *ppvObject = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| ISWbemObject_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI object_GetTypeInfoCount( |
| ISWbemObject *iface, |
| UINT *count ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| |
| TRACE( "%p, %p\n", object, count ); |
| *count = 1; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI object_GetTypeInfo( |
| ISWbemObject *iface, |
| UINT index, |
| LCID lcid, |
| ITypeInfo **info ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| FIXME( "%p, %u, %u, %p\n", object, index, lcid, info ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT init_members( struct object *object ) |
| { |
| LONG bound, i; |
| SAFEARRAY *sa; |
| HRESULT hr; |
| |
| if (object->members) return S_OK; |
| |
| hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa ); |
| if (FAILED( hr )) return hr; |
| hr = SafeArrayGetUBound( sa, 1, &bound ); |
| if (FAILED( hr )) |
| { |
| SafeArrayDestroy( sa ); |
| return hr; |
| } |
| if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) ))) |
| { |
| SafeArrayDestroy( sa ); |
| return E_OUTOFMEMORY; |
| } |
| for (i = 0; i <= bound; i++) |
| { |
| hr = SafeArrayGetElement( sa, &i, &object->members[i].name ); |
| if (FAILED( hr )) |
| { |
| for (i--; i >= 0; i--) SysFreeString( object->members[i].name ); |
| SafeArrayDestroy( sa ); |
| heap_free( object->members ); |
| object->members = NULL; |
| return E_OUTOFMEMORY; |
| } |
| object->members[i].dispid = 0; |
| } |
| object->nb_members = bound + 1; |
| SafeArrayDestroy( sa ); |
| return S_OK; |
| } |
| |
| static DISPID get_member_dispid( struct object *object, const WCHAR *name ) |
| { |
| UINT i; |
| for (i = 0; i < object->nb_members; i++) |
| { |
| if (!strcmpiW( object->members[i].name, name )) |
| { |
| if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid; |
| return object->members[i].dispid; |
| } |
| } |
| return DISPID_UNKNOWN; |
| } |
| |
| static HRESULT WINAPI object_GetIDsOfNames( |
| ISWbemObject *iface, |
| REFIID riid, |
| LPOLESTR *names, |
| UINT count, |
| LCID lcid, |
| DISPID *dispid ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| HRESULT hr; |
| UINT i; |
| ITypeInfo *typeinfo; |
| |
| TRACE( "%p, %s, %p, %u, %u, %p\n", object, debugstr_guid(riid), names, count, lcid, dispid ); |
| |
| if (!names || !count || !dispid) return E_INVALIDARG; |
| |
| hr = init_members( object ); |
| if (FAILED( hr )) return hr; |
| |
| hr = get_typeinfo( ISWbemObject_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| if (SUCCEEDED(hr)) return hr; |
| |
| for (i = 0; i < count; i++) |
| { |
| if ((dispid[i] = get_member_dispid( object, names[i] )) == DISPID_UNKNOWN) break; |
| } |
| if (i != count) return DISP_E_UNKNOWNNAME; |
| return S_OK; |
| } |
| |
| static BSTR get_member_name( struct object *object, DISPID dispid ) |
| { |
| UINT i; |
| for (i = 0; i < object->nb_members; i++) |
| { |
| if (object->members[i].dispid == dispid) return object->members[i].name; |
| } |
| return NULL; |
| } |
| |
| static HRESULT WINAPI object_Invoke( |
| ISWbemObject *iface, |
| DISPID member, |
| REFIID riid, |
| LCID lcid, |
| WORD flags, |
| DISPPARAMS *params, |
| VARIANT *result, |
| EXCEPINFO *excep_info, |
| UINT *arg_err ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| BSTR name; |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid), |
| lcid, flags, params, result, excep_info, arg_err ); |
| |
| if (member <= DISPID_BASE) |
| { |
| hr = get_typeinfo( ISWbemObject_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_Invoke( typeinfo, &object->ISWbemObject_iface, member, flags, |
| params, result, excep_info, arg_err ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| if (flags != (DISPATCH_METHOD|DISPATCH_PROPERTYGET)) |
| { |
| FIXME( "flags %x not supported\n", flags ); |
| return E_NOTIMPL; |
| } |
| if (!(name = get_member_name( object, member ))) |
| return DISP_E_MEMBERNOTFOUND; |
| |
| memset( params, 0, sizeof(*params) ); |
| return IWbemClassObject_Get( object->object, name, 0, result, NULL, NULL ); |
| } |
| |
| static HRESULT WINAPI object_Put_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectPath **objWbemObjectPath ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_PutAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_Delete_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_DeleteAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_Instances_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_InstancesAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_Subclasses_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_SubclassesAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_Associators_( |
| ISWbemObject *iface, |
| BSTR strAssocClass, |
| BSTR strResultClass, |
| BSTR strResultRole, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredAssocQualifier, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_AssociatorsAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| BSTR strAssocClass, |
| BSTR strResultClass, |
| BSTR strResultRole, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredAssocQualifier, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_References_( |
| ISWbemObject *iface, |
| BSTR strResultClass, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_ReferencesAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| BSTR strResultClass, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_ExecMethod_( |
| ISWbemObject *iface, |
| BSTR strMethodName, |
| IDispatch *objWbemInParameters, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObject **objWbemOutParameters ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_ExecMethodAsync_( |
| ISWbemObject *iface, |
| IDispatch *objWbemSink, |
| BSTR strMethodName, |
| IDispatch *objWbemInParameters, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_Clone_( |
| ISWbemObject *iface, |
| ISWbemObject **objWbemObject ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_GetObjectText_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| BSTR *strObjectText ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_SpawnDerivedClass_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| ISWbemObject **objWbemObject ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_SpawnInstance_( |
| ISWbemObject *iface, |
| LONG iFlags, |
| ISWbemObject **objWbemObject ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_CompareTo_( |
| ISWbemObject *iface, |
| IDispatch *objWbemObject, |
| LONG iFlags, |
| VARIANT_BOOL *bResult ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_get_Qualifiers_( |
| ISWbemObject *iface, |
| ISWbemQualifierSet **objWbemQualifierSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_get_Properties_( ISWbemObject *iface, ISWbemPropertySet **prop_set ) |
| { |
| struct object *object = impl_from_ISWbemObject( iface ); |
| |
| TRACE( "%p, %p\n", object, prop_set ); |
| return SWbemPropertySet_create( object->object, prop_set ); |
| } |
| |
| static HRESULT WINAPI object_get_Methods_( |
| ISWbemObject *iface, |
| ISWbemMethodSet **objWbemMethodSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_get_Derivation_( |
| ISWbemObject *iface, |
| VARIANT *strClassNameArray ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_get_Path_( |
| ISWbemObject *iface, |
| ISWbemObjectPath **objWbemObjectPath ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI object_get_Security_( |
| ISWbemObject *iface, |
| ISWbemSecurity **objWbemSecurity ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static const ISWbemObjectVtbl object_vtbl = |
| { |
| object_QueryInterface, |
| object_AddRef, |
| object_Release, |
| object_GetTypeInfoCount, |
| object_GetTypeInfo, |
| object_GetIDsOfNames, |
| object_Invoke, |
| object_Put_, |
| object_PutAsync_, |
| object_Delete_, |
| object_DeleteAsync_, |
| object_Instances_, |
| object_InstancesAsync_, |
| object_Subclasses_, |
| object_SubclassesAsync_, |
| object_Associators_, |
| object_AssociatorsAsync_, |
| object_References_, |
| object_ReferencesAsync_, |
| object_ExecMethod_, |
| object_ExecMethodAsync_, |
| object_Clone_, |
| object_GetObjectText_, |
| object_SpawnDerivedClass_, |
| object_SpawnInstance_, |
| object_CompareTo_, |
| object_get_Qualifiers_, |
| object_get_Properties_, |
| object_get_Methods_, |
| object_get_Derivation_, |
| object_get_Path_, |
| object_get_Security_ |
| }; |
| |
| static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject **obj ) |
| { |
| struct object *object; |
| |
| TRACE( "%p, %p\n", obj, wbem_object ); |
| |
| if (!(object = heap_alloc( sizeof(*object) ))) return E_OUTOFMEMORY; |
| object->ISWbemObject_iface.lpVtbl = &object_vtbl; |
| object->refs = 1; |
| object->object = wbem_object; |
| IWbemClassObject_AddRef( object->object ); |
| object->members = NULL; |
| object->nb_members = 0; |
| object->last_dispid = DISPID_BASE; |
| |
| *obj = &object->ISWbemObject_iface; |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |
| |
| struct objectset |
| { |
| ISWbemObjectSet ISWbemObjectSet_iface; |
| LONG refs; |
| IEnumWbemClassObject *objectenum; |
| LONG count; |
| }; |
| |
| static inline struct objectset *impl_from_ISWbemObjectSet( |
| ISWbemObjectSet *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct objectset, ISWbemObjectSet_iface ); |
| } |
| |
| static ULONG WINAPI objectset_AddRef( |
| ISWbemObjectSet *iface ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| return InterlockedIncrement( &objectset->refs ); |
| } |
| |
| static ULONG WINAPI objectset_Release( |
| ISWbemObjectSet *iface ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| LONG refs = InterlockedDecrement( &objectset->refs ); |
| if (!refs) |
| { |
| TRACE( "destroying %p\n", objectset ); |
| IEnumWbemClassObject_Release( objectset->objectenum ); |
| heap_free( objectset ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI objectset_QueryInterface( |
| ISWbemObjectSet *iface, |
| REFIID riid, |
| void **ppvObject ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| |
| TRACE( "%p %s %p\n", objectset, debugstr_guid(riid), ppvObject ); |
| |
| if (IsEqualGUID( riid, &IID_ISWbemObjectSet ) || |
| IsEqualGUID( riid, &IID_IDispatch ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *ppvObject = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| ISWbemObjectSet_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI objectset_GetTypeInfoCount( |
| ISWbemObjectSet *iface, |
| UINT *count ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| TRACE( "%p, %p\n", objectset, count ); |
| *count = 1; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI objectset_GetTypeInfo( |
| ISWbemObjectSet *iface, |
| UINT index, |
| LCID lcid, |
| ITypeInfo **info ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| TRACE( "%p, %u, %u, %p\n", objectset, index, lcid, info ); |
| |
| return get_typeinfo( ISWbemObjectSet_tid, info ); |
| } |
| |
| static HRESULT WINAPI objectset_GetIDsOfNames( |
| ISWbemObjectSet *iface, |
| REFIID riid, |
| LPOLESTR *names, |
| UINT count, |
| LCID lcid, |
| DISPID *dispid ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %p, %u, %u, %p\n", objectset, debugstr_guid(riid), names, count, lcid, dispid ); |
| |
| if (!names || !count || !dispid) return E_INVALIDARG; |
| |
| hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI objectset_Invoke( |
| ISWbemObjectSet *iface, |
| DISPID member, |
| REFIID riid, |
| LCID lcid, |
| WORD flags, |
| DISPPARAMS *params, |
| VARIANT *result, |
| EXCEPINFO *excep_info, |
| UINT *arg_err ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", objectset, member, debugstr_guid(riid), |
| lcid, flags, params, result, excep_info, arg_err ); |
| |
| hr = get_typeinfo( ISWbemObjectSet_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_Invoke( typeinfo, &objectset->ISWbemObjectSet_iface, member, flags, |
| params, result, excep_info, arg_err ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI objectset_get__NewEnum( |
| ISWbemObjectSet *iface, |
| IUnknown **pUnk ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| IEnumWbemClassObject *objectenum; |
| HRESULT hr; |
| |
| TRACE( "%p, %p\n", objectset, pUnk ); |
| |
| hr = IEnumWbemClassObject_Clone( objectset->objectenum, &objectenum ); |
| if (FAILED( hr )) return hr; |
| |
| hr = EnumVARIANT_create( objectenum, (IEnumVARIANT **)pUnk ); |
| IEnumWbemClassObject_Release( objectenum ); |
| return hr; |
| } |
| |
| static HRESULT WINAPI objectset_Item( |
| ISWbemObjectSet *iface, |
| BSTR strObjectPath, |
| LONG iFlags, |
| ISWbemObject **objWbemObject ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI objectset_get_Count( |
| ISWbemObjectSet *iface, |
| LONG *iCount ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| |
| TRACE( "%p, %p\n", objectset, iCount ); |
| |
| *iCount = objectset->count; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI objectset_get_Security_( |
| ISWbemObjectSet *iface, |
| ISWbemSecurity **objWbemSecurity ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI objectset_ItemIndex( |
| ISWbemObjectSet *iface, |
| LONG lIndex, |
| ISWbemObject **objWbemObject ) |
| { |
| struct objectset *objectset = impl_from_ISWbemObjectSet( iface ); |
| LONG count; |
| HRESULT hr; |
| IEnumVARIANT *enum_var; |
| VARIANT var; |
| |
| TRACE( "%p, %d, %p\n", objectset, lIndex, objWbemObject ); |
| |
| *objWbemObject = NULL; |
| hr = ISWbemObjectSet_get_Count( iface, &count ); |
| if (FAILED(hr)) return hr; |
| |
| if (lIndex >= count) return WBEM_E_NOT_FOUND; |
| |
| hr = ISWbemObjectSet_get__NewEnum( iface, (IUnknown **)&enum_var ); |
| if (FAILED(hr)) return hr; |
| |
| IEnumVARIANT_Reset( enum_var ); |
| hr = IEnumVARIANT_Skip( enum_var, lIndex ); |
| if (SUCCEEDED(hr)) |
| hr = IEnumVARIANT_Next( enum_var, 1, &var, NULL ); |
| IEnumVARIANT_Release( enum_var ); |
| |
| if (SUCCEEDED(hr)) |
| { |
| if (V_VT( &var ) == VT_DISPATCH) |
| hr = IDispatch_QueryInterface( V_DISPATCH( &var ), &IID_ISWbemObject, (void **)objWbemObject ); |
| else |
| hr = WBEM_E_NOT_FOUND; |
| VariantClear( &var ); |
| } |
| |
| return hr; |
| } |
| |
| static const ISWbemObjectSetVtbl objectset_vtbl = |
| { |
| objectset_QueryInterface, |
| objectset_AddRef, |
| objectset_Release, |
| objectset_GetTypeInfoCount, |
| objectset_GetTypeInfo, |
| objectset_GetIDsOfNames, |
| objectset_Invoke, |
| objectset_get__NewEnum, |
| objectset_Item, |
| objectset_get_Count, |
| objectset_get_Security_, |
| objectset_ItemIndex |
| }; |
| |
| static LONG get_object_count( IEnumWbemClassObject *iter ) |
| { |
| LONG count = 0; |
| while (IEnumWbemClassObject_Skip( iter, WBEM_INFINITE, 1 ) == S_OK) count++; |
| IEnumWbemClassObject_Reset( iter ); |
| return count; |
| } |
| |
| static HRESULT SWbemObjectSet_create( IEnumWbemClassObject *wbem_objectenum, ISWbemObjectSet **obj ) |
| { |
| struct objectset *objectset; |
| |
| TRACE( "%p, %p\n", obj, wbem_objectenum ); |
| |
| if (!(objectset = heap_alloc( sizeof(*objectset) ))) return E_OUTOFMEMORY; |
| objectset->ISWbemObjectSet_iface.lpVtbl = &objectset_vtbl; |
| objectset->refs = 1; |
| objectset->objectenum = wbem_objectenum; |
| IEnumWbemClassObject_AddRef( objectset->objectenum ); |
| objectset->count = get_object_count( objectset->objectenum ); |
| |
| *obj = &objectset->ISWbemObjectSet_iface; |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |
| |
| struct enumvar |
| { |
| IEnumVARIANT IEnumVARIANT_iface; |
| LONG refs; |
| IEnumWbemClassObject *objectenum; |
| }; |
| |
| static inline struct enumvar *impl_from_IEnumVARIANT( |
| IEnumVARIANT *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct enumvar, IEnumVARIANT_iface ); |
| } |
| |
| static ULONG WINAPI enumvar_AddRef( |
| IEnumVARIANT *iface ) |
| { |
| struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); |
| return InterlockedIncrement( &enumvar->refs ); |
| } |
| |
| static ULONG WINAPI enumvar_Release( |
| IEnumVARIANT *iface ) |
| { |
| struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); |
| LONG refs = InterlockedDecrement( &enumvar->refs ); |
| if (!refs) |
| { |
| TRACE( "destroying %p\n", enumvar ); |
| IEnumWbemClassObject_Release( enumvar->objectenum ); |
| heap_free( enumvar ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI enumvar_QueryInterface( |
| IEnumVARIANT *iface, |
| REFIID riid, |
| void **ppvObject ) |
| { |
| struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); |
| |
| TRACE( "%p %s %p\n", enumvar, debugstr_guid(riid), ppvObject ); |
| |
| if (IsEqualGUID( riid, &IID_IEnumVARIANT ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *ppvObject = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| IEnumVARIANT_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI enumvar_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *var, ULONG *fetched ) |
| { |
| struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); |
| IWbemClassObject *obj; |
| ULONG count = 0; |
| |
| TRACE( "%p, %u, %p, %p\n", iface, celt, var, fetched ); |
| |
| if (celt) IEnumWbemClassObject_Next( enumvar->objectenum, WBEM_INFINITE, 1, &obj, &count ); |
| if (count) |
| { |
| ISWbemObject *sobj; |
| HRESULT hr; |
| |
| hr = SWbemObject_create( obj, &sobj ); |
| IWbemClassObject_Release( obj ); |
| if (FAILED( hr )) return hr; |
| |
| V_VT( var ) = VT_DISPATCH; |
| V_DISPATCH( var ) = (IDispatch *)sobj; |
| } |
| if (fetched) *fetched = count; |
| return (count < celt) ? S_FALSE : S_OK; |
| } |
| |
| static HRESULT WINAPI enumvar_Skip( IEnumVARIANT *iface, ULONG celt ) |
| { |
| struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); |
| |
| TRACE( "%p, %u\n", iface, celt ); |
| |
| return IEnumWbemClassObject_Skip( enumvar->objectenum, WBEM_INFINITE, celt ); |
| } |
| |
| static HRESULT WINAPI enumvar_Reset( IEnumVARIANT *iface ) |
| { |
| struct enumvar *enumvar = impl_from_IEnumVARIANT( iface ); |
| |
| TRACE( "%p\n", iface ); |
| |
| return IEnumWbemClassObject_Reset( enumvar->objectenum ); |
| } |
| |
| static HRESULT WINAPI enumvar_Clone( IEnumVARIANT *iface, IEnumVARIANT **penum ) |
| { |
| FIXME( "%p, %p\n", iface, penum ); |
| return E_NOTIMPL; |
| } |
| |
| static const struct IEnumVARIANTVtbl enumvar_vtbl = |
| { |
| enumvar_QueryInterface, |
| enumvar_AddRef, |
| enumvar_Release, |
| enumvar_Next, |
| enumvar_Skip, |
| enumvar_Reset, |
| enumvar_Clone |
| }; |
| |
| static HRESULT EnumVARIANT_create( IEnumWbemClassObject *objectenum, IEnumVARIANT **obj ) |
| { |
| struct enumvar *enumvar; |
| |
| if (!(enumvar = heap_alloc( sizeof(*enumvar) ))) return E_OUTOFMEMORY; |
| enumvar->IEnumVARIANT_iface.lpVtbl = &enumvar_vtbl; |
| enumvar->refs = 1; |
| enumvar->objectenum = objectenum; |
| IEnumWbemClassObject_AddRef( enumvar->objectenum ); |
| |
| *obj = &enumvar->IEnumVARIANT_iface; |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |
| |
| struct services |
| { |
| ISWbemServices ISWbemServices_iface; |
| LONG refs; |
| IWbemServices *services; |
| }; |
| |
| static inline struct services *impl_from_ISWbemServices( |
| ISWbemServices *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct services, ISWbemServices_iface ); |
| } |
| |
| static ULONG WINAPI services_AddRef( |
| ISWbemServices *iface ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| return InterlockedIncrement( &services->refs ); |
| } |
| |
| static ULONG WINAPI services_Release( |
| ISWbemServices *iface ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| LONG refs = InterlockedDecrement( &services->refs ); |
| if (!refs) |
| { |
| TRACE( "destroying %p\n", services ); |
| IWbemServices_Release( services->services ); |
| heap_free( services ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI services_QueryInterface( |
| ISWbemServices *iface, |
| REFIID riid, |
| void **ppvObject ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| |
| TRACE( "%p %s %p\n", services, debugstr_guid(riid), ppvObject ); |
| |
| if (IsEqualGUID( riid, &IID_ISWbemServices ) || |
| IsEqualGUID( riid, &IID_IDispatch ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *ppvObject = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| ISWbemServices_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI services_GetTypeInfoCount( |
| ISWbemServices *iface, |
| UINT *count ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| TRACE( "%p, %p\n", services, count ); |
| |
| *count = 1; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI services_GetTypeInfo( |
| ISWbemServices *iface, |
| UINT index, |
| LCID lcid, |
| ITypeInfo **info ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| TRACE( "%p, %u, %u, %p\n", services, index, lcid, info ); |
| |
| return get_typeinfo( ISWbemServices_tid, info ); |
| } |
| |
| static HRESULT WINAPI services_GetIDsOfNames( |
| ISWbemServices *iface, |
| REFIID riid, |
| LPOLESTR *names, |
| UINT count, |
| LCID lcid, |
| DISPID *dispid ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %p, %u, %u, %p\n", services, debugstr_guid(riid), names, count, lcid, dispid ); |
| |
| if (!names || !count || !dispid) return E_INVALIDARG; |
| |
| hr = get_typeinfo( ISWbemServices_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI services_Invoke( |
| ISWbemServices *iface, |
| DISPID member, |
| REFIID riid, |
| LCID lcid, |
| WORD flags, |
| DISPPARAMS *params, |
| VARIANT *result, |
| EXCEPINFO *excep_info, |
| UINT *arg_err ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", services, member, debugstr_guid(riid), |
| lcid, flags, params, result, excep_info, arg_err ); |
| |
| hr = get_typeinfo( ISWbemServices_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_Invoke( typeinfo, &services->ISWbemServices_iface, member, flags, |
| params, result, excep_info, arg_err ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI services_Get( |
| ISWbemServices *iface, |
| BSTR strObjectPath, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObject **objWbemObject ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| IWbemClassObject *obj; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %d, %p, %p\n", iface, debugstr_w(strObjectPath), iFlags, objWbemNamedValueSet, |
| objWbemObject ); |
| |
| if (objWbemNamedValueSet) FIXME( "ignoring context\n" ); |
| |
| hr = IWbemServices_GetObject( services->services, strObjectPath, iFlags, NULL, &obj, NULL ); |
| if (hr != S_OK) return hr; |
| |
| hr = SWbemObject_create( obj, objWbemObject ); |
| IWbemClassObject_Release( obj ); |
| return hr; |
| } |
| |
| static HRESULT WINAPI services_GetAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strObjectPath, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_Delete( |
| ISWbemServices *iface, |
| BSTR strObjectPath, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_DeleteAsync( |
| ISWbemServices* This, |
| IDispatch *objWbemSink, |
| BSTR strObjectPath, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static BSTR build_query_string( const WCHAR *class ) |
| { |
| static const WCHAR selectW[] = {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',0}; |
| UINT len = strlenW(class) + sizeof(selectW) / sizeof(selectW[0]); |
| BSTR ret; |
| |
| if (!(ret = SysAllocStringLen( NULL, len ))) return NULL; |
| strcpyW( ret, selectW ); |
| strcatW( ret, class ); |
| return ret; |
| } |
| |
| static HRESULT WINAPI services_InstancesOf( |
| ISWbemServices *iface, |
| BSTR strClass, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| static const WCHAR wqlW[] = {'W','Q','L',0}; |
| BSTR query, wql = SysAllocString( wqlW ); |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %x, %p, %p\n", iface, debugstr_w(strClass), iFlags, objWbemNamedValueSet, |
| objWbemObjectSet ); |
| |
| if (!(query = build_query_string( strClass ))) |
| { |
| SysFreeString( wql ); |
| return E_OUTOFMEMORY; |
| } |
| hr = ISWbemServices_ExecQuery( iface, query, wql, iFlags, objWbemNamedValueSet, objWbemObjectSet ); |
| SysFreeString( wql ); |
| SysFreeString( query ); |
| return hr; |
| } |
| |
| static HRESULT WINAPI services_InstancesOfAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strClass, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_SubclassesOf( |
| ISWbemServices *iface, |
| BSTR strSuperclass, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_SubclassesOfAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strSuperclass, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ExecQuery( |
| ISWbemServices *iface, |
| BSTR strQuery, |
| BSTR strQueryLanguage, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| struct services *services = impl_from_ISWbemServices( iface ); |
| IEnumWbemClassObject *iter; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %s, %x, %p, %p\n", iface, debugstr_w(strQuery), debugstr_w(strQueryLanguage), |
| iFlags, objWbemNamedValueSet, objWbemObjectSet ); |
| |
| if (objWbemNamedValueSet) FIXME( "ignoring context\n" ); |
| |
| hr = IWbemServices_ExecQuery( services->services, strQueryLanguage, strQuery, iFlags, NULL, &iter ); |
| if (hr != S_OK) return hr; |
| |
| hr = SWbemObjectSet_create( iter, objWbemObjectSet ); |
| IEnumWbemClassObject_Release( iter ); |
| return hr; |
| } |
| |
| static HRESULT WINAPI services_ExecQueryAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strQuery, |
| BSTR strQueryLanguage, |
| LONG lFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_AssociatorsOf( |
| ISWbemServices *iface, |
| BSTR strObjectPath, |
| BSTR strAssocClass, |
| BSTR strResultClass, |
| BSTR strResultRole, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredAssocQualifier, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_AssociatorsOfAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strObjectPath, |
| BSTR strAssocClass, |
| BSTR strResultClass, |
| BSTR strResultRole, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredAssocQualifier, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ReferencesTo( |
| ISWbemServices *iface, |
| BSTR strObjectPath, |
| BSTR strResultClass, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObjectSet **objWbemObjectSet ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ReferencesToAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strObjectPath, |
| BSTR strResultClass, |
| BSTR strRole, |
| VARIANT_BOOL bClassesOnly, |
| VARIANT_BOOL bSchemaOnly, |
| BSTR strRequiredQualifier, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ExecNotificationQuery( |
| ISWbemServices *iface, |
| BSTR strQuery, |
| BSTR strQueryLanguage, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemEventSource **objWbemEventSource ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ExecNotificationQueryAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strQuery, |
| BSTR strQueryLanguage, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ExecMethod( |
| ISWbemServices *iface, |
| BSTR strObjectPath, |
| BSTR strMethodName, |
| IDispatch *objWbemInParameters, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemObject **objWbemOutParameters ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_ExecMethodAsync( |
| ISWbemServices *iface, |
| IDispatch *objWbemSink, |
| BSTR strObjectPath, |
| BSTR strMethodName, |
| IDispatch *objWbemInParameters, |
| LONG iFlags, |
| IDispatch *objWbemNamedValueSet, |
| IDispatch *objWbemAsyncContext ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static HRESULT WINAPI services_get_Security_( |
| ISWbemServices *iface, |
| ISWbemSecurity **objWbemSecurity ) |
| { |
| FIXME( "\n" ); |
| return E_NOTIMPL; |
| } |
| |
| static const ISWbemServicesVtbl services_vtbl = |
| { |
| services_QueryInterface, |
| services_AddRef, |
| services_Release, |
| services_GetTypeInfoCount, |
| services_GetTypeInfo, |
| services_GetIDsOfNames, |
| services_Invoke, |
| services_Get, |
| services_GetAsync, |
| services_Delete, |
| services_DeleteAsync, |
| services_InstancesOf, |
| services_InstancesOfAsync, |
| services_SubclassesOf, |
| services_SubclassesOfAsync, |
| services_ExecQuery, |
| services_ExecQueryAsync, |
| services_AssociatorsOf, |
| services_AssociatorsOfAsync, |
| services_ReferencesTo, |
| services_ReferencesToAsync, |
| services_ExecNotificationQuery, |
| services_ExecNotificationQueryAsync, |
| services_ExecMethod, |
| services_ExecMethodAsync, |
| services_get_Security_ |
| }; |
| |
| static HRESULT SWbemServices_create( IWbemServices *wbem_services, ISWbemServices **obj ) |
| { |
| struct services *services; |
| |
| TRACE( "%p, %p\n", obj, wbem_services ); |
| |
| if (!(services = heap_alloc( sizeof(*services) ))) return E_OUTOFMEMORY; |
| services->ISWbemServices_iface.lpVtbl = &services_vtbl; |
| services->refs = 1; |
| services->services = wbem_services; |
| IWbemServices_AddRef( services->services ); |
| |
| *obj = &services->ISWbemServices_iface; |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |
| |
| struct locator |
| { |
| ISWbemLocator ISWbemLocator_iface; |
| LONG refs; |
| IWbemLocator *locator; |
| }; |
| |
| static inline struct locator *impl_from_ISWbemLocator( ISWbemLocator *iface ) |
| { |
| return CONTAINING_RECORD( iface, struct locator, ISWbemLocator_iface ); |
| } |
| |
| static ULONG WINAPI locator_AddRef( |
| ISWbemLocator *iface ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| return InterlockedIncrement( &locator->refs ); |
| } |
| |
| static ULONG WINAPI locator_Release( |
| ISWbemLocator *iface ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| LONG refs = InterlockedDecrement( &locator->refs ); |
| if (!refs) |
| { |
| TRACE( "destroying %p\n", locator ); |
| if (locator->locator) |
| IWbemLocator_Release( locator->locator ); |
| heap_free( locator ); |
| } |
| return refs; |
| } |
| |
| static HRESULT WINAPI locator_QueryInterface( |
| ISWbemLocator *iface, |
| REFIID riid, |
| void **ppvObject ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| |
| TRACE( "%p, %s, %p\n", locator, debugstr_guid( riid ), ppvObject ); |
| |
| if (IsEqualGUID( riid, &IID_ISWbemLocator ) || |
| IsEqualGUID( riid, &IID_IDispatch ) || |
| IsEqualGUID( riid, &IID_IUnknown )) |
| { |
| *ppvObject = iface; |
| } |
| else |
| { |
| FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); |
| return E_NOINTERFACE; |
| } |
| ISWbemLocator_AddRef( iface ); |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI locator_GetTypeInfoCount( |
| ISWbemLocator *iface, |
| UINT *count ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| |
| TRACE( "%p, %p\n", locator, count ); |
| *count = 1; |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI locator_GetTypeInfo( |
| ISWbemLocator *iface, |
| UINT index, |
| LCID lcid, |
| ITypeInfo **info ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| TRACE( "%p, %u, %u, %p\n", locator, index, lcid, info ); |
| |
| return get_typeinfo( ISWbemLocator_tid, info ); |
| } |
| |
| static HRESULT WINAPI locator_GetIDsOfNames( |
| ISWbemLocator *iface, |
| REFIID riid, |
| LPOLESTR *names, |
| UINT count, |
| LCID lcid, |
| DISPID *dispid ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %p, %u, %u, %p\n", locator, debugstr_guid(riid), names, count, lcid, dispid ); |
| |
| if (!names || !count || !dispid) return E_INVALIDARG; |
| |
| hr = get_typeinfo( ISWbemLocator_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static HRESULT WINAPI locator_Invoke( |
| ISWbemLocator *iface, |
| DISPID member, |
| REFIID riid, |
| LCID lcid, |
| WORD flags, |
| DISPPARAMS *params, |
| VARIANT *result, |
| EXCEPINFO *excep_info, |
| UINT *arg_err ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| ITypeInfo *typeinfo; |
| HRESULT hr; |
| |
| TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", locator, member, debugstr_guid(riid), |
| lcid, flags, params, result, excep_info, arg_err ); |
| |
| hr = get_typeinfo( ISWbemLocator_tid, &typeinfo ); |
| if (SUCCEEDED(hr)) |
| { |
| hr = ITypeInfo_Invoke( typeinfo, &locator->ISWbemLocator_iface, member, flags, |
| params, result, excep_info, arg_err ); |
| ITypeInfo_Release( typeinfo ); |
| } |
| return hr; |
| } |
| |
| static BSTR build_resource_string( BSTR server, BSTR namespace ) |
| { |
| static const WCHAR defaultW[] = {'r','o','o','t','\\','d','e','f','a','u','l','t',0}; |
| ULONG len, len_server = 0, len_namespace = 0; |
| BSTR ret; |
| |
| if (server && *server) len_server = strlenW( server ); |
| else len_server = 1; |
| if (namespace && *namespace) len_namespace = strlenW( namespace ); |
| else len_namespace = sizeof(defaultW) / sizeof(defaultW[0]) - 1; |
| |
| if (!(ret = SysAllocStringLen( NULL, 2 + len_server + 1 + len_namespace ))) return NULL; |
| |
| ret[0] = ret[1] = '\\'; |
| if (server && *server) strcpyW( ret + 2, server ); |
| else ret[2] = '.'; |
| |
| len = len_server + 2; |
| ret[len++] = '\\'; |
| |
| if (namespace && *namespace) strcpyW( ret + len, namespace ); |
| else strcpyW( ret + len, defaultW ); |
| return ret; |
| } |
| |
| static HRESULT WINAPI locator_ConnectServer( |
| ISWbemLocator *iface, |
| BSTR strServer, |
| BSTR strNamespace, |
| BSTR strUser, |
| BSTR strPassword, |
| BSTR strLocale, |
| BSTR strAuthority, |
| LONG iSecurityFlags, |
| IDispatch *objWbemNamedValueSet, |
| ISWbemServices **objWbemServices ) |
| { |
| struct locator *locator = impl_from_ISWbemLocator( iface ); |
| IWbemServices *services; |
| BSTR resource; |
| HRESULT hr; |
| |
| TRACE( "%p, %s, %s, %s, %p, %s, %s, 0x%08x, %p, %p\n", iface, debugstr_w(strServer), |
| debugstr_w(strNamespace), debugstr_w(strUser), strPassword, debugstr_w(strLocale), |
| debugstr_w(strAuthority), iSecurityFlags, objWbemNamedValueSet, objWbemServices ); |
| |
| if (objWbemNamedValueSet) FIXME( "context not supported\n" ); |
| |
| if (!locator->locator) |
| { |
| hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, |
| (void **)&locator->locator ); |
| if (hr != S_OK) return hr; |
| } |
| |
| if (!(resource = build_resource_string( strServer, strNamespace ))) return E_OUTOFMEMORY; |
| hr = IWbemLocator_ConnectServer( locator->locator, resource, strUser, strPassword, strLocale, |
| iSecurityFlags, strAuthority, NULL, &services ); |
| SysFreeString( resource ); |
| if (hr != S_OK) return hr; |
| |
| hr = SWbemServices_create( services, objWbemServices ); |
| IWbemServices_Release( services ); |
| return hr; |
| } |
| |
| static HRESULT WINAPI locator_get_Security_( |
| ISWbemLocator *iface, |
| ISWbemSecurity **objWbemSecurity ) |
| { |
| FIXME( "%p, %p\n", iface, objWbemSecurity ); |
| return E_NOTIMPL; |
| } |
| |
| static const ISWbemLocatorVtbl locator_vtbl = |
| { |
| locator_QueryInterface, |
| locator_AddRef, |
| locator_Release, |
| locator_GetTypeInfoCount, |
| locator_GetTypeInfo, |
| locator_GetIDsOfNames, |
| locator_Invoke, |
| locator_ConnectServer, |
| locator_get_Security_ |
| }; |
| |
| HRESULT SWbemLocator_create( void **obj ) |
| { |
| struct locator *locator; |
| |
| TRACE( "%p\n", obj ); |
| |
| if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY; |
| locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl; |
| locator->refs = 1; |
| locator->locator = NULL; |
| |
| *obj = &locator->ISWbemLocator_iface; |
| TRACE( "returning iface %p\n", *obj ); |
| return S_OK; |
| } |