diff --git a/dlls/urlmon/ftp.c b/dlls/urlmon/ftp.c index f5e35064c90..4fa0924387d 100644 --- a/dlls/urlmon/ftp.c +++ b/dlls/urlmon/ftp.c @@ -36,14 +36,21 @@ typedef struct { #define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(FtpProtocol, base, iface) -static HRESULT FtpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags, +static HRESULT FtpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags, HINTERNET internet_session, IInternetBindInfo *bind_info) { FtpProtocol *This = ASYNCPROTOCOL_THIS(prot); + BSTR url; + HRESULT hres; + + hres = IUri_GetAbsoluteUri(uri, &url); + if(FAILED(hres)) + return hres; This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0, request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE, (DWORD_PTR)&This->base); + SysFreeString(url); if (!This->base.request && GetLastError() != ERROR_IO_PENDING) { WARN("InternetOpenUrl failed: %d\n", GetLastError()); return INET_E_RESOURCE_NOT_FOUND; @@ -145,6 +152,8 @@ static HRESULT WINAPI FtpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, DWORD grfPI, HANDLE_PTR dwReserved) { FtpProtocol *This = PROTOCOL_THIS(iface); + IUri *uri; + HRESULT hres; static const WCHAR ftpW[] = {'f','t','p',':'}; @@ -154,7 +163,14 @@ static HRESULT WINAPI FtpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, if(strncmpW(szUrl, ftpW, sizeof(ftpW)/sizeof(WCHAR))) return MK_E_SYNTAX; - return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink, pOIBindInfo); + hres = CreateUri(szUrl, 0, 0, &uri); + if(FAILED(hres)) + return hres; + + hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo); + + IUri_Release(uri); + return hres; } static HRESULT WINAPI FtpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) diff --git a/dlls/urlmon/gopher.c b/dlls/urlmon/gopher.c index 18e397285df..d8781ce7925 100644 --- a/dlls/urlmon/gopher.c +++ b/dlls/urlmon/gopher.c @@ -34,13 +34,20 @@ typedef struct { #define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(GopherProtocol, base, iface) -static HRESULT GopherProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags, +static HRESULT GopherProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags, HINTERNET internet_session, IInternetBindInfo *bind_info) { GopherProtocol *This = ASYNCPROTOCOL_THIS(prot); + BSTR url; + HRESULT hres; + + hres = IUri_GetAbsoluteUri(uri, &url); + if(FAILED(hres)) + return hres; This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0, request_flags, (DWORD_PTR)&This->base); + SysFreeString(url); if (!This->base.request && GetLastError() != ERROR_IO_PENDING) { WARN("InternetOpenUrl failed: %d\n", GetLastError()); return INET_E_RESOURCE_NOT_FOUND; @@ -125,11 +132,20 @@ static HRESULT WINAPI GopherProtocol_Start(IInternetProtocol *iface, LPCWSTR szU DWORD grfPI, HANDLE_PTR dwReserved) { GopherProtocol *This = PROTOCOL_THIS(iface); + IUri *uri; + HRESULT hres; TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); - return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink, pOIBindInfo); + hres = CreateUri(szUrl, 0, 0, &uri); + if(FAILED(hres)) + return hres; + + hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo); + + IUri_Release(uri); + return hres; } static HRESULT WINAPI GopherProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c index 04ca2326bd1..722ec501b4d 100644 --- a/dlls/urlmon/http.c +++ b/dlls/urlmon/http.c @@ -67,19 +67,18 @@ static LPWSTR query_http_info(HttpProtocol *This, DWORD option) #define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(HttpProtocol, base, iface) -static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags, +static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD request_flags, HINTERNET internet_session, IInternetBindInfo *bind_info) { HttpProtocol *This = ASYNCPROTOCOL_THIS(prot); LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL; IServiceProvider *service_provider = NULL; IHttpNegotiate2 *http_negotiate2 = NULL; - LPWSTR host, user, pass, path; + BSTR url, host, user, pass, path; LPOLESTR accept_mimes[257]; const WCHAR **accept_types; - URL_COMPONENTSW url_comp; BYTE security_id[512]; - DWORD len = 0; + DWORD len = 0, port; ULONG num; BOOL res, b; HRESULT hres; @@ -89,24 +88,28 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD requ {'P','O','S','T',0}, {'P','U','T',0}}; - memset(&url_comp, 0, sizeof(url_comp)); - url_comp.dwStructSize = sizeof(url_comp); - url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength = url_comp.dwExtraInfoLength = - url_comp.dwUserNameLength = url_comp.dwPasswordLength = 1; - if (!InternetCrackUrlW(url, 0, 0, &url_comp)) - return MK_E_SYNTAX; + hres = IUri_GetPort(uri, &port); + if(FAILED(hres)) + return hres; - if(!url_comp.nPort) - url_comp.nPort = This->https ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT; + hres = IUri_GetHost(uri, &host); + if(FAILED(hres)) + return hres; - host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength); - user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength); - pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength); - This->base.connection = InternetConnectW(internet_session, host, url_comp.nPort, user, pass, - INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base); - heap_free(pass); - heap_free(user); - heap_free(host); + hres = IUri_GetUserName(uri, &user); + if(SUCCEEDED(hres)) { + hres = IUri_GetPassword(uri, &pass); + + if(SUCCEEDED(hres)) { + This->base.connection = InternetConnectW(internet_session, host, port, user, pass, + INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base); + SysFreeString(pass); + } + SysFreeString(user); + } + SysFreeString(host); + if(FAILED(hres)) + return hres; if(!This->base.connection) { WARN("InternetConnect failed: %d\n", GetLastError()); return INET_E_CANNOT_CONNECT; @@ -128,21 +131,21 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD requ } accept_mimes[num] = 0; - path = heap_alloc((url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength+1)*sizeof(WCHAR)); - if(url_comp.dwUrlPathLength) - memcpy(path, url_comp.lpszUrlPath, url_comp.dwUrlPathLength*sizeof(WCHAR)); - if(url_comp.dwExtraInfoLength) - memcpy(path+url_comp.dwUrlPathLength, url_comp.lpszExtraInfo, url_comp.dwExtraInfoLength*sizeof(WCHAR)); - path[url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength] = 0; if(This->https) request_flags |= INTERNET_FLAG_SECURE; - This->base.request = HttpOpenRequestW(This->base.connection, - This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM - ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb, - path, NULL, NULL, accept_types, request_flags, (DWORD_PTR)&This->base); - heap_free(path); + + hres = IUri_GetPathAndQuery(uri, &path); + if(SUCCEEDED(hres)) { + This->base.request = HttpOpenRequestW(This->base.connection, + This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM + ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb, + path, NULL, NULL, accept_types, request_flags, (DWORD_PTR)&This->base); + SysFreeString(path); + } while(num--) CoTaskMemFree(accept_mimes[num]); + if(FAILED(hres)) + return hres; if (!This->base.request) { WARN("HttpOpenRequest failed: %d\n", GetLastError()); return INET_E_RESOURCE_NOT_FOUND; @@ -162,8 +165,15 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD requ return hres; } + hres = IUri_GetAbsoluteUri(uri, &url); + if(FAILED(hres)) { + IServiceProvider_Release(service_provider); + return hres; + } + hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, wszHeaders, 0, &addl_header); + SysFreeString(url); if(hres != S_OK) { WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres); IServiceProvider_Release(service_provider); @@ -391,6 +401,8 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl DWORD grfPI, HANDLE_PTR dwReserved) { HttpProtocol *This = PROTOCOL_THIS(iface); + IUri *uri; + HRESULT hres; static const WCHAR httpW[] = {'h','t','t','p',':'}; static const WCHAR httpsW[] = {'h','t','t','p','s',':'}; @@ -403,7 +415,14 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl : strncmpW(szUrl, httpW, sizeof(httpW)/sizeof(WCHAR))) return MK_E_SYNTAX; - return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink, pOIBindInfo); + hres = CreateUri(szUrl, 0, 0, &uri); + if(FAILED(hres)) + return hres; + + hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo); + + IUri_Release(uri); + return hres; } static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) diff --git a/dlls/urlmon/protocol.c b/dlls/urlmon/protocol.c index 3f3cbe505bc..b423c67354f 100644 --- a/dlls/urlmon/protocol.c +++ b/dlls/urlmon/protocol.c @@ -234,7 +234,7 @@ HINTERNET get_internet_session(IInternetBindInfo *bind_info) return internet_session; } -HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url, +HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, IUri *uri, IInternetProtocolSink *protocol_sink, IInternetBindInfo *bind_info) { DWORD request_flags; @@ -265,7 +265,7 @@ HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url, if(protocol->bindf & BINDF_NEEDFILE) request_flags |= INTERNET_FLAG_NEED_FILE; - hres = protocol->vtbl->open_request(protocol, url, request_flags, internet_session, bind_info); + hres = protocol->vtbl->open_request(protocol, uri, request_flags, internet_session, bind_info); if(FAILED(hres)) { protocol_close_connection(protocol); return report_result(protocol, hres); diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 071af8dd73e..e6bc5943930 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -105,12 +105,12 @@ typedef struct { } Protocol; struct ProtocolVtbl { - HRESULT (*open_request)(Protocol*,LPCWSTR,DWORD,HINTERNET,IInternetBindInfo*); + HRESULT (*open_request)(Protocol*,IUri*,DWORD,HINTERNET,IInternetBindInfo*); HRESULT (*start_downloading)(Protocol*); void (*close_connection)(Protocol*); }; -HRESULT protocol_start(Protocol*,IInternetProtocol*,LPCWSTR,IInternetProtocolSink*,IInternetBindInfo*); +HRESULT protocol_start(Protocol*,IInternetProtocol*,IUri*,IInternetProtocolSink*,IInternetBindInfo*); HRESULT protocol_continue(Protocol*,PROTOCOLDATA*); HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*); HRESULT protocol_lock_request(Protocol*);