Signed-off-by: Dmitry Timoshkov dmitry@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); }