ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ftmarshal.c
Go to the documentation of this file.
00001 /*
00002  *  free threaded marshaller
00003  *
00004  *  Copyright 2002  Juergen Schmied
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <stdlib.h>
00024 #include <stdarg.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <assert.h>
00028 
00029 #define COBJMACROS
00030 
00031 #include "windef.h"
00032 #include "winbase.h"
00033 #include "objbase.h"
00034 
00035 #include "wine/debug.h"
00036 
00037 #include "compobj_private.h"
00038 
00039 WINE_DEFAULT_DEBUG_CHANNEL(ole);
00040 
00041 typedef struct _FTMarshalImpl {
00042         IUnknown IUnknown_iface;
00043     LONG ref;
00044         IMarshal IMarshal_iface;
00045 
00046     IUnknown *pUnkOuter;
00047 } FTMarshalImpl;
00048 
00049 static inline FTMarshalImpl *impl_from_IUnknown(IUnknown *iface)
00050 {
00051     return CONTAINING_RECORD(iface, FTMarshalImpl, IUnknown_iface);
00052 }
00053 
00054 static inline FTMarshalImpl *impl_from_IMarshal( IMarshal *iface )
00055 {
00056     return CONTAINING_RECORD(iface, FTMarshalImpl, IMarshal_iface);
00057 }
00058 
00059 /* inner IUnknown to handle aggregation */
00060 static HRESULT WINAPI
00061 IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
00062 {
00063 
00064     FTMarshalImpl *This = impl_from_IUnknown(iface);
00065 
00066     TRACE ("\n");
00067     *ppv = NULL;
00068 
00069     if (IsEqualIID (&IID_IUnknown, riid))
00070         *ppv = &This->IUnknown_iface;
00071     else if (IsEqualIID (&IID_IMarshal, riid))
00072         *ppv = &This->IMarshal_iface;
00073     else {
00074     FIXME ("No interface for %s.\n", debugstr_guid (riid));
00075     return E_NOINTERFACE;
00076     }
00077     IUnknown_AddRef ((IUnknown *) * ppv);
00078     return S_OK;
00079 }
00080 
00081 static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
00082 {
00083 
00084     FTMarshalImpl *This = impl_from_IUnknown(iface);
00085 
00086     TRACE ("\n");
00087     return InterlockedIncrement (&This->ref);
00088 }
00089 
00090 static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
00091 {
00092 
00093     FTMarshalImpl *This = impl_from_IUnknown(iface);
00094 
00095     TRACE ("\n");
00096     if (InterlockedDecrement (&This->ref))
00097     return This->ref;
00098     HeapFree (GetProcessHeap (), 0, This);
00099     return 0;
00100 }
00101 
00102 static const IUnknownVtbl iunkvt =
00103 {
00104     IiFTMUnknown_fnQueryInterface,
00105     IiFTMUnknown_fnAddRef,
00106     IiFTMUnknown_fnRelease
00107 };
00108 
00109 static HRESULT WINAPI
00110 FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
00111 {
00112 
00113     FTMarshalImpl *This = impl_from_IMarshal(iface);
00114 
00115     TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppv);
00116     return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
00117 }
00118 
00119 static ULONG WINAPI
00120 FTMarshalImpl_AddRef (LPMARSHAL iface)
00121 {
00122 
00123     FTMarshalImpl *This = impl_from_IMarshal(iface);
00124 
00125     TRACE ("\n");
00126     return IUnknown_AddRef (This->pUnkOuter);
00127 }
00128 
00129 static ULONG WINAPI
00130 FTMarshalImpl_Release (LPMARSHAL iface)
00131 {
00132 
00133     FTMarshalImpl *This = impl_from_IMarshal(iface);
00134 
00135     TRACE ("\n");
00136     return IUnknown_Release (This->pUnkOuter);
00137 }
00138 
00139 static HRESULT WINAPI
00140 FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
00141                         void *pvDestContext, DWORD mshlflags, CLSID * pCid)
00142 {
00143     TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
00144         dwDestContext, pvDestContext, mshlflags, pCid);
00145     if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
00146         *pCid = CLSID_InProcFreeMarshaler;
00147     else
00148         *pCid = CLSID_DfMarshal;
00149     return S_OK;
00150 }
00151 
00152 static HRESULT WINAPI
00153 FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
00154                         void *pvDestContext, DWORD mshlflags, DWORD * pSize)
00155 {
00156 
00157     IMarshal *pMarshal = NULL;
00158     HRESULT hres;
00159 
00160     TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
00161         dwDestContext, pvDestContext, mshlflags, pSize);
00162 
00163     /* if the marshalling happens inside the same process the interface pointer is
00164        copied between the apartments */
00165     if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
00166         *pSize = sizeof (mshlflags) + sizeof (pv) + sizeof (DWORD) + sizeof (GUID);
00167         return S_OK;
00168     }
00169 
00170     /* use the standard marshaller to handle all other cases */
00171     CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
00172     hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
00173     IMarshal_Release (pMarshal);
00174     return hres;
00175 }
00176 
00177 static HRESULT WINAPI
00178 FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
00179                    DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
00180 {
00181 
00182     IMarshal *pMarshal = NULL;
00183     HRESULT hres;
00184 
00185     TRACE("(%p, %s, %p, 0x%x, %p, 0x%x)\n", pStm, debugstr_guid(riid), pv,
00186         dwDestContext, pvDestContext, mshlflags);
00187 
00188     /* if the marshalling happens inside the same process the interface pointer is
00189        copied between the apartments */
00190     if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
00191         void *object;
00192         DWORD constant = 0;
00193         GUID unknown_guid = { 0 };
00194 
00195         hres = IUnknown_QueryInterface((IUnknown *)pv, riid, &object);
00196         if (FAILED(hres))
00197             return hres;
00198 
00199         /* don't hold a reference to table-weak marshaled interfaces */
00200         if (mshlflags & MSHLFLAGS_TABLEWEAK)
00201             IUnknown_Release((IUnknown *)object);
00202 
00203         hres = IStream_Write (pStm, &mshlflags, sizeof (mshlflags), NULL);
00204         if (hres != S_OK) return STG_E_MEDIUMFULL;
00205 
00206         hres = IStream_Write (pStm, &object, sizeof (object), NULL);
00207         if (hres != S_OK) return STG_E_MEDIUMFULL;
00208 
00209         if (sizeof(object) == sizeof(DWORD))
00210         {
00211             hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
00212             if (hres != S_OK) return STG_E_MEDIUMFULL;
00213         }
00214 
00215         hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
00216         if (hres != S_OK) return STG_E_MEDIUMFULL;
00217 
00218         return S_OK;
00219     }
00220 
00221     /* use the standard marshaler to handle all other cases */
00222     CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
00223     hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
00224     IMarshal_Release (pMarshal);
00225     return hres;
00226 }
00227 
00228 static HRESULT WINAPI
00229 FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
00230 {
00231     DWORD mshlflags;
00232     IUnknown *object;
00233     DWORD constant;
00234     GUID unknown_guid;
00235     HRESULT hres;
00236 
00237     TRACE ("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
00238 
00239     hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
00240     if (hres != S_OK) return STG_E_READFAULT;
00241 
00242     hres = IStream_Read (pStm, &object, sizeof (object), NULL);
00243     if (hres != S_OK) return STG_E_READFAULT;
00244 
00245     if (sizeof(object) == sizeof(DWORD))
00246     {
00247         hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
00248         if (hres != S_OK) return STG_E_READFAULT;
00249         if (constant != 0)
00250             FIXME("constant is 0x%x instead of 0\n", constant);
00251     }
00252 
00253     hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
00254     if (hres != S_OK) return STG_E_READFAULT;
00255 
00256     hres = IUnknown_QueryInterface(object, riid, ppv);
00257     if (!(mshlflags & (MSHLFLAGS_TABLEWEAK|MSHLFLAGS_TABLESTRONG)))
00258         IUnknown_Release(object);
00259     return hres;
00260 }
00261 
00262 static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
00263 {
00264     DWORD mshlflags;
00265     IUnknown *object;
00266     DWORD constant;
00267     GUID unknown_guid;
00268     HRESULT hres;
00269 
00270     TRACE ("(%p)\n", pStm);
00271 
00272     hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
00273     if (hres != S_OK) return STG_E_READFAULT;
00274 
00275     hres = IStream_Read (pStm, &object, sizeof (object), NULL);
00276     if (hres != S_OK) return STG_E_READFAULT;
00277 
00278     if (sizeof(object) == sizeof(DWORD))
00279     {
00280         hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
00281         if (hres != S_OK) return STG_E_READFAULT;
00282         if (constant != 0)
00283             FIXME("constant is 0x%x instead of 0\n", constant);
00284     }
00285 
00286     hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
00287     if (hres != S_OK) return STG_E_READFAULT;
00288 
00289     IUnknown_Release(object);
00290     return S_OK;
00291 }
00292 
00293 static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
00294 {
00295     TRACE ("()\n");
00296     /* nothing to do */
00297     return S_OK;
00298 }
00299 
00300 static const IMarshalVtbl ftmvtbl =
00301 {
00302     FTMarshalImpl_QueryInterface,
00303     FTMarshalImpl_AddRef,
00304     FTMarshalImpl_Release,
00305     FTMarshalImpl_GetUnmarshalClass,
00306     FTMarshalImpl_GetMarshalSizeMax,
00307     FTMarshalImpl_MarshalInterface,
00308     FTMarshalImpl_UnmarshalInterface,
00309     FTMarshalImpl_ReleaseMarshalData,
00310     FTMarshalImpl_DisconnectObject
00311 };
00312 
00313 /***********************************************************************
00314  *          CoCreateFreeThreadedMarshaler [OLE32.@]
00315  *
00316  * Creates a free-threaded marshaler.
00317  *
00318  * PARAMS
00319  *  punkOuter    [I] Optional. Outer unknown.
00320  *  ppunkMarshal [O] On return, the inner unknown of the created free-threaded marshaler.
00321  *
00322  * RETURNS
00323  *  Success: S_OK
00324  *  Failure: E_OUTOFMEMORY if no memory available to create object.
00325  *
00326  * NOTES
00327  *  Objects that ensure their state is maintained consistent when used by
00328  *  multiple threads and reference no single-threaded objects are known as
00329  *  free-threaded. The free-threaded marshaler enables these objects to be
00330  *  efficiently marshaled within the same process, by not creating proxies
00331  *  (as they aren't needed for the object to be safely used), whilst still
00332  *  allowing the object to be used in inter-process and inter-machine contexts.
00333  */
00334 HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
00335 {
00336 
00337     FTMarshalImpl *ftm;
00338 
00339     TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
00340 
00341     ftm = HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
00342     if (!ftm)
00343     return E_OUTOFMEMORY;
00344 
00345     ftm->IUnknown_iface.lpVtbl = &iunkvt;
00346     ftm->IMarshal_iface.lpVtbl = &ftmvtbl;
00347     ftm->ref = 1;
00348     ftm->pUnkOuter = punkOuter ? punkOuter : &ftm->IUnknown_iface;
00349 
00350     *ppunkMarshal = &ftm->IUnknown_iface;
00351     return S_OK;
00352 }
00353 
00354 static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface,
00355                                                   REFIID riid, LPVOID *ppv)
00356 {
00357     *ppv = NULL;
00358     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
00359     {
00360         *ppv = iface;
00361         IUnknown_AddRef(iface);
00362         return S_OK;
00363     }
00364     return E_NOINTERFACE;
00365 }
00366 
00367 static ULONG WINAPI FTMarshalCF_AddRef(LPCLASSFACTORY iface)
00368 {
00369     return 2; /* non-heap based object */
00370 }
00371 
00372 static ULONG WINAPI FTMarshalCF_Release(LPCLASSFACTORY iface)
00373 {
00374     return 1; /* non-heap based object */
00375 }
00376 
00377 static HRESULT WINAPI FTMarshalCF_CreateInstance(LPCLASSFACTORY iface,
00378     LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
00379 {
00380     IUnknown *pUnknown;
00381     HRESULT  hr;
00382 
00383     TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
00384 
00385     *ppv = NULL;
00386 
00387     hr = CoCreateFreeThreadedMarshaler(pUnk, &pUnknown);
00388 
00389     if (SUCCEEDED(hr))
00390     {
00391         hr = IUnknown_QueryInterface(pUnknown, riid, ppv);
00392         IUnknown_Release(pUnknown);
00393     }
00394 
00395     return hr;
00396 }
00397 
00398 static HRESULT WINAPI FTMarshalCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
00399 {
00400     FIXME("(%d), stub!\n",fLock);
00401     return S_OK;
00402 }
00403 
00404 static const IClassFactoryVtbl FTMarshalCFVtbl =
00405 {
00406     FTMarshalCF_QueryInterface,
00407     FTMarshalCF_AddRef,
00408     FTMarshalCF_Release,
00409     FTMarshalCF_CreateInstance,
00410     FTMarshalCF_LockServer
00411 };
00412 static const IClassFactoryVtbl *FTMarshalCF = &FTMarshalCFVtbl;
00413 
00414 HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv)
00415 {
00416     return IClassFactory_QueryInterface((IClassFactory *)&FTMarshalCF, riid, ppv);
00417 }

Generated on Fri May 25 2012 04:23:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.