mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
prevent memory leaks if callbacks to usermode never return
svn path=/trunk/; revision=9473
This commit is contained in:
parent
ef7b36dd46
commit
f2992e0c09
7 changed files with 103 additions and 39 deletions
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -199,8 +199,6 @@ IntInitializeDesktopGraphics(VOID)
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue