Jacek Caban : urlmon: Use a copy of PROTOCOLDATA in Switch/ Continue implementation.

Alexandre Julliard julliard at winehq.org
Fri Jun 5 08:56:52 CDT 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Jun  4 22:50:23 2009 +0200

urlmon: Use a copy of PROTOCOLDATA in Switch/Continue implementation.

---

 dlls/urlmon/bindprot.c       |   22 ++++++++++++++++------
 dlls/urlmon/tests/protocol.c |    8 ++++++++
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/dlls/urlmon/bindprot.c b/dlls/urlmon/bindprot.c
index f63824b..aef8c23 100644
--- a/dlls/urlmon/bindprot.c
+++ b/dlls/urlmon/bindprot.c
@@ -608,10 +608,14 @@ static HRESULT WINAPI ProtocolHandler_Start(IInternetProtocol *iface, LPCWSTR sz
 static HRESULT WINAPI ProtocolHandler_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
 {
     BindProtocol *This = PROTOCOLHANDLER_THIS(iface);
+    HRESULT hres;
 
     TRACE("(%p)->(%p)\n", This, pProtocolData);
 
-    return IInternetProtocol_Continue(This->protocol, pProtocolData);
+    hres = IInternetProtocol_Continue(This->protocol, pProtocolData);
+
+    heap_free(pProtocolData);
+    return hres;
 }
 
 static HRESULT WINAPI ProtocolHandler_Abort(IInternetProtocol *iface, HRESULT hrReason,
@@ -874,14 +878,14 @@ static ULONG WINAPI BPInternetProtocolSink_Release(IInternetProtocolSink *iface)
 
 typedef struct {
     task_header_t header;
-    PROTOCOLDATA data;
+    PROTOCOLDATA *data;
 } switch_task_t;
 
 static void switch_proc(BindProtocol *bind, task_header_t *t)
 {
     switch_task_t *task = (switch_task_t*)t;
 
-    IInternetProtocol_Continue(bind->protocol_handler, &task->data);
+    IInternetProtocol_Continue(bind->protocol_handler, task->data);
 
     heap_free(task);
 }
@@ -890,12 +894,18 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface
         PROTOCOLDATA *pProtocolData)
 {
     BindProtocol *This = PROTSINK_THIS(iface);
+    PROTOCOLDATA *data;
 
     TRACE("(%p)->(%p)\n", This, pProtocolData);
 
     TRACE("flags %x state %x data %p cb %u\n", pProtocolData->grfFlags, pProtocolData->dwState,
           pProtocolData->pData, pProtocolData->cbData);
 
+    data = heap_alloc(sizeof(PROTOCOLDATA));
+    if(!data)
+        return E_OUTOFMEMORY;
+    memcpy(data, pProtocolData, sizeof(PROTOCOLDATA));
+
     if(!do_direct_notif(This)) {
         switch_task_t *task;
 
@@ -903,18 +913,18 @@ static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface
         if(!task)
             return E_OUTOFMEMORY;
 
-        task->data = *pProtocolData;
+        task->data = data;
 
         push_task(This, &task->header, switch_proc);
         return S_OK;
     }
 
     if(!This->protocol_sink) {
-        IInternetProtocol_Continue(This->protocol_handler, pProtocolData);
+        IInternetProtocol_Continue(This->protocol_handler, data);
         return S_OK;
     }
 
-    return IInternetProtocolSink_Switch(This->protocol_sink, pProtocolData);
+    return IInternetProtocolSink_Switch(This->protocol_sink, data);
 }
 
 static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text)
diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c
index e8aa8f9..50820e8 100644
--- a/dlls/urlmon/tests/protocol.c
+++ b/dlls/urlmon/tests/protocol.c
@@ -436,6 +436,10 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
         CHECK_EXPECT(Switch);
 
     ok(pProtocolData != NULL, "pProtocolData == NULL\n");
+    if(binding_test) {
+        ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
+        ok(!memcmp(pProtocolData, &protocoldata, sizeof(PROTOCOLDATA)), "*pProtocolData != protocoldata\n");
+    }
 
     pdata = pProtocolData;
 
@@ -1321,6 +1325,10 @@ static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocol *iface,
     ok(pProtocolData != NULL, "pProtocolData == NULL\n");
     if(!pProtocolData || tested_protocol == BIND_TEST)
         return S_OK;
+    if(binding_test) {
+        ok(pProtocolData != &protocoldata, "pProtocolData == &protocoldata\n");
+        ok(!memcmp(pProtocolData, &protocoldata, sizeof(PROTOCOLDATA)), "*pProtocolData != protocoldata\n");
+    }
 
     switch(prot_state) {
     case 1: {




More information about the wine-cvs mailing list