Commit 72c8b283 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

urlmon: Added IInternetProtocolEx support to http protocol handler.

parent 8205f627
......@@ -20,6 +20,9 @@
#include "urlmon_main.h"
#include "wininet.h"
#define NO_SHLWAPI_REG
#include "shlwapi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
......@@ -27,7 +30,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct {
Protocol base;
const IInternetProtocolVtbl *lpIInternetProtocolVtbl;
const IInternetProtocolExVtbl *lpIInternetProtocolExVtbl;
const IInternetPriorityVtbl *lpInternetPriorityVtbl;
const IWinInetHttpInfoVtbl *lpWinInetHttpInfoVtbl;
......@@ -38,6 +41,7 @@ typedef struct {
LONG ref;
} HttpProtocol;
#define PROTOCOLEX(x) ((IInternetProtocolEx*)&(x)->lpIInternetProtocolExVtbl)
#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
#define INETHTTPINFO(x) ((IWinInetHttpInfo*) &(x)->lpWinInetHttpInfoVtbl)
......@@ -371,22 +375,25 @@ static const ProtocolVtbl AsyncProtocolVtbl = {
HttpProtocol_close_connection
};
#define PROTOCOL_THIS(iface) DEFINE_THIS(HttpProtocol, IInternetProtocol, iface)
#define PROTOCOL_THIS(iface) DEFINE_THIS(HttpProtocol, IInternetProtocolEx, iface)
static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
*ppv = NULL;
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = PROTOCOL(This);
*ppv = PROTOCOLEX(This);
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
*ppv = PROTOCOL(This);
*ppv = PROTOCOLEX(This);
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
*ppv = PROTOCOL(This);
*ppv = PROTOCOLEX(This);
}else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) {
TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv);
*ppv = PROTOCOLEX(This);
}else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
*ppv = PRIORITY(This);
......@@ -407,7 +414,7 @@ static HRESULT WINAPI HttpProtocol_QueryInterface(IInternetProtocol *iface, REFI
return E_NOINTERFACE;
}
static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocol *iface)
static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocolEx *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
LONG ref = InterlockedIncrement(&This->ref);
......@@ -415,7 +422,7 @@ static ULONG WINAPI HttpProtocol_AddRef(IInternetProtocol *iface)
return ref;
}
static ULONG WINAPI HttpProtocol_Release(IInternetProtocol *iface)
static ULONG WINAPI HttpProtocol_Release(IInternetProtocolEx *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
LONG ref = InterlockedDecrement(&This->ref);
......@@ -432,7 +439,7 @@ static ULONG WINAPI HttpProtocol_Release(IInternetProtocol *iface)
return ref;
}
static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
static HRESULT WINAPI HttpProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl,
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE_PTR dwReserved)
{
......@@ -440,28 +447,21 @@ static HRESULT WINAPI HttpProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
IUri *uri;
HRESULT hres;
static const WCHAR httpW[] = {'h','t','t','p',':'};
static const WCHAR httpsW[] = {'h','t','t','p','s',':'};
TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink,
pOIBindInfo, grfPI, dwReserved);
if(This->https
? strncmpW(szUrl, httpsW, sizeof(httpsW)/sizeof(WCHAR))
: strncmpW(szUrl, httpW, sizeof(httpW)/sizeof(WCHAR)))
return MK_E_SYNTAX;
hres = CreateUri(szUrl, 0, 0, &uri);
if(FAILED(hres))
return hres;
hres = protocol_start(&This->base, PROTOCOL(This), uri, pOIProtSink, pOIBindInfo);
hres = IInternetProtocolEx_StartEx(PROTOCOLEX(This), uri, pOIProtSink, pOIBindInfo,
grfPI, (HANDLE*)dwReserved);
IUri_Release(uri);
return hres;
}
static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -470,7 +470,7 @@ static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDA
return protocol_continue(&This->base, pProtocolData);
}
static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason,
DWORD dwOptions)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -480,7 +480,7 @@ static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocol *iface, HRESULT hrRea
return protocol_abort(&This->base, hrReason);
}
static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -490,21 +490,21 @@ static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocol *iface, DWORD dwO
return S_OK;
}
static HRESULT WINAPI HttpProtocol_Suspend(IInternetProtocol *iface)
static HRESULT WINAPI HttpProtocol_Suspend(IInternetProtocolEx *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_Resume(IInternetProtocol *iface)
static HRESULT WINAPI HttpProtocol_Resume(IInternetProtocolEx *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
FIXME("(%p)\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_Read(IInternetProtocol *iface, void *pv,
static HRESULT WINAPI HttpProtocol_Read(IInternetProtocolEx *iface, void *pv,
ULONG cb, ULONG *pcbRead)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -514,7 +514,7 @@ static HRESULT WINAPI HttpProtocol_Read(IInternetProtocol *iface, void *pv,
return protocol_read(&This->base, pv, cb, pcbRead);
}
static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove,
DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -522,7 +522,7 @@ static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER
return E_NOTIMPL;
}
static HRESULT WINAPI HttpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
static HRESULT WINAPI HttpProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -531,7 +531,7 @@ static HRESULT WINAPI HttpProtocol_LockRequest(IInternetProtocol *iface, DWORD d
return protocol_lock_request(&This->base);
}
static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocol *iface)
static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocolEx *iface)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
......@@ -540,9 +540,29 @@ static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocol *iface)
return protocol_unlock_request(&This->base);
}
static HRESULT WINAPI HttpProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE *dwReserved)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
DWORD scheme = 0;
HRESULT hres;
TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink,
pOIBindInfo, grfPI, dwReserved);
hres = IUri_GetScheme(pUri, &scheme);
if(FAILED(hres))
return hres;
if(scheme != (This->https ? URL_SCHEME_HTTPS : URL_SCHEME_HTTP))
return MK_E_SYNTAX;
return protocol_start(&This->base, (IInternetProtocol*)PROTOCOLEX(This), pUri, pOIProtSink, pOIBindInfo);
}
#undef PROTOCOL_THIS
static const IInternetProtocolVtbl HttpProtocolVtbl = {
static const IInternetProtocolExVtbl HttpProtocolVtbl = {
HttpProtocol_QueryInterface,
HttpProtocol_AddRef,
HttpProtocol_Release,
......@@ -555,7 +575,8 @@ static const IInternetProtocolVtbl HttpProtocolVtbl = {
HttpProtocol_Read,
HttpProtocol_Seek,
HttpProtocol_LockRequest,
HttpProtocol_UnlockRequest
HttpProtocol_UnlockRequest,
HttpProtocol_StartEx
};
#define PRIORITY_THIS(iface) DEFINE_THIS(HttpProtocol, InternetPriority, iface)
......@@ -563,19 +584,19 @@ static const IInternetProtocolVtbl HttpProtocolVtbl = {
static HRESULT WINAPI HttpPriority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
{
HttpProtocol *This = PRIORITY_THIS(iface);
return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
}
static ULONG WINAPI HttpPriority_AddRef(IInternetPriority *iface)
{
HttpProtocol *This = PRIORITY_THIS(iface);
return IInternetProtocol_AddRef(PROTOCOL(This));
return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
}
static ULONG WINAPI HttpPriority_Release(IInternetPriority *iface)
{
HttpProtocol *This = PRIORITY_THIS(iface);
return IInternetProtocol_Release(PROTOCOL(This));
return IInternetProtocolEx_Release(PROTOCOLEX(This));
}
static HRESULT WINAPI HttpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
......@@ -613,19 +634,19 @@ static const IInternetPriorityVtbl HttpPriorityVtbl = {
static HRESULT WINAPI HttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv)
{
HttpProtocol *This = INETINFO_THIS(iface);
return IBinding_QueryInterface(PROTOCOL(This), riid, ppv);
return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This), riid, ppv);
}
static ULONG WINAPI HttpInfo_AddRef(IWinInetHttpInfo *iface)
{
HttpProtocol *This = INETINFO_THIS(iface);
return IBinding_AddRef(PROTOCOL(This));
return IInternetProtocolEx_AddRef(PROTOCOLEX(This));
}
static ULONG WINAPI HttpInfo_Release(IWinInetHttpInfo *iface)
{
HttpProtocol *This = INETINFO_THIS(iface);
return IBinding_Release(PROTOCOL(This));
return IInternetProtocolEx_Release(PROTOCOLEX(This));
}
static HRESULT WINAPI HttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption,
......@@ -663,14 +684,14 @@ static HRESULT create_http_protocol(BOOL https, void **ppobj)
return E_OUTOFMEMORY;
ret->base.vtbl = &AsyncProtocolVtbl;
ret->lpIInternetProtocolVtbl = &HttpProtocolVtbl;
ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;
ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl;
ret->lpIInternetProtocolExVtbl = &HttpProtocolVtbl;
ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;
ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl;
ret->https = https;
ret->ref = 1;
*ppobj = PROTOCOL(ret);
*ppobj = PROTOCOLEX(ret);
URLMON_LockModule();
return S_OK;
......
......@@ -2149,6 +2149,7 @@ static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl };
#define TEST_REDIRECT 0x0080
#define TEST_ABORT 0x0100
#define TEST_ASYNCREQ 0x0200
#define TEST_USEIURI 0x0400
static void init_test(int prot, DWORD flags)
{
......@@ -2565,11 +2566,17 @@ static void test_file_protocol(void) {
test_file_protocol_fail();
}
static BOOL http_protocol_start(LPCWSTR url)
static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri)
{
static BOOL got_user_agent = FALSE;
IUri *uri = NULL;
HRESULT hres;
if(use_iuri && pCreateUri) {
hres = pCreateUri(url, 0, 0, &uri);
ok(hres == S_OK, "CreateUri failed: %08x\n", hres);
}
SET_EXPECT(GetBindInfo);
if (!(bindf & BINDF_FROMURLMON))
SET_EXPECT(ReportProgress_DIRECTBIND);
......@@ -2585,8 +2592,21 @@ static BOOL http_protocol_start(LPCWSTR url)
SET_EXPECT(Stream_Seek);
}
hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
ok(hres == S_OK, "Start failed: %08x\n", hres);
if(uri) {
IInternetProtocolEx *protocolex;
hres = IInternetProtocol_QueryInterface(async_protocol, &IID_IInternetProtocolEx, (void**)&protocolex);
ok(hres == S_OK, "Could not get IInternetProtocolEx iface: %08x\n", hres);
hres = IInternetProtocolEx_StartEx(protocolex, uri, &protocol_sink, &bind_info, 0, 0);
ok(hres == S_OK, "Start failed: %08x\n", hres);
IInternetProtocolEx_Release(protocolex);
IUri_Release(uri);
}else {
hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
ok(hres == S_OK, "Start failed: %08x\n", hres);
}
if(FAILED(hres))
return FALSE;
......@@ -2714,7 +2734,7 @@ static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tym
SET_EXPECT(Switch);
}
if(!http_protocol_start(url))
if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0))
return;
if(!direct_read && !test_abort)
......@@ -2837,7 +2857,7 @@ static void test_http_protocol(void)
trace("Testing http protocol (direct read)...\n");
bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
test_http_protocol_url(winehq_url, HTTP_TEST, TEST_DIRECT_READ, TYMED_NULL);
test_http_protocol_url(winehq_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL);
trace("Testing http protocol (redirected)...\n");
bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON;
......@@ -3376,6 +3396,9 @@ START_TEST(protocol)
return;
}
if(!pCreateUri)
win_skip("CreateUri not supported\n");
OleInitialize(NULL);
event_complete = CreateEvent(NULL, FALSE, FALSE, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment