mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 08:30:21 +00:00
- Revert 38750, a dereference happens when that hook is freed by IntFreeHook.
- Change thread dereferencing mechanism in NtUserSetWindowsHookEx: * A thread may be referenced in some cases when it's a system-wide hook, however dereference flag was not set for these, so they leaked a reference. Add a ThreadReferenced boolean var to track real references, and set hook's flag according to it. * There should be no need to call ObDereferenceObject on a thread when a call to IntRemoveHook was already performed (in failure branches). IntFreeHook() will dereference the thread object. svn path=/trunk/; revision=38754
This commit is contained in:
parent
3bb7973d97
commit
2ed6687632
1 changed files with 15 additions and 30 deletions
|
@ -969,6 +969,7 @@ NtUserSetWindowsHookEx(
|
||||||
UNICODE_STRING ModuleName;
|
UNICODE_STRING ModuleName;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HHOOK Handle;
|
HHOOK Handle;
|
||||||
|
BOOLEAN ThreadReferenced = FALSE;
|
||||||
DECLARE_RETURN(HHOOK);
|
DECLARE_RETURN(HHOOK);
|
||||||
|
|
||||||
DPRINT("Enter NtUserSetWindowsHookEx\n");
|
DPRINT("Enter NtUserSetWindowsHookEx\n");
|
||||||
|
@ -1008,6 +1009,8 @@ NtUserSetWindowsHookEx(
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
|
/* Thread was referenced */
|
||||||
|
ThreadReferenced = TRUE;
|
||||||
if (Thread->ThreadsProcess != PsGetCurrentProcess())
|
if (Thread->ThreadsProcess != PsGetCurrentProcess())
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
|
@ -1032,6 +1035,9 @@ NtUserSetWindowsHookEx(
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
RETURN( (HANDLE) NULL);
|
RETURN( (HANDLE) NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Thread was referenced */
|
||||||
|
ThreadReferenced = TRUE;
|
||||||
}
|
}
|
||||||
else if (NULL == Mod)
|
else if (NULL == Mod)
|
||||||
{
|
{
|
||||||
|
@ -1056,10 +1062,8 @@ NtUserSetWindowsHookEx(
|
||||||
DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE");
|
DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (NULL != Thread)
|
/* Dereference thread if needed */
|
||||||
{
|
if (ThreadReferenced) ObDereferenceObject(Thread);
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
SetLastWin32Error(ERROR_NOT_SUPPORTED);
|
SetLastWin32Error(ERROR_NOT_SUPPORTED);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
|
@ -1071,10 +1075,8 @@ NtUserSetWindowsHookEx(
|
||||||
|
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (NULL != Thread)
|
/* Dereference thread if needed */
|
||||||
{
|
if (ThreadReferenced) ObDereferenceObject(Thread);
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
RETURN( (HANDLE) NULL);
|
RETURN( (HANDLE) NULL);
|
||||||
}
|
}
|
||||||
|
@ -1082,15 +1084,14 @@ NtUserSetWindowsHookEx(
|
||||||
Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
|
Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
|
||||||
if (NULL == Hook)
|
if (NULL == Hook)
|
||||||
{
|
{
|
||||||
if (NULL != Thread)
|
/* Dereference thread if needed */
|
||||||
{
|
if (ThreadReferenced) ObDereferenceObject(Thread);
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != Thread)
|
/* Let IntFreeHook now that this thread needs a dereference */
|
||||||
|
if (ThreadReferenced)
|
||||||
{
|
{
|
||||||
Hook->Flags |= HOOK_THREAD_REFERENCED;
|
Hook->Flags |= HOOK_THREAD_REFERENCED;
|
||||||
}
|
}
|
||||||
|
@ -1102,10 +1103,6 @@ NtUserSetWindowsHookEx(
|
||||||
{
|
{
|
||||||
UserDereferenceObject(Hook);
|
UserDereferenceObject(Hook);
|
||||||
IntRemoveHook(Hook, WinStaObj, FALSE);
|
IntRemoveHook(Hook, WinStaObj, FALSE);
|
||||||
if (NULL != Thread)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
|
@ -1117,10 +1114,6 @@ NtUserSetWindowsHookEx(
|
||||||
{
|
{
|
||||||
UserDereferenceObject(Hook);
|
UserDereferenceObject(Hook);
|
||||||
IntRemoveHook(Hook, WinStaObj, FALSE);
|
IntRemoveHook(Hook, WinStaObj, FALSE);
|
||||||
if (NULL != Thread)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
|
@ -1134,10 +1127,6 @@ NtUserSetWindowsHookEx(
|
||||||
ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK);
|
ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK);
|
||||||
UserDereferenceObject(Hook);
|
UserDereferenceObject(Hook);
|
||||||
IntRemoveHook(Hook, WinStaObj, FALSE);
|
IntRemoveHook(Hook, WinStaObj, FALSE);
|
||||||
if (NULL != Thread)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
|
@ -1154,13 +1143,9 @@ NtUserSetWindowsHookEx(
|
||||||
|
|
||||||
// Clear the client threads next hook.
|
// Clear the client threads next hook.
|
||||||
ClientInfo->phkCurrent = 0;
|
ClientInfo->phkCurrent = 0;
|
||||||
|
|
||||||
UserDereferenceObject(Hook);
|
UserDereferenceObject(Hook);
|
||||||
|
|
||||||
if (NULL != Thread)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(WinStaObj);
|
ObDereferenceObject(WinStaObj);
|
||||||
|
|
||||||
RETURN( Handle);
|
RETURN( Handle);
|
||||||
|
|
Loading…
Reference in a new issue