| /* |
| * Copyright 2001 Hidenori Takeshima |
| * |
| * FIXME - stub |
| * |
| * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "config.h" |
| |
| #include "winerror.h" |
| #include "winnls.h" /* for PRIMARYLANGID */ |
| #include "winreg.h" /* for HKEY_LOCAL_MACHINE */ |
| #include "winuser.h" |
| #include "oleauto.h" |
| |
| #include "wine/debug.h" |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| typedef struct CStdDispImpl |
| { |
| ICOM_VFIELD(IDispatch); |
| struct { ICOM_VFIELD(IUnknown); } unkimpl; |
| UINT ref; |
| |
| IUnknown* punk; |
| void* pvThis; |
| ITypeInfo* pti; |
| } CStdDispImpl; |
| |
| static HRESULT CStdDispImpl_Construct( |
| CStdDispImpl* This, |
| IUnknown* punkOuter, void* pvThis, ITypeInfo* pti ) |
| { |
| This->punk = punkOuter; |
| This->pvThis = pvThis; |
| This->pti = pti; ITypeInfo_AddRef(pti); |
| |
| return S_OK; |
| } |
| |
| static void CStdDispImpl_Destruct( |
| CStdDispImpl* This ) |
| { |
| if ( This->pti != NULL ) |
| ITypeInfo_Release(This->pti); |
| } |
| |
| |
| /****************************************************************************/ |
| |
| |
| static HRESULT WINAPI In_CStdDispImpl_fnQueryInterface( |
| IUnknown* iface,REFIID riid,void** ppvobj) |
| { |
| CStdDispImpl* This = (CStdDispImpl*)(((BYTE*)iface)-offsetof(CStdDispImpl,unkimpl)); |
| |
| if ( IsEqualGUID(riid,&IID_IUnknown) ) |
| { |
| *ppvobj = (void*)iface; |
| IUnknown_AddRef(iface); |
| return S_OK; |
| } |
| if ( IsEqualGUID(riid,&IID_IDispatch) ) |
| { |
| *ppvobj = (void*)This; |
| IUnknown_AddRef((IUnknown*)This); |
| return S_OK; |
| } |
| |
| return E_NOINTERFACE; |
| } |
| |
| static ULONG WINAPI In_CStdDispImpl_fnAddRef(IUnknown* iface) |
| { |
| CStdDispImpl* This = (CStdDispImpl*)(((BYTE*)iface)-offsetof(CStdDispImpl,unkimpl)); |
| |
| return ++ This->ref; |
| } |
| |
| static ULONG WINAPI In_CStdDispImpl_fnRelease(IUnknown* iface) |
| { |
| CStdDispImpl* This = (CStdDispImpl*)(((BYTE*)iface)-offsetof(CStdDispImpl,unkimpl)); |
| |
| if ( -- This->ref > 0 ) return This->ref; |
| |
| ++ This->ref; |
| CStdDispImpl_Destruct(This); |
| HeapFree(GetProcessHeap(),0,This); |
| return 0; |
| } |
| |
| |
| /****************************************************************************/ |
| |
| |
| |
| static HRESULT WINAPI CStdDispImpl_fnQueryInterface( |
| IDispatch* iface,REFIID riid,void** ppvobj) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| return IUnknown_QueryInterface(This->punk,riid,ppvobj); |
| } |
| |
| static ULONG WINAPI CStdDispImpl_fnAddRef(IDispatch* iface) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| return IUnknown_AddRef(This->punk); |
| } |
| |
| static ULONG WINAPI CStdDispImpl_fnRelease(IDispatch* iface) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| return IUnknown_Release(This->punk); |
| } |
| |
| |
| static HRESULT WINAPI CStdDispImpl_fnGetTypeInfoCount( |
| IDispatch* iface,UINT* pctinfo) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| FIXME("(%p)\n",This); |
| if ( pctinfo == NULL ) return E_POINTER; |
| *pctinfo = 1; |
| |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI CStdDispImpl_fnGetTypeInfo( |
| IDispatch* iface, |
| UINT itiindex,LCID lcid,ITypeInfo** ppti) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| FIXME("(%p)\n",This); |
| |
| if ( ppti != NULL ) return E_POINTER; |
| *ppti = NULL; |
| |
| if ( itiindex != 0 ) return DISP_E_BADINDEX; |
| /* lcid is ignored */ |
| ITypeInfo_AddRef(This->pti); |
| *ppti = This->pti; |
| |
| return S_OK; |
| } |
| |
| static HRESULT WINAPI CStdDispImpl_fnGetIDsOfNames( |
| IDispatch* iface, |
| REFIID riid,LPOLESTR* ppwszNames,UINT cNames,LCID lcid,DISPID* pdispid) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| FIXME("(%p)\n",This); |
| return DispGetIDsOfNames(This->pti,ppwszNames,cNames,pdispid); |
| } |
| |
| static HRESULT WINAPI CStdDispImpl_fnInvoke( |
| IDispatch* iface, |
| DISPID dispid,REFIID riid,LCID lcid,WORD wFlags, |
| DISPPARAMS* pDispParams,VARIANT* pVarResult, |
| EXCEPINFO* pExcepInfo,UINT* puArgErr) |
| { |
| ICOM_THIS(CStdDispImpl,iface); |
| |
| FIXME("(%p)\n",This); |
| return DispInvoke(This->pvThis, |
| This->pti,dispid,wFlags, |
| pDispParams,pVarResult, |
| pExcepInfo,puArgErr); |
| } |
| |
| static ICOM_VTABLE(IUnknown) iunk = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| |
| /* IUnknown */ |
| In_CStdDispImpl_fnQueryInterface, |
| In_CStdDispImpl_fnAddRef, |
| In_CStdDispImpl_fnRelease, |
| }; |
| |
| static ICOM_VTABLE(IDispatch) idisp = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| |
| /* IUnknown */ |
| CStdDispImpl_fnQueryInterface, |
| CStdDispImpl_fnAddRef, |
| CStdDispImpl_fnRelease, |
| /* IDispatch */ |
| CStdDispImpl_fnGetTypeInfoCount, |
| CStdDispImpl_fnGetTypeInfo, |
| CStdDispImpl_fnGetIDsOfNames, |
| CStdDispImpl_fnInvoke, |
| }; |
| |
| /*****************************************************************************/ |
| |
| HRESULT WINAPI CreateStdDispatch( |
| IUnknown* punkOuter, |
| void* pvThis, |
| ITypeInfo* pti, |
| IUnknown** ppvobj ) |
| { |
| HRESULT hr; |
| CStdDispImpl* This; |
| |
| if ( punkOuter == NULL || pvThis == NULL || |
| pti == NULL || ppvobj == NULL ) |
| return E_POINTER; |
| |
| This = (CStdDispImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdDispImpl)); |
| if ( This == NULL ) return E_OUTOFMEMORY; |
| ICOM_VTBL(This) = &idisp; |
| ICOM_VTBL(&(This->unkimpl)) = &iunk; |
| This->ref = 1; |
| |
| hr = CStdDispImpl_Construct( This, punkOuter, pvThis, pti ); |
| if ( FAILED(hr) ) |
| { |
| IUnknown_Release((IUnknown*)(&This->unkimpl)); |
| return hr; |
| } |
| *ppvobj = (IUnknown*)(&This->unkimpl); |
| |
| return S_OK; |
| } |