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
|
@ stub CoCancelCall
|
||||||
@ stdcall CoCopyProxy(ptr ptr)
|
@ stdcall CoCopyProxy(ptr ptr)
|
||||||
@ stdcall CoCreateErrorInfo(ptr) CreateErrorInfo
|
@ stdcall CoCreateErrorInfo(ptr) CreateErrorInfo
|
||||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) ole32.CoCreateFreeThreadedMarshaler
|
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr)
|
||||||
@ stdcall CoCreateGuid(ptr)
|
@ stdcall CoCreateGuid(ptr)
|
||||||
@ stdcall CoCreateInstance(ptr ptr long ptr ptr)
|
@ stdcall CoCreateInstance(ptr ptr long ptr ptr)
|
||||||
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx
|
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr) ole32.CoCreateInstanceEx
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2002 Juergen Schmied
|
||||||
* Copyright 2002 Marcus Meissner
|
* Copyright 2002 Marcus Meissner
|
||||||
* Copyright 2004 Mike Hearn, for CodeWeavers
|
* Copyright 2004 Mike Hearn, for CodeWeavers
|
||||||
* Copyright 2004 Rob Shearman, for CodeWeavers
|
* Copyright 2004 Rob Shearman, for CodeWeavers
|
||||||
|
@ -22,9 +23,28 @@
|
||||||
#include "objbase.h"
|
#include "objbase.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
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.@)
|
* CoMarshalHresult (combase.@)
|
||||||
*/
|
*/
|
||||||
|
@ -84,3 +104,278 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, IUnknown *unk,
|
||||||
|
|
||||||
return hr;
|
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);
|
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,
|
static HRESULT WINAPI FTMarshalCF_QueryInterface(LPCLASSFACTORY iface,
|
||||||
REFIID riid, LPVOID *ppv)
|
REFIID riid, LPVOID *ppv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
@ stdcall CoAllowSetForegroundWindow(ptr ptr)
|
@ stdcall CoAllowSetForegroundWindow(ptr ptr)
|
||||||
@ stdcall CoBuildVersion()
|
@ stdcall CoBuildVersion()
|
||||||
@ stdcall CoCopyProxy(ptr ptr) combase.CoCopyProxy
|
@ stdcall CoCopyProxy(ptr ptr) combase.CoCopyProxy
|
||||||
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr)
|
@ stdcall CoCreateFreeThreadedMarshaler(ptr ptr) combase.CoCreateFreeThreadedMarshaler
|
||||||
@ stdcall CoCreateGuid(ptr) combase.CoCreateGuid
|
@ stdcall CoCreateGuid(ptr) combase.CoCreateGuid
|
||||||
@ stdcall CoCreateInstance(ptr ptr long ptr ptr) combase.CoCreateInstance
|
@ stdcall CoCreateInstance(ptr ptr long ptr ptr) combase.CoCreateInstance
|
||||||
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr)
|
@ stdcall CoCreateInstanceEx(ptr ptr long ptr long ptr)
|
||||||
|
|
Loading…
Reference in New Issue