/* * Copyright 2012 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 #include "windef.h" #include "winbase.h" #include "objbase.h" #include "wbemcli.h" #include "wine/debug.h" #include "wbemprox_private.h" WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); struct enum_class_object { IEnumWbemClassObject IEnumWbemClassObject_iface; LONG refs; struct query *query; }; static inline struct enum_class_object *impl_from_IEnumWbemClassObject( IEnumWbemClassObject *iface ) { return CONTAINING_RECORD(iface, struct enum_class_object, IEnumWbemClassObject_iface); } static ULONG WINAPI enum_class_object_AddRef( IEnumWbemClassObject *iface ) { struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); return InterlockedIncrement( &ec->refs ); } static ULONG WINAPI enum_class_object_Release( IEnumWbemClassObject *iface ) { struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); LONG refs = InterlockedDecrement( &ec->refs ); if (!refs) { TRACE("destroying %p\n", ec); free_query( ec->query ); heap_free( ec ); } return refs; } static HRESULT WINAPI enum_class_object_QueryInterface( IEnumWbemClassObject *iface, REFIID riid, void **ppvObject ) { struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); TRACE("%p, %s, %p\n", ec, debugstr_guid( riid ), ppvObject ); if ( IsEqualGUID( riid, &IID_IEnumWbemClassObject ) || IsEqualGUID( riid, &IID_IUnknown ) ) { *ppvObject = ec; } else { FIXME("interface %s not implemented\n", debugstr_guid(riid)); return E_NOINTERFACE; } IEnumWbemClassObject_AddRef( iface ); return S_OK; } static HRESULT WINAPI enum_class_object_Reset( IEnumWbemClassObject *iface ) { struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); struct view *view = ec->query->view; TRACE("%p\n", iface); view->index = 0; return WBEM_S_NO_ERROR; } static HRESULT WINAPI enum_class_object_Next( IEnumWbemClassObject *iface, LONG lTimeout, ULONG uCount, IWbemClassObject **apObjects, ULONG *puReturned ) { struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); struct view *view = ec->query->view; HRESULT hr; TRACE("%p, %d, %u, %p, %p\n", iface, lTimeout, uCount, apObjects, puReturned); if (!uCount) return WBEM_S_FALSE; if (!apObjects || !puReturned) return WBEM_E_INVALID_PARAMETER; if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n"); *puReturned = 0; if (view->index + uCount > view->count) return WBEM_S_FALSE; hr = WbemClassObject_create( NULL, iface, view->index, (void **)apObjects ); if (hr != S_OK) return hr; view->index++; *puReturned = 1; if (view->index == view->count) return WBEM_S_FALSE; if (uCount > 1) return WBEM_S_TIMEDOUT; return WBEM_S_NO_ERROR; } static HRESULT WINAPI enum_class_object_NextAsync( IEnumWbemClassObject *iface, ULONG uCount, IWbemObjectSink *pSink ) { FIXME("%p, %u, %p\n", iface, uCount, pSink); return E_NOTIMPL; } static HRESULT WINAPI enum_class_object_Clone( IEnumWbemClassObject *iface, IEnumWbemClassObject **ppEnum ) { FIXME("%p, %p\n", iface, ppEnum); return E_NOTIMPL; } static HRESULT WINAPI enum_class_object_Skip( IEnumWbemClassObject *iface, LONG lTimeout, ULONG nCount ) { struct enum_class_object *ec = impl_from_IEnumWbemClassObject( iface ); struct view *view = ec->query->view; TRACE("%p, %d, %u\n", iface, lTimeout, nCount); if (lTimeout != WBEM_INFINITE) FIXME("timeout not supported\n"); if (view->index + nCount >= view->count) { view->index = view->count - 1; return WBEM_S_FALSE; } view->index += nCount; return WBEM_S_NO_ERROR; } static const IEnumWbemClassObjectVtbl enum_class_object_vtbl = { enum_class_object_QueryInterface, enum_class_object_AddRef, enum_class_object_Release, enum_class_object_Reset, enum_class_object_Next, enum_class_object_NextAsync, enum_class_object_Clone, enum_class_object_Skip }; HRESULT EnumWbemClassObject_create( IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj ) { struct enum_class_object *ec; TRACE("%p, %p\n", pUnkOuter, ppObj); ec = heap_alloc( sizeof(*ec) ); if (!ec) return E_OUTOFMEMORY; ec->IEnumWbemClassObject_iface.lpVtbl = &enum_class_object_vtbl; ec->refs = 1; ec->query = query; *ppObj = &ec->IEnumWbemClassObject_iface; TRACE("returning iface %p\n", *ppObj); return S_OK; } struct class_object { IWbemClassObject IWbemClassObject_iface; LONG refs; IEnumWbemClassObject *iter; UINT index; }; static inline struct class_object *impl_from_IWbemClassObject( IWbemClassObject *iface ) { return CONTAINING_RECORD(iface, struct class_object, IWbemClassObject_iface); } static ULONG WINAPI class_object_AddRef( IWbemClassObject *iface ) { struct class_object *co = impl_from_IWbemClassObject( iface ); return InterlockedIncrement( &co->refs ); } static ULONG WINAPI class_object_Release( IWbemClassObject *iface ) { struct class_object *co = impl_from_IWbemClassObject( iface ); LONG refs = InterlockedDecrement( &co->refs ); if (!refs) { TRACE("destroying %p\n", co); if (co->iter) IEnumWbemClassObject_Release( co->iter ); heap_free( co ); } return refs; } static HRESULT WINAPI class_object_QueryInterface( IWbemClassObject *iface, REFIID riid, void **ppvObject ) { struct class_object *co = impl_from_IWbemClassObject( iface ); TRACE("%p, %s, %p\n", co, debugstr_guid( riid ), ppvObject ); if ( IsEqualGUID( riid, &IID_IWbemClassObject ) || IsEqualGUID( riid, &IID_IUnknown ) ) { *ppvObject = co; } else { FIXME("interface %s not implemented\n", debugstr_guid(riid)); return E_NOINTERFACE; } IWbemClassObject_AddRef( iface ); return S_OK; } static HRESULT WINAPI class_object_GetQualifierSet( IWbemClassObject *iface, IWbemQualifierSet **ppQualSet ) { FIXME("%p, %p\n", iface, ppQualSet); return E_NOTIMPL; } static HRESULT WINAPI class_object_Get( IWbemClassObject *iface, LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE *pType, LONG *plFlavor ) { struct class_object *co = impl_from_IWbemClassObject( iface ); struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); struct view *view = ec->query->view; TRACE("%p, %s, %08x, %p, %p, %p\n", iface, debugstr_w(wszName), lFlags, pVal, pType, plFlavor); if (plFlavor) { FIXME("flavor parameter not supported\n"); *plFlavor = 0; } return get_propval( view, co->index, wszName, pVal, pType ); } static HRESULT WINAPI class_object_Put( IWbemClassObject *iface, LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE Type ) { FIXME("%p, %s, %08x, %p, %u\n", iface, debugstr_w(wszName), lFlags, pVal, Type); return E_NOTIMPL; } static HRESULT WINAPI class_object_Delete( IWbemClassObject *iface, LPCWSTR wszName ) { FIXME("%p, %s\n", iface, debugstr_w(wszName)); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetNames( IWbemClassObject *iface, LPCWSTR wszQualifierName, LONG lFlags, VARIANT *pQualifierVal, SAFEARRAY **pNames ) { struct class_object *co = impl_from_IWbemClassObject( iface ); struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter ); TRACE("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszQualifierName), lFlags, pQualifierVal, pNames); if (wszQualifierName || pQualifierVal) { FIXME("qualifier not supported\n"); return E_NOTIMPL; } if (lFlags != WBEM_FLAG_ALWAYS) { FIXME("flags %08x not supported\n", lFlags); return E_NOTIMPL; } return get_properties( ec->query->view, pNames ); } static HRESULT WINAPI class_object_BeginEnumeration( IWbemClassObject *iface, LONG lEnumFlags ) { FIXME("%p, %08x\n", iface, lEnumFlags); return E_NOTIMPL; } static HRESULT WINAPI class_object_Next( IWbemClassObject *iface, LONG lFlags, BSTR *strName, VARIANT *pVal, CIMTYPE *pType, LONG *plFlavor ) { FIXME("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor); return E_NOTIMPL; } static HRESULT WINAPI class_object_EndEnumeration( IWbemClassObject *iface ) { FIXME("%p\n", iface); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetPropertyQualifierSet( IWbemClassObject *iface, LPCWSTR wszProperty, IWbemQualifierSet **ppQualSet ) { FIXME("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); return E_NOTIMPL; } static HRESULT WINAPI class_object_Clone( IWbemClassObject *iface, IWbemClassObject **ppCopy ) { FIXME("%p, %p\n", iface, ppCopy); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetObjectText( IWbemClassObject *iface, LONG lFlags, BSTR *pstrObjectText ) { FIXME("%p, %08x, %p\n", iface, lFlags, pstrObjectText); return E_NOTIMPL; } static HRESULT WINAPI class_object_SpawnDerivedClass( IWbemClassObject *iface, LONG lFlags, IWbemClassObject **ppNewClass ) { FIXME("%p, %08x, %p\n", iface, lFlags, ppNewClass); return E_NOTIMPL; } static HRESULT WINAPI class_object_SpawnInstance( IWbemClassObject *iface, LONG lFlags, IWbemClassObject **ppNewInstance ) { FIXME("%p, %08x, %p\n", iface, lFlags, ppNewInstance); return E_NOTIMPL; } static HRESULT WINAPI class_object_CompareTo( IWbemClassObject *iface, LONG lFlags, IWbemClassObject *pCompareTo ) { FIXME("%p, %08x, %p\n", iface, lFlags, pCompareTo); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetPropertyOrigin( IWbemClassObject *iface, LPCWSTR wszName, BSTR *pstrClassName ) { FIXME("%p, %s, %p\n", iface, debugstr_w(wszName), pstrClassName); return E_NOTIMPL; } static HRESULT WINAPI class_object_InheritsFrom( IWbemClassObject *iface, LPCWSTR strAncestor ) { FIXME("%p, %s\n", iface, debugstr_w(strAncestor)); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetMethod( IWbemClassObject *iface, LPCWSTR wszName, LONG lFlags, IWbemClassObject **ppInSignature, IWbemClassObject **ppOutSignature ) { FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, ppInSignature, ppOutSignature); return E_NOTIMPL; } static HRESULT WINAPI class_object_PutMethod( IWbemClassObject *iface, LPCWSTR wszName, LONG lFlags, IWbemClassObject *pInSignature, IWbemClassObject *pOutSignature ) { FIXME("%p, %s, %08x, %p, %p\n", iface, debugstr_w(wszName), lFlags, pInSignature, pOutSignature); return E_NOTIMPL; } static HRESULT WINAPI class_object_DeleteMethod( IWbemClassObject *iface, LPCWSTR wszName ) { FIXME("%p, %s\n", iface, debugstr_w(wszName)); return E_NOTIMPL; } static HRESULT WINAPI class_object_BeginMethodEnumeration( IWbemClassObject *iface, LONG lEnumFlags) { FIXME("%p, %08x\n", iface, lEnumFlags); return E_NOTIMPL; } static HRESULT WINAPI class_object_NextMethod( IWbemClassObject *iface, LONG lFlags, BSTR *pstrName, IWbemClassObject **ppInSignature, IWbemClassObject **ppOutSignature) { FIXME("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature); return E_NOTIMPL; } static HRESULT WINAPI class_object_EndMethodEnumeration( IWbemClassObject *iface ) { FIXME("%p\n", iface); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetMethodQualifierSet( IWbemClassObject *iface, LPCWSTR wszMethod, IWbemQualifierSet **ppQualSet) { FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethod), ppQualSet); return E_NOTIMPL; } static HRESULT WINAPI class_object_GetMethodOrigin( IWbemClassObject *iface, LPCWSTR wszMethodName, BSTR *pstrClassName) { FIXME("%p, %s, %p\n", iface, debugstr_w(wszMethodName), pstrClassName); return E_NOTIMPL; } static const IWbemClassObjectVtbl class_object_vtbl = { class_object_QueryInterface, class_object_AddRef, class_object_Release, class_object_GetQualifierSet, class_object_Get, class_object_Put, class_object_Delete, class_object_GetNames, class_object_BeginEnumeration, class_object_Next, class_object_EndEnumeration, class_object_GetPropertyQualifierSet, class_object_Clone, class_object_GetObjectText, class_object_SpawnDerivedClass, class_object_SpawnInstance, class_object_CompareTo, class_object_GetPropertyOrigin, class_object_InheritsFrom, class_object_GetMethod, class_object_PutMethod, class_object_DeleteMethod, class_object_BeginMethodEnumeration, class_object_NextMethod, class_object_EndMethodEnumeration, class_object_GetMethodQualifierSet, class_object_GetMethodOrigin }; HRESULT WbemClassObject_create( IUnknown *pUnkOuter, IEnumWbemClassObject *iter, UINT index, LPVOID *ppObj ) { struct class_object *co; TRACE("%p, %p\n", pUnkOuter, ppObj); co = heap_alloc( sizeof(*co) ); if (!co) return E_OUTOFMEMORY; co->IWbemClassObject_iface.lpVtbl = &class_object_vtbl; co->refs = 1; co->iter = iter; co->index = index; if (iter) IEnumWbemClassObject_AddRef( iter ); *ppObj = &co->IWbemClassObject_iface; TRACE("returning iface %p\n", *ppObj); return S_OK; }