mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 12:10:00 +00:00
combase: Move CoCreateFreeThreadedMarshaler().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0bcbc4693e
commit
3a413b91b9
|
@ -77,7 +77,7 @@
|
|||
@ stub CoCancelCall
|
||||
@ stdcall CoCopyProxy(ptr ptr)
|
||||
@ stdcall CoCreateErrorInfo(ptr) CreateErrorInfo
|
||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) ole32.CoCreateFreeThreadedMarshaler
|
||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr)
|
||||
@ stdcall CoCreateGuid(ptr)
|
||||
@ stdcall CoCreateInstance(ptr ptr long ptr ptr)
|
||||
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002 Juergen Schmied
|
||||
* Copyright 2002 Marcus Meissner
|
||||
* Copyright 2004 Mike Hearn, for CodeWeavers
|
||||
* Copyright 2004 Rob Shearman, for CodeWeavers
|
||||
|
@ -22,9 +23,28 @@
|
|||
#include "objbase.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
struct ftmarshaler
|
||||
{
|
||||
IUnknown IUnknown_inner;
|
||||
IMarshal IMarshal_iface;
|
||||
IUnknown *outer_unk;
|
||||
LONG refcount;
|
||||
};
|
||||
|
||||
static struct ftmarshaler *impl_ft_from_IUnknown(IUnknown *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct ftmarshaler, IUnknown_inner);
|
||||
}
|
||||
|
||||
static struct ftmarshaler *impl_ft_from_IMarshal(IMarshal *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct ftmarshaler, IMarshal_iface);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CoMarshalHresult (combase.@)
|
||||
*/
|
||||
|
@ -84,3 +104,278 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, IUnknown *unk,
|
|||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface);
|
||||
|
||||
TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj);
|
||||
|
||||
*obj = NULL;
|
||||
|
||||
if (IsEqualIID(&IID_IUnknown, riid))
|
||||
*obj = &marshaler->IUnknown_inner;
|
||||
else if (IsEqualIID(&IID_IMarshal, riid))
|
||||
*obj = &marshaler->IMarshal_iface;
|
||||
else
|
||||
{
|
||||
FIXME("No interface for %s\n", debugstr_guid(riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
IUnknown_AddRef((IUnknown *)*obj);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ftmarshaler_inner_AddRef(IUnknown *iface)
|
||||
{
|
||||
struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface);
|
||||
ULONG refcount = InterlockedIncrement(&marshaler->refcount);
|
||||
|
||||
TRACE("%p, refcount %u\n", iface, refcount);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static ULONG WINAPI ftmarshaler_inner_Release(IUnknown *iface)
|
||||
{
|
||||
struct ftmarshaler *marshaler = impl_ft_from_IUnknown(iface);
|
||||
ULONG refcount = InterlockedDecrement(&marshaler->refcount);
|
||||
|
||||
TRACE("%p, refcount %u\n", iface, refcount);
|
||||
|
||||
if (!refcount)
|
||||
heap_free(marshaler);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static const IUnknownVtbl ftmarshaler_inner_vtbl =
|
||||
{
|
||||
ftmarshaler_inner_QueryInterface,
|
||||
ftmarshaler_inner_AddRef,
|
||||
ftmarshaler_inner_Release
|
||||
};
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_QueryInterface(IMarshal *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface);
|
||||
|
||||
TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj);
|
||||
|
||||
return IUnknown_QueryInterface(marshaler->outer_unk, riid, obj);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ftmarshaler_AddRef(IMarshal *iface)
|
||||
{
|
||||
struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface);
|
||||
|
||||
TRACE("%p\n", iface);
|
||||
|
||||
return IUnknown_AddRef(marshaler->outer_unk);
|
||||
}
|
||||
|
||||
static ULONG WINAPI ftmarshaler_Release(IMarshal *iface)
|
||||
{
|
||||
struct ftmarshaler *marshaler = impl_ft_from_IMarshal(iface);
|
||||
|
||||
TRACE("%p\n", iface);
|
||||
|
||||
return IUnknown_Release(marshaler->outer_unk);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
|
||||
DWORD dest_context, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
|
||||
{
|
||||
TRACE("%s, %p, %#x, %p, %#x, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, clsid);
|
||||
|
||||
if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX)
|
||||
*clsid = CLSID_InProcFreeMarshaler;
|
||||
else
|
||||
*clsid = CLSID_StdMarshal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
|
||||
DWORD dest_context, void *pvDestContext, DWORD mshlflags, DWORD *size)
|
||||
{
|
||||
IMarshal *marshal = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%s, %p, %#x, %p, %#x, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, size);
|
||||
|
||||
/* If the marshalling happens inside the same process the interface pointer is
|
||||
copied between the apartments */
|
||||
if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX)
|
||||
{
|
||||
*size = sizeof(mshlflags) + sizeof(pv) + sizeof(DWORD) + sizeof(GUID);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Use the standard marshaller to handle all other cases */
|
||||
CoGetStandardMarshal(riid, pv, dest_context, pvDestContext, mshlflags, &marshal);
|
||||
hr = IMarshal_GetMarshalSizeMax(marshal, riid, pv, dest_context, pvDestContext, mshlflags, size);
|
||||
IMarshal_Release(marshal);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid,
|
||||
void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags)
|
||||
{
|
||||
IMarshal *marshal = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p, %s, %p, %#x, %p, %#x\n", stream, debugstr_guid(riid), pv,
|
||||
dest_context, pvDestContext, mshlflags);
|
||||
|
||||
/* If the marshalling happens inside the same process the interface pointer is
|
||||
copied between the apartments */
|
||||
if (dest_context == MSHCTX_INPROC || dest_context == MSHCTX_CROSSCTX)
|
||||
{
|
||||
void *object;
|
||||
DWORD constant = 0;
|
||||
GUID unknown_guid = { 0 };
|
||||
|
||||
hr = IUnknown_QueryInterface((IUnknown *)pv, riid, &object);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
/* don't hold a reference to table-weak marshaled interfaces */
|
||||
if (mshlflags & MSHLFLAGS_TABLEWEAK)
|
||||
IUnknown_Release((IUnknown *)object);
|
||||
|
||||
hr = IStream_Write(stream, &mshlflags, sizeof(mshlflags), NULL);
|
||||
if (hr != S_OK) return STG_E_MEDIUMFULL;
|
||||
|
||||
hr = IStream_Write(stream, &object, sizeof(object), NULL);
|
||||
if (hr != S_OK) return STG_E_MEDIUMFULL;
|
||||
|
||||
if (sizeof(object) == sizeof(DWORD))
|
||||
{
|
||||
hr = IStream_Write(stream, &constant, sizeof(constant), NULL);
|
||||
if (hr != S_OK) return STG_E_MEDIUMFULL;
|
||||
}
|
||||
|
||||
hr = IStream_Write(stream, &unknown_guid, sizeof(unknown_guid), NULL);
|
||||
if (hr != S_OK) return STG_E_MEDIUMFULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* Use the standard marshaler to handle all other cases */
|
||||
CoGetStandardMarshal(riid, pv, dest_context, pvDestContext, mshlflags, &marshal);
|
||||
hr = IMarshal_MarshalInterface(marshal, stream, riid, pv, dest_context, pvDestContext, mshlflags);
|
||||
IMarshal_Release(marshal);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv)
|
||||
{
|
||||
DWORD mshlflags;
|
||||
IUnknown *object;
|
||||
DWORD constant;
|
||||
GUID unknown_guid;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), ppv);
|
||||
|
||||
hr = IStream_Read(stream, &mshlflags, sizeof(mshlflags), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
|
||||
hr = IStream_Read(stream, &object, sizeof(object), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
|
||||
if (sizeof(object) == sizeof(DWORD))
|
||||
{
|
||||
hr = IStream_Read(stream, &constant, sizeof(constant), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
if (constant != 0)
|
||||
FIXME("constant is 0x%x instead of 0\n", constant);
|
||||
}
|
||||
|
||||
hr = IStream_Read(stream, &unknown_guid, sizeof(unknown_guid), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
|
||||
hr = IUnknown_QueryInterface(object, riid, ppv);
|
||||
if (!(mshlflags & (MSHLFLAGS_TABLEWEAK | MSHLFLAGS_TABLESTRONG)))
|
||||
IUnknown_Release(object);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_ReleaseMarshalData(IMarshal *iface, IStream *stream)
|
||||
{
|
||||
DWORD mshlflags;
|
||||
IUnknown *object;
|
||||
DWORD constant;
|
||||
GUID unknown_guid;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p\n", stream);
|
||||
|
||||
hr = IStream_Read(stream, &mshlflags, sizeof(mshlflags), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
|
||||
hr = IStream_Read(stream, &object, sizeof(object), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
|
||||
if (sizeof(object) == sizeof(DWORD))
|
||||
{
|
||||
hr = IStream_Read(stream, &constant, sizeof(constant), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
if (constant != 0)
|
||||
FIXME("constant is 0x%x instead of 0\n", constant);
|
||||
}
|
||||
|
||||
hr = IStream_Read(stream, &unknown_guid, sizeof(unknown_guid), NULL);
|
||||
if (hr != S_OK) return STG_E_READFAULT;
|
||||
|
||||
IUnknown_Release(object);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ftmarshaler_DisconnectObject(IMarshal *iface, DWORD reserved)
|
||||
{
|
||||
TRACE("\n");
|
||||
|
||||
/* nothing to do */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IMarshalVtbl ftmarshaler_vtbl =
|
||||
{
|
||||
ftmarshaler_QueryInterface,
|
||||
ftmarshaler_AddRef,
|
||||
ftmarshaler_Release,
|
||||
ftmarshaler_GetUnmarshalClass,
|
||||
ftmarshaler_GetMarshalSizeMax,
|
||||
ftmarshaler_MarshalInterface,
|
||||
ftmarshaler_UnmarshalInterface,
|
||||
ftmarshaler_ReleaseMarshalData,
|
||||
ftmarshaler_DisconnectObject
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CoCreateFreeThreadedMarshaler (combase.@)
|
||||
*/
|
||||
HRESULT WINAPI CoCreateFreeThreadedMarshaler(IUnknown *outer, IUnknown **marshaler)
|
||||
{
|
||||
struct ftmarshaler *object;
|
||||
|
||||
TRACE("%p, %p\n", outer, marshaler);
|
||||
|
||||
object = heap_alloc(sizeof(*object));
|
||||
if (!object)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->IUnknown_inner.lpVtbl = &ftmarshaler_inner_vtbl;
|
||||
object->IMarshal_iface.lpVtbl = &ftmarshaler_vtbl;
|
||||
object->refcount = 1;
|
||||
object->outer_unk = outer ? outer : &object->IUnknown_inner;
|
||||
|
||||
*marshaler = &object->IUnknown_inner;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -36,318 +36,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
typedef struct _FTMarshalImpl {
|
||||
IUnknown IUnknown_inner;
|
||||
IMarshal IMarshal_iface;
|
||||
IUnknown *outer_unk;
|
||||
LONG ref;
|
||||
} FTMarshalImpl;
|
||||
|
||||
static inline FTMarshalImpl *impl_from_IUnknown(IUnknown *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, FTMarshalImpl, IUnknown_inner);
|
||||
}
|
||||
|
||||
static inline FTMarshalImpl *impl_from_IMarshal( IMarshal *iface )
|
||||
{
|
||||
return CONTAINING_RECORD(iface, FTMarshalImpl, IMarshal_iface);
|
||||
}
|
||||
|
||||
/* inner IUnknown to handle aggregation */
|
||||
static HRESULT WINAPI
|
||||
IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = impl_from_IUnknown(iface);
|
||||
|
||||
TRACE ("\n");
|
||||
*ppv = NULL;
|
||||
|
||||
if (IsEqualIID (&IID_IUnknown, riid))
|
||||
*ppv = &This->IUnknown_inner;
|
||||
else if (IsEqualIID (&IID_IMarshal, riid))
|
||||
*ppv = &This->IMarshal_iface;
|
||||
else {
|
||||
FIXME ("No interface for %s.\n", debugstr_guid (riid));
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
IUnknown_AddRef ((IUnknown *) * ppv);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = impl_from_IUnknown(iface);
|
||||
|
||||
TRACE ("\n");
|
||||
return InterlockedIncrement (&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = impl_from_IUnknown(iface);
|
||||
|
||||
TRACE ("\n");
|
||||
if (InterlockedDecrement (&This->ref))
|
||||
return This->ref;
|
||||
HeapFree (GetProcessHeap (), 0, This);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const IUnknownVtbl iunkvt =
|
||||
{
|
||||
IiFTMUnknown_fnQueryInterface,
|
||||
IiFTMUnknown_fnAddRef,
|
||||
IiFTMUnknown_fnRelease
|
||||
};
|
||||
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = impl_from_IMarshal(iface);
|
||||
|
||||
TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppv);
|
||||
return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
FTMarshalImpl_AddRef (LPMARSHAL iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = impl_from_IMarshal(iface);
|
||||
|
||||
TRACE ("\n");
|
||||
return IUnknown_AddRef(This->outer_unk);
|
||||
}
|
||||
|
||||
static ULONG WINAPI
|
||||
FTMarshalImpl_Release (LPMARSHAL iface)
|
||||
{
|
||||
|
||||
FTMarshalImpl *This = impl_from_IMarshal(iface);
|
||||
|
||||
TRACE ("\n");
|
||||
return IUnknown_Release(This->outer_unk);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlflags, CLSID * pCid)
|
||||
{
|
||||
TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
|
||||
dwDestContext, pvDestContext, mshlflags, pCid);
|
||||
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
|
||||
*pCid = CLSID_InProcFreeMarshaler;
|
||||
else
|
||||
*pCid = CLSID_StdMarshal;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
|
||||
void *pvDestContext, DWORD mshlflags, DWORD * pSize)
|
||||
{
|
||||
|
||||
IMarshal *pMarshal = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%s, %p, 0x%x, %p, 0x%x, %p)\n", debugstr_guid(riid), pv,
|
||||
dwDestContext, pvDestContext, mshlflags, pSize);
|
||||
|
||||
/* if the marshalling happens inside the same process the interface pointer is
|
||||
copied between the apartments */
|
||||
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
|
||||
*pSize = sizeof (mshlflags) + sizeof (pv) + sizeof (DWORD) + sizeof (GUID);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* use the standard marshaller to handle all other cases */
|
||||
CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
|
||||
hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
|
||||
IMarshal_Release (pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
|
||||
DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
|
||||
{
|
||||
|
||||
IMarshal *pMarshal = NULL;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p, %s, %p, 0x%x, %p, 0x%x)\n", pStm, debugstr_guid(riid), pv,
|
||||
dwDestContext, pvDestContext, mshlflags);
|
||||
|
||||
/* if the marshalling happens inside the same process the interface pointer is
|
||||
copied between the apartments */
|
||||
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
|
||||
void *object;
|
||||
DWORD constant = 0;
|
||||
GUID unknown_guid = { 0 };
|
||||
|
||||
hres = IUnknown_QueryInterface((IUnknown *)pv, riid, &object);
|
||||
if (FAILED(hres))
|
||||
return hres;
|
||||
|
||||
/* don't hold a reference to table-weak marshaled interfaces */
|
||||
if (mshlflags & MSHLFLAGS_TABLEWEAK)
|
||||
IUnknown_Release((IUnknown *)object);
|
||||
|
||||
hres = IStream_Write (pStm, &mshlflags, sizeof (mshlflags), NULL);
|
||||
if (hres != S_OK) return STG_E_MEDIUMFULL;
|
||||
|
||||
hres = IStream_Write (pStm, &object, sizeof (object), NULL);
|
||||
if (hres != S_OK) return STG_E_MEDIUMFULL;
|
||||
|
||||
if (sizeof(object) == sizeof(DWORD))
|
||||
{
|
||||
hres = IStream_Write (pStm, &constant, sizeof (constant), NULL);
|
||||
if (hres != S_OK) return STG_E_MEDIUMFULL;
|
||||
}
|
||||
|
||||
hres = IStream_Write (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
|
||||
if (hres != S_OK) return STG_E_MEDIUMFULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* use the standard marshaler to handle all other cases */
|
||||
CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
|
||||
hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
|
||||
IMarshal_Release (pMarshal);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI
|
||||
FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
|
||||
{
|
||||
DWORD mshlflags;
|
||||
IUnknown *object;
|
||||
DWORD constant;
|
||||
GUID unknown_guid;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE ("(%p, %s, %p)\n", pStm, debugstr_guid(riid), ppv);
|
||||
|
||||
hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
|
||||
hres = IStream_Read (pStm, &object, sizeof (object), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
|
||||
if (sizeof(object) == sizeof(DWORD))
|
||||
{
|
||||
hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
if (constant != 0)
|
||||
FIXME("constant is 0x%x instead of 0\n", constant);
|
||||
}
|
||||
|
||||
hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
|
||||
hres = IUnknown_QueryInterface(object, riid, ppv);
|
||||
if (!(mshlflags & (MSHLFLAGS_TABLEWEAK|MSHLFLAGS_TABLESTRONG)))
|
||||
IUnknown_Release(object);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
|
||||
{
|
||||
DWORD mshlflags;
|
||||
IUnknown *object;
|
||||
DWORD constant;
|
||||
GUID unknown_guid;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE ("(%p)\n", pStm);
|
||||
|
||||
hres = IStream_Read (pStm, &mshlflags, sizeof (mshlflags), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
|
||||
hres = IStream_Read (pStm, &object, sizeof (object), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
|
||||
if (sizeof(object) == sizeof(DWORD))
|
||||
{
|
||||
hres = IStream_Read (pStm, &constant, sizeof (constant), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
if (constant != 0)
|
||||
FIXME("constant is 0x%x instead of 0\n", constant);
|
||||
}
|
||||
|
||||
hres = IStream_Read (pStm, &unknown_guid, sizeof (unknown_guid), NULL);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
|
||||
IUnknown_Release(object);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
|
||||
{
|
||||
TRACE ("()\n");
|
||||
/* nothing to do */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IMarshalVtbl ftmvtbl =
|
||||
{
|
||||
FTMarshalImpl_QueryInterface,
|
||||
FTMarshalImpl_AddRef,
|
||||
FTMarshalImpl_Release,
|
||||
FTMarshalImpl_GetUnmarshalClass,
|
||||
FTMarshalImpl_GetMarshalSizeMax,
|
||||
FTMarshalImpl_MarshalInterface,
|
||||
FTMarshalImpl_UnmarshalInterface,
|
||||
FTMarshalImpl_ReleaseMarshalData,
|
||||
FTMarshalImpl_DisconnectObject
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* CoCreateFreeThreadedMarshaler [OLE32.@]
|
||||
*
|
||||
* Creates a free-threaded marshaler.
|
||||
*
|
||||
* PARAMS
|
||||
* punkOuter [I] Optional. Outer unknown.
|
||||
* ppunkMarshal [O] On return, the inner unknown of the created free-threaded marshaler.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: E_OUTOFMEMORY if no memory available to create object.
|
||||
*
|
||||
* NOTES
|
||||
* Objects that ensure their state is maintained consistent when used by
|
||||
* multiple threads and reference no single-threaded objects are known as
|
||||
* free-threaded. The free-threaded marshaler enables these objects to be
|
||||
* efficiently marshaled within the same process, by not creating proxies
|
||||
* (as they aren't needed for the object to be safely used), whilst still
|
||||
* allowing the object to be used in inter-process and inter-machine contexts.
|
||||
*/
|
||||
HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
|
||||
{
|
||||
|
||||
FTMarshalImpl *ftm;
|
||||
|
||||
TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
|
||||
|
||||
ftm = HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
|
||||
if (!ftm)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
ftm->IUnknown_inner.lpVtbl = &iunkvt;
|
||||
ftm->IMarshal_iface.lpVtbl = &ftmvtbl;
|
||||
ftm->ref = 1;
|
||||
ftm->outer_unk = punkOuter ? punkOuter : &ftm->IUnknown_inner;
|
||||
|
||||
*ppunkMarshal = &ftm->IUnknown_inner;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface,
|
||||
REFIID riid, LPVOID *ppv)
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
@ stdcall CoAllowSetForegroundWindow(ptr ptr)
|
||||
@ stdcall CoBuildVersion()
|
||||
@ stdcall CoCopyProxy(ptr ptr) combase.CoCopyProxy
|
||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr)
|
||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) combase.CoCreateFreeThreadedMarshaler
|
||||
@ stdcall CoCreateGuid(ptr) combase.CoCreateGuid
|
||||
@ stdcall CoCreateInstance(ptr ptr long ptr ptr) combase.CoCreateInstance
|
||||
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr)
|
||||
|
|
Loading…
Reference in a new issue