[ros-diffs] [fireball] 38754: - 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.

fireball at svn.reactos.org fireball at svn.reactos.org
Wed Jan 14 10:51:51 CET 2009


Author: fireball
Date: Wed Jan 14 03:51:50 2009
New Revision: 38754

URL: http://svn.reactos.org/svn/reactos?rev=38754&view=rev
Log:
- 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.

Modified:
    trunk/reactos/subsystems/win32/win32k/ntuser/hook.c

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/hook.c?rev=38754&r1=38753&r2=38754&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] Wed Jan 14 03:51:50 2009
@@ -969,6 +969,7 @@
    UNICODE_STRING ModuleName;
    NTSTATUS Status;
    HHOOK Handle;
+   BOOLEAN ThreadReferenced = FALSE;
    DECLARE_RETURN(HHOOK);
 
    DPRINT("Enter NtUserSetWindowsHookEx\n");
@@ -1008,6 +1009,8 @@
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
          RETURN( NULL);
       }
+      /* Thread was referenced */
+      ThreadReferenced = TRUE;
       if (Thread->ThreadsProcess != PsGetCurrentProcess())
       {
          ObDereferenceObject(Thread);
@@ -1032,6 +1035,9 @@
             SetLastNtError(Status);
             RETURN( (HANDLE) NULL);
          }
+
+         /* Thread was referenced */
+         ThreadReferenced = TRUE;
       }
       else if (NULL ==  Mod)
       {
@@ -1056,10 +1062,8 @@
       DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE");
 #endif
 
-      if (NULL != Thread)
-      {
-         ObDereferenceObject(Thread);
-      }
+      /* Dereference thread if needed */
+      if (ThreadReferenced) ObDereferenceObject(Thread);
       SetLastWin32Error(ERROR_NOT_SUPPORTED);
       RETURN( NULL);
    }
@@ -1071,10 +1075,8 @@
 
    if (! NT_SUCCESS(Status))
    {
-      if (NULL != Thread)
-      {
-         ObDereferenceObject(Thread);
-      }
+      /* Dereference thread if needed */
+      if (ThreadReferenced) ObDereferenceObject(Thread);
       SetLastNtError(Status);
       RETURN( (HANDLE) NULL);
    }
@@ -1082,15 +1084,14 @@
    Hook = IntAddHook(Thread, HookId, Global, WinStaObj);
    if (NULL == Hook)
    {
-      if (NULL != Thread)
-      {
-         ObDereferenceObject(Thread);
-      }
+      /* Dereference thread if needed */
+      if (ThreadReferenced) ObDereferenceObject(Thread);
       ObDereferenceObject(WinStaObj);
       RETURN( NULL);
    }
 
-   if (NULL != Thread)
+   /* Let IntFreeHook now that this thread needs a dereference */
+   if (ThreadReferenced)
    {
       Hook->Flags |= HOOK_THREAD_REFERENCED;
    }
@@ -1102,10 +1103,6 @@
       {
          UserDereferenceObject(Hook);
          IntRemoveHook(Hook, WinStaObj, FALSE);
-         if (NULL != Thread)
-         {
-            ObDereferenceObject(Thread);
-         }
          ObDereferenceObject(WinStaObj);
          SetLastNtError(Status);
          RETURN( NULL);
@@ -1117,10 +1114,6 @@
       {
          UserDereferenceObject(Hook);
          IntRemoveHook(Hook, WinStaObj, FALSE);
-         if (NULL != Thread)
-         {
-            ObDereferenceObject(Thread);
-         }
          ObDereferenceObject(WinStaObj);
          SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
          RETURN( NULL);
@@ -1134,10 +1127,6 @@
          ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK);
          UserDereferenceObject(Hook);
          IntRemoveHook(Hook, WinStaObj, FALSE);
-         if (NULL != Thread)
-         {
-            ObDereferenceObject(Thread);
-         }
          ObDereferenceObject(WinStaObj);
          SetLastNtError(Status);
          RETURN( NULL);
@@ -1154,13 +1143,9 @@
 
 // Clear the client threads next hook.
    ClientInfo->phkCurrent = 0;
-   
+
    UserDereferenceObject(Hook);
 
-   if (NULL != Thread)
-   {
-      ObDereferenceObject(Thread);
-   }
    ObDereferenceObject(WinStaObj);
 
    RETURN( Handle);



More information about the Ros-diffs mailing list