From 67d2fdc34a894c9d48b21a6ea3c72fb3612b93da Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sun, 29 Mar 2009 21:31:15 +0200 Subject: [PATCH] urlmon: Added IWinInetHttpInfo support to Binding object. --- dlls/urlmon/binding.c | 74 +++++++++++++++++++++++++++++++++++++++ dlls/urlmon/bindprot.c | 16 ++++++++- dlls/urlmon/session.c | 6 +++- dlls/urlmon/tests/url.c | 18 ++++++++++ dlls/urlmon/urlmon_main.h | 5 +-- 5 files changed, 115 insertions(+), 4 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index fb30367954a..28d0802174b 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -80,6 +80,7 @@ struct Binding { const IBindingVtbl *lpBindingVtbl; const IInternetProtocolSinkVtbl *lpInternetProtocolSinkVtbl; const IInternetBindInfoVtbl *lpInternetBindInfoVtbl; + const IWinInetHttpInfoVtbl *lpWinInetHttpInfoVtbl; const IServiceProviderVtbl *lpServiceProviderVtbl; LONG ref; @@ -117,6 +118,7 @@ struct Binding { #define BINDING(x) ((IBinding*) &(x)->lpBindingVtbl) #define PROTSINK(x) ((IInternetProtocolSink*) &(x)->lpInternetProtocolSinkVtbl) #define BINDINF(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl) +#define INETINFO(x) ((IWinInetHttpInfo*) &(x)->lpWinInetHttpInfoVtbl) #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) #define STREAM(x) ((IStream*) &(x)->lpStreamVtbl) @@ -901,6 +903,31 @@ static HRESULT WINAPI Binding_QueryInterface(IBinding *iface, REFIID riid, void }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); *ppv = SERVPROV(This); + }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) { + TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv); + + /* NOTE: This violidates COM rules, but tests prove that we should do it */ + if(!get_wininet_info(This->protocol)) + return E_NOINTERFACE; + + *ppv = INETINFO(This); + }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { + IWinInetHttpInfo *http_info; + IWinInetInfo *info; + HRESULT hres; + + TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); + + info = get_wininet_info(This->protocol); + if(!info) + return E_NOINTERFACE; + + hres = IWinInetInfo_QueryInterface(info, &IID_IWinInetHttpInfo, (void**)&http_info); + if(FAILED(hres)) + return E_NOINTERFACE; + + IWinInetHttpInfo_Release(http_info); + *ppv = INETINFO(This); } if(*ppv) { @@ -1448,6 +1475,52 @@ static const IInternetBindInfoVtbl InternetBindInfoVtbl = { InternetBindInfo_GetBindString }; +#define INETINFO_THIS(iface) DEFINE_THIS(Binding, WinInetHttpInfo, iface) + +static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv) +{ + Binding *This = INETINFO_THIS(iface); + return IBinding_QueryInterface(BINDING(This), riid, ppv); +} + +static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface) +{ + Binding *This = INETINFO_THIS(iface); + return IBinding_AddRef(BINDING(This)); +} + +static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface) +{ + Binding *This = INETINFO_THIS(iface); + return IBinding_Release(BINDING(This)); +} + +static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption, + void *pBuffer, DWORD *pcbBuffer) +{ + Binding *This = INETINFO_THIS(iface); + FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer); + return E_NOTIMPL; +} + +static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption, + void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved) +{ + Binding *This = INETINFO_THIS(iface); + FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved); + return E_NOTIMPL; +} + +#undef INETINFO_THIS + +static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = { + WinInetHttpInfo_QueryInterface, + WinInetHttpInfo_AddRef, + WinInetHttpInfo_Release, + WinInetHttpInfo_QueryOption, + WinInetHttpInfo_QueryInfo +}; + #define SERVPROV_THIS(iface) DEFINE_THIS(Binding, ServiceProvider, iface) static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, @@ -1559,6 +1632,7 @@ static HRESULT Binding_Create(IMoniker *mon, Binding *binding_ctx, LPCWSTR url, ret->lpBindingVtbl = &BindingVtbl; ret->lpInternetProtocolSinkVtbl = &InternetProtocolSinkVtbl; ret->lpInternetBindInfoVtbl = &InternetBindInfoVtbl; + ret->lpWinInetHttpInfoVtbl = &WinInetHttpInfoVtbl; ret->lpServiceProviderVtbl = &ServiceProviderVtbl; ret->ref = 1; diff --git a/dlls/urlmon/bindprot.c b/dlls/urlmon/bindprot.c index 07f2722bf7c..ea2ee7c95cd 100644 --- a/dlls/urlmon/bindprot.c +++ b/dlls/urlmon/bindprot.c @@ -34,6 +34,7 @@ typedef struct { IInternetBindInfo *bind_info; IInternetProtocolSink *protocol_sink; IServiceProvider *service_provider; + IWinInetInfo *wininet_info; LONG priority; @@ -104,6 +105,8 @@ static ULONG WINAPI BindProtocol_Release(IInternetProtocol *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + if(This->wininet_info) + IWinInetInfo_Release(This->wininet_info); if(This->protocol) IInternetProtocol_Release(This->protocol); if(This->bind_info) @@ -126,6 +129,7 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl IInternetProtocol *protocol = NULL; IInternetPriority *priority; IServiceProvider *service_provider; + BOOL urlmon_protocol = FALSE; CLSID clsid = IID_NULL; LPOLESTR clsid_str; HRESULT hres; @@ -149,7 +153,7 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl IClassFactory *cf; IUnknown *unk; - hres = get_protocol_handler(szUrl, &clsid, &cf); + hres = get_protocol_handler(szUrl, &clsid, &urlmon_protocol, &cf); if(FAILED(hres)) return hres; @@ -178,6 +182,9 @@ static HRESULT WINAPI BindProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl This->protocol = protocol; + if(urlmon_protocol) + IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&This->wininet_info); + IInternetBindInfo_AddRef(pOIBindInfo); This->bind_info = pOIBindInfo; @@ -304,6 +311,13 @@ void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *s IServiceProvider_Release(service_provider); } +IWinInetInfo *get_wininet_info(IInternetProtocol *bind_protocol) +{ + BindProtocol *This = PROTOCOL_THIS(bind_protocol); + + return This->wininet_info; +} + #undef PROTOCOL_THIS static const IInternetProtocolVtbl BindProtocolVtbl = { diff --git a/dlls/urlmon/session.c b/dlls/urlmon/session.c index 72308e1eeec..9cacde7ae91 100644 --- a/dlls/urlmon/session.c +++ b/dlls/urlmon/session.c @@ -228,7 +228,7 @@ IInternetProtocolInfo *get_protocol_info(LPCWSTR url) return ret; } -HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret) +HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, BOOL *urlmon_protocol, IClassFactory **ret) { name_space *ns; WCHAR schema[64]; @@ -250,6 +250,8 @@ HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret) IClassFactory_AddRef(*ret); if(clsid) *clsid = ns->clsid; + if(urlmon_protocol) + *urlmon_protocol = ns->urlmon; } LeaveCriticalSection(&session_cs); @@ -257,6 +259,8 @@ HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret) if(*ret) return S_OK; + if(urlmon_protocol) + *urlmon_protocol = FALSE; return get_protocol_cf(schema, schema_len, clsid, ret); } diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index 843b38b8dbd..c40718b57df 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -173,6 +173,7 @@ static BOOL stopped_binding = FALSE, stopped_obj_binding = FALSE, emulate_protoc static DWORD read = 0, bindf = 0, prot_state = 0, thread_id, tymed; static CHAR mime_type[512]; static IInternetProtocolSink *protocol_sink = NULL; +static IBinding *current_binding; static HANDLE complete_event, complete_event2; static HRESULT binding_hres; static BOOL have_IHttpNegotiate2; @@ -1179,6 +1180,8 @@ static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD if(pib == (void*)0xdeadbeef) return S_OK; + current_binding = pib; + hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon); ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n"); if(SUCCEEDED(hres)) @@ -1338,6 +1341,21 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulP default: ok(0, "unexpected code %d\n", ulStatusCode); }; + + if(current_binding) { + IWinInetHttpInfo *http_info; + HRESULT hres; + + hres = IBinding_QueryInterface(current_binding, &IID_IWinInetHttpInfo, (void**)&http_info); + if(!emulate_protocol && test_protocol != FILE_TEST && is_urlmon_protocol(test_protocol)) + ok(hres == S_OK, "Could not get IWinInetHttpInfo iface: %08x\n", hres); + else + ok(hres == E_NOINTERFACE, + "QueryInterface(IID_IWinInetHttpInfo) returned: %08x, expected E_NOINTERFACE\n", hres); + if(SUCCEEDED(hres)) + IWinInetHttpInfo_Release(http_info); + } + return S_OK; } diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 54c0435de8d..637e58e1306 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -57,8 +57,8 @@ static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_ref #define DEFINE_THIS2(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,ifc))) #define DEFINE_THIS(cls,ifc,iface) DEFINE_THIS2(cls,lp ## ifc ## Vtbl,iface) -IInternetProtocolInfo *get_protocol_info(LPCWSTR url); -HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret); +IInternetProtocolInfo *get_protocol_info(LPCWSTR); +HRESULT get_protocol_handler(LPCWSTR,CLSID*,BOOL*,IClassFactory**); BOOL is_registered_protocol(LPCWSTR); void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL); @@ -67,6 +67,7 @@ HRESULT bind_to_object(IMoniker *mon, LPCWSTR url, IBindCtx *pbc, REFIID riid, v HRESULT create_binding_protocol(LPCWSTR url, BOOL from_urlmon, IInternetProtocol **protocol); void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink); +IWinInetInfo *get_wininet_info(IInternetProtocol*); typedef struct ProtocolVtbl ProtocolVtbl;