[PATCH 3/6] combase: Move CoCreateFreeThreadedMarshaler().
Nikolay Sivov
nsivov at codeweavers.com
Wed Aug 12 03:12:29 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/combase/combase.spec | 2 +-
dlls/combase/marshal.c | 295 +++++++++++++++++++++++++++++++++++
dlls/ole32/ftmarshal.c | 312 --------------------------------------
dlls/ole32/ole32.spec | 2 +-
4 files changed, 297 insertions(+), 314 deletions(-)
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
index 5ee52d950ee..79410be8be0 100644
--- a/dlls/combase/combase.spec
+++ b/dlls/combase/combase.spec
@@ -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
diff --git a/dlls/combase/marshal.c b/dlls/combase/marshal.c
index fe4c2f3adf8..2b0c0058125 100644
--- a/dlls/combase/marshal.c
+++ b/dlls/combase/marshal.c
@@ -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;
+}
diff --git a/dlls/ole32/ftmarshal.c b/dlls/ole32/ftmarshal.c
index 851810df42a..8777b553618 100644
--- a/dlls/ole32/ftmarshal.c
+++ b/dlls/ole32/ftmarshal.c
@@ -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)
{
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index 1587f926381..d1dedd39c3f 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -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)
--
2.28.0
More information about the wine-devel
mailing list