Gabriel Ivăncescu : mshtml: Inform Gecko of progress done via OnProgress.

Alexandre Julliard julliard at winehq.org
Tue Jul 26 15:35:16 CDT 2022


Module: wine
Branch: master
Commit: 434c6e2d325d05f5a69f597df0ed4df7034a5ba3
URL:    https://gitlab.winehq.org/wine/wine/-/commit/434c6e2d325d05f5a69f597df0ed4df7034a5ba3

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Mon Jul 25 21:54:04 2022 +0300

mshtml: Inform Gecko of progress done via OnProgress.

Currently we don't support 64-bit progress values (BINDSTATUS_64BIT_PROGRESS
is not implemented in wine), so this is limited to 4 GB.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>

---

 dlls/mshtml/binding.h    |  4 ++-
 dlls/mshtml/navigate.c   | 68 ++++++++++++++++++++++++++++++++++++------------
 dlls/mshtml/nsiface.idl  | 11 ++++++++
 dlls/mshtml/script.c     |  2 +-
 dlls/mshtml/tests/xhr.js |  2 --
 5 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h
index 9a043864927..5d2915a836b 100644
--- a/dlls/mshtml/binding.h
+++ b/dlls/mshtml/binding.h
@@ -104,6 +104,8 @@ struct nsChannelBSC {
     nsChannel *nschannel;
     nsIStreamListener *nslistener;
     nsISupports *nscontext;
+    ULONG progress;
+    ULONG total;
     BOOL is_js;
     BOOL is_doc_channel;
     BOOL response_processed;
@@ -117,7 +119,7 @@ struct BSCallbackVtbl {
     HRESULT (*start_binding)(BSCallback*);
     HRESULT (*stop_binding)(BSCallback*,HRESULT);
     HRESULT (*read_data)(BSCallback*,IStream*);
-    HRESULT (*on_progress)(BSCallback*,ULONG,LPCWSTR);
+    HRESULT (*on_progress)(BSCallback*,ULONG,ULONG,ULONG,LPCWSTR);
     HRESULT (*on_response)(BSCallback*,DWORD,LPCWSTR);
     HRESULT (*beginning_transaction)(BSCallback*,WCHAR**);
 };
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c
index 6f684630cd6..ef764bde58c 100644
--- a/dlls/mshtml/navigate.c
+++ b/dlls/mshtml/navigate.c
@@ -326,7 +326,7 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
     TRACE("%p)->(%lu %lu %lu %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
             debugstr_w(szStatusText));
 
-    return This->vtbl->on_progress(This, ulStatusCode, szStatusText);
+    return This->vtbl->on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText);
 }
 
 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
@@ -1067,6 +1067,37 @@ static void on_stop_nsrequest(nsChannelBSC *This, HRESULT result)
     }
 }
 
+static void notify_progress(nsChannelBSC *This)
+{
+    nsChannel *nschannel = This->nschannel;
+    nsIProgressEventSink *sink = NULL;
+    nsresult nsres;
+
+    if(!nschannel)
+        return;
+
+    if(nschannel->notif_callback)
+        if(NS_FAILED(nsIInterfaceRequestor_GetInterface(nschannel->notif_callback, &IID_nsIProgressEventSink, (void**)&sink)))
+            sink = NULL;
+
+    if(!sink && nschannel->load_group) {
+        nsIRequestObserver *req_observer;
+
+        if(NS_SUCCEEDED(nsILoadGroup_GetGroupObserver(nschannel->load_group, &req_observer)) && req_observer) {
+            nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIProgressEventSink, (void**)&sink);
+            nsIRequestObserver_Release(req_observer);
+            if(NS_FAILED(nsres))
+                sink = NULL;
+        }
+    }
+
+    if(sink) {
+        nsIProgressEventSink_OnProgress(sink, (nsIRequest*)&nschannel->nsIHttpChannel_iface, This->nscontext,
+                                        This->progress, (This->total == ~0) ? -1 : This->total);
+        nsIProgressEventSink_Release(sink);
+    }
+}
+
 static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
 {
     DWORD read;
@@ -1147,6 +1178,8 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
                 return hres;
         }
 
