Nikolay Sivov : combase: Move CoReleaseMarshalData().

Alexandre Julliard julliard at winehq.org
Tue Sep 1 15:43:31 CDT 2020


Module: wine
Branch: master
Commit: 1a6afac0e49eaf9eca7295611596e14093670144
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1a6afac0e49eaf9eca7295611596e14093670144

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Sep  1 15:16:30 2020 +0100

combase: Move CoReleaseMarshalData().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/combase/combase.spec      |   2 +-
 dlls/combase/combase_private.h |   2 +
 dlls/combase/marshal.c         | 141 +++++++++++++++++++++++++++++++++++++++++
 dlls/ole32/marshal.c           |  50 ---------------
 dlls/ole32/ole32.spec          |   2 +-
 5 files changed, 145 insertions(+), 52 deletions(-)

diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
index 4ac93ff545..e1ffdc8253 100644
--- a/dlls/combase/combase.spec
+++ b/dlls/combase/combase.spec
@@ -146,7 +146,7 @@
 @ stdcall CoRegisterPSClsid(ptr ptr)
 @ stdcall CoRegisterSurrogate(ptr) ole32.CoRegisterSurrogate
 @ stdcall CoRegisterSurrogateEx(ptr ptr) ole32.CoRegisterSurrogateEx
-@ stdcall CoReleaseMarshalData(ptr) ole32.CoReleaseMarshalData
+@ stdcall CoReleaseMarshalData(ptr)
 @ stdcall CoReleaseServerProcess()
 @ stdcall CoResumeClassObjects() ole32.CoResumeClassObjects
 @ stub CoRetireServer
diff --git a/dlls/combase/combase_private.h b/dlls/combase/combase_private.h
index 898d42b3c7..cc1c3d3438 100644
--- a/dlls/combase/combase_private.h
+++ b/dlls/combase/combase_private.h
@@ -222,3 +222,5 @@ struct stub_manager * WINAPI get_stub_manager_from_object(struct apartment *apt,
 void stub_manager_disconnect(struct stub_manager *m) DECLSPEC_HIDDEN;
 ULONG WINAPI stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) DECLSPEC_HIDDEN;
 ULONG WINAPI stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) DECLSPEC_HIDDEN;
+struct stub_manager * WINAPI get_stub_manager(struct apartment *apt, OID oid);
+void WINAPI stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak);
diff --git a/dlls/combase/marshal.c b/dlls/combase/marshal.c
index db5089f013..bfe31ff17d 100644
--- a/dlls/combase/marshal.c
+++ b/dlls/combase/marshal.c
@@ -29,6 +29,9 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
+/* private flag indicating that the object was marshaled as table-weak */
+#define SORFP_TABLEWEAK SORF_OXRES1
+
 struct ftmarshaler
 {
     IUnknown IUnknown_inner;
@@ -507,3 +510,141 @@ cleanup:
 
     return hr;
 }
