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