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
);