[PATCH] urlmon: Implement marshalling for IBindStatusCallback::GetBindInfo

Andrew Eikum aeikum at codeweavers.com
Fri Dec 19 13:06:53 CST 2014


---
 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




More information about the wine-patches mailing list