~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/ole32/ftmarshal.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.