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
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ole);
39 typedef struct _FTMarshalImpl {
40 const IUnknownVtbl *lpVtbl;
42 const IMarshalVtbl *lpvtblFTM;
47 #define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl)
48 #define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM)
50 static inline FTMarshalImpl *impl_from_IMarshal( IMarshal *iface )
52 return (FTMarshalImpl *)((char*)iface - FIELD_OFFSET(FTMarshalImpl, lpvtblFTM));
55 /* inner IUnknown to handle aggregation */
57 IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
60 FTMarshalImpl *This = (FTMarshalImpl *)iface;
65 if (IsEqualIID (&IID_IUnknown, riid))
66 *ppv = _IFTMUnknown_ (This);
67 else if (IsEqualIID (&IID_IMarshal, riid))
68 *ppv = _IFTMarshal_ (This);
70 FIXME ("No interface for %s.\n", debugstr_guid (riid));
73 IUnknown_AddRef ((IUnknown *) * ppv);
77 static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
80 FTMarshalImpl *This = (FTMarshalImpl *)iface;
83 return InterlockedIncrement (&This->ref);
86 static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
89 FTMarshalImpl *This = (FTMarshalImpl *)iface;
92 if (InterlockedDecrement (&This->ref))
94 HeapFree (GetProcessHeap (), 0, This);
98 static const IUnknownVtbl iunkvt =
100 IiFTMUnknown_fnQueryInterface,
101 IiFTMUnknown_fnAddRef,
102 IiFTMUnknown_fnRelease
105 static HRESULT WINAPI
106 FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
109 FTMarshalImpl *This = impl_from_IMarshal(iface);
111 TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv);
112 return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
116 FTMarshalImpl_AddRef (LPMARSHAL iface)
119 FTMarshalImpl *This = impl_from_IMarshal(iface);
122 return IUnknown_AddRef (This->pUnkOuter);
126 FTMarshalImpl_Release (LPMARSHAL iface)
129 FTMarshalImpl *This = impl_from_IMarshal(iface);
132 return IUnknown_Release (This->pUnkOuter);
135 static HRESULT WINAPI
136 FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
137 void *pvDestContext, DWORD mshlflags, CLSID * pCid)
139 FIXME ("(), stub!\n");
143 static HRESULT WINAPI
144 FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
145 void *pvDestContext, DWORD mshlflags, DWORD * pSize)
148 IMarshal *pMarshal = NULL;
151 FTMarshalImpl *This = impl_from_IMarshal(iface);
153 FIXME ("(), stub!\n");
155 /* if the marshalling happens inside the same process the interface pointer is
156 copied between the apartments */
157 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
158 *pSize = sizeof (This);
162 /* use the standard marshaller to handle all other cases */
163 CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
164 hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
165 IMarshal_Release (pMarshal);
169 static HRESULT WINAPI
170 FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
171 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
174 IMarshal *pMarshal = NULL;
177 FTMarshalImpl *This = impl_from_IMarshal(iface);
179 FIXME ("(), stub!\n");
181 /* if the marshalling happens inside the same process the interface pointer is
182 copied between the apartments */
183 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
184 return IStream_Write (pStm, This, sizeof (This), 0);
187 /* use the standard marshaler to handle all other cases */
188 CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
189 hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
190 IMarshal_Release (pMarshal);
194 static HRESULT WINAPI
195 FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
197 FIXME ("(), stub!\n");
201 static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
203 FIXME ("(), stub!\n");
207 static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
209 FIXME ("(), stub!\n");
213 static const IMarshalVtbl ftmvtbl =
215 FTMarshalImpl_QueryInterface,
216 FTMarshalImpl_AddRef,
217 FTMarshalImpl_Release,
218 FTMarshalImpl_GetUnmarshalClass,
219 FTMarshalImpl_GetMarshalSizeMax,
220 FTMarshalImpl_MarshalInterface,
221 FTMarshalImpl_UnmarshalInterface,
222 FTMarshalImpl_ReleaseMarshalData,
223 FTMarshalImpl_DisconnectObject
226 /***********************************************************************
227 * CoCreateFreeThreadedMarshaler [OLE32.@]
230 HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
235 TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
237 ftm = HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
239 return E_OUTOFMEMORY;
241 ftm->lpVtbl = &iunkvt;
242 ftm->lpvtblFTM = &ftmvtbl;
244 ftm->pUnkOuter = punkOuter;
246 *ppunkMarshal = _IFTMUnknown_ (ftm);