+
+/* Creates an IMarshal* object according to the data marshaled to the stream.
+ * The function leaves the stream pointer at the start of the data written
+ * to the stream by the IMarshal* object.
+ */
+static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, IID *iid)
+{
+    OBJREF objref;
+    HRESULT hr;
+    ULONG res;
+
+    /* read common OBJREF header */
+    hr = IStream_Read(stream, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
+    if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref)))
+    {
+        ERR("Failed to read common OBJREF header, 0x%08x\n", hr);
+        return STG_E_READFAULT;
+    }
+
+    /* sanity check on header */
+    if (objref.signature != OBJREF_SIGNATURE)
+    {
+        ERR("Bad OBJREF signature 0x%08x\n", objref.signature);
+        return RPC_E_INVALID_OBJREF;
+    }
+
+    if (iid) *iid = objref.iid;
+
+    /* FIXME: handler marshaling */
+    if (objref.flags & OBJREF_STANDARD)
+    {
+        TRACE("Using standard unmarshaling\n");
+        *marshal = NULL;
+        return S_FALSE;
+    }
+    else if (objref.flags & OBJREF_CUSTOM)
+    {
+        ULONG custom_header_size = FIELD_OFFSET(OBJREF, u_objref.u_custom.pData) -
+                                   FIELD_OFFSET(OBJREF, u_objref.u_custom);
+        TRACE("Using custom unmarshaling\n");
+        /* read constant sized OR_CUSTOM data from stream */
+        hr = IStream_Read(stream, &objref.u_objref.u_custom,
+                          custom_header_size, &res);
+        if (hr != S_OK || (res != custom_header_size))
+        {
+            ERR("Failed to read OR_CUSTOM header, 0x%08x\n", hr);
+            return STG_E_READFAULT;
+        }
+        /* now create the marshaler specified in the stream */
+        hr = CoCreateInstance(&objref.u_objref.u_custom.clsid, NULL,
+                              CLSCTX_INPROC_SERVER, &IID_IMarshal,
+                              (LPVOID*)marshal);
+    }
+    else
+    {
+        FIXME("Invalid or unimplemented marshaling type specified: %x\n",
+            objref.flags);
+        return RPC_E_INVALID_OBJREF;
+    }
+
+    if (hr != S_OK)
+        ERR("Failed to create marshal, 0x%08x\n", hr);
+
+    return hr;
+}
+
+static HRESULT std_release_marshal_data(IStream *stream)
+{
+    struct stub_manager *stubmgr;
+    struct OR_STANDARD  obj;
+    struct apartment *apt;
+    ULONG res;
+    HRESULT hr;
+
+    hr = IStream_Read(stream, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
+    if (hr != S_OK) return STG_E_READFAULT;
+
+    if (obj.saResAddr.wNumEntries)
+    {
+        ERR("unsupported size of DUALSTRINGARRAY\n");
+        return E_NOTIMPL;
+    }
+
+    TRACE("oxid = %s, oid = %s, ipid = %s\n", wine_dbgstr_longlong(obj.std.oxid),
+            wine_dbgstr_longlong(obj.std.oid), wine_dbgstr_guid(&obj.std.ipid));
+
+    if (!(apt = apartment_findfromoxid(obj.std.oxid)))
+    {
+        WARN("Could not map OXID %s to apartment object\n",
+            wine_dbgstr_longlong(obj.std.oxid));
+        return RPC_E_INVALID_OBJREF;
+    }
+
+    if (!(stubmgr = get_stub_manager(apt, obj.std.oid)))
+    {
+        apartment_release(apt);
+        ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n",
+            wine_dbgstr_longlong(obj.std.oxid), wine_dbgstr_longlong(obj.std.oid));
+        return RPC_E_INVALID_OBJREF;
+    }
+
+    stub_manager_release_marshal_data(stubmgr, obj.std.cPublicRefs, &obj.std.ipid, obj.std.flags & SORFP_TABLEWEAK);
+
+    stub_manager_int_release(stubmgr);
+    apartment_release(apt);
+
+    return S_OK;
+}
+
+/***********************************************************************
+ *            CoReleaseMarshalData        (combase.@)
+ */
+HRESULT WINAPI CoReleaseMarshalData(IStream *stream)
+{
+    IMarshal *marshal;
+    HRESULT hr;
+
+    TRACE("%p\n", stream);
+
+    hr = get_unmarshaler_from_stream(stream, &marshal, NULL);
+    if (hr == S_FALSE)
+    {
+        hr = std_release_marshal_data(stream);
+        if (hr != S_OK)
+            ERR("StdMarshal ReleaseMarshalData failed with error %#x\n", hr);
+        return hr;
+    }
+    if (hr != S_OK)
+        return hr;
+
+    /* call the helper object to do the releasing of marshal data */
+    hr = IMarshal_ReleaseMarshalData(marshal, stream);
+    if (hr != S_OK)
+        ERR("IMarshal::ReleaseMarshalData failed with error %#x\n", hr);
+
+    IMarshal_Release(marshal);
+    return hr;
+}
diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c
index 87017dbc92..e462c9ffd4 100644
--- a/dlls/ole32/marshal.c
+++ b/dlls/ole32/marshal.c
@@ -1837,56 +1837,6 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
     return hr;
 }
 
-/***********************************************************************
- *		CoReleaseMarshalData	[OLE32.@]
- *
- * Releases resources associated with an object that has been marshaled into
- * a stream.
- *
- * PARAMS
- *
- *  pStream [I] The stream that the object has been marshaled into.
- *
- * RETURNS
- *  Success: S_OK.
- *  Failure: HRESULT error code.
- *
- * NOTES
- * 
- * Call this function to release resources associated with a normal or
- * table-weak marshal that will not be unmarshaled, and all table-strong
- * marshals when they are no longer needed.
- *
- * SEE ALSO
- *  CoMarshalInterface(), CoUnmarshalInterface().
- */
-HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
-{
-    HRESULT	hr;
-    LPMARSHAL pMarshal;
-
-    TRACE("(%p)\n", pStream);
-
-    hr = get_unmarshaler_from_stream(pStream, &pMarshal, NULL);
-    if (hr == S_FALSE)
-    {
-        hr = std_release_marshal_data(pStream);
-        if (hr != S_OK)
-            ERR("StdMarshal ReleaseMarshalData failed with error 0x%08x\n", hr);
-        return hr;
-    }
-    if (hr != S_OK)
-        return hr;
-
-    /* call the helper object to do the releasing of marshal data */
-    hr = IMarshal_ReleaseMarshalData(pMarshal, pStream);
-    if (hr != S_OK)
-        ERR("IMarshal::ReleaseMarshalData failed with error 0x%08x\n", hr);
-
-    IMarshal_Release(pMarshal);
-    return hr;
-}
-
 static HRESULT WINAPI StdMarshalCF_QueryInterface(LPCLASSFACTORY iface,
                                                   REFIID riid, LPVOID *ppv)
 {
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index 972629ecb7..2ecfcf6b51 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -72,7 +72,7 @@
 @ stdcall CoRegisterPSClsid(ptr ptr) combase.CoRegisterPSClsid
 @ stdcall CoRegisterSurrogate(ptr)
 @ stdcall CoRegisterSurrogateEx(ptr ptr)
-@ stdcall CoReleaseMarshalData(ptr)
+@ stdcall CoReleaseMarshalData(ptr) combase.CoReleaseMarshalData
 @ stdcall CoReleaseServerProcess() combase.CoReleaseServerProcess
 @ stdcall CoResumeClassObjects()
 @ stdcall CoRevertToSelf() combase.CoRevertToSelf




More information about the wine-cvs mailing list