From 648994c3ef40b9a2dc49ac6f971e291b9b99c73c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 24 Nov 2004 18:43:18 +0000 Subject: [PATCH] Changed winproc allocation to be based only on the procedure address, to avoid the need to keep track of winprocs for each window and class. --- dlls/user/winproc.h | 11 +- windows/class.c | 25 +-- windows/defdlg.c | 1 - windows/timer.c | 3 +- windows/win.c | 5 +- windows/winproc.c | 381 ++++++++++++++++++-------------------------- 6 files changed, 165 insertions(+), 261 deletions(-) diff --git a/dlls/user/winproc.h b/dlls/user/winproc.h index dd5ea18c808..6cfc515d9df 100644 --- a/dlls/user/winproc.h +++ b/dlls/user/winproc.h @@ -36,13 +36,6 @@ typedef enum WIN_PROC_32W } WINDOWPROCTYPE; -typedef enum -{ - WIN_PROC_CLASS, - WIN_PROC_WINDOW, - WIN_PROC_TIMER -} WINDOWPROCUSER; - typedef struct { WPARAM16 wParam; @@ -60,9 +53,7 @@ typedef struct struct tagWINDOWPROC; extern WNDPROC16 WINPROC_GetProc( WNDPROC proc, WINDOWPROCTYPE type ); -extern BOOL WINPROC_SetProc( WNDPROC *pFirst, WNDPROC func, - WINDOWPROCTYPE type, WINDOWPROCUSER user ); -extern void WINPROC_FreeProc( WNDPROC proc, WINDOWPROCUSER user ); +extern WNDPROC WINPROC_AllocProc( WNDPROC func, WINDOWPROCTYPE type ); extern WINDOWPROCTYPE WINPROC_GetProcType( WNDPROC proc ); extern INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, diff --git a/windows/class.c b/windows/class.c index 0c7cdc953b8..f8a0538e704 100644 --- a/windows/class.c +++ b/windows/class.c @@ -187,20 +187,14 @@ static WNDPROC16 CLASS_SetProc( CLASS *classPtr, WNDPROC newproc, WINDOWPROCTYPE if (!*proc || type == WIN_PROC_32W) proc = &classPtr->winprocW; } ret = WINPROC_GetProc( *proc, type ); - WINPROC_SetProc( proc, newproc, type, WIN_PROC_CLASS ); - /* now free the one that we didn't set */ + *proc = WINPROC_AllocProc( newproc, type ); + /* now clear the one that we didn't set */ if (classPtr->winprocA && classPtr->winprocW) { if (proc == &classPtr->winprocA) - { - WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS ); classPtr->winprocW = 0; - } else - { - WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS ); classPtr->winprocA = 0; - } } return ret; } @@ -303,8 +297,6 @@ static void CLASS_FreeClass( CLASS *classPtr ) if (classPtr->dce) DCE_FreeDCE( classPtr->dce ); if (classPtr->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1)) DeleteObject( classPtr->hbrBackground ); - WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS ); - WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS ); UnMapLS( classPtr->segMenuName ); HeapFree( GetProcessHeap(), 0, classPtr->menuName ); HeapFree( GetProcessHeap(), 0, classPtr ); @@ -458,10 +450,8 @@ static CLASS *register_builtin( const struct builtin_class_descr *descr ) classPtr->hCursor = LoadCursorA( 0, (LPSTR)descr->cursor ); classPtr->hbrBackground = descr->brush; - if (descr->procA) WINPROC_SetProc( &classPtr->winprocA, descr->procA, - WIN_PROC_32A, WIN_PROC_CLASS ); - if (descr->procW) WINPROC_SetProc( &classPtr->winprocW, descr->procW, - WIN_PROC_32W, WIN_PROC_CLASS ); + if (descr->procA) classPtr->winprocA = WINPROC_AllocProc( descr->procA, WIN_PROC_32A ); + if (descr->procW) classPtr->winprocW = WINPROC_AllocProc( descr->procW, WIN_PROC_32W ); release_class_ptr( classPtr ); return classPtr; } @@ -623,8 +613,7 @@ ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc ) classPtr->hCursor = HCURSOR_32(wc->hCursor); classPtr->hbrBackground = HBRUSH_32(wc->hbrBackground); - WINPROC_SetProc( &classPtr->winprocA, (WNDPROC)wc->lpfnWndProc, - WIN_PROC_16, WIN_PROC_CLASS ); + classPtr->winprocA = WINPROC_AllocProc( (WNDPROC)wc->lpfnWndProc, WIN_PROC_16 ); CLASS_SetMenuNameA( classPtr, MapSL(wc->lpszMenuName) ); release_class_ptr( classPtr ); return atom; @@ -662,7 +651,7 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) classPtr->hIconSm = wc->hIconSm; classPtr->hCursor = wc->hCursor; classPtr->hbrBackground = wc->hbrBackground; - WINPROC_SetProc( &classPtr->winprocA, wc->lpfnWndProc, WIN_PROC_32A, WIN_PROC_CLASS ); + classPtr->winprocA = WINPROC_AllocProc( wc->lpfnWndProc, WIN_PROC_32A ); CLASS_SetMenuNameA( classPtr, wc->lpszMenuName ); release_class_ptr( classPtr ); return atom; @@ -700,7 +689,7 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) classPtr->hIconSm = wc->hIconSm; classPtr->hCursor = wc->hCursor; classPtr->hbrBackground = wc->hbrBackground; - WINPROC_SetProc( &classPtr->winprocW, wc->lpfnWndProc, WIN_PROC_32W, WIN_PROC_CLASS ); + classPtr->winprocW = WINPROC_AllocProc( wc->lpfnWndProc, WIN_PROC_32W ); CLASS_SetMenuNameW( classPtr, wc->lpszMenuName ); release_class_ptr( classPtr ); return atom; diff --git a/windows/defdlg.c b/windows/defdlg.c index 4f81462103f..5ed5b9e75ef 100644 --- a/windows/defdlg.c +++ b/windows/defdlg.c @@ -247,7 +247,6 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam, } if (dlgInfo->hUserFont) DeleteObject( dlgInfo->hUserFont ); if (dlgInfo->hMenu) DestroyMenu( dlgInfo->hMenu ); - WINPROC_FreeProc( DEFDLG_GetDlgProc( hwnd ), WIN_PROC_WINDOW ); HeapFree( GetProcessHeap(), 0, dlgInfo ); } /* Window clean-up */ diff --git a/windows/timer.c b/windows/timer.c index 30d4677a8ba..c3d28704171 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -77,7 +77,6 @@ static void TIMER_ClearTimer( TIMER * pTimer ) pTimer->msg = 0; pTimer->id = 0; pTimer->timeout = 0; - WINPROC_FreeProc( pTimer->proc, WIN_PROC_TIMER ); } @@ -172,7 +171,7 @@ static UINT_PTR TIMER_SetTimer( HWND hwnd, UINT_PTR id, UINT timeout, if (!hwnd) id = i + 1; - if (proc) WINPROC_SetProc( &winproc, proc, type, WIN_PROC_TIMER ); + if (proc) winproc = WINPROC_AllocProc( proc, type ); SERVER_START_REQ( set_win_timer ) { diff --git a/windows/win.c b/windows/win.c index bad768562ae..f6387f9f413 100644 --- a/windows/win.c +++ b/windows/win.c @@ -650,7 +650,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) } DCE_FreeWindowDCE( hwnd ); /* Always do this to catch orphaned DCs */ if (USER_Driver.pDestroyWindow) USER_Driver.pDestroyWindow( hwnd ); - WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW ); wndPtr->class = NULL; wndPtr->dwMagic = 0; /* Mark it as invalid */ WIN_ReleaseWndPtr( wndPtr ); @@ -2058,7 +2057,7 @@ static LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, LONG_PTR newval, } case GWLP_WNDPROC: retval = (ULONG_PTR)WINPROC_GetProc( wndPtr->winproc, type ); - WINPROC_SetProc( &wndPtr->winproc, (WNDPROC)newval, type, WIN_PROC_WINDOW ); + wndPtr->winproc = WINPROC_AllocProc( (WNDPROC)newval, type ); WIN_ReleasePtr( wndPtr ); return retval; case GWLP_ID: @@ -2070,7 +2069,7 @@ static LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, LONG_PTR newval, { WNDPROC *ptr = (WNDPROC *)((char *)wndPtr->wExtra + DWLP_DLGPROC); retval = (ULONG_PTR)WINPROC_GetProc( *ptr, type ); - WINPROC_SetProc( ptr, (WNDPROC)newval, type, WIN_PROC_WINDOW ); + *ptr = WINPROC_AllocProc( (WNDPROC)newval, type ); WIN_ReleasePtr( wndPtr ); return retval; } diff --git a/windows/winproc.c b/windows/winproc.c index c6fcc472fd3..ca145253c1f 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -47,6 +47,8 @@ WINE_DECLARE_DEBUG_CHANNEL(msg); WINE_DECLARE_DEBUG_CHANNEL(relay); WINE_DEFAULT_DEBUG_CHANNEL(win); +#ifdef __i386__ + #include "pshpack1.h" /* Window procedure 16-to-32-bit thunk */ @@ -78,8 +80,28 @@ typedef struct BYTE jmp; /* jmp proc (relative jump) */ WNDPROC proc; } WINPROC_JUMP; + #include "poppack.h" +#else /* __i386__ */ + +typedef struct +{ + WNDPROC proc; +} WINPROC_THUNK_FROM16; + +typedef struct +{ + WNDPROC16 proc; +} WINPROC_THUNK_FROM32; + +typedef struct +{ + WNDPROC proc; +} WINPROC_JUMP; + +#endif /* __i386__ */ + typedef union { WINPROC_THUNK_FROM16 t_from16; @@ -88,21 +110,11 @@ typedef union typedef struct tagWINDOWPROC { - WINPROC_THUNK thunk; /* Thunk */ - WINPROC_JUMP jmp; /* Jump */ - struct tagWINDOWPROC *next; /* Next window proc */ - UINT magic; /* Magic number */ - WINDOWPROCTYPE type; /* Function type */ - WINDOWPROCUSER user; /* Function user */ + WINPROC_THUNK thunk; /* Thunk */ + WINPROC_JUMP jmp; /* Jump */ + BYTE type; /* Function type */ } WINDOWPROC; -#define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24)) - -#define WINPROC_THUNKPROC(pproc) \ - (((pproc)->type == WIN_PROC_16) ? \ - (WNDPROC16)((pproc)->thunk.t_from32.proc) : \ - (WNDPROC16)((pproc)->thunk.t_from16.proc)) - static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); @@ -113,7 +125,6 @@ static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd, #define MAX_WINPROCS (0x10000 / sizeof(WINDOWPROC)) static WINDOWPROC winproc_array[MAX_WINPROCS]; -static WINDOWPROC *winproc_first_free; static UINT winproc_used; static CRITICAL_SECTION winproc_cs; @@ -125,34 +136,109 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION winproc_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; -/* allocate a window procedure from the global array */ -static WINDOWPROC *alloc_winproc(void) -{ - WINDOWPROC *ret = NULL; - - EnterCriticalSection( &winproc_cs ); - if ((ret = winproc_first_free)) - winproc_first_free = ret->next; - else if (winproc_used < MAX_WINPROCS) - ret = &winproc_array[winproc_used++]; - LeaveCriticalSection( &winproc_cs ); - return ret; -} - -static void free_winproc( WINDOWPROC *proc ) -{ - EnterCriticalSection( &winproc_cs ); - proc->magic = 0; - proc->next = winproc_first_free; - winproc_first_free = proc; - LeaveCriticalSection( &winproc_cs ); -} - static BOOL is_valid_winproc( WINDOWPROC *proc ) { - if (proc < winproc_array || proc >= winproc_array + MAX_WINPROCS) return FALSE; + /* check array limits */ + if (proc < winproc_array || proc >= winproc_array + winproc_used) return FALSE; + /* check alignment */ if (proc != winproc_array + (proc - winproc_array)) return FALSE; - return (proc->magic == WINPROC_MAGIC); + return (proc->type != WIN_PROC_INVALID); +} + +/* find an existing winproc for a given function and type */ +/* FIXME: probably should do something more clever than a linear search */ +static inline WINDOWPROC *find_winproc( WNDPROC func, WINDOWPROCTYPE type ) +{ + unsigned int i; + + if (type == WIN_PROC_16) + { + for (i = 0; i < winproc_used; i++) + { + if (winproc_array[i].type == type && + winproc_array[i].thunk.t_from32.proc == (WNDPROC16)func) + return &winproc_array[i]; + } + } + else + { + for (i = 0; i < winproc_used; i++) + { + if (winproc_array[i].type == type && + winproc_array[i].thunk.t_from16.proc == func) + return &winproc_array[i]; + } + } + return NULL; +} + +/* initialize a new winproc */ +static inline void set_winproc( WINDOWPROC *proc, WNDPROC func, WINDOWPROCTYPE type ) +{ +#ifdef __i386__ + static FARPROC16 relay_32A, relay_32W; + + switch(type) + { + case WIN_PROC_16: + proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */ + proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */ + proc->thunk.t_from32.proc = (WNDPROC16)func; + proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */ + proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/ + proc->thunk.t_from32.relay = /* relative jump */ + (void(*)())((DWORD)WINPROC_CallProc32ATo16 - + (DWORD)(&proc->thunk.t_from32.relay + 1)); + break; + case WIN_PROC_32A: + if (!relay_32A) relay_32A = GetProcAddress16( GetModuleHandle16("user"), + "__wine_call_wndproc_32A" ); + proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */ + proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */ + proc->thunk.t_from16.proc = func; + proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */ + proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/ + proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32A); + proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32A); + proc->jmp.jmp = 0xe9; + /* Fixup relative jump */ + proc->jmp.proc = (WNDPROC)((DWORD)func - (DWORD)(&proc->jmp.proc + 1)); + break; + case WIN_PROC_32W: + if (!relay_32W) relay_32W = GetProcAddress16( GetModuleHandle16("user"), + "__wine_call_wndproc_32W" ); + proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */ + proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */ + proc->thunk.t_from16.proc = func; + proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */ + proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/ + proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32W); + proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32W); + proc->jmp.jmp = 0xe9; + /* Fixup relative jump */ + proc->jmp.proc = (WNDPROC)((char *)func - (char *)(&proc->jmp.proc + 1)); + break; + default: + /* Should not happen */ + break; + } +#else /* __i386__ */ + switch(type) + { + case WIN_PROC_16: + proc->thunk.t_from32.proc = (WNDPROC16)func; + break; + case WIN_PROC_32A: + case WIN_PROC_32W: + proc->thunk.t_from16.proc = func; + break; + default: + /* Should not happen */ + break; + } +#endif /* __i386__ */ + + proc->type = type; } static WORD get_winproc_selector(void) @@ -437,96 +523,15 @@ static WINDOWPROC *WINPROC_GetPtr( WNDPROC handle ) /* Check for a segmented pointer */ - if (!IsBadReadPtr16( (SEGPTR)handle, sizeof(proc->thunk) )) - { - ptr = MapSL( (SEGPTR)handle ); - /* It must be the thunk address */ - proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk); - if (is_valid_winproc(proc)) return proc; - } + ptr = MapSL( (SEGPTR)handle ); + /* It must be the thunk address */ + proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk); + if (is_valid_winproc(proc)) return proc; return NULL; } -/********************************************************************** - * WINPROC_AllocWinProc - * - * Allocate a new window procedure. - */ -static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC func, WINDOWPROCTYPE type, - WINDOWPROCUSER user ) -{ - static FARPROC16 relay_32A, relay_32W; - - WINDOWPROC *proc, *oldproc; - - /* Allocate a window procedure */ - - if (!(proc = alloc_winproc())) return 0; - - /* Check if the function is already a win proc */ - - if ((oldproc = WINPROC_GetPtr( func ))) - { - *proc = *oldproc; - } - else - { - switch(type) - { - case WIN_PROC_16: - proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */ - proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */ - proc->thunk.t_from32.proc = (WNDPROC16)func; - proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */ - proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/ - proc->thunk.t_from32.relay = /* relative jump */ - (void(*)())((DWORD)WINPROC_CallProc32ATo16 - - (DWORD)(&proc->thunk.t_from32.relay + 1)); - break; - case WIN_PROC_32A: - if (!relay_32A) relay_32A = GetProcAddress16( GetModuleHandle16("user"), - "__wine_call_wndproc_32A" ); - proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */ - proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */ - proc->thunk.t_from16.proc = func; - proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */ - proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/ - proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32A); - proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32A); - proc->jmp.jmp = 0xe9; - /* Fixup relative jump */ - proc->jmp.proc = (WNDPROC)((DWORD)func - (DWORD)(&proc->jmp.proc + 1)); - break; - case WIN_PROC_32W: - if (!relay_32W) relay_32W = GetProcAddress16( GetModuleHandle16("user"), - "__wine_call_wndproc_32W" ); - proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */ - proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */ - proc->thunk.t_from16.proc = func; - proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */ - proc->thunk.t_from16.ljmp = 0xea; /* ljmp relay*/ - proc->thunk.t_from16.relay_offset = OFFSETOF(relay_32W); - proc->thunk.t_from16.relay_sel = SELECTOROF(relay_32W); - proc->jmp.jmp = 0xe9; - /* Fixup relative jump */ - proc->jmp.proc = (WNDPROC)((char *)func - (char *)(&proc->jmp.proc + 1)); - break; - default: - /* Should not happen */ - break; - } - proc->magic = WINPROC_MAGIC; - proc->type = type; - proc->user = user; - } - proc->next = NULL; - TRACE("(%p,%d): returning %p\n", func, type, proc ); - return proc; -} - - /********************************************************************** * WINPROC_GetProc * @@ -560,119 +565,43 @@ WNDPROC16 WINPROC_GetProc( WNDPROC proc, WINDOWPROCTYPE type ) /********************************************************************** - * WINPROC_SetProc + * WINPROC_AllocProc * - * Set the window procedure for a window or class. There are - * three tree classes of winproc callbacks: - * - * 1) class -> wp - not subclassed - * class -> wp -> wp -> wp -> wp - SetClassLong() - * / / - * 2) window -' / - not subclassed - * window -> wp -> wp ' - SetWindowLong() - * - * 3) timer -> wp - SetTimer() - * - * Initially, winproc of the window points to the current winproc - * thunk of its class. Subclassing prepends a new thunk to the - * window winproc chain at the head of the list. Thus, window thunk - * list includes class thunks and the latter are preserved when the - * window is destroyed. + * Allocate a window procedure for a window or class. * + * Note that allocated winprocs are never freed; the idea is that even if an app creates a + * lot of windows, it will usually only have a limited number of window procedures, so the + * array won't grow too large, and this way we avoid the need to track allocations per window. */ -BOOL WINPROC_SetProc( WNDPROC *pFirst, WNDPROC func, - WINDOWPROCTYPE type, WINDOWPROCUSER user ) +WNDPROC WINPROC_AllocProc( WNDPROC func, WINDOWPROCTYPE type ) { - BOOL bRecycle = FALSE; - WINDOWPROC *proc, **ppPrev; + WINDOWPROC *proc; - /* Check if function is already in the list */ + if (!func) return NULL; - ppPrev = (WINDOWPROC **)pFirst; - proc = WINPROC_GetPtr( func ); - while (*ppPrev) + EnterCriticalSection( &winproc_cs ); + + /* check if the function is already a win proc */ + if (!(proc = WINPROC_GetPtr( func ))) { - if (proc) + /* then check if we already have a winproc for that function */ + if (!(proc = find_winproc( func, type ))) { - if (*ppPrev == proc) + if (winproc_used >= MAX_WINPROCS) + FIXME( "too many winprocs, cannot allocate one for %p/%d\n", func, type ); + else { - if ((*ppPrev)->user != user) - { - /* terminal thunk is being restored */ - - WINPROC_FreeProc( *pFirst, (*ppPrev)->user ); - *(WINDOWPROC **)pFirst = *ppPrev; - return TRUE; - } - bRecycle = TRUE; - break; - } - } - else - { - if (((*ppPrev)->type == type) && - (func == (WNDPROC)WINPROC_THUNKPROC(*ppPrev))) - { - if((*ppPrev)->user == user) - { - bRecycle = TRUE; - } - else - { - WINPROC_FreeProc( (WNDPROC)*ppPrev, user ); - *ppPrev = NULL; - } - break; + proc = &winproc_array[winproc_used++]; + set_winproc( proc, func, type ); + TRACE( "allocated %p for %p/%d (%d/%d used)\n", + proc, func, type, winproc_used, MAX_WINPROCS ); } } - - /* WPF_CLASS thunk terminates window thunk list */ - if ((*ppPrev)->user != user) break; - ppPrev = &(*ppPrev)->next; + else TRACE( "reusing %p for %p/%d\n", proc, func, type ); } - if (bRecycle) - { - /* Extract this thunk from the list */ - proc = *ppPrev; - *ppPrev = proc->next; - } - else /* Allocate a new one */ - { - if (proc) /* Was already a win proc */ - { - type = proc->type; - func = (WNDPROC)WINPROC_THUNKPROC(proc); - } - proc = WINPROC_AllocWinProc( func, type, user ); - if (!proc) return FALSE; - } - - /* Add the win proc at the head of the list */ - - TRACE("(%p,%p,%d): res=%p\n", *pFirst, func, type, proc ); - proc->next = *(WINDOWPROC **)pFirst; - *(WINDOWPROC **)pFirst = proc; - return TRUE; -} - - -/********************************************************************** - * WINPROC_FreeProc - * - * Free a list of win procs. - */ -void WINPROC_FreeProc( WNDPROC proc, WINDOWPROCUSER user ) -{ - WINDOWPROC *ptr = (WINDOWPROC *)proc; - while (ptr) - { - WINDOWPROC *next = ptr->next; - if (ptr->user != user) break; - TRACE("freeing %p (%d)\n", ptr, user); - free_winproc( ptr ); - ptr = next; - } + LeaveCriticalSection( &winproc_cs ); + return (WNDPROC)proc; } @@ -683,9 +612,7 @@ void WINPROC_FreeProc( WNDPROC proc, WINDOWPROCUSER user ) */ WINDOWPROCTYPE WINPROC_GetProcType( WNDPROC proc ) { - if (!proc || - (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC)) - return WIN_PROC_INVALID; + if (!proc) return WIN_PROC_INVALID; return ((WINDOWPROC *)proc)->type; } /**********************************************************************