2 * free threaded marshaller
4 * Copyright 2002 Juergen Schmied
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(ole);
35 typedef struct _FTMarshalImpl {
36 ICOM_VFIELD (IUnknown);
38 ICOM_VTABLE (IMarshal) * lpvtblFTM;
43 #define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl)
44 #define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM)
46 #define _IFTMarshall_Offset ((int)(&(((FTMarshalImpl*)0)->lpvtblFTM)))
47 #define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
49 /* inner IUnknown to handle aggregation */
50 HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
53 ICOM_THIS (FTMarshalImpl, iface);
58 if (IsEqualIID (&IID_IUnknown, riid))
59 *ppv = _IFTMUnknown_ (This);
60 else if (IsEqualIID (&IID_IMarshal, riid))
61 *ppv = _IFTMarshal_ (This);
63 FIXME ("No interface for %s.\n", debugstr_guid (riid));
66 IUnknown_AddRef ((IUnknown *) * ppv);
70 ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
73 ICOM_THIS (FTMarshalImpl, iface);
76 return InterlockedIncrement (&This->ref);
79 ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
82 ICOM_THIS (FTMarshalImpl, iface);
85 if (InterlockedDecrement (&This->ref))
87 HeapFree (GetProcessHeap (), 0, This);
91 static ICOM_VTABLE (IUnknown) iunkvt =
93 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
94 IiFTMUnknown_fnQueryInterface,
95 IiFTMUnknown_fnAddRef,
96 IiFTMUnknown_fnRelease
99 HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
102 _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
104 TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv);
105 return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
108 ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
111 _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
114 return IUnknown_AddRef (This->pUnkOuter);
117 ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
120 _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
123 return IUnknown_Release (This->pUnkOuter);
126 HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
127 void *pvDestContext, DWORD mshlflags, CLSID * pCid)
129 FIXME ("(), stub!\n");
133 HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
134 void *pvDestContext, DWORD mshlflags, DWORD * pSize)
137 IMarshal *pMarshal = NULL;
140 _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
142 FIXME ("(), stub!\n");
144 /* if the marshalling happens inside the same process the interface pointer is
145 copied between the apartments */
146 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
147 *pSize = sizeof (This);
151 /* use the standard marshaller to handle all other cases */
152 CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
153 hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
154 IMarshal_Release (pMarshal);
160 HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
161 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
164 IMarshal *pMarshal = NULL;
167 _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
169 FIXME ("(), stub!\n");
171 /* if the marshalling happens inside the same process the interface pointer is
172 copied between the apartments */
173 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
174 return IStream_Write (pStm, This, sizeof (This), 0);
177 /* use the standard marshaler to handle all other cases */
178 CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
179 hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
180 IMarshal_Release (pMarshal);
184 HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
186 FIXME ("(), stub!\n");
190 HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
192 FIXME ("(), stub!\n");
196 HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
198 FIXME ("(), stub!\n");
202 ICOM_VTABLE (IMarshal) ftmvtbl =
204 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
205 FTMarshalImpl_QueryInterface,
206 FTMarshalImpl_AddRef,
207 FTMarshalImpl_Release,
208 FTMarshalImpl_GetUnmarshalClass,
209 FTMarshalImpl_GetMarshalSizeMax,
210 FTMarshalImpl_MarshalInterface,
211 FTMarshalImpl_UnmarshalInterface,
212 FTMarshalImpl_ReleaseMarshalData,
213 FTMarshalImpl_DisconnectObject
216 /***********************************************************************
217 * CoCreateFreeThreadedMarshaler [OLE32.5]
220 HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
225 TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
227 ftm = (FTMarshalImpl *) HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
229 return E_OUTOFMEMORY;
231 ftm->lpVtbl = &iunkvt;
232 ftm->lpvtblFTM = &ftmvtbl;
234 ftm->pUnkOuter = punkOuter;
236 *ppunkMarshal = _IFTMUnknown_ (ftm);