Jacek Caban : urlmon: Added user marshaling implementation for OnDataAvailable.

Alexandre Julliard julliard at winehq.org
Tue Nov 14 16:18:47 CST 2017


Module: wine
Branch: master
Commit: 185b235d2f60747be61afa6a79cd2daf05dcbd09
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=185b235d2f60747be61afa6a79cd2daf05dcbd09

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Nov 13 23:30:05 2017 +0100

urlmon: Added user marshaling implementation for OnDataAvailable.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/urlmon/usrmarshal.c | 155 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 151 insertions(+), 4 deletions(-)

diff --git a/dlls/urlmon/usrmarshal.c b/dlls/urlmon/usrmarshal.c
index e15c91b..f196883 100644
--- a/dlls/urlmon/usrmarshal.c
+++ b/dlls/urlmon/usrmarshal.c
@@ -16,6 +16,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define NONAMELESSUNION
+
 #include "urlmon_main.h"
 
 #include "wine/debug.h"
@@ -84,6 +86,115 @@ HRESULT __RPC_STUB IBindHost_MonikerBindToObject_Stub(IBindHost* This,
     return IBindHost_MonikerBindToObject(This, moniker, bc, bsc, riid, (void**)obj);
 }
 
+static HRESULT marshal_stgmed(STGMEDIUM *stgmed, RemSTGMEDIUM **ret)
+{
+    RemSTGMEDIUM *rem_stgmed;
+    IStream *stream = NULL;
+    ULONG size = 0;
+    HRESULT hres = S_OK;
+
+    if((stgmed->tymed == TYMED_ISTREAM && stgmed->u.pstm) || stgmed->pUnkForRelease) {
+        hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    switch(stgmed->tymed) {
+    case TYMED_NULL:
+        break;
+    case TYMED_ISTREAM:
+        if(stgmed->u.pstm)
+            hres = CoMarshalInterface(stream, &IID_IStream, (IUnknown*)stgmed->u.pstm,
+                                      MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
+        break;
+    default:
+        FIXME("unsupported tymed %u\n", stgmed->tymed);
+        break;
+    }
+
+    if(SUCCEEDED(hres) && stgmed->pUnkForRelease)
+        hres = CoMarshalInterface(stream, &IID_IUnknown, stgmed->pUnkForRelease,
+                                  MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
+    if(FAILED(hres)) {
+        if(stream)
+            IStream_Release(stream);
+        return hres;
+    }
+
+    if(stream) {
+        LARGE_INTEGER zero;
+        ULARGE_INTEGER off;
+
+        zero.QuadPart = 0;
+        IStream_Seek(stream, zero, STREAM_SEEK_CUR, &off);
+        size = off.QuadPart;
+        IStream_Seek(stream, zero, STREAM_SEEK_SET, &off);
+    }
+
+    rem_stgmed = heap_alloc_zero(FIELD_OFFSET(RemSTGMEDIUM, data[size]));
+    if(!rem_stgmed) {
+        if(stream)
+            IStream_Release(stream);
+        return E_OUTOFMEMORY;
+    }
+
+    rem_stgmed->tymed = stgmed->tymed;
+    rem_stgmed->dwHandleType = 0;
+    rem_stgmed->pData = stgmed->u.pstm != NULL;
+    rem_stgmed->pUnkForRelease = stgmed->pUnkForRelease != NULL;
+    rem_stgmed->cbData = size;
+    if(stream) {
+        IStream_Read(stream, rem_stgmed->data, size, &size);
+        IStream_Release(stream);
+    }
+
+    *ret = rem_stgmed;
+    return S_OK;
+}
+
+static HRESULT unmarshal_stgmed(RemSTGMEDIUM *rem_stgmed, STGMEDIUM *stgmed)
+{
+    IStream *stream = NULL;
+    HRESULT hres = S_OK;
+
+    stgmed->tymed = rem_stgmed->tymed;
+
+    if((stgmed->tymed == TYMED_ISTREAM && rem_stgmed->pData) || rem_stgmed->pUnkForRelease) {
+        LARGE_INTEGER zero;
+
+        hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
+        if(FAILED(hres))
+            return hres;
+
+        hres = IStream_Write(stream, rem_stgmed->data, rem_stgmed->cbData, NULL);
+        if(FAILED(hres)) {
+            IStream_Release(stream);
+            return hres;
+        }
+
+        zero.QuadPart = 0;
+        IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
+    }
+
+    switch(stgmed->tymed) {
+    case TYMED_NULL:
+        break;
+    case TYMED_ISTREAM:
+        if(rem_stgmed->pData)
+            hres = CoUnmarshalInterface(stream, &IID_IStream, (void**)&stgmed->u.pstm);
+        break;
+    default:
+        FIXME("unsupported tymed %u\n", stgmed->tymed);
+        break;
+    }
+
+    if(SUCCEEDED(hres) && rem_stgmed->pUnkForRelease)
+        hres = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&stgmed->pUnkForRelease);
+    if(stream)
+        IStream_Release(stream);
+    return hres;
+}
+
 HRESULT CALLBACK IBindStatusCallbackEx_GetBindInfoEx_Proxy(
         IBindStatusCallbackEx* This, DWORD *grfBINDF, BINDINFO *pbindinfo,
         DWORD *grfBINDF2, DWORD *pdwReserved)
@@ -119,16 +230,52 @@ HRESULT CALLBACK IBindStatusCallback_OnDataAvailable_Proxy(
         IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
         FORMATETC *pformatetc, STGMEDIUM *pstgmed)
 {
-    FIXME("stub\n");
-    return E_NOTIMPL;
+    RemFORMATETC rem_formatetc;
+    RemSTGMEDIUM *rem_stgmed;
+    HRESULT hres;
+
+    TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
+
+    hres = marshal_stgmed(pstgmed, &rem_stgmed);
+    if(FAILED(hres))
+        return hres;
+
+    rem_formatetc.cfFormat = pformatetc->cfFormat;
+    rem_formatetc.ptd = 0;
+    rem_formatetc.dwAspect = pformatetc->dwAspect;
+    rem_formatetc.lindex = pformatetc->lindex;
+    rem_formatetc.tymed = pformatetc->tymed;
+
+    hres = IBindStatusCallback_RemoteOnDataAvailable_Proxy(This, grfBSCF, dwSize, &rem_formatetc, rem_stgmed);
+
+    heap_free(rem_stgmed);
+    return hres;
 }
 
 HRESULT __RPC_STUB IBindStatusCallback_OnDataAvailable_Stub(
         IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
         RemFORMATETC *pformatetc, RemSTGMEDIUM *pstgmed)
 {
-    FIXME("stub\n");
-    return E_NOTIMPL;
+    STGMEDIUM stgmed = { TYMED_NULL };
+    FORMATETC formatetc;
+    HRESULT hres;
+
+    TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
+
+    hres = unmarshal_stgmed(pstgmed, &stgmed);
+    if(FAILED(hres))
+        return hres;
+
+    formatetc.cfFormat = pformatetc->cfFormat;
+    formatetc.ptd = NULL;
+    formatetc.dwAspect = pformatetc->dwAspect;
+    formatetc.lindex = pformatetc->lindex;
+    formatetc.tymed = pformatetc->tymed;
+
+    hres = IBindStatusCallback_OnDataAvailable(This, grfBSCF, dwSize, &formatetc, &stgmed);
+
+    ReleaseStgMedium(&stgmed);
+    return hres;
 }
 
 HRESULT CALLBACK IBinding_GetBindResult_Proxy(IBinding* This,




More information about the wine-cvs mailing list