Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftmarshal.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
1.7.6.1
|