From 9c9838d9e8d95986d181fc4a8dbdbe16cd254a24 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 24 May 2006 18:00:08 +0200 Subject: [PATCH] urlmon: Use registered protocols. --- dlls/urlmon/binding.c | 2 +- dlls/urlmon/internet.c | 16 -------- dlls/urlmon/session.c | 82 ++++++++++++++++++++++++++++++++++----- dlls/urlmon/urlmon_main.h | 3 +- 4 files changed, 76 insertions(+), 27 deletions(-) diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c index e1c63f6720f..efbd12fdf3b 100644 --- a/dlls/urlmon/binding.c +++ b/dlls/urlmon/binding.c @@ -789,7 +789,7 @@ static HRESULT get_protocol(Binding *This, LPCWSTR url) return S_OK; } - hres = get_protocol_iface(url, &unk); + hres = get_protocol_handler(url, &unk); if(FAILED(hres)) return hres; diff --git a/dlls/urlmon/internet.c b/dlls/urlmon/internet.c index ef9939e30a3..8ae22e0eb29 100644 --- a/dlls/urlmon/internet.c +++ b/dlls/urlmon/internet.c @@ -61,22 +61,6 @@ static HRESULT parse_schema(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, return S_OK; } -static IInternetProtocolInfo *get_protocol_info(LPCWSTR url) -{ - IInternetProtocolInfo *ret = NULL; - IUnknown *unk; - HRESULT hres; - - hres = get_protocol_iface(url, &unk); - if(FAILED(hres)) - return NULL; - - IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&ret); - IUnknown_Release(unk); - - return ret; -} - static HRESULT parse_security_url(LPCWSTR url, DWORD flags, LPWSTR result, DWORD size, DWORD *rsize) { IInternetProtocolInfo *protocol_info; diff --git a/dlls/urlmon/session.c b/dlls/urlmon/session.c index 4a1a9b302ca..deb71465bfc 100644 --- a/dlls/urlmon/session.c +++ b/dlls/urlmon/session.c @@ -1,5 +1,5 @@ /* - * Copyright 2005 Jacek Caban + * Copyright 2005-2006 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -42,11 +42,23 @@ typedef struct name_space { static name_space *name_space_list = NULL; -HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret) +static IClassFactory *find_name_space(LPCWSTR protocol) { - WCHAR schema[64], str_clsid[64]; + name_space *iter; + + for(iter = name_space_list; iter; iter = iter->next) { + if(!strcmpW(iter->protocol, protocol)) + return iter->cf; + } + + return NULL; +} + +static HRESULT get_protocol_iface(LPCWSTR schema, DWORD schema_len, IUnknown **ret) +{ + WCHAR str_clsid[64]; HKEY hkey = NULL; - DWORD res, type, size, schema_len; + DWORD res, type, size; CLSID clsid; LPWSTR wszKey; HRESULT hres; @@ -55,11 +67,6 @@ HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret) {'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'}; static const WCHAR wszCLSID[] = {'C','L','S','I','D',0}; - hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), - &schema_len, 0); - if(FAILED(hres) || !schema_len) - return E_FAIL; - wszKey = HeapAlloc(GetProcessHeap(), 0, sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR)); memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey)); memcpy(wszKey + sizeof(wszProtocolsKey)/sizeof(WCHAR), schema, (schema_len+1)*sizeof(WCHAR)); @@ -88,6 +95,63 @@ HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret) return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)ret); } +IInternetProtocolInfo *get_protocol_info(LPCWSTR url) +{ + IInternetProtocolInfo *ret = NULL; + IClassFactory *cf; + IUnknown *unk; + WCHAR schema[64]; + DWORD schema_len; + HRESULT hres; + + hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), + &schema_len, 0); + if(FAILED(hres) || !schema_len) + return NULL; + + cf = find_name_space(schema); + if(cf) { + hres = IClassFactory_QueryInterface(cf, &IID_IInternetProtocolInfo, (void**)&ret); + if(SUCCEEDED(hres)) + return ret; + + hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret); + if(SUCCEEDED(hres)) + return ret; + } + + hres = get_protocol_iface(schema, schema_len, &unk); + if(FAILED(hres)) + return NULL; + + hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&ret); + IUnknown_Release(unk); + + return ret; +} + +HRESULT get_protocol_handler(LPCWSTR url, IUnknown **ret) +{ + IClassFactory *cf; + WCHAR schema[64]; + DWORD schema_len; + HRESULT hres; + + hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), + &schema_len, 0); + if(FAILED(hres) || !schema_len) + return schema_len ? hres : E_FAIL; + + cf = find_name_space(schema); + if(cf) { + hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)ret); + if(SUCCEEDED(hres)) + return hres; + } + + return get_protocol_iface(schema, schema_len, ret); +} + static HRESULT WINAPI InternetSession_QueryInterface(IInternetSession *iface, REFIID riid, void **ppv) { diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index c67b52a4717..0eb7db690be 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -54,7 +54,8 @@ typedef struct HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, DWORD dwSize, LPWSTR pszFileName, HANDLE *phfile, IUMCacheStream **ppstr); void UMCloseCacheFileStream(IUMCacheStream *pstr); -HRESULT get_protocol_iface(LPCWSTR url, IUnknown **ret); +IInternetProtocolInfo *get_protocol_info(LPCWSTR url); +HRESULT get_protocol_handler(LPCWSTR url, IUnknown **ret); HRESULT start_binding(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);