X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=dll%2Fwin32%2Furlmon%2Fsession.c;h=7c5a3bb931dadcff75b307d5e6ca36715fa73a68;hp=fc36c0bcceb535a931fd791476d985b4b699a657;hb=057a69972f640131d96047073766b10296195b40;hpb=65ce146169bcce3a42186e27b946aaa1d36c208e diff --git a/dll/win32/urlmon/session.c b/dll/win32/urlmon/session.c index fc36c0bcceb..7c5a3bb931d 100644 --- a/dll/win32/urlmon/session.c +++ b/dll/win32/urlmon/session.c @@ -17,31 +17,26 @@ */ #include "urlmon_main.h" -#include "winreg.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(urlmon); - -typedef struct name_space { +typedef struct { LPWSTR protocol; IClassFactory *cf; CLSID clsid; BOOL urlmon; - struct name_space *next; + struct list entry; } name_space; -typedef struct mime_filter { +typedef struct { IClassFactory *cf; CLSID clsid; LPWSTR mime; - struct mime_filter *next; + struct list entry; } mime_filter; -static name_space *name_space_list = NULL; -static mime_filter *mime_filter_list = NULL; +static struct list name_space_list = LIST_INIT(name_space_list); +static struct list mime_filter_list = LIST_INIT(mime_filter_list); static CRITICAL_SECTION session_cs; static CRITICAL_SECTION_DEBUG session_cs_dbg = @@ -63,8 +58,8 @@ static name_space *find_name_space(LPCWSTR protocol) { name_space *iter; - for(iter = name_space_list; iter; iter = iter->next) { - if(!strcmpW(iter->protocol, protocol)) + LIST_FOR_EACH_ENTRY(iter, &name_space_list, name_space, entry) { + if(!strcmpiW(iter->protocol, protocol)) return iter; } @@ -119,7 +114,7 @@ static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid, return SUCCEEDED(hres) ? S_OK : MK_E_SYNTAX; } -static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL urlmon_protocol) +HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL urlmon_protocol) { name_space *new_name_space; @@ -134,8 +129,7 @@ static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR proto EnterCriticalSection(&session_cs); - new_name_space->next = name_space_list; - name_space_list = new_name_space; + list_add_head(&name_space_list, &new_name_space->entry); LeaveCriticalSection(&session_cs); @@ -144,44 +138,28 @@ static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR proto static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol) { - name_space *iter, *last = NULL; + name_space *iter; EnterCriticalSection(&session_cs); - for(iter = name_space_list; iter; iter = iter->next) { - if(iter->cf == cf && !strcmpW(iter->protocol, protocol)) - break; - last = iter; - } - - if(iter) { - if(last) - last->next = iter->next; - else - name_space_list = iter->next; - } + LIST_FOR_EACH_ENTRY(iter, &name_space_list, name_space, entry) { + if(iter->cf == cf && !strcmpiW(iter->protocol, protocol)) { + list_remove(&iter->entry); - LeaveCriticalSection(&session_cs); + LeaveCriticalSection(&session_cs); - if(iter) { - if(!iter->urlmon) - IClassFactory_Release(iter->cf); - heap_free(iter->protocol); - heap_free(iter); + if(!iter->urlmon) + IClassFactory_Release(iter->cf); + heap_free(iter->protocol); + heap_free(iter); + return S_OK; + } } + LeaveCriticalSection(&session_cs); return S_OK; } - -void register_urlmon_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR protocol, BOOL do_register) -{ - if(do_register) - register_namespace(cf, clsid, protocol, TRUE); - else - unregister_namespace(cf, protocol); -} - BOOL is_registered_protocol(LPCWSTR url) { DWORD schema_len; @@ -277,14 +255,22 @@ HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, BOOL *urlmon_protocol, ICl IInternetProtocol *get_mime_filter(LPCWSTR mime) { + static const WCHAR filtersW[] = {'P','r','o','t','o','c','o','l','s', + '\\','F','i','l','t','e','r',0 }; + static const WCHAR CLSIDW[] = {'C','L','S','I','D',0}; + IClassFactory *cf = NULL; IInternetProtocol *ret; mime_filter *iter; + HKEY hlist, hfilter; + WCHAR clsidw[64]; + CLSID clsid; + DWORD res, type, size; HRESULT hres; EnterCriticalSection(&session_cs); - for(iter = mime_filter_list; iter; iter = iter->next) { + LIST_FOR_EACH_ENTRY(iter, &mime_filter_list, mime_filter, entry) { if(!strcmpW(iter->mime, mime)) { cf = iter->cf; break; @@ -293,12 +279,44 @@ IInternetProtocol *get_mime_filter(LPCWSTR mime) LeaveCriticalSection(&session_cs); - if(!cf) + if(cf) { + hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&ret); + if(FAILED(hres)) { + WARN("CreateInstance failed: %08x\n", hres); + return NULL; + } + + return ret; + } + + res = RegOpenKeyW(HKEY_CLASSES_ROOT, filtersW, &hlist); + if(res != ERROR_SUCCESS) { + TRACE("Could not open MIME filters key\n"); + return NULL; + } + + res = RegOpenKeyW(hlist, mime, &hfilter); + CloseHandle(hlist); + if(res != ERROR_SUCCESS) + return NULL; + + size = sizeof(clsidw); + res = RegQueryValueExW(hfilter, CLSIDW, NULL, &type, (LPBYTE)clsidw, &size); + CloseHandle(hfilter); + if(res!=ERROR_SUCCESS || type!=REG_SZ) { + WARN("Could not get filter CLSID for %s\n", debugstr_w(mime)); + return NULL; + } + + hres = CLSIDFromString(clsidw, &clsid); + if(FAILED(hres)) { + WARN("CLSIDFromString failed for %s (%x)\n", debugstr_w(mime), hres); return NULL; + } - hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&ret); + hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&ret); if(FAILED(hres)) { - WARN("CreateInstance failed: %08x\n", hres); + WARN("CoCreateInstance failed: %08x\n", hres); return NULL; } @@ -379,8 +397,7 @@ static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface EnterCriticalSection(&session_cs); - filter->next = mime_filter_list; - mime_filter_list = filter; + list_add_head(&mime_filter_list, &filter->entry); LeaveCriticalSection(&session_cs); @@ -390,33 +407,26 @@ static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *iface, IClassFactory *pCF, LPCWSTR pwzType) { - mime_filter *iter, *prev = NULL; + mime_filter *iter; TRACE("(%p %s)\n", pCF, debugstr_w(pwzType)); EnterCriticalSection(&session_cs); - for(iter = mime_filter_list; iter; iter = iter->next) { - if(iter->cf == pCF && !strcmpW(iter->mime, pwzType)) - break; - prev = iter; - } - - if(iter) { - if(prev) - prev->next = iter->next; - else - mime_filter_list = iter->next; - } + LIST_FOR_EACH_ENTRY(iter, &mime_filter_list, mime_filter, entry) { + if(iter->cf == pCF && !strcmpW(iter->mime, pwzType)) { + list_remove(&iter->entry); - LeaveCriticalSection(&session_cs); + LeaveCriticalSection(&session_cs); - if(iter) { - IClassFactory_Release(iter->cf); - heap_free(iter->mime); - heap_free(iter); + IClassFactory_Release(iter->cf); + heap_free(iter->mime); + heap_free(iter); + return S_OK; + } } + LeaveCriticalSection(&session_cs); return S_OK; } @@ -517,31 +527,90 @@ static LPWSTR user_agent; static void ensure_useragent(void) { - DWORD size = sizeof(DWORD), res, type; - HKEY hkey; - - static const WCHAR user_agentW[] = {'U','s','e','r',' ','A','g','e','n','t',0}; + OSVERSIONINFOW info = {sizeof(info)}; + const WCHAR *os_type, *is_nt; + WCHAR buf[512], *ret, *tmp; + DWORD res, idx=0; + size_t len, size; + BOOL is_wow; + HKEY key; + + static const WCHAR formatW[] = + {'M','o','z','i','l','l','a','/','4','.','0', + ' ','(','c','o','m','p','a','t','i','b','l','e',';', + ' ','M','S','I','E',' ','8','.','0',';', + ' ','W','i','n','d','o','w','s',' ','%','s','%','d','.','%','d',';', + ' ','%','s',';',' ','T','r','i','d','e','n','t','/','5','.','0',0}; + static const WCHAR post_platform_keyW[] = + {'S','O','F','T','W','A','R','E', + '\\','M','i','c','r','o','s','o','f','t', + '\\','W','i','n','d','o','w','s', + '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n', + '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s', + '\\','5','.','0','\\','U','s','e','r',' ','A','g','e','n','t', + '\\','P','o','s','t',' ','P','l','a','t','f','o','r','m',0}; + static const WCHAR ntW[] = {'N','T',' ',0}; + static const WCHAR win32W[] = {'W','i','n','3','2',0}; + static const WCHAR win64W[] = {'W','i','n','6','4',0}; + static const WCHAR wow64W[] = {'W','O','W','6','4',0}; + static const WCHAR emptyW[] = {0}; if(user_agent) return; - res = RegOpenKeyW(HKEY_CURRENT_USER, internet_settings_keyW, &hkey); - if(res != ERROR_SUCCESS) + GetVersionExW(&info); + is_nt = info.dwPlatformId == VER_PLATFORM_WIN32_NT ? ntW : emptyW; + + if(sizeof(void*) == 8) + os_type = win64W; + else if(IsWow64Process(GetCurrentProcess(), &is_wow) && is_wow) + os_type = wow64W; + else + os_type = win32W; + + sprintfW(buf, formatW, is_nt, info.dwMajorVersion, info.dwMinorVersion, os_type); + len = strlenW(buf); + + size = len+40; + ret = heap_alloc(size * sizeof(WCHAR)); + if(!ret) return; - res = RegQueryValueExW(hkey, user_agentW, NULL, &type, NULL, &size); - if(res == ERROR_SUCCESS && type == REG_SZ) { - user_agent = heap_alloc(size); - res = RegQueryValueExW(hkey, user_agentW, NULL, &type, (LPBYTE)user_agent, &size); - if(res != ERROR_SUCCESS) { - heap_free(user_agent); - user_agent = NULL; + memcpy(ret, buf, len*sizeof(WCHAR)); + + res = RegOpenKeyW(HKEY_LOCAL_MACHINE, post_platform_keyW, &key); + if(res == ERROR_SUCCESS) { + DWORD value_len; + + while(1) { + value_len = sizeof(buf)/sizeof(WCHAR); + res = RegEnumValueW(key, idx, buf, &value_len, NULL, NULL, NULL, NULL); + if(res != ERROR_SUCCESS) + break; + idx++; + + if(len + value_len + 2 /* strlen("; ") */ + 1 /* trailing ')' */ >= size) { + tmp = heap_realloc(ret, (size*2+value_len)*sizeof(WCHAR)); + if(!tmp) + break; + ret = tmp; + size = size*2+value_len; + } + + ret[len++] = ';'; + ret[len++] = ' '; + memcpy(ret+len, buf, value_len*sizeof(WCHAR)); + len += value_len; } - }else { - WARN("Could not find User Agent value: %u\n", res); + + RegCloseKey(key); } - RegCloseKey(hkey); + ret[len++] = ')'; + ret[len++] = 0; + + user_agent = ret; + TRACE("Using user agent %s\n", debugstr_w(user_agent)); } LPWSTR get_useragent(void) @@ -691,5 +760,21 @@ HRESULT WINAPI ObtainUserAgentString(DWORD dwOption, LPSTR pcszUAOut, DWORD *cbS void free_session(void) { + name_space *ns_iter, *ns_last; + mime_filter *mf_iter, *mf_last; + + LIST_FOR_EACH_ENTRY_SAFE(ns_iter, ns_last, &name_space_list, name_space, entry) { + if(!ns_iter->urlmon) + IClassFactory_Release(ns_iter->cf); + heap_free(ns_iter->protocol); + heap_free(ns_iter); + } + + LIST_FOR_EACH_ENTRY_SAFE(mf_iter, mf_last, &mime_filter_list, mime_filter, entry) { + IClassFactory_Release(mf_iter->cf); + heap_free(mf_iter->mime); + heap_free(mf_iter); + } + heap_free(user_agent); }