diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index 8bcac10cdc8..be5ed85a8e3 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -131,7 +131,7 @@ @ stdcall CoLockObjectExternal(ptr long long) ole32.CoLockObjectExternal @ stdcall CoMarshalHresult(ptr long) @ 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 CoPushServiceDomain @ stub CoQueryAuthenticationServices diff --git a/dlls/combase/marshal.c b/dlls/combase/marshal.c index 3c577a9bff1..9a88be72368 100644 --- a/dlls/combase/marshal.c +++ b/dlls/combase/marshal.c @@ -411,3 +411,98 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *size, REFIID riid, IUnknown *unk, IMarshal_Release(marshal); 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; +} diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c index ea8432e2ee6..343d1c834f7 100644 --- a/dlls/ole32/marshal.c +++ b/dlls/ole32/marshal.c @@ -1689,26 +1689,6 @@ HRESULT WINAPI CoGetStandardMarshal(REFIID riid, IUnknown *pUnk, 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] * @@ -1777,135 +1757,6 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, 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.@] * diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 772599b4cff..7ab90e7b7a7 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -59,7 +59,7 @@ @ stdcall CoLockObjectExternal(ptr long long) @ stdcall CoMarshalHresult(ptr long) combase.CoMarshalHresult @ 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 @ stdcall CoQueryClientBlanket(ptr ptr ptr ptr ptr ptr ptr) combase.CoQueryClientBlanket @ stdcall CoQueryProxyBlanket(ptr ptr ptr ptr ptr ptr ptr ptr) combase.CoQueryProxyBlanket