+        notify_progress(This);
+
         nsres = nsIStreamListener_OnDataAvailable(This->nslistener,
                 (nsIRequest*)&This->nschannel->nsIHttpChannel_iface, This->nscontext,
                 &This->nsstream->nsIInputStream_iface, This->bsc.read-This->nsstream->buf_size,
@@ -1656,7 +1689,7 @@ static void handle_extern_mime_navigation(nsChannelBSC *This)
     IUri_Release(uri);
 }
 
-static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text)
+static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text)
 {
     nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
 
@@ -1684,21 +1717,24 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW
         DWORD status, size = sizeof(DWORD);
         HRESULT hres;
 
-        if(!This->bsc.binding)
-            break;
-
-        hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&http_info);
-        if(FAILED(hres))
-            break;
-
-        hres = IWinInetHttpInfo_QueryInfo(http_info,
-                HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL);
-        IWinInetHttpInfo_Release(http_info);
-        if(FAILED(hres) || status == HTTP_STATUS_OK)
-            break;
-
-        handle_navigation_error(This, status);
+        if(This->bsc.binding) {
+            hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&http_info);
+            if(SUCCEEDED(hres)) {
+                hres = IWinInetHttpInfo_QueryInfo(http_info,
+                        HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL);
+                IWinInetHttpInfo_Release(http_info);
+                if(SUCCEEDED(hres) && status != HTTP_STATUS_OK)
+                    handle_navigation_error(This, status);
+            }
+        }
+        /* fall through */
     }
+    case BINDSTATUS_DOWNLOADINGDATA:
+    case BINDSTATUS_ENDDOWNLOADDATA:
+        /* Defer it to just before calling OnDataAvailable, otherwise it can have wrong state */
+        This->progress = progress;
+        This->total = total;
+        break;
     }
 
     return S_OK;
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index c4b479b16e3..f6e0a909278 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -771,6 +771,17 @@ interface nsIChannelEventSink : nsISupports
                                     nsIAsyncVerifyRedirectCallback *callback);
 }
 
+[
+    object,
+    uuid(87d55fba-cb7e-4f38-84c1-5c6c2b2a55e9),
+    local
+]
+interface nsIProgressEventSink : nsISupports
+{
+    nsresult OnProgress(nsIRequest *aRequest, nsISupports *aContext, int64_t aProgress, int64_t aProgressMax);
+    nsresult OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult aStatus, const char16_t *aStatusArg);
+}
+
 [
     object,
     uuid(79de76e5-994e-4f6b-81aa-42d9adb6e67e),
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c
index e49449a61f8..769ca72db6f 100644
--- a/dlls/mshtml/script.c
+++ b/dlls/mshtml/script.c
@@ -1053,7 +1053,7 @@ static HRESULT ScriptBSC_read_data(BSCallback *bsc, IStream *stream)
     return S_OK;
 }
 
-static HRESULT ScriptBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text)
+static HRESULT ScriptBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text)
 {
     return S_OK;
 }
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js
index cc8a03dadb4..dd3750632c7 100644
--- a/dlls/mshtml/tests/xhr.js
+++ b/dlls/mshtml/tests/xhr.js
@@ -59,9 +59,7 @@ function test_xhr() {
             for(var i = 0; i < props.length; i++)
                 ok(props[i] in e, props[i] + " not available in loadend");
             ok(e.lengthComputable === true, "lengthComputable in loadend = " + e.lengthComputable);
-            todo_wine.
             ok(e.loaded === xml.length, "loaded in loadend = " + e.loaded);
-            todo_wine.
             ok(e.total === xml.length, "total in loadend = " + e.total);
             next_test();
         };




More information about the wine-cvs mailing list