prevent memory leaks if callbacks to usermode never return

svn path=/trunk/; revision=9473
This commit is contained in:
Thomas Bluemel 2004-05-22 21:12:15 +00:00
parent ef7b36dd46
commit f2992e0c09
7 changed files with 103 additions and 39 deletions

View file

@ -8,6 +8,8 @@ typedef struct _W32THREAD
PVOID MessageQueue; PVOID MessageQueue;
FAST_MUTEX WindowListLock; FAST_MUTEX WindowListLock;
LIST_ENTRY WindowListHead; LIST_ENTRY WindowListHead;
FAST_MUTEX W32CallbackListLock;
LIST_ENTRY W32CallbackListHead;
struct _KBDTABLES* KeyboardLayout; struct _KBDTABLES* KeyboardLayout;
struct _DESKTOP_OBJECT* Desktop; struct _DESKTOP_OBJECT* Desktop;
HANDLE hDesktop; HANDLE hDesktop;

View file

@ -21,9 +21,6 @@ IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
HMENU STDCALL HMENU STDCALL
IntLoadSysMenuTemplate(); IntLoadSysMenuTemplate();
BOOL STDCALL
IntLoadDefaultCursors(BOOL SetDefault);
LRESULT STDCALL LRESULT STDCALL
IntCallHookProc(INT HookId, IntCallHookProc(INT HookId,
INT Code, INT Code,
@ -33,4 +30,13 @@ IntCallHookProc(INT HookId,
BOOLEAN Ansi, BOOLEAN Ansi,
PUNICODE_STRING ModuleName); PUNICODE_STRING ModuleName);
VOID FASTCALL
IntCleanupThreadCallbacks(PW32THREAD W32Thread);
PVOID FASTCALL
IntCbAllocateMemory(ULONG Size);
VOID FASTCALL
IntCbFreeMemory(PVOID Data);
#endif /* _WIN32K_CALLBACK_H */ #endif /* _WIN32K_CALLBACK_H */

View file

@ -21,6 +21,7 @@
#define TAG_TIMER TAG('T', 'I', 'M', 'R') /* timer entry */ #define TAG_TIMER TAG('T', 'I', 'M', 'R') /* timer entry */
#define TAG_TIMERTD TAG('T', 'I', 'M', 'T') /* timer thread dereference list */ #define TAG_TIMERTD TAG('T', 'I', 'M', 'T') /* timer thread dereference list */
#define TAG_TIMERBMP TAG('T', 'I', 'M', 'B') /* timers bitmap */ #define TAG_TIMERBMP TAG('T', 'I', 'M', 'B') /* timers bitmap */
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K') /* callback memory */
/* objects */ /* objects */
#define TAG_BEZIER TAG('B', 'E', 'Z', 'R') /* bezier */ #define TAG_BEZIER TAG('B', 'E', 'Z', 'R') /* bezier */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dllmain.c,v 1.75 2004/05/22 16:48:50 weiden Exp $ /* $Id: dllmain.c,v 1.76 2004/05/22 21:12:15 weiden Exp $
* *
* Entry Point for win32k.sys * Entry Point for win32k.sys
*/ */
@ -149,6 +149,8 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
Win32Thread->MessagePumpHookValue = 0; Win32Thread->MessagePumpHookValue = 0;
InitializeListHead(&Win32Thread->WindowListHead); InitializeListHead(&Win32Thread->WindowListHead);
ExInitializeFastMutex(&Win32Thread->WindowListLock); ExInitializeFastMutex(&Win32Thread->WindowListLock);
InitializeListHead(&Win32Thread->W32CallbackListHead);
ExInitializeFastMutex(&Win32Thread->W32CallbackListLock);
/* By default threads get assigned their process's desktop. */ /* By default threads get assigned their process's desktop. */
Win32Thread->Desktop = NULL; Win32Thread->Desktop = NULL;
@ -182,6 +184,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
DestroyThreadWindows(Thread); DestroyThreadWindows(Thread);
IntBlockInput(Win32Thread, FALSE); IntBlockInput(Win32Thread, FALSE);
MsqDestroyMessageQueue(Win32Thread->MessageQueue); MsqDestroyMessageQueue(Win32Thread->MessageQueue);
IntCleanupThreadCallbacks(Win32Thread);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -16,15 +16,19 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: callback.c,v 1.22 2004/05/10 17:07:18 weiden Exp $ /* $Id: callback.c,v 1.23 2004/05/22 21:12:15 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* PURPOSE: Window classes * PURPOSE: Window classes
* FILE: subsys/win32k/ntuser/wndproc.c * FILE: subsys/win32k/ntuser/wndproc.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Thomas Weidenmueller (w3seek@users.sourceforge.net)
* REVISION HISTORY: * REVISION HISTORY:
* 06-06-2001 CSH Created * 06-06-2001 CSH Created
* NOTES: Please use the Callback Memory Management functions for
* callbacks to make sure, the memory is freed on thread
* termination!
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -34,7 +38,78 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K') /* CALLBACK MEMORY MANAGEMENT ************************************************/
typedef struct _INT_CALLBACK_HEADER
{
/* list entry in the W32THREAD structure */
LIST_ENTRY ListEntry;
} INT_CALLBACK_HEADER, *PINT_CALLBACK_HEADER;
PVOID FASTCALL
IntCbAllocateMemory(ULONG Size)
{
PINT_CALLBACK_HEADER Mem;
PW32THREAD W32Thread;
if(!(Mem = ExAllocatePoolWithTag(PagedPool, Size + sizeof(INT_CALLBACK_HEADER),
TAG_CALLBACK)))
{
return NULL;
}
W32Thread = PsGetWin32Thread();
ASSERT(W32Thread);
/* insert the callback memory into the thread's callback list */
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
InsertTailList(&W32Thread->W32CallbackListHead, &Mem->ListEntry);
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
return (Mem + 1);
}
VOID FASTCALL
IntCbFreeMemory(PVOID Data)
{
PINT_CALLBACK_HEADER Mem;
PW32THREAD W32Thread;
ASSERT(Data);
Mem = ((PINT_CALLBACK_HEADER)Data - 1);
W32Thread = PsGetWin32Thread();
ASSERT(W32Thread);
/* remove the memory block from the thread's callback list */
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
RemoveEntryList(&Mem->ListEntry);
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
/* free memory */
ExFreePool(Mem);
}
VOID FASTCALL
IntCleanupThreadCallbacks(PW32THREAD W32Thread)
{
PLIST_ENTRY CurrentEntry;
PINT_CALLBACK_HEADER Mem;
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
while (!IsListEmpty(&W32Thread->W32CallbackListHead))
{
CurrentEntry = RemoveHeadList(&W32Thread->W32CallbackListHead);
Mem = CONTAINING_RECORD(CurrentEntry, INT_CALLBACK_HEADER,
ListEntry);
/* free memory */
ExFreePool(Mem);
}
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
}
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -85,7 +160,7 @@ IntCallWindowProc(WNDPROC Proc,
if (0 < lParamBufferSize) if (0 < lParamBufferSize)
{ {
ArgumentLength = sizeof(WINDOWPROC_CALLBACK_ARGUMENTS) + lParamBufferSize; ArgumentLength = sizeof(WINDOWPROC_CALLBACK_ARGUMENTS) + lParamBufferSize;
Arguments = ExAllocatePoolWithTag(PagedPool,ArgumentLength, TAG_CALLBACK); Arguments = IntCbAllocateMemory(ArgumentLength);
if (NULL == Arguments) if (NULL == Arguments)
{ {
DPRINT1("Unable to allocate buffer for window proc callback\n"); DPRINT1("Unable to allocate buffer for window proc callback\n");
@ -117,7 +192,7 @@ IntCallWindowProc(WNDPROC Proc,
{ {
if (0 < lParamBufferSize) if (0 < lParamBufferSize)
{ {
ExFreePool(Arguments); IntCbFreeMemory(Arguments);
} }
return -1; return -1;
} }
@ -128,7 +203,7 @@ IntCallWindowProc(WNDPROC Proc,
RtlMoveMemory((PVOID) lParam, RtlMoveMemory((PVOID) lParam,
(PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)), (PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
lParamBufferSize); lParamBufferSize);
ExFreePool(Arguments); IntCbFreeMemory(Arguments);
} }
return Result; return Result;
@ -156,28 +231,6 @@ IntLoadSysMenuTemplate()
return (HMENU)Result; return (HMENU)Result;
} }
BOOL STDCALL
IntLoadDefaultCursors(BOOL SetDefault)
{
LRESULT Result;
NTSTATUS Status;
PVOID ResultPointer;
ULONG ResultLength;
ResultPointer = &Result;
ResultLength = sizeof(LRESULT);
Status = NtW32Call(USER32_CALLBACK_LOADDEFAULTCURSORS,
&SetDefault,
sizeof(BOOL),
&ResultPointer,
&ResultLength);
if (!NT_SUCCESS(Status))
{
return(0);
}
return (BOOL)Result;
}
LRESULT STDCALL LRESULT STDCALL
IntCallHookProc(INT HookId, IntCallHookProc(INT HookId,
INT Code, INT Code,
@ -229,7 +282,7 @@ IntCallHookProc(INT HookId,
return 0; return 0;
} }
Argument = ExAllocatePoolWithTag(PagedPool, ArgumentLength, TAG_CALLBACK); Argument = IntCbAllocateMemory(ArgumentLength);
if (NULL == Argument) if (NULL == Argument)
{ {
DPRINT1("HookProc callback failed: out of memory\n"); DPRINT1("HookProc callback failed: out of memory\n");
@ -283,6 +336,9 @@ IntCallHookProc(INT HookId,
ArgumentLength, ArgumentLength,
&ResultPointer, &ResultPointer,
&ResultLength); &ResultLength);
IntCbFreeMemory(Argument);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return 0; return 0;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: message.c,v 1.68 2004/05/22 09:22:41 weiden Exp $ /* $Id: message.c,v 1.69 2004/05/22 21:12:15 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -410,8 +410,6 @@ IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *Hit
if(!(Window = IntGetWindowObject(Msg->hwnd))) if(!(Window = IntGetWindowObject(Msg->hwnd)))
{ {
/* FIXME - change the mouse cursor to an arrow, maybe do this a better way */
IntLoadDefaultCursors(TRUE);
/* let's just eat the message?! */ /* let's just eat the message?! */
return TRUE; return TRUE;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* $Id: winsta.c,v 1.62 2004/05/15 23:07:11 weiden Exp $ * $Id: winsta.c,v 1.63 2004/05/22 21:12:15 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -198,9 +198,7 @@ IntInitializeDesktopGraphics(VOID)
DC_SetOwnership(ScreenDeviceContext, NULL); DC_SetOwnership(ScreenDeviceContext, NULL);
EnableMouse(ScreenDeviceContext); EnableMouse(ScreenDeviceContext);
/* not the best place to load the cursors but it's good for now */
IntLoadDefaultCursors(FALSE);
NtUserAcquireOrReleaseInputOwnership(FALSE); NtUserAcquireOrReleaseInputOwnership(FALSE);
return TRUE; return TRUE;