Commit 475b2d6b authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

ole32: Make standard marshaler responsible for marshaling OBJREF header.

parent 862ea507
...@@ -392,10 +392,21 @@ static HRESULT WINAPI Proxy_GetMarshalSizeMax( ...@@ -392,10 +392,21 @@ static HRESULT WINAPI Proxy_GetMarshalSizeMax(
IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize) void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{ {
*pSize = sizeof(STDOBJREF); *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
return S_OK; return S_OK;
} }
static void fill_std_objref(OBJREF *objref, const GUID *iid, STDOBJREF *std)
{
objref->signature = OBJREF_SIGNATURE;
objref->flags = OBJREF_STANDARD;
objref->iid = *iid;
if(std)
objref->u_objref.u_standard.std = *std;
memset(&objref->u_objref.u_standard.saResAddr, 0,
sizeof(objref->u_objref.u_standard.saResAddr));
}
static HRESULT WINAPI Proxy_MarshalInterface( static HRESULT WINAPI Proxy_MarshalInterface(
LPMARSHAL iface, IStream *pStm, REFIID riid, void* pv, DWORD dwDestContext, LPMARSHAL iface, IStream *pStm, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags) void* pvDestContext, DWORD mshlflags)
...@@ -459,12 +470,16 @@ static HRESULT WINAPI Proxy_MarshalInterface( ...@@ -459,12 +470,16 @@ static HRESULT WINAPI Proxy_MarshalInterface(
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
OBJREF objref;
TRACE("writing stdobjref: flags = %04x cPublicRefs = %d oxid = %s oid = %s ipid = %s\n", TRACE("writing stdobjref: flags = %04x cPublicRefs = %d oxid = %s oid = %s ipid = %s\n",
stdobjref.flags, stdobjref.cPublicRefs, stdobjref.flags, stdobjref.cPublicRefs,
wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oxid),
wine_dbgstr_longlong(stdobjref.oid), wine_dbgstr_longlong(stdobjref.oid),
debugstr_guid(&stdobjref.ipid)); debugstr_guid(&stdobjref.ipid));
hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), NULL); fill_std_objref(&objref, riid, &stdobjref);
hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF,
u_objref.u_standard.saResAddr.aStringArray), NULL);
} }
} }
else else
...@@ -490,7 +505,11 @@ static HRESULT WINAPI Proxy_MarshalInterface( ...@@ -490,7 +505,11 @@ static HRESULT WINAPI Proxy_MarshalInterface(
1, &iid, &qiresults); 1, &iid, &qiresults);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = IStream_Write(pStm, &qiresults->std, sizeof(qiresults->std), NULL); OBJREF objref;
fill_std_objref(&objref, riid, &qiresults->std);
hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF,
u_objref.u_standard.saResAddr.aStringArray), NULL);
if (FAILED(hr)) if (FAILED(hr))
{ {
REMINTERFACEREF rif; REMINTERFACEREF rif;
...@@ -1277,7 +1296,7 @@ StdMarshalImpl_GetMarshalSizeMax( ...@@ -1277,7 +1296,7 @@ StdMarshalImpl_GetMarshalSizeMax(
IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, DWORD* pSize) void* pvDestContext, DWORD mshlflags, DWORD* pSize)
{ {
*pSize = sizeof(STDOBJREF); *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
return S_OK; return S_OK;
} }
...@@ -1286,10 +1305,10 @@ StdMarshalImpl_MarshalInterface( ...@@ -1286,10 +1305,10 @@ StdMarshalImpl_MarshalInterface(
IMarshal *iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context, IMarshal *iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context,
void* dest_context_data, DWORD mshlflags) void* dest_context_data, DWORD mshlflags)
{ {
STDOBJREF stdobjref;
ULONG res; ULONG res;
HRESULT hres; HRESULT hres;
APARTMENT *apt; APARTMENT *apt;
OBJREF objref;
TRACE("(...,%s,...)\n", debugstr_guid(riid)); TRACE("(...,%s,...)\n", debugstr_guid(riid));
...@@ -1302,7 +1321,9 @@ StdMarshalImpl_MarshalInterface( ...@@ -1302,7 +1321,9 @@ StdMarshalImpl_MarshalInterface(
/* make sure this apartment can be reached from other threads / processes */ /* make sure this apartment can be reached from other threads / processes */
RPC_StartRemoting(apt); RPC_StartRemoting(apt);
hres = marshal_object(apt, &stdobjref, riid, pv, dest_context, dest_context_data, mshlflags); fill_std_objref(&objref, riid, NULL);
hres = marshal_object(apt, &objref.u_objref.u_standard.std, riid,
pv, dest_context, dest_context_data, mshlflags);
apartment_release(apt); apartment_release(apt);
if (hres != S_OK) if (hres != S_OK)
{ {
...@@ -1310,7 +1331,8 @@ StdMarshalImpl_MarshalInterface( ...@@ -1310,7 +1331,8 @@ StdMarshalImpl_MarshalInterface(
return hres; return hres;
} }
return IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res); return IStream_Write(pStm, &objref,
FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray), &res);
} }
/* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with /* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
...@@ -1385,12 +1407,11 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, ...@@ -1385,12 +1407,11 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
return hr; return hr;
} }
static HRESULT WINAPI static HRESULT std_unmarshal_interface(MSHCTX dest_context, void *dest_context_data,
StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv) IStream *pStm, REFIID riid, void **ppv)
{ {
StdMarshalImpl *This = impl_from_StdMarshal(iface);
struct stub_manager *stubmgr = NULL; struct stub_manager *stubmgr = NULL;
STDOBJREF stdobjref; struct OR_STANDARD obj;
ULONG res; ULONG res;
HRESULT hres; HRESULT hres;
APARTMENT *apt; APARTMENT *apt;
...@@ -1407,7 +1428,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v ...@@ -1407,7 +1428,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
} }
/* read STDOBJREF from wire */ /* read STDOBJREF from wire */
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); hres = IStream_Read(pStm, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
if (hres != S_OK) if (hres != S_OK)
{ {
apartment_release(apt); apartment_release(apt);
...@@ -1421,8 +1442,14 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v ...@@ -1421,8 +1442,14 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
return hres; return hres;
} }
if (obj.saResAddr.wNumEntries)
{
ERR("unsupported size of DUALSTRINGARRAY\n");
return E_NOTIMPL;
}
/* check if we're marshalling back to ourselves */ /* check if we're marshalling back to ourselves */
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid))) if ((oxid == obj.std.oxid) && (stubmgr = get_stub_manager(apt, obj.std.oid)))
{ {
TRACE("Unmarshalling object marshalled in same apartment for iid %s, " TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
"returning original object %p\n", debugstr_guid(riid), stubmgr->object); "returning original object %p\n", debugstr_guid(riid), stubmgr->object);
...@@ -1430,8 +1457,8 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v ...@@ -1430,8 +1457,8 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv); hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
/* unref the ifstub. FIXME: only do this on success? */ /* unref the ifstub. FIXME: only do this on success? */
if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid)) if (!stub_manager_is_table_marshaled(stubmgr, &obj.std.ipid))
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE); stub_manager_ext_release(stubmgr, obj.std.cPublicRefs, obj.std.flags & SORFP_TABLEWEAK, FALSE);
stub_manager_int_release(stubmgr); stub_manager_int_release(stubmgr);
apartment_release(apt); apartment_release(apt);
...@@ -1443,28 +1470,28 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v ...@@ -1443,28 +1470,28 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
* ignore table marshaling and normal marshaling rules regarding number of * ignore table marshaling and normal marshaling rules regarding number of
* unmarshals, etc, but if you abuse these rules then your proxy could end * unmarshals, etc, but if you abuse these rules then your proxy could end
* up returning RPC_E_DISCONNECTED. */ * up returning RPC_E_DISCONNECTED. */
if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE))) if ((stub_apt = apartment_findfromoxid(obj.std.oxid, TRUE)))
{ {
if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid))) if ((stubmgr = get_stub_manager(stub_apt, obj.std.oid)))
{ {
if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid)) if (!stub_manager_notify_unmarshal(stubmgr, &obj.std.ipid))
hres = CO_E_OBJNOTCONNECTED; hres = CO_E_OBJNOTCONNECTED;
} }
else else
{ {
WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n", WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(obj.std.oxid),
wine_dbgstr_longlong(stdobjref.oid)); wine_dbgstr_longlong(obj.std.oid));
hres = CO_E_OBJNOTCONNECTED; hres = CO_E_OBJNOTCONNECTED;
} }
} }
else else
TRACE("Treating unmarshal from OXID %s as inter-process\n", TRACE("Treating unmarshal from OXID %s as inter-process\n",
wine_dbgstr_longlong(stdobjref.oxid)); wine_dbgstr_longlong(obj.std.oxid));
if (hres == S_OK) if (hres == S_OK)
hres = unmarshal_object(&stdobjref, apt, This->dest_context, hres = unmarshal_object(&obj.std, apt, dest_context,
This->dest_context_data, riid, dest_context_data, riid,
stubmgr ? &stubmgr->oxid_info : NULL, ppv); stubmgr ? &stubmgr->oxid_info : NULL, ppv);
if (stubmgr) stub_manager_int_release(stubmgr); if (stubmgr) stub_manager_int_release(stubmgr);
...@@ -1478,40 +1505,74 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v ...@@ -1478,40 +1505,74 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
} }
static HRESULT WINAPI static HRESULT WINAPI
StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm) StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
{ {
STDOBJREF stdobjref; StdMarshalImpl *This = impl_from_StdMarshal(iface);
OBJREF objref;
HRESULT hr;
ULONG res;
hr = IStream_Read(pStm, &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;
}
if (objref.signature != OBJREF_SIGNATURE)
{
ERR("Bad OBJREF signature 0x%08x\n", objref.signature);
return RPC_E_INVALID_OBJREF;
}
if (!(objref.flags & OBJREF_STANDARD))
{
FIXME("unsupported objref.flags = %x\n", objref.flags);
return E_NOTIMPL;
}
return std_unmarshal_interface(This->dest_context,
This->dest_context_data, pStm, riid, ppv);
}
static HRESULT std_release_marshal_data(IStream *pStm)
{
struct OR_STANDARD obj;
ULONG res; ULONG res;
HRESULT hres; HRESULT hres;
struct stub_manager *stubmgr; struct stub_manager *stubmgr;
APARTMENT *apt; APARTMENT *apt;
TRACE("iface=%p, pStm=%p\n", iface, pStm); hres = IStream_Read(pStm, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
if (hres != S_OK) return STG_E_READFAULT; if (hres != 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", TRACE("oxid = %s, oid = %s, ipid = %s\n",
wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(obj.std.oxid),
wine_dbgstr_longlong(stdobjref.oid), wine_dbgstr_longlong(obj.std.oid),
wine_dbgstr_guid(&stdobjref.ipid)); wine_dbgstr_guid(&obj.std.ipid));
if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE))) if (!(apt = apartment_findfromoxid(obj.std.oxid, TRUE)))
{ {
WARN("Could not map OXID %s to apartment object\n", WARN("Could not map OXID %s to apartment object\n",
wine_dbgstr_longlong(stdobjref.oxid)); wine_dbgstr_longlong(obj.std.oxid));
return RPC_E_INVALID_OBJREF; return RPC_E_INVALID_OBJREF;
} }
if (!(stubmgr = get_stub_manager(apt, stdobjref.oid))) if (!(stubmgr = get_stub_manager(apt, obj.std.oid)))
{ {
apartment_release(apt); apartment_release(apt);
ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n", ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n",
wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid)); wine_dbgstr_longlong(obj.std.oxid), wine_dbgstr_longlong(obj.std.oid));
return RPC_E_INVALID_OBJREF; return RPC_E_INVALID_OBJREF;
} }
stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs, &stdobjref.ipid, stdobjref.flags & SORFP_TABLEWEAK); stub_manager_release_marshal_data(stubmgr, obj.std.cPublicRefs, &obj.std.ipid, obj.std.flags & SORFP_TABLEWEAK);
stub_manager_int_release(stubmgr); stub_manager_int_release(stubmgr);
apartment_release(apt); apartment_release(apt);
...@@ -1520,6 +1581,37 @@ StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm) ...@@ -1520,6 +1581,37 @@ StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
} }
static HRESULT WINAPI static HRESULT WINAPI
StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
{
OBJREF objref;
HRESULT hr;
ULONG res;
TRACE("iface=%p, pStm=%p\n", iface, pStm);
hr = IStream_Read(pStm, &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;
}
if (objref.signature != OBJREF_SIGNATURE)
{
ERR("Bad OBJREF signature 0x%08x\n", objref.signature);
return RPC_E_INVALID_OBJREF;
}
if (!(objref.flags & OBJREF_STANDARD))
{
FIXME("unsupported objref.flags = %x\n", objref.flags);
return E_NOTIMPL;
}
return std_release_marshal_data(pStm);
}
static HRESULT WINAPI
StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved) StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved)
{ {
FIXME("(), stub!\n"); FIXME("(), stub!\n");
...@@ -1652,7 +1744,8 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, ...@@ -1652,7 +1744,8 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
if (objref.flags & OBJREF_STANDARD) if (objref.flags & OBJREF_STANDARD)
{ {
TRACE("Using standard unmarshaling\n"); TRACE("Using standard unmarshaling\n");
hr = StdMarshalImpl_Construct(&IID_IMarshal, 0, NULL, (LPVOID*)marshal); *marshal = NULL;
return S_FALSE;
} }
else if (objref.flags & OBJREF_CUSTOM) else if (objref.flags & OBJREF_CUSTOM)
{ {
...@@ -1728,12 +1821,8 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk, ...@@ -1728,12 +1821,8 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext, hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
pvDestContext, mshlFlags, pulSize); pvDestContext, mshlFlags, pulSize);
if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal)) if (!IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal))
/* add on the size of the common header */ /* add on the size of the whole OBJREF structure like native does */
*pulSize += FIELD_OFFSET(OBJREF, u_objref);
else
/* custom marshaling: add on the size of the whole OBJREF structure
* like native does */
*pulSize += sizeof(OBJREF); *pulSize += sizeof(OBJREF);
IMarshal_Release(pMarshal); IMarshal_Release(pMarshal);
...@@ -1791,7 +1880,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, ...@@ -1791,7 +1880,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
{ {
HRESULT hr; HRESULT hr;
CLSID marshaler_clsid; CLSID marshaler_clsid;
OBJREF objref;
LPMARSHAL pMarshal; LPMARSHAL pMarshal;
TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), pUnk, TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), pUnk,
...@@ -1802,9 +1890,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, ...@@ -1802,9 +1890,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
if (!pUnk || !pStream) if (!pUnk || !pStream)
return E_INVALIDARG; return E_INVALIDARG;
objref.signature = OBJREF_SIGNATURE;
objref.iid = *riid;
/* get the marshaler for the specified interface */ /* get the marshaler for the specified interface */
hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal);
if (hr != S_OK) if (hr != S_OK)
...@@ -1825,19 +1910,14 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, ...@@ -1825,19 +1910,14 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal)) if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal))
{ {
TRACE("Using standard marshaling\n"); TRACE("Using standard marshaling\n");
objref.flags = OBJREF_STANDARD;
/* write the common OBJREF header to the stream */
hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
if (hr != S_OK)
{
ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr);
goto cleanup;
}
} }
else else
{ {
OBJREF objref;
TRACE("Using custom marshaling\n"); TRACE("Using custom marshaling\n");
objref.signature = OBJREF_SIGNATURE;
objref.iid = *riid;
objref.flags = OBJREF_CUSTOM; objref.flags = OBJREF_CUSTOM;
objref.u_objref.u_custom.clsid = marshaler_clsid; objref.u_objref.u_custom.clsid = marshaler_clsid;
objref.u_objref.u_custom.cbExtension = 0; objref.u_objref.u_custom.cbExtension = 0;
...@@ -1912,13 +1992,20 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) ...@@ -1912,13 +1992,20 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
return E_INVALIDARG; return E_INVALIDARG;
hr = get_unmarshaler_from_stream(pStream, &pMarshal, &iid); hr = get_unmarshaler_from_stream(pStream, &pMarshal, &iid);
if (hr != S_OK) if (hr == S_FALSE)
return hr; {
hr = std_unmarshal_interface(0, NULL, pStream, &iid, (void**)&object);
/* call the helper object to do the actual unmarshaling */ if (hr != S_OK)
hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object); ERR("StdMarshal UnmarshalInterface failed, 0x%08x\n", hr);
if (hr != S_OK) }
ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr); else if (hr == S_OK)
{
/* call the helper object to do the actual unmarshaling */
hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object);
IMarshal_Release(pMarshal);
if (hr != S_OK)
ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr);
}
if (hr == S_OK) if (hr == S_OK)
{ {
...@@ -1938,8 +2025,6 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) ...@@ -1938,8 +2025,6 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
} }
} }
IMarshal_Release(pMarshal);
TRACE("completed with hr 0x%x\n", hr); TRACE("completed with hr 0x%x\n", hr);
return hr; return hr;
...@@ -1976,6 +2061,13 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream) ...@@ -1976,6 +2061,13 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
TRACE("(%p)\n", pStream); TRACE("(%p)\n", pStream);
hr = get_unmarshaler_from_stream(pStream, &pMarshal, NULL); 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) if (hr != S_OK)
return hr; return hr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment