mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +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;
|
||||
FAST_MUTEX WindowListLock;
|
||||
LIST_ENTRY WindowListHead;
|
||||
FAST_MUTEX W32CallbackListLock;
|
||||
LIST_ENTRY W32CallbackListHead;
|
||||
struct _KBDTABLES* KeyboardLayout;
|
||||
struct _DESKTOP_OBJECT* Desktop;
|
||||
HANDLE hDesktop;
|
||||
|
|
|
@ -21,9 +21,6 @@ IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
|
|||
HMENU STDCALL
|
||||
IntLoadSysMenuTemplate();
|
||||
|
||||
BOOL STDCALL
|
||||
IntLoadDefaultCursors(BOOL SetDefault);
|
||||
|
||||
LRESULT STDCALL
|
||||
IntCallHookProc(INT HookId,
|
||||
INT Code,
|
||||
|
@ -33,4 +30,13 @@ IntCallHookProc(INT HookId,
|
|||
BOOLEAN Ansi,
|
||||
PUNICODE_STRING ModuleName);
|
||||
|
||||
VOID FASTCALL
|
||||
IntCleanupThreadCallbacks(PW32THREAD W32Thread);
|
||||
|
||||
PVOID FASTCALL
|
||||
IntCbAllocateMemory(ULONG Size);
|
||||
|
||||
VOID FASTCALL
|
||||
IntCbFreeMemory(PVOID Data);
|
||||
|
||||
#endif /* _WIN32K_CALLBACK_H */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define TAG_TIMER TAG('T', 'I', 'M', 'R') /* timer entry */
|
||||
#define TAG_TIMERTD TAG('T', 'I', 'M', 'T') /* timer thread dereference list */
|
||||
#define TAG_TIMERBMP TAG('T', 'I', 'M', 'B') /* timers bitmap */
|
||||
#define TAG_CALLBACK TAG('C', 'B', 'C', 'K') /* callback memory */
|
||||
|
||||
/* objects */
|
||||
#define TAG_BEZIER TAG('B', 'E', 'Z', 'R') /* bezier */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
*/
|
||||
|
@ -149,6 +149,8 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
|
|||
Win32Thread->MessagePumpHookValue = 0;
|
||||
InitializeListHead(&Win32Thread->WindowListHead);
|
||||
ExInitializeFastMutex(&Win32Thread->WindowListLock);
|
||||
InitializeListHead(&Win32Thread->W32CallbackListHead);
|
||||
ExInitializeFastMutex(&Win32Thread->W32CallbackListLock);
|
||||
|
||||
/* By default threads get assigned their process's desktop. */
|
||||
Win32Thread->Desktop = NULL;
|
||||
|
@ -182,6 +184,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
|
|||
DestroyThreadWindows(Thread);
|
||||
IntBlockInput(Win32Thread, FALSE);
|
||||
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
|
||||
IntCleanupThreadCallbacks(Win32Thread);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -16,15 +16,19 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Window classes
|
||||
* FILE: subsys/win32k/ntuser/wndproc.c
|
||||
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Thomas Weidenmueller (w3seek@users.sourceforge.net)
|
||||
* REVISION HISTORY:
|
||||
* 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 ******************************************************************/
|
||||
|
@ -34,7 +38,78 @@
|
|||
#define NDEBUG
|
||||
#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 *****************************************************************/
|
||||
|
||||
|
@ -85,7 +160,7 @@ IntCallWindowProc(WNDPROC Proc,
|
|||
if (0 < lParamBufferSize)
|
||||
{
|
||||
ArgumentLength = sizeof(WINDOWPROC_CALLBACK_ARGUMENTS) + lParamBufferSize;
|
||||
Arguments = ExAllocatePoolWithTag(PagedPool,ArgumentLength, TAG_CALLBACK);
|
||||
Arguments = IntCbAllocateMemory(ArgumentLength);
|
||||
if (NULL == Arguments)
|
||||
{
|
||||
DPRINT1("Unable to allocate buffer for window proc callback\n");
|
||||
|
@ -117,7 +192,7 @@ IntCallWindowProc(WNDPROC Proc,
|
|||
{
|
||||
if (0 < lParamBufferSize)
|
||||
{
|
||||
ExFreePool(Arguments);
|
||||
IntCbFreeMemory(Arguments);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -128,7 +203,7 @@ IntCallWindowProc(WNDPROC Proc,
|
|||
RtlMoveMemory((PVOID) lParam,
|
||||
(PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
|
||||
lParamBufferSize);
|
||||
ExFreePool(Arguments);
|
||||
IntCbFreeMemory(Arguments);
|
||||
}
|
||||
|
||||
return Result;
|
||||
|
@ -156,28 +231,6 @@ IntLoadSysMenuTemplate()
|
|||
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
|
||||
IntCallHookProc(INT HookId,
|
||||
INT Code,
|
||||
|
@ -229,7 +282,7 @@ IntCallHookProc(INT HookId,
|
|||
return 0;
|
||||
}
|
||||
|
||||
Argument = ExAllocatePoolWithTag(PagedPool, ArgumentLength, TAG_CALLBACK);
|
||||
Argument = IntCbAllocateMemory(ArgumentLength);
|
||||
if (NULL == Argument)
|
||||
{
|
||||
DPRINT1("HookProc callback failed: out of memory\n");
|
||||
|
@ -283,6 +336,9 @@ IntCallHookProc(INT HookId,
|
|||
ArgumentLength,
|
||||
&ResultPointer,
|
||||
&ResultLength);
|
||||
|
||||
IntCbFreeMemory(Argument);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -410,8 +410,6 @@ IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *Hit
|
|||
|
||||
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?! */
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -198,9 +198,7 @@ IntInitializeDesktopGraphics(VOID)
|
|||
DC_SetOwnership(ScreenDeviceContext, NULL);
|
||||
|
||||
EnableMouse(ScreenDeviceContext);
|
||||
|
||||
/* not the best place to load the cursors but it's good for now */
|
||||
IntLoadDefaultCursors(FALSE);
|
||||
|
||||
NtUserAcquireOrReleaseInputOwnership(FALSE);
|
||||
|
||||
return TRUE;
|
||||
|
|
Loading…
Reference in a new issue