[PATCH 2/4] urlmon: Handle HTTP_STATUS_DENIED error.

Dmitry Timoshkov dmitry at baikal.ru
Tue Jun 22 09:54:31 CDT 2021


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/urlmon/http.c     | 64 +++++++++++++++++++++++++++++++-----------
 dlls/urlmon/protocol.c | 16 +++++++++++
 2 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c
index bee226bd474..d001278c794 100644
--- a/dlls/urlmon/http.c
+++ b/dlls/urlmon/http.c
@@ -128,7 +128,7 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
     IHttpSecurity *http_security;
     BOOL security_problem;
     DWORD dlg_flags;
-    HWND hwnd;
+    HWND hwnd = 0;
     DWORD res;
     HRESULT hres;
 
@@ -160,6 +160,36 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
         return E_ABORT;
     }
 
+    if(error == HTTP_STATUS_DENIED || error == ERROR_ACCESS_DENIED) {
+        IAuthenticate *auth;
+
+        hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
+                                             (void**)&auth);
+        if(SUCCEEDED(hres)) {
+            LPWSTR user = NULL, pass = NULL;
+
+            hres = IAuthenticate_Authenticate(auth, &hwnd, &user, &pass);
+            IAuthenticate_Release(auth);
+
+            if(FAILED(hres)) {
+                IServiceProvider_Release(serv_prov);
+                return E_ACCESSDENIED;
+            }
+
+            if(!hwnd) {
+                InternetSetOptionW(This->base.request, INTERNET_OPTION_USERNAME, user, 0);
+                InternetSetOptionW(This->base.request, INTERNET_OPTION_PASSWORD, pass, 0);
+                CoTaskMemFree(user);
+                CoTaskMemFree(pass);
+                IServiceProvider_Release(serv_prov);
+                return user ? RPC_E_RETRY : E_ACCESSDENIED;
+            }
+        }
+
+        error = ERROR_SUCCESS;
+        /* fall through to InternetErrorDlg */
+    }
+
     if(security_problem) {
         hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpSecurity, &IID_IHttpSecurity,
                                              (void**)&http_security);
@@ -210,24 +240,26 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
         }
         /* fallthrough */
     default:
-        hres = IServiceProvider_QueryService(serv_prov, &IID_IWindowForBindingUI, &IID_IWindowForBindingUI, (void**)&wfb_ui);
-        if(SUCCEEDED(hres)) {
-            const IID *iid_reason;
-
-            if(security_problem)
-                iid_reason = &IID_IHttpSecurity;
-            else if(error == ERROR_INTERNET_INCORRECT_PASSWORD)
-                iid_reason = &IID_IAuthenticate;
-            else
-                iid_reason = &IID_IWindowForBindingUI;
+        if(!hwnd) {
+            hres = IServiceProvider_QueryService(serv_prov, &IID_IWindowForBindingUI, &IID_IWindowForBindingUI, (void**)&wfb_ui);
+            if(SUCCEEDED(hres)) {
+                const IID *iid_reason;
+
+                if(security_problem)
+                    iid_reason = &IID_IHttpSecurity;
+                else if(error == ERROR_INTERNET_INCORRECT_PASSWORD)
+                    iid_reason = &IID_IAuthenticate;
+                else
+                    iid_reason = &IID_IWindowForBindingUI;
+
+                hres = IWindowForBindingUI_GetWindow(wfb_ui, iid_reason, &hwnd);
+                IWindowForBindingUI_Release(wfb_ui);
+            }
 
-            hres = IWindowForBindingUI_GetWindow(wfb_ui, iid_reason, &hwnd);
-            IWindowForBindingUI_Release(wfb_ui);
+            if(FAILED(hres)) hwnd = NULL;
         }
 
-        if(FAILED(hres)) hwnd = NULL;
-
-        dlg_flags = FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA;
+        dlg_flags = FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FILTER_FOR_ERRORS;
         if(This->base.bindf & BINDF_NO_UI)
             dlg_flags |= FLAGS_ERROR_UI_FLAGS_NO_UI;
 
diff --git a/dlls/urlmon/protocol.c b/dlls/urlmon/protocol.c
index 2acffdc1ffe..4825eac82cc 100644
--- a/dlls/urlmon/protocol.c
+++ b/dlls/urlmon/protocol.c
@@ -220,6 +220,22 @@ static void WINAPI internet_status_callback(HINTERNET internet, DWORD_PTR contex
         IInternetProtocol_Release(protocol->protocol);
         break;
 
+    case INTERNET_STATUS_RESPONSE_RECEIVED:
+    {
+        DWORD status, size;
+
+        TRACE("%p INTERNET_STATUS_RESPONSE_RECEIVED (%u bytes)\n", protocol, *(const DWORD *)status_info);
+
+        size = sizeof(status);
+        if (HttpQueryInfoW(protocol->request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, 0))
+        {
+            TRACE("request status: %u\n", status);
+            if (status == HTTP_STATUS_DENIED) /* FIXME: other errors */
+                protocol->flags |= FLAG_ERROR;
+        }
+        break;
+    }
+
     default:
         WARN("Unhandled Internet status callback %d\n", internet_status);
     }
-- 
2.31.1




More information about the wine-devel mailing list