| /* |
| * free threaded marshaller |
| * |
| * Copyright 2002 Juergen Schmied |
| * |
| * 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 <stdlib.h> |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "objbase.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| typedef struct _FTMarshalImpl { |
| ICOM_VFIELD (IUnknown); |
| DWORD ref; |
| ICOM_VTABLE (IMarshal) * lpvtblFTM; |
| |
| IUnknown *pUnkOuter; |
| } FTMarshalImpl; |
| |
| #define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl) |
| #define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM) |
| |
| #define _IFTMarshall_Offset ((int)(&(((FTMarshalImpl*)0)->lpvtblFTM))) |
| #define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset); |
| |
| /* inner IUnknown to handle aggregation */ |
| HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv) |
| { |
| |
| ICOM_THIS (FTMarshalImpl, iface); |
| |
| TRACE ("\n"); |
| *ppv = NULL; |
| |
| if (IsEqualIID (&IID_IUnknown, riid)) |
| *ppv = _IFTMUnknown_ (This); |
| else if (IsEqualIID (&IID_IMarshal, riid)) |
| *ppv = _IFTMarshal_ (This); |
| else { |
| FIXME ("No interface for %s.\n", debugstr_guid (riid)); |
| return E_NOINTERFACE; |
| } |
| IUnknown_AddRef ((IUnknown *) * ppv); |
| return S_OK; |
| } |
| |
| ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface) |
| { |
| |
| ICOM_THIS (FTMarshalImpl, iface); |
| |
| TRACE ("\n"); |
| return InterlockedIncrement (&This->ref); |
| } |
| |
| ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface) |
| { |
| |
| ICOM_THIS (FTMarshalImpl, iface); |
| |
| TRACE ("\n"); |
| if (InterlockedDecrement (&This->ref)) |
| return This->ref; |
| HeapFree (GetProcessHeap (), 0, This); |
| return 0; |
| } |
| |
| static ICOM_VTABLE (IUnknown) iunkvt = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| IiFTMUnknown_fnQueryInterface, |
| IiFTMUnknown_fnAddRef, |
| IiFTMUnknown_fnRelease |
| }; |
| |
| HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv) |
| { |
| |
| _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface); |
| |
| TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv); |
| return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv); |
| } |
| |
| ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface) |
| { |
| |
| _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface); |
| |
| TRACE ("\n"); |
| return IUnknown_AddRef (This->pUnkOuter); |
| } |
| |
| ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface) |
| { |
| |
| _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface); |
| |
| TRACE ("\n"); |
| return IUnknown_Release (This->pUnkOuter); |
| } |
| |
| HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext, |
| void *pvDestContext, DWORD mshlflags, CLSID * pCid) |
| { |
| FIXME ("(), stub!\n"); |
| return S_OK; |
| } |
| |
| HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext, |
| void *pvDestContext, DWORD mshlflags, DWORD * pSize) |
| { |
| |
| IMarshal *pMarshal = NULL; |
| HRESULT hres; |
| |
| _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface); |
| |
| FIXME ("(), stub!\n"); |
| |
| /* if the marshalling happens inside the same process the interface pointer is |
| copied between the apartments */ |
| if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) { |
| *pSize = sizeof (This); |
| return S_OK; |
| } |
| |
| /* use the standard marshaller to handle all other cases */ |
| CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal); |
| hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize); |
| IMarshal_Release (pMarshal); |
| return hres; |
| |
| return S_OK; |
| } |
| |
| HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv, |
| DWORD dwDestContext, void *pvDestContext, DWORD mshlflags) |
| { |
| |
| IMarshal *pMarshal = NULL; |
| HRESULT hres; |
| |
| _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface); |
| |
| FIXME ("(), stub!\n"); |
| |
| /* if the marshalling happens inside the same process the interface pointer is |
| copied between the apartments */ |
| if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) { |
| return IStream_Write (pStm, This, sizeof (This), 0); |
| } |
| |
| /* use the standard marshaler to handle all other cases */ |
| CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal); |
| hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags); |
| IMarshal_Release (pMarshal); |
| return hres; |
| } |
| |
| HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv) |
| { |
| FIXME ("(), stub!\n"); |
| return S_OK; |
| } |
| |
| HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm) |
| { |
| FIXME ("(), stub!\n"); |
| return S_OK; |
| } |
| |
| HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved) |
| { |
| FIXME ("(), stub!\n"); |
| return S_OK; |
| } |
| |
| ICOM_VTABLE (IMarshal) ftmvtbl = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| FTMarshalImpl_QueryInterface, |
| FTMarshalImpl_AddRef, |
| FTMarshalImpl_Release, |
| FTMarshalImpl_GetUnmarshalClass, |
| FTMarshalImpl_GetMarshalSizeMax, |
| FTMarshalImpl_MarshalInterface, |
| FTMarshalImpl_UnmarshalInterface, |
| FTMarshalImpl_ReleaseMarshalData, |
| FTMarshalImpl_DisconnectObject |
| }; |
| |
| /*********************************************************************** |
| * CoCreateFreeThreadedMarshaler [OLE32.@] |
| * |
| */ |
| HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal) |
| { |
| |
| FTMarshalImpl *ftm; |
| |
| TRACE ("(%p %p)\n", punkOuter, ppunkMarshal); |
| |
| ftm = (FTMarshalImpl *) HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl)); |
| if (!ftm) |
| return E_OUTOFMEMORY; |
| |
| ftm->lpVtbl = &iunkvt; |
| ftm->lpvtblFTM = &ftmvtbl; |
| ftm->ref = 1; |
| ftm->pUnkOuter = punkOuter; |
| |
| *ppunkMarshal = _IFTMUnknown_ (ftm); |
| return S_OK; |
| } |