/* * 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 #include "windef.h" #include "winbase.h" #include "initguid.h" #include "objbase.h" #include "wbemdisp.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wbemdisp_private.h" WINE_DEFAULT_DEBUG_CHANNEL(wbemdisp); struct locator { ISWbemLocator ISWbemLocator_iface; LONG refs; }; 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 ); 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; } enum type_id { ISWbemLocator_tid, last_tid }; static ITypeLib *wbemdisp_typelib; static ITypeInfo *wbemdisp_typeinfo[last_tid]; static REFIID wbemdisp_tid_id[] = { &IID_ISWbemLocator }; 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]; 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 HRESULT WINAPI locator_ConnectServer( ISWbemLocator *iface, BSTR strServer, BSTR strNamespace, BSTR strUser, BSTR strPassword, BSTR strLocale, BSTR strAuthority, LONG iSecurityFlags, IDispatch *objWbemNamedValueSet, ISWbemServices **objWbemServices ) { FIXME( "%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 ); return E_NOTIMPL; } 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( IUnknown *unk, void **obj ) { struct locator *locator; TRACE( "%p, %p\n", unk, obj ); if (!(locator = heap_alloc( sizeof(*locator) ))) return E_OUTOFMEMORY; locator->ISWbemLocator_iface.lpVtbl = &locator_vtbl; locator->refs = 1; *obj = &locator->ISWbemLocator_iface; TRACE( "returning iface %p\n", *obj ); return S_OK; }