Commit a821cc34 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

urlmon: Make session object thread safe.

parent a23a3607
...@@ -43,6 +43,15 @@ typedef struct mime_filter { ...@@ -43,6 +43,15 @@ typedef struct mime_filter {
static name_space *name_space_list = NULL; static name_space *name_space_list = NULL;
static mime_filter *mime_filter_list = NULL; static mime_filter *mime_filter_list = NULL;
static CRITICAL_SECTION session_cs;
static CRITICAL_SECTION_DEBUG session_cs_dbg =
{
0, 0, &session_cs,
{ &session_cs_dbg.ProcessLocksList, &session_cs_dbg.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": session") }
};
static CRITICAL_SECTION session_cs = { &session_cs_dbg, -1, 0, 0, 0, 0 };
static name_space *find_name_space(LPCWSTR protocol) static name_space *find_name_space(LPCWSTR protocol)
{ {
name_space *iter; name_space *iter;
...@@ -115,9 +124,13 @@ static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR proto ...@@ -115,9 +124,13 @@ static HRESULT register_namespace(IClassFactory *cf, REFIID clsid, LPCWSTR proto
new_name_space->urlmon = urlmon_protocol; new_name_space->urlmon = urlmon_protocol;
new_name_space->protocol = heap_strdupW(protocol); new_name_space->protocol = heap_strdupW(protocol);
EnterCriticalSection(&session_cs);
new_name_space->next = name_space_list; new_name_space->next = name_space_list;
name_space_list = new_name_space; name_space_list = new_name_space;
LeaveCriticalSection(&session_cs);
return S_OK; return S_OK;
} }
...@@ -125,6 +138,8 @@ static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol) ...@@ -125,6 +138,8 @@ static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol)
{ {
name_space *iter, *last = NULL; name_space *iter, *last = NULL;
EnterCriticalSection(&session_cs);
for(iter = name_space_list; iter; iter = iter->next) { for(iter = name_space_list; iter; iter = iter->next) {
if(iter->cf == cf && !strcmpW(iter->protocol, protocol)) if(iter->cf == cf && !strcmpW(iter->protocol, protocol))
break; break;
...@@ -136,7 +151,11 @@ static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol) ...@@ -136,7 +151,11 @@ static HRESULT unregister_namespace(IClassFactory *cf, LPCWSTR protocol)
last->next = iter->next; last->next = iter->next;
else else
name_space_list = iter->next; name_space_list = iter->next;
}
LeaveCriticalSection(&session_cs);
if(iter) {
if(!iter->urlmon) if(!iter->urlmon)
IClassFactory_Release(iter->cf); IClassFactory_Release(iter->cf);
heap_free(iter->protocol); heap_free(iter->protocol);
...@@ -183,20 +202,20 @@ IInternetProtocolInfo *get_protocol_info(LPCWSTR url) ...@@ -183,20 +202,20 @@ IInternetProtocolInfo *get_protocol_info(LPCWSTR url)
if(FAILED(hres) || !schema_len) if(FAILED(hres) || !schema_len)
return NULL; return NULL;
ns = find_name_space(schema); EnterCriticalSection(&session_cs);
if(ns) {
if(ns->urlmon)
return NULL;
ns = find_name_space(schema);
if(ns && !ns->urlmon) {
hres = IClassFactory_QueryInterface(ns->cf, &IID_IInternetProtocolInfo, (void**)&ret); hres = IClassFactory_QueryInterface(ns->cf, &IID_IInternetProtocolInfo, (void**)&ret);
if(SUCCEEDED(hres)) if(FAILED(hres))
return ret; hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
hres = IClassFactory_CreateInstance(ns->cf, NULL, &IID_IInternetProtocolInfo, (void**)&ret);
if(SUCCEEDED(hres))
return ret;
} }
LeaveCriticalSection(&session_cs);
if(ns && SUCCEEDED(hres))
return ret;
hres = get_protocol_cf(schema, schema_len, NULL, &cf); hres = get_protocol_cf(schema, schema_len, NULL, &cf);
if(FAILED(hres)) if(FAILED(hres))
return NULL; return NULL;
...@@ -216,20 +235,28 @@ HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret) ...@@ -216,20 +235,28 @@ HRESULT get_protocol_handler(LPCWSTR url, CLSID *clsid, IClassFactory **ret)
DWORD schema_len; DWORD schema_len;
HRESULT hres; HRESULT hres;
*ret = NULL;
hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), hres = CoInternetParseUrl(url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]),
&schema_len, 0); &schema_len, 0);
if(FAILED(hres) || !schema_len) if(FAILED(hres) || !schema_len)
return schema_len ? hres : E_FAIL; return schema_len ? hres : E_FAIL;
EnterCriticalSection(&session_cs);
ns = find_name_space(schema); ns = find_name_space(schema);
if(ns) { if(ns) {
*ret = ns->cf; *ret = ns->cf;
IClassFactory_AddRef(*ret); IClassFactory_AddRef(*ret);
if(clsid) if(clsid)
*clsid = ns->clsid; *clsid = ns->clsid;
return S_OK;
} }
LeaveCriticalSection(&session_cs);
if(*ret)
return S_OK;
return get_protocol_cf(schema, schema_len, clsid, ret); return get_protocol_cf(schema, schema_len, clsid, ret);
} }
...@@ -305,9 +332,13 @@ static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface ...@@ -305,9 +332,13 @@ static HRESULT WINAPI InternetSession_RegisterMimeFilter(IInternetSession *iface
filter->clsid = *rclsid; filter->clsid = *rclsid;
filter->mime = heap_strdupW(pwzType); filter->mime = heap_strdupW(pwzType);
EnterCriticalSection(&session_cs);
filter->next = mime_filter_list; filter->next = mime_filter_list;
mime_filter_list = filter; mime_filter_list = filter;
LeaveCriticalSection(&session_cs);
return S_OK; return S_OK;
} }
...@@ -318,23 +349,28 @@ static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *ifa ...@@ -318,23 +349,28 @@ static HRESULT WINAPI InternetSession_UnregisterMimeFilter(IInternetSession *ifa
TRACE("(%p %s)\n", pCF, debugstr_w(pwzType)); TRACE("(%p %s)\n", pCF, debugstr_w(pwzType));
EnterCriticalSection(&session_cs);
for(iter = mime_filter_list; iter; iter = iter->next) { for(iter = mime_filter_list; iter; iter = iter->next) {
if(iter->cf == pCF && !strcmpW(iter->mime, pwzType)) if(iter->cf == pCF && !strcmpW(iter->mime, pwzType))
break; break;
prev = iter; prev = iter;
} }
if(!iter) if(iter) {
return S_OK; if(prev)
prev->next = iter->next;
else
mime_filter_list = iter->next;
}
if(prev) LeaveCriticalSection(&session_cs);
prev->next = iter->next;
else
mime_filter_list = iter->next;
IClassFactory_Release(iter->cf); if(iter) {
heap_free(iter->mime); IClassFactory_Release(iter->cf);
heap_free(iter); heap_free(iter->mime);
heap_free(iter);
}
return S_OK; return S_OK;
} }
......
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