combase: Move CoMarshalInterface().

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:
Nikolay Sivov 2020-08-14 09:16:28 +03:00 committed by Alexandre Julliard
parent 3aefd100d7
commit bca780c020
4 changed files with 97 additions and 151 deletions

View File

@ -131,7 +131,7 @@
@ stdcall CoLockObjectExternal(ptr long long) ole32.CoLockObjectExternal @ stdcall CoLockObjectExternal(ptr long long) ole32.CoLockObjectExternal
@ stdcall CoMarshalHresult(ptr long) @ stdcall CoMarshalHresult(ptr long)
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr) @ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr)
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long) ole32.CoMarshalInterface @ stdcall CoMarshalInterface(ptr ptr ptr long ptr long)
@ stub CoPopServiceDomain @ stub CoPopServiceDomain
@ stub CoPushServiceDomain @ stub CoPushServiceDomain
@ stub CoQueryAuthenticationServices @ stub CoQueryAuthenticationServices

View File

@ -411,3 +411,98 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *size, REFIID riid, IUnknown *unk,
IMarshal_Release(marshal); IMarshal_Release(marshal);
return hr; return hr;
} }
static void dump_mshflags(MSHLFLAGS flags)
{
if (flags & MSHLFLAGS_TABLESTRONG)
TRACE(" MSHLFLAGS_TABLESTRONG");
if (flags & MSHLFLAGS_TABLEWEAK)
TRACE(" MSHLFLAGS_TABLEWEAK");
if (!(flags & (MSHLFLAGS_TABLESTRONG|MSHLFLAGS_TABLEWEAK)))
TRACE(" MSHLFLAGS_NORMAL");
if (flags & MSHLFLAGS_NOPING)
TRACE(" MSHLFLAGS_NOPING");
}
/***********************************************************************
* CoMarshalInterface (combase.@)
*/
HRESULT WINAPI CoMarshalInterface(IStream *stream, REFIID riid, IUnknown *unk,
DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
{
CLSID marshaler_clsid;
IMarshal *marshal;
HRESULT hr;
TRACE("%p, %s, %p, %x, %p, ", stream, debugstr_guid(riid), unk, dest_context, pvDestContext);
dump_mshflags(mshlFlags);
TRACE("\n");
if (!unk || !stream)
return E_INVALIDARG;
hr = IUnknown_QueryInterface(unk, &IID_IMarshal, (void **)&marshal);
if (hr != S_OK)
hr = CoGetStandardMarshal(riid, unk, dest_context, pvDestContext, mshlFlags, &marshal);
if (hr != S_OK)
{
ERR("Failed to get marshaller, %#x\n", hr);
return hr;
}
hr = IMarshal_GetUnmarshalClass(marshal, riid, unk, dest_context, pvDestContext, mshlFlags,
&marshaler_clsid);
if (hr != S_OK)
{
ERR("IMarshal::GetUnmarshalClass failed, %#x\n", hr);
goto cleanup;
}
/* FIXME: implement handler marshaling too */
if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal))
{
TRACE("Using standard marshaling\n");
}
else
{
OBJREF objref;
TRACE("Using custom marshaling\n");
objref.signature = OBJREF_SIGNATURE;
objref.iid = *riid;
objref.flags = OBJREF_CUSTOM;
objref.u_objref.u_custom.clsid = marshaler_clsid;
objref.u_objref.u_custom.cbExtension = 0;
objref.u_objref.u_custom.size = 0;
hr = IMarshal_GetMarshalSizeMax(marshal, riid, unk, dest_context, pvDestContext, mshlFlags,
&objref.u_objref.u_custom.size);
if (hr != S_OK)
{
ERR("Failed to get max size of marshal data, error %#x\n", hr);
goto cleanup;
}
/* write constant sized common header and OR_CUSTOM data into stream */
hr = IStream_Write(stream, &objref, FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL);
if (hr != S_OK)
{
ERR("Failed to write OR_CUSTOM header to stream with %#x\n", hr);
goto cleanup;
}
}
TRACE("Calling IMarshal::MarshalInterface\n");
hr = IMarshal_MarshalInterface(marshal, stream, riid, unk, dest_context, pvDestContext, mshlFlags);
if (hr != S_OK)
{
ERR("Failed to marshal the interface %s, hr %#x\n", debugstr_guid(riid), hr);
goto cleanup;
}
cleanup:
IMarshal_Release(marshal);
TRACE("completed with hr %#x\n", hr);
return hr;
}

View File

@ -1689,26 +1689,6 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk,
return StdMarshalImpl_Construct(&IID_IMarshal, dwDestContext, pvDestContext, (void**)ppMarshal); return StdMarshalImpl_Construct(&IID_IMarshal, dwDestContext, pvDestContext, (void**)ppMarshal);
} }
/***********************************************************************
* get_marshaler [internal]
*
* Retrieves an IMarshal interface for an object.
*/
static HRESULT get_marshaler(REFIID riid, IUnknown *pUnk, DWORD dwDestContext,
void *pvDestContext, DWORD mshlFlags,
LPMARSHAL *pMarshal)
{
HRESULT hr;
if (!pUnk)
return E_POINTER;
hr = IUnknown_QueryInterface(pUnk, &IID_IMarshal, (LPVOID*)pMarshal);
if (hr != S_OK)
hr = CoGetStandardMarshal(riid, pUnk, dwDestContext, pvDestContext,
mshlFlags, pMarshal);
return hr;
}
/*********************************************************************** /***********************************************************************
* get_unmarshaler_from_stream [internal] * get_unmarshaler_from_stream [internal]
* *
@ -1777,135 +1757,6 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
return hr; return hr;
} }
static void dump_MSHLFLAGS(MSHLFLAGS flags)
{
if (flags & MSHLFLAGS_TABLESTRONG)
TRACE(" MSHLFLAGS_TABLESTRONG");
if (flags & MSHLFLAGS_TABLEWEAK)
TRACE(" MSHLFLAGS_TABLEWEAK");
if (!(flags & (MSHLFLAGS_TABLESTRONG|MSHLFLAGS_TABLEWEAK)))
TRACE(" MSHLFLAGS_NORMAL");
if (flags & MSHLFLAGS_NOPING)
TRACE(" MSHLFLAGS_NOPING");
}
/***********************************************************************
* CoMarshalInterface [OLE32.@]
*
* Marshals an interface into a stream so that the object can then be
* unmarshaled from another COM apartment and used remotely.
*
* PARAMS
* pStream [I] Stream the object will be marshaled into.
* riid [I] Identifier of the interface to marshal.
* pUnk [I] Pointer to the object to marshal.
* dwDestContext [I] Destination. Used to enable or disable optimizations.
* pvDestContext [I] Reserved. Must be NULL.
* mshlFlags [I] Flags that affect the marshaling. See notes.
*
* RETURNS
* Success: S_OK.
* Failure: HRESULT code.
*
* NOTES
*
* The mshlFlags parameter can take one or more of the following flags:
*| MSHLFLAGS_NORMAL - Unmarshal once, releases stub on last proxy release.
*| MSHLFLAGS_TABLESTRONG - Unmarshal many, release when CoReleaseMarshalData() called.
*| MSHLFLAGS_TABLEWEAK - Unmarshal many, releases stub on last proxy release.
*| MSHLFLAGS_NOPING - No automatic garbage collection (and so reduces network traffic).
*
* If a marshaled object is not unmarshaled, then CoReleaseMarshalData() must
* be called in order to release the resources used in the marshaling.
*
* SEE ALSO
* CoUnmarshalInterface(), CoReleaseMarshalData().
*/
HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
DWORD dwDestContext, void *pvDestContext,
DWORD mshlFlags)
{
HRESULT hr;
CLSID marshaler_clsid;
LPMARSHAL pMarshal;
TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), pUnk,
dwDestContext, pvDestContext);
dump_MSHLFLAGS(mshlFlags);
TRACE(")\n");
if (!pUnk || !pStream)
return E_INVALIDARG;
/* get the marshaler for the specified interface */
hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal);
if (hr != S_OK)
{
ERR("Failed to get marshaller, 0x%08x\n", hr);
return hr;
}
hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags, &marshaler_clsid);
if (hr != S_OK)
{
ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr);
goto cleanup;
}
/* FIXME: implement handler marshaling too */
if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal))
{
TRACE("Using standard marshaling\n");
}
else
{
OBJREF objref;
TRACE("Using custom marshaling\n");
objref.signature = OBJREF_SIGNATURE;
objref.iid = *riid;
objref.flags = OBJREF_CUSTOM;
objref.u_objref.u_custom.clsid = marshaler_clsid;
objref.u_objref.u_custom.cbExtension = 0;
objref.u_objref.u_custom.size = 0;
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags,
&objref.u_objref.u_custom.size);
if (hr != S_OK)
{
ERR("Failed to get max size of marshal data, error 0x%08x\n", hr);
goto cleanup;
}
/* write constant sized common header and OR_CUSTOM data into stream */
hr = IStream_Write(pStream, &objref,
FIELD_OFFSET(OBJREF, u_objref.u_custom.pData), NULL);
if (hr != S_OK)
{
ERR("Failed to write OR_CUSTOM header to stream with 0x%08x\n", hr);
goto cleanup;
}
}
TRACE("Calling IMarshal::MarshalInterface\n");
/* call helper object to do the actual marshaling */
hr = IMarshal_MarshalInterface(pMarshal, pStream, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags);
if (hr != S_OK)
{
ERR("Failed to marshal the interface %s, %x\n", debugstr_guid(riid), hr);
goto cleanup;
}
cleanup:
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%08x\n", hr);
return hr;
}
/*********************************************************************** /***********************************************************************
* CoUnmarshalInterface [OLE32.@] * CoUnmarshalInterface [OLE32.@]
* *

View File

@ -59,7 +59,7 @@
@ stdcall CoLockObjectExternal(ptr long long) @ stdcall CoLockObjectExternal(ptr long long)
@ stdcall CoMarshalHresult(ptr long) combase.CoMarshalHresult @ stdcall CoMarshalHresult(ptr long) combase.CoMarshalHresult
@ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr) combase.CoMarshalInterThreadInterfaceInStream @ stdcall CoMarshalInterThreadInterfaceInStream(ptr ptr ptr) combase.CoMarshalInterThreadInterfaceInStream
@ stdcall CoMarshalInterface(ptr ptr ptr long ptr long) @ stdcall CoMarshalInterface(ptr ptr ptr long ptr long) combase.CoMarshalInterface
@ stub CoQueryAuthenticationServices @ stub CoQueryAuthenticationServices
@ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr) combase.CoQueryClientBlanket @ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr) combase.CoQueryClientBlanket
@ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr) combase.CoQueryProxyBlanket @ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr) combase.CoQueryProxyBlanket