[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