ReactOS 0.4.15-dev-7958-gcd0bb1a
ftmarshal.c
Go to the documentation of this file.
1/*
2 * free threaded marshaller
3 *
4 * Copyright 2002 Juergen Schmied
5 *
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.
10 *
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.
15 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdlib.h>
22#include <stdarg.h>
23#include <stdio.h>
24#include <string.h>
25#include <assert.h>
26
27#define COBJMACROS
28
29#include "windef.h"
30#include "winbase.h"
31#include "objbase.h"
32
33#include "wine/debug.h"
34
35#include "compobj_private.h"
36
38
39typedef struct _FTMarshalImpl {
45
47{
48 return CONTAINING_RECORD(iface, FTMarshalImpl, IUnknown_inner);
49}
50
52{
53 return CONTAINING_RECORD(iface, FTMarshalImpl, IMarshal_iface);
54}
55
56/* inner IUnknown to handle aggregation */
57static HRESULT WINAPI
59{
60
62
63 TRACE ("\n");
64 *ppv = NULL;
65
67 *ppv = &This->IUnknown_inner;
68 else if (IsEqualIID (&IID_IMarshal, riid))
69 *ppv = &This->IMarshal_iface;
70 else {
71 FIXME ("No interface for %s.\n", debugstr_guid (riid));
72 return E_NOINTERFACE;
73 }
74 IUnknown_AddRef ((IUnknown *) * ppv);
75 return S_OK;
76}
77
79{
80
82
83 TRACE ("\n");
84 return InterlockedIncrement (&This->ref);
85}
86
88{
89
91
92 TRACE ("\n");
93 if (InterlockedDecrement (&This->ref))
94 return This->ref;
96 return 0;
97}
98
99static const IUnknownVtbl iunkvt =
100{
104};
105
106static HRESULT WINAPI
108{
109
111
112 TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppv);
113 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
114}
115
116static ULONG WINAPI
118{
119
121
122 TRACE ("\n");
123 return IUnknown_AddRef(This->outer_unk);
124}
125
126static ULONG WINAPI
128{
129
131
132 TRACE ("\n");
133 return IUnknown_Release(This->outer_unk);
134}
135
136static HRESULT WINAPI
138 void *pvDestContext, DWORD mshlflags, CLSID * pCid)
139{
140 TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
141 dwDestContext, pvDestContext, mshlflags, pCid);
142 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
144 else
145 *pCid = CLSID_StdMarshal;
146 return S_OK;
147}
148
149static HRESULT WINAPI
151 void *pvDestContext, DWORD mshlflags, DWORD * pSize)
152{
153
154 IMarshal *pMarshal = NULL;
156
157 TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
158 dwDestContext, pvDestContext, mshlflags, pSize);
159
160 /* if the marshalling happens inside the same process the interface pointer is
161 copied between the apartments */
162 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
163 *pSize = sizeof (mshlflags) + sizeof (pv) + sizeof (DWORD) + sizeof (GUID);
164 return S_OK;
165 }
166
167 /* use the standard marshaller to handle all other cases */
168 CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
169 hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
170 IMarshal_Release (pMarshal);
171 return hres;
172}
173
174static HRESULT WINAPI
176 DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
177{
178
179 IMarshal *pMarshal = NULL;
181
182 TRACE("(%p, %s, %p, 0x%x, %p, 0x%x)\n", pStm, debugstr_guid(riid), pv,
183 dwDestContext, pvDestContext, mshlflags);
184
185 /* if the marshalling happens inside the same process the interface pointer is
186 copied between the apartments */
187 if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
188 void *object;
189 DWORD constant = 0;
190 GUID unknown_guid = { 0 };
191
192 hres = IUnknown_QueryInterface((IUnknown *)pv, riid, &object);
193 if (FAILED(hres))
194 return hres;
195
196 /* don't hold a reference to table-weak marshaled interfaces */
197 if (mshlflags & MSHLFLAGS_TABLEWEAK)
198 IUnknown_Release((IUnknown *)object);
199
200 hres = IStream_Write (pStm, &mshlflags, sizeof (mshlflags), NULL);
201 if (hres != S_OK) return STG_E_MEDIUMFULL;
202
203 hres = IStream_Write (pStm, &object, sizeof (object), NULL);
204 if (hres != S_OK) return STG_E_MEDIUMFULL;
205
206 if (sizeof(object) == sizeof(DWORD))
207 {
208 hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
209 if (hres != S_OK) return STG_E_MEDIUMFULL;
210 }
211
212 hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
213 if (hres != S_OK) return STG_E_MEDIUMFULL;
214
215 return S_OK;
216 }
217
218 /* use the standard marshaler to handle all other cases */
219 CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
220 hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
221 IMarshal_Release (pMarshal);
222 return hres;
223}
224
225static HRESULT WINAPI
227{
228 DWORD mshlflags;
231 GUID unknown_guid;
233
234 TRACE ("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
235
236 hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
237 if (hres != S_OK) return STG_E_READFAULT;
238
239 hres = IStream_Read (pStm, &object, sizeof (object), NULL);
240 if (hres != S_OK) return STG_E_READFAULT;
241
242 if (sizeof(object) == sizeof(DWORD))
243 {
244 hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
245 if (hres != S_OK) return STG_E_READFAULT;
246 if (constant != 0)
247 FIXME("constant is 0x%x instead of 0\n", constant);
248 }
249
250 hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
251 if (hres != S_OK) return STG_E_READFAULT;
252
253 hres = IUnknown_QueryInterface(object, riid, ppv);
254 if (!(mshlflags & (MSHLFLAGS_TABLEWEAK|MSHLFLAGS_TABLESTRONG)))
255 IUnknown_Release(object);
256 return hres;
257}
258
260{
261 DWORD mshlflags;
264 GUID unknown_guid;
266
267 TRACE ("(%p)\n", pStm);
268
269 hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
270 if (hres != S_OK) return STG_E_READFAULT;
271
272 hres = IStream_Read (pStm, &object, sizeof (object), NULL);
273 if (hres != S_OK) return STG_E_READFAULT;
274
275 if (sizeof(object) == sizeof(DWORD))
276 {
277 hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
278 if (hres != S_OK) return STG_E_READFAULT;
279 if (constant != 0)
280 FIXME("constant is 0x%x instead of 0\n", constant);
281 }
282
283 hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
284 if (hres != S_OK) return STG_E_READFAULT;
285
286 IUnknown_Release(object);
287 return S_OK;
288}
289
291{
292 TRACE ("()\n");
293 /* nothing to do */
294 return S_OK;
295}
296
297static const IMarshalVtbl ftmvtbl =
298{
308};
309
310/***********************************************************************
311 * CoCreateFreeThreadedMarshaler [OLE32.@]
312 *
313 * Creates a free-threaded marshaler.
314 *
315 * PARAMS
316 * punkOuter [I] Optional. Outer unknown.
317 * ppunkMarshal [O] On return, the inner unknown of the created free-threaded marshaler.
318 *
319 * RETURNS
320 * Success: S_OK
321 * Failure: E_OUTOFMEMORY if no memory available to create object.
322 *
323 * NOTES
324 * Objects that ensure their state is maintained consistent when used by
325 * multiple threads and reference no single-threaded objects are known as
326 * free-threaded. The free-threaded marshaler enables these objects to be
327 * efficiently marshaled within the same process, by not creating proxies
328 * (as they aren't needed for the object to be safely used), whilst still
329 * allowing the object to be used in inter-process and inter-machine contexts.
330 */
332{
333
334 FTMarshalImpl *ftm;
335
336 TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
337
338 ftm = HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
339 if (!ftm)
340 return E_OUTOFMEMORY;
341
342 ftm->IUnknown_inner.lpVtbl = &iunkvt;
343 ftm->IMarshal_iface.lpVtbl = &ftmvtbl;
344 ftm->ref = 1;
345 ftm->outer_unk = punkOuter ? punkOuter : &ftm->IUnknown_inner;
346
347 *ppunkMarshal = &ftm->IUnknown_inner;
348 return S_OK;
349}
350
351static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface,
353{
354 *ppv = NULL;
356 {
357 *ppv = iface;
358 IClassFactory_AddRef(iface);
359 return S_OK;
360 }
361 return E_NOINTERFACE;
362}
363
364static ULONG WINAPI FTMarshalCF_AddRef(LPCLASSFACTORY iface)
365{
366 return 2; /* non-heap based object */
367}
368
369static ULONG WINAPI FTMarshalCF_Release(LPCLASSFACTORY iface)
370{
371 return 1; /* non-heap based object */
372}
373
374static HRESULT WINAPI FTMarshalCF_CreateInstance(LPCLASSFACTORY iface,
376{
378 HRESULT hr;
379
380 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
381
382 *ppv = NULL;
383
385
386 if (SUCCEEDED(hr))
387 {
388 hr = IUnknown_QueryInterface(pUnknown, riid, ppv);
389 IUnknown_Release(pUnknown);
390 }
391
392 return hr;
393}
394
395static HRESULT WINAPI FTMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
396{
397 FIXME("(%d), stub!\n",fLock);
398 return S_OK;
399}
400
401static const IClassFactoryVtbl FTMarshalCFVtbl =
402{
408};
409static const IClassFactoryVtbl *FTMarshalCF = &FTMarshalCFVtbl;
410
412{
413 return IClassFactory_QueryInterface((IClassFactory *)&FTMarshalCF, riid, ppv);
414}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
const GUID IID_IClassFactory
#define FIXME(fmt,...)
Definition: debug.h:111
const CLSID CLSID_StdMarshal
const CLSID CLSID_InProcFreeMarshaler
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPMARSHAL *ppMarshal)
Definition: marshal.c:1676
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static ULONG WINAPI FTMarshalImpl_AddRef(LPMARSHAL iface)
Definition: ftmarshal.c:117
static FTMarshalImpl * impl_from_IMarshal(IMarshal *iface)
Definition: ftmarshal.c:51
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
Definition: ftmarshal.c:259
static HRESULT WINAPI FTMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv)
Definition: ftmarshal.c:226
static FTMarshalImpl * impl_from_IUnknown(IUnknown *iface)
Definition: ftmarshal.c:46
static ULONG WINAPI IiFTMUnknown_fnAddRef(IUnknown *iface)
Definition: ftmarshal.c:78
static HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize)
Definition: ftmarshal.c:150
static HRESULT WINAPI FTMarshalImpl_MarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
Definition: ftmarshal.c:175
static HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid)
Definition: ftmarshal.c:137
static ULONG WINAPI FTMarshalCF_AddRef(LPCLASSFACTORY iface)
Definition: ftmarshal.c:364
static HRESULT WINAPI FTMarshalImpl_QueryInterface(LPMARSHAL iface, REFIID riid, LPVOID *ppv)
Definition: ftmarshal.c:107
static const IUnknownVtbl iunkvt
Definition: ftmarshal.c:99
static HRESULT WINAPI FTMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
Definition: ftmarshal.c:395
static const IMarshalVtbl ftmvtbl
Definition: ftmarshal.c:297
struct _FTMarshalImpl FTMarshalImpl
HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv)
Definition: ftmarshal.c:411
static const IClassFactoryVtbl FTMarshalCFVtbl
Definition: ftmarshal.c:401
static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppv)
Definition: ftmarshal.c:351
static HRESULT WINAPI FTMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved)
Definition: ftmarshal.c:290
static HRESULT WINAPI FTMarshalCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
Definition: ftmarshal.c:374
HRESULT WINAPI CoCreateFreeThreadedMarshaler(LPUNKNOWN punkOuter, LPUNKNOWN *ppunkMarshal)
Definition: ftmarshal.c:331
static ULONG WINAPI IiFTMUnknown_fnRelease(IUnknown *iface)
Definition: ftmarshal.c:87
static const IClassFactoryVtbl * FTMarshalCF
Definition: ftmarshal.c:409
static ULONG WINAPI FTMarshalCF_Release(LPCLASSFACTORY iface)
Definition: ftmarshal.c:369
static ULONG WINAPI FTMarshalImpl_Release(LPMARSHAL iface)
Definition: ftmarshal.c:127
static HRESULT WINAPI IiFTMUnknown_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppv)
Definition: ftmarshal.c:58
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
HRESULT hres
Definition: protocol.c:465
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
static LPUNKNOWN
Definition: ndr_ole.c:49
#define DWORD
Definition: nt_native.h:44
interface IMarshal * LPMARSHAL
Definition: objfwd.h:11
long LONG
Definition: pedump.c:60
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
IUnknown * outer_unk
Definition: ftmarshal.c:42
IUnknown IUnknown_inner
Definition: ftmarshal.c:40
IMarshal IMarshal_iface
Definition: ftmarshal.c:41
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_READFAULT
Definition: winerror.h:2576
#define STG_E_MEDIUMFULL
Definition: winerror.h:2581