From: Andrew Eikum Subject: [PATCH] urlmon: Implement marshalling for IBindStatusCallback::GetBindInfo Message-Id: <20141219190653.GA828@foghorn.codeweavers.com> Date: Fri, 19 Dec 2014 13:06:53 -0600 --- dlls/urlmon/usrmarshal.c | 112 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 4 deletions(-) diff --git a/dlls/urlmon/usrmarshal.c b/dlls/urlmon/usrmarshal.c index d669918..9d70f88 100644 --- a/dlls/urlmon/usrmarshal.c +++ b/dlls/urlmon/usrmarshal.c @@ -103,16 +103,120 @@ HRESULT __RPC_STUB IBindStatusCallbackEx_GetBindInfoEx_Stub( HRESULT CALLBACK IBindStatusCallback_GetBindInfo_Proxy( IBindStatusCallback* This, DWORD *grfBINDF, BINDINFO *pbindinfo) { - FIXME("stub\n"); - return E_NOTIMPL; + RemBINDINFO bi; + RemSTGMEDIUM *stg; + HRESULT hr; + ULONG size; + void *pv; + + TRACE("(%p %p %p)\n", This, grfBINDF, pbindinfo); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = sizeof(bi); + + /* There does not seem to be a documented way to determine the correct size + * for RemSTGMEDIUM. Here, we use a NULL value to indicate we just want + * cbstgmedData. */ + hr = IBindStatusCallback_RemoteGetBindInfo_Proxy(This, grfBINDF, &bi, NULL); + if(FAILED(hr)) { + WARN("RemoteGetBindInfo (size) failed: %08x\n", hr); + return hr; + } + + /* Next, allocate RemSTGMEDIUM and call again to complete the full request. */ + stg = HeapAlloc(GetProcessHeap(), 0, sizeof(RemSTGMEDIUM) + bi.cbstgmedData); + memset(stg, 0, sizeof(*stg)); + stg->cbData = bi.cbstgmedData; + + hr = IBindStatusCallback_RemoteGetBindInfo_Proxy(This, grfBINDF, &bi, stg); + if(hr != S_OK) { + WARN("RemoteGetBindInfo failed: %08x\n", hr); + HeapFree(GetProcessHeap(), 0, stg); + return hr; + } + + /* copy retrieved data into caller's structs */ + size = pbindinfo->cbSize; + memset(pbindinfo, 0, pbindinfo->cbSize); + pbindinfo->cbSize = size; + /* TODO: szExtraInfo */ + pbindinfo->stgmedData.tymed = TYMED_HGLOBAL; + pbindinfo->stgmedData.u.hGlobal = GlobalAlloc(0, bi.cbstgmedData); + pv = GlobalLock(pbindinfo->stgmedData.u.hGlobal); + memcpy(pv, stg->data, bi.cbstgmedData); + GlobalUnlock(pbindinfo->stgmedData.u.hGlobal); + pbindinfo->grfBindInfoF = bi.grfBindInfoF; + pbindinfo->dwBindVerb = bi.dwBindVerb; + /* TODO: szCustomVerb */ + pbindinfo->cbstgmedData = bi.cbstgmedData; + + if(pbindinfo->cbSize >= offsetof(BINDINFO, dwReserved)) { + pbindinfo->dwOptions = bi.dwOptions; + pbindinfo->dwOptionsFlags = bi.dwOptionsFlags; + pbindinfo->dwCodePage = bi.dwCodePage; + /* TODO: securityAttributes */ + /* TODO: iid, pUnk */ + } + + HeapFree(GetProcessHeap(), 0, stg); + + return S_OK; } HRESULT __RPC_STUB IBindStatusCallback_GetBindInfo_Stub( IBindStatusCallback* This, DWORD *grfBINDF, RemBINDINFO *pbindinfo, RemSTGMEDIUM *pstgmed) { - FIXME("stub\n"); - return E_NOTIMPL; + HRESULT hr; + BINDINFO bi; + ULONG cb; + void *pv; + + TRACE("(%p %p %p %p)\n", This, grfBINDF, pbindinfo, pstgmed); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = pbindinfo->cbSize; + + hr = IBindStatusCallback_GetBindInfo(This, grfBINDF, &bi); + if(FAILED(hr)) { + WARN("local GetBindInfo failed: %08x\n", hr); + return hr; + } + + if(!pstgmed || bi.cbstgmedData > pstgmed->cbData) { + pbindinfo->cbstgmedData = bi.cbstgmedData; + ReleaseBindInfo(&bi); + return S_FALSE; + } + + if(bi.stgmedData.tymed != TYMED_HGLOBAL) { + FIXME("Can't handle non-HGLOBAL STGMEDIUM\n"); + ReleaseBindInfo(&bi); + return E_NOTIMPL; + } + + pv = GlobalLock(bi.stgmedData.u.hGlobal); + memcpy(pstgmed->data, pv, bi.cbstgmedData); + GlobalUnlock(bi.stgmedData.u.hGlobal); + + cb = pbindinfo->cbSize; + memset(pbindinfo, 0, sizeof(*pbindinfo)); + + pbindinfo->cbSize = cb; + /* TODO: szExtraInfo */ + pbindinfo->grfBindInfoF = bi.grfBindInfoF; + pbindinfo->dwBindVerb = bi.dwBindVerb; + /* TODO: szCustomVerb */ + pbindinfo->cbstgmedData = bi.cbstgmedData; + pbindinfo->dwOptions = bi.dwOptions; + pbindinfo->dwOptionsFlags = bi.dwOptionsFlags; + pbindinfo->dwCodePage = bi.dwCodePage; + /* TODO: securityAttributes */ + /* TODO: iid, pUnk */ + + ReleaseBindInfo(&bi); + + return S_OK; } HRESULT CALLBACK IBindStatusCallback_OnDataAvailable_Proxy( -- 2.2.0