urlmon: Cache the binding notif window.
This commit is contained in:
parent
f85e7dc3c2
commit
bee36fe831
|
@ -125,6 +125,7 @@ struct Binding {
|
|||
#define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl)
|
||||
|
||||
#define WM_MK_CONTINUE (WM_USER+101)
|
||||
#define WM_MK_RELEASE (WM_USER+102)
|
||||
|
||||
static void push_task(Binding *binding, task_header_t *task, task_proc_t proc)
|
||||
{
|
||||
|
@ -177,7 +178,8 @@ static void fill_stgmed_buffer(stgmed_buf_t *buf)
|
|||
|
||||
static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if(msg == WM_MK_CONTINUE) {
|
||||
switch(msg) {
|
||||
case WM_MK_CONTINUE: {
|
||||
Binding *binding = (Binding*)lParam;
|
||||
task_header_t *task;
|
||||
|
||||
|
@ -190,6 +192,15 @@ static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||
IBinding_Release(BINDING(binding));
|
||||
return 0;
|
||||
}
|
||||
case WM_MK_RELEASE: {
|
||||
tls_data_t *data = get_tls_data();
|
||||
|
||||
if(!--data->notif_hwnd_cnt) {
|
||||
DestroyWindow(hwnd);
|
||||
data->notif_hwnd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
@ -197,12 +208,21 @@ static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||
static HWND get_notif_hwnd(void)
|
||||
{
|
||||
static ATOM wnd_class = 0;
|
||||
HWND hwnd;
|
||||
tls_data_t *tls_data;
|
||||
|
||||
static const WCHAR wszURLMonikerNotificationWindow[] =
|
||||
{'U','R','L',' ','M','o','n','i','k','e','r',' ',
|
||||
'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
|
||||
|
||||
tls_data = get_tls_data();
|
||||
if(!tls_data)
|
||||
return NULL;
|
||||
|
||||
if(tls_data->notif_hwnd_cnt) {
|
||||
tls_data->notif_hwnd_cnt++;
|
||||
return tls_data->notif_hwnd;
|
||||
}
|
||||
|
||||
if(!wnd_class) {
|
||||
static WNDCLASSEXW wndclass = {
|
||||
sizeof(wndclass), 0,
|
||||
|
@ -219,13 +239,30 @@ static HWND get_notif_hwnd(void)
|
|||
wnd_class = 1;
|
||||
}
|
||||
|
||||
hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow,
|
||||
wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE,
|
||||
NULL, URLMON_hInstance, NULL);
|
||||
tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow,
|
||||
wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE,
|
||||
NULL, URLMON_hInstance, NULL);
|
||||
if(tls_data->notif_hwnd)
|
||||
tls_data->notif_hwnd_cnt++;
|
||||
|
||||
TRACE("hwnd = %p\n", hwnd);
|
||||
TRACE("hwnd = %p\n", tls_data->notif_hwnd);
|
||||
|
||||
return hwnd;
|
||||
return tls_data->notif_hwnd;
|
||||
}
|
||||
|
||||
static void release_notif_hwnd(HWND hwnd)
|
||||
{
|
||||
tls_data_t *data = get_tls_data();
|
||||
|
||||
if(!data || data->notif_hwnd != hwnd) {
|
||||
PostMessageW(data->notif_hwnd, WM_MK_RELEASE, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!--data->notif_hwnd_cnt) {
|
||||
DestroyWindow(data->notif_hwnd);
|
||||
data->notif_hwnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_BINDINFO(BINDINFO *bi)
|
||||
|
@ -957,8 +994,8 @@ static ULONG WINAPI Binding_Release(IBinding *iface)
|
|||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if (This->notif_hwnd)
|
||||
DestroyWindow( This->notif_hwnd );
|
||||
if(This->notif_hwnd)
|
||||
release_notif_hwnd(This->notif_hwnd);
|
||||
if(This->mon)
|
||||
IMoniker_Release(This->mon);
|
||||
if(This->callback)
|
||||
|
|
|
@ -36,9 +36,88 @@ LONG URLMON_refCount = 0;
|
|||
|
||||
HINSTANCE URLMON_hInstance = 0;
|
||||
static HMODULE hCabinet = NULL;
|
||||
static DWORD urlmon_tls;
|
||||
|
||||
static void init_session(BOOL);
|
||||
|
||||
static struct list tls_list = LIST_INIT(tls_list);
|
||||
|
||||
static CRITICAL_SECTION tls_cs;
|
||||
static CRITICAL_SECTION_DEBUG tls_cs_dbg =
|
||||
{
|
||||
0, 0, &tls_cs,
|
||||
{ &tls_cs_dbg.ProcessLocksList, &tls_cs_dbg.ProcessLocksList },
|
||||
0, 0, { (DWORD_PTR)(__FILE__ ": tls") }
|
||||
};
|
||||
|
||||
static CRITICAL_SECTION tls_cs = { &tls_cs_dbg, -1, 0, 0, 0, 0 };
|
||||
|
||||
tls_data_t *get_tls_data(void)
|
||||
{
|
||||
tls_data_t *data;
|
||||
|
||||
if(!urlmon_tls) {
|
||||
DWORD tls = TlsAlloc();
|
||||
tls = InterlockedCompareExchange((LONG*)&urlmon_tls, tls, 0);
|
||||
if(tls != urlmon_tls)
|
||||
TlsFree(tls);
|
||||
}
|
||||
|
||||
data = TlsGetValue(urlmon_tls);
|
||||
if(!data) {
|
||||
data = heap_alloc_zero(sizeof(tls_data_t));
|
||||
if(!data)
|
||||
return NULL;
|
||||
|
||||
EnterCriticalSection(&tls_cs);
|
||||
list_add_tail(&tls_list, &data->entry);
|
||||
LeaveCriticalSection(&tls_cs);
|
||||
|
||||
TlsSetValue(urlmon_tls, data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void free_tls_list(void)
|
||||
{
|
||||
tls_data_t *data;
|
||||
|
||||
if(!urlmon_tls)
|
||||
return;
|
||||
|
||||
while(!list_empty(&tls_list)) {
|
||||
data = LIST_ENTRY(list_head(&tls_list), tls_data_t, entry);
|
||||
list_remove(&data->entry);
|
||||
heap_free(data);
|
||||
}
|
||||
|
||||
TlsFree(urlmon_tls);
|
||||
}
|
||||
|
||||
static void detach_thread(void)
|
||||
{
|
||||
tls_data_t *data;
|
||||
|
||||
if(!urlmon_tls)
|
||||
return;
|
||||
|
||||
data = TlsGetValue(urlmon_tls);
|
||||
if(!data)
|
||||
return;
|
||||
|
||||
EnterCriticalSection(&tls_cs);
|
||||
list_remove(&data->entry);
|
||||
LeaveCriticalSection(&tls_cs);
|
||||
|
||||
if(data->notif_hwnd) {
|
||||
WARN("notif_hwnd not destroyed\n");
|
||||
DestroyWindow(data->notif_hwnd);
|
||||
}
|
||||
|
||||
heap_free(data);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (URLMON.init)
|
||||
*/
|
||||
|
@ -48,7 +127,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
|||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
URLMON_hInstance = hinstDLL;
|
||||
init_session(TRUE);
|
||||
break;
|
||||
|
@ -58,8 +136,13 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
|||
FreeLibrary(hCabinet);
|
||||
hCabinet = NULL;
|
||||
init_session(FALSE);
|
||||
free_tls_list();
|
||||
URLMON_hInstance = 0;
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
detach_thread();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "wininet.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
extern HINSTANCE URLMON_hInstance;
|
||||
extern HRESULT SecManagerImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj);
|
||||
|
@ -106,6 +107,15 @@ HRESULT protocol_lock_request(Protocol*);
|
|||
HRESULT protocol_unlock_request(Protocol*);
|
||||
void protocol_close_connection(Protocol*);
|
||||
|
||||
typedef struct {
|
||||
HWND notif_hwnd;
|
||||
DWORD notif_hwnd_cnt;
|
||||
|
||||
struct list entry;
|
||||
} tls_data_t;
|
||||
|
||||
tls_data_t *get_tls_data(void);
|
||||
|
||||
static inline void *heap_alloc(size_t len)
|
||||
{
|
||||
return HeapAlloc(GetProcessHeap(), 0, len);
|
||||
|
|
Loading…
Reference in New Issue