[ros-diffs] [weiden] 30514: Optimize SendMessageA/W to allow certain messages be sent without calling win32k

weiden at svn.reactos.org weiden at svn.reactos.org
Sat Nov 17 01:40:23 CET 2007


Author: weiden
Date: Sat Nov 17 03:40:22 2007
New Revision: 30514

URL: http://svn.reactos.org/svn/reactos?rev=30514&view=rev
Log:
Optimize SendMessageA/W to allow certain messages be sent without calling win32k

Modified:
    trunk/reactos/dll/win32/user32/include/user32.h
    trunk/reactos/dll/win32/user32/windows/message.c
    trunk/reactos/include/reactos/win32k/ntuser.h
    trunk/reactos/subsystems/win32/win32k/include/win32.h
    trunk/reactos/subsystems/win32/win32k/include/window.h
    trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
    trunk/reactos/subsystems/win32/win32k/ntuser/message.c
    trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
    trunk/reactos/subsystems/win32/win32k/ntuser/window.c

Modified: trunk/reactos/dll/win32/user32/include/user32.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/include/user32.h?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/include/user32.h (original)
+++ trunk/reactos/dll/win32/user32/include/user32.h Sat Nov 17 03:40:22 2007
@@ -85,6 +85,12 @@
     return (PVOID)((ULONG_PTR)Ptr + g_pi->UserHeapDelta);
 }
 
+static __inline BOOL
+IsThreadHooked(PW32THREADINFO ti)
+{
+    return ti->Hooks != 0;
+}
+
 PCALLPROC FASTCALL ValidateCallProc(HANDLE hCallProc);
 PWINDOW FASTCALL ValidateHwnd(HWND hwnd);
 PWINDOW FASTCALL ValidateHwndOrDesk(HWND hwnd);

Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/message.c?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c Sat Nov 17 03:40:22 2007
@@ -1298,6 +1298,30 @@
 }
 
 
+static LRESULT WINAPI
+IntCallMessageProc(IN PWINDOW Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN LPARAM lParam, IN BOOL Ansi)
+{
+    WNDPROC WndProc;
+    BOOL IsAnsi;
+
+    if (Wnd->IsSystem)
+    {
+        WndProc = (Ansi ? Wnd->WndProcExtra : Wnd->WndProc);
+        IsAnsi = Ansi;
+    }
+    else
+    {
+        WndProc = Wnd->WndProc;
+        IsAnsi = !Wnd->Unicode;
+    }
+
+    if (!Ansi)
+        return IntCallWindowProcW(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
+    else
+        return IntCallWindowProcA(IsAnsi, WndProc, hWnd, Msg, wParam, lParam);
+}
+
+
 /*
  * @implemented
  */
@@ -1651,6 +1675,25 @@
   NTUSERSENDMESSAGEINFO Info;
   LRESULT Result;
 
+  if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
+  {
+      PWINDOW Window;
+      PW32THREADINFO ti = GetW32ThreadInfo();
+
+      Window = ValidateHwnd(Wnd);
+      if (Window != NULL && SharedPtrToUser(Window->ti) == ti && !IsThreadHooked(ti))
+      {
+          /* NOTE: We can directly send messages to the window procedure
+                   if *all* the following conditions are met:
+
+                   * Window belongs to calling thread
+                   * The calling thread is not being hooked
+           */
+
+          return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, FALSE);
+      }
+  }
+
   UMMsg.hwnd = Wnd;
   UMMsg.message = Msg;
   UMMsg.wParam = wParam;
@@ -1688,6 +1731,25 @@
   MSG KMMsg;
   LRESULT Result;
   NTUSERSENDMESSAGEINFO Info;
+
+  if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
+  {
+      PWINDOW Window;
+      PW32THREADINFO ti = GetW32ThreadInfo();
+
+      Window = ValidateHwnd(Wnd);
+      if (Window != NULL && SharedPtrToUser(Window->ti) == ti && !IsThreadHooked(ti))
+      {
+          /* NOTE: We can directly send messages to the window procedure
+                   if *all* the following conditions are met:
+
+                   * Window belongs to calling thread
+                   * The calling thread is not being hooked
+           */
+
+          return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, TRUE);
+      }
+  }
 
   AnsiMsg.hwnd = Wnd;
   AnsiMsg.message = Msg;

Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntuser.h?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Sat Nov 17 03:40:22 2007
@@ -100,6 +100,16 @@
     struct _W32THREADINFO *ti;
     RECT WindowRect;
     RECT ClientRect;
+
+    WNDPROC WndProc;
+    union
+    {
+        /* Pointer to a call procedure handle */
+        PCALLPROC CallProc;
+        /* Extra Wnd proc (windows of system classes) */
+        WNDPROC WndProcExtra;
+    };
+
     /* Size of the extra data associated with the window. */
     ULONG ExtraDataSize;
     /* Style. */
@@ -117,6 +127,8 @@
     UNICODE_STRING WindowName;
 
     UINT Unicode : 1;
+    /* Indicates whether the window is derived from a system class */
+    UINT IsSystem : 1;
 } WINDOW, *PWINDOW;
 
 typedef struct _W32PROCESSINFO
@@ -141,6 +153,8 @@
     PVOID DesktopHeapBase;
     ULONG_PTR DesktopHeapLimit;
     ULONG_PTR DesktopHeapDelta;
+    /* A mask of what hooks are currently active */
+    ULONG Hooks;
 } W32THREADINFO, *PW32THREADINFO;
 
 /* Window Client Information structure */

Modified: trunk/reactos/subsystems/win32/win32k/include/win32.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/win32.h?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/win32.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/win32.h Sat Nov 17 03:40:22 2007
@@ -14,7 +14,7 @@
   DWORD MessagePumpHookValue;
   BOOLEAN IsExiting;
   SINGLE_LIST_ENTRY  ReferencesList;
-
+  ULONG Hooks;
   PW32THREADINFO ThreadInfo;
 } W32THREAD, *PW32THREAD;
 

Modified: trunk/reactos/subsystems/win32/win32k/include/window.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/window.h?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/window.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/window.h Sat Nov 17 03:40:22 2007
@@ -36,15 +36,6 @@
   PW32THREADINFO ti;
   /* Pointer to the desktop */
   PDESKTOP Desktop;
-  union
-  {
-    /* Pointer to a call procedure handle */
-    PCALLPROC CallProc;
-    /* Extra Wnd proc (windows of system classes) */
-    WNDPROC WndProcExtra;
-  };
-  /* Indicates whether the window is derived from a system class */
-  BOOL IsSystem;
   /* Context help id */
   DWORD ContextHelpId;
   /* system menu handle. */
@@ -78,7 +69,6 @@
   ULONG PropListItems;
   /* Scrollbar info */
   PWINDOW_SCROLLINFO Scroll;
-  WNDPROC WndProc;
   PETHREAD OwnerThread;
   HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/
   PINTERNALPOS InternalPos;

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=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c Sat Nov 17 03:40:22 2007
@@ -35,6 +35,7 @@
 #include <debug.h>
 
 #define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
+#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
 
 static PHOOKTABLE GlobalHooks;
 
@@ -89,6 +90,7 @@
 static PHOOK
 IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinStaObj)
 {
+   PW32THREAD W32Thread;
    PHOOK Hook;
    PHOOKTABLE Table = Global ? GlobalHooks : MsqGetHooks(((PW32THREAD)Thread->Tcb.Win32Thread)->MessageQueue);
    HANDLE Handle;
@@ -119,6 +121,13 @@
    Hook->Self = Handle;
    Hook->Thread = Thread;
    Hook->HookId = HookId;
+
+   W32Thread = ((PW32THREAD)Thread->Tcb.Win32Thread);
+   ASSERT(W32Thread != NULL);
+   W32Thread->Hooks |= HOOKID_TO_FLAG(HookId);
+   if (W32Thread->ThreadInfo != NULL)
+       W32Thread->ThreadInfo->Hooks = W32Thread->Hooks;
+
    RtlInitUnicodeString(&Hook->ModuleName, NULL);
 
    InsertHeadList(&Table->Hooks[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
@@ -213,6 +222,7 @@
 static VOID
 IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj, BOOL TableAlreadyLocked)
 {
+   PW32THREAD W32Thread;
    PHOOKTABLE Table = IntGetTable(Hook);
 
    ASSERT(NULL != Table);
@@ -220,6 +230,12 @@
    {
       return;
    }
+
+   W32Thread = ((PW32THREAD)Hook->Thread->Tcb.Win32Thread);
+   ASSERT(W32Thread != NULL);
+   W32Thread->Hooks &= ~HOOKID_TO_FLAG(Hook->HookId);
+   if (W32Thread->ThreadInfo != NULL)
+       W32Thread->ThreadInfo->Hooks = W32Thread->Hooks;
 
    if (0 != Table->Counts[HOOKID_TO_INDEX(Hook->HookId)])
    {

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/message.c?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c Sat Nov 17 03:40:22 2007
@@ -379,14 +379,14 @@
             MsgInfo.HandledByKernel = FALSE;
             Result = 0;
 
-            if (Window->IsSystem)
+            if (Window->Wnd->IsSystem)
             {
-                MsgInfo.Proc = (!MsgInfo.Ansi ? Window->WndProc : Window->WndProcExtra);
+                MsgInfo.Proc = (!MsgInfo.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
             }
             else
             {
                 MsgInfo.Ansi = !Window->Wnd->Unicode;
-                MsgInfo.Proc = Window->WndProc;
+                MsgInfo.Proc = Window->Wnd->WndProc;
             }
          }
       }
@@ -1390,7 +1390,7 @@
           RETURN( FALSE);
       }
 
-      Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
+      Result = (ULONG_PTR)co_IntCallWindowProc(Window->Wnd->WndProc, !Window->Wnd->Unicode, hWnd, Msg, wParam,
                lParamPacked,lParamBufferSize);
 
       if(uResult)
@@ -1569,14 +1569,14 @@
          Info.Ansi = ! Window->Wnd->Unicode;
       }
 
-      if (Window->IsSystem)
-      {
-          Info.Proc = (!Info.Ansi ? Window->WndProc : Window->WndProcExtra);
+      if (Window->Wnd->IsSystem)
+      {
+          Info.Proc = (!Info.Ansi ? Window->Wnd->WndProc : Window->Wnd->WndProcExtra);
       }
       else
       {
           Info.Ansi = !Window->Wnd->Unicode;
-          Info.Proc = Window->WndProc;
+          Info.Proc = Window->Wnd->WndProc;
       }
    }
    else

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/misc.c?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Sat Nov 17 03:40:22 2007
@@ -2585,6 +2585,7 @@
             /* initialize it */
             ti->kpi = GetW32ProcessInfo();
             ti->pi = UserHeapAddressToUser(ti->kpi);
+            ti->Hooks = W32Thread->Hooks;
             if (W32Thread->Desktop != NULL)
             {
                 ti->Desktop = W32Thread->Desktop->DesktopInfo;

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/window.c?rev=30514&r1=30513&r2=30514&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Sat Nov 17 03:40:22 2007
@@ -519,33 +519,33 @@
 
     ASSERT(UserIsEnteredExclusive() == TRUE);
 
-    if (Window->IsSystem)
+    if (Wnd->IsSystem)
     {
-        return (Ansi ? Window->WndProcExtra : Window->WndProc);
+        return (Ansi ? Wnd->WndProcExtra : Wnd->WndProc);
     }
     else
     {
         if (!Ansi == Wnd->Unicode)
         {
-            return Window->WndProc;
+            return Wnd->WndProc;
         }
         else
         {
-            if (Window->CallProc != NULL)
+            if (Wnd->CallProc != NULL)
             {
-                return GetCallProcHandle(Window->CallProc);
+                return GetCallProcHandle(Wnd->CallProc);
             }
             else
             {
                 PCALLPROC NewCallProc, CallProc;
 
                 NewCallProc = UserFindCallProc(Wnd->Class,
-                                               Window->WndProc,
+                                               Wnd->WndProc,
                                                Wnd->Unicode);
                 if (NewCallProc == NULL)
                 {
                     NewCallProc = CreateCallProc(Wnd->ti->Desktop,
-                                                 Window->WndProc,
+                                                 Wnd->WndProc,
                                                  Wnd->Unicode,
                                                  Wnd->ti->kpi);
                     if (NewCallProc == NULL)
@@ -558,8 +558,8 @@
                                            NewCallProc);
                 }
 
-                CallProc = Window->CallProc;
-                Window->CallProc = NewCallProc;
+                CallProc = Wnd->CallProc;
+                Wnd->CallProc = NewCallProc;
 
                 return GetCallProcHandle((CallProc == NULL ? NewCallProc : CallProc));
             }
@@ -1645,19 +1645,19 @@
 
    Wnd->UserData = 0;
 
-   Window->IsSystem = Wnd->Class->System;
+   Wnd->IsSystem = Wnd->Class->System;
    if (Wnd->Class->System)
    {
        /* NOTE: Always create a unicode window for system classes! */
        Wnd->Unicode = TRUE;
-       Window->WndProc = Wnd->Class->WndProc;
-       Window->WndProcExtra = Wnd->Class->WndProcExtra;
+       Wnd->WndProc = Wnd->Class->WndProc;
+       Wnd->WndProcExtra = Wnd->Class->WndProcExtra;
    }
    else
    {
        Wnd->Unicode = Wnd->Class->Unicode;
-       Window->WndProc = Wnd->Class->WndProc;
-       Window->CallProc = NULL;
+       Wnd->WndProc = Wnd->Class->WndProc;
+       Wnd->CallProc = NULL;
    }
 
    Window->OwnerThread = PsGetCurrentThread();
@@ -3608,25 +3608,25 @@
     }
 
     /* attempt to get the previous window proc */
-    if (Window->IsSystem)
+    if (Wnd->IsSystem)
     {
-        Ret = (Ansi ? Window->WndProcExtra : Window->WndProc);
+        Ret = (Ansi ? Wnd->WndProcExtra : Wnd->WndProc);
     }
     else
     {
         if (!Ansi == Wnd->Unicode)
         {
-            Ret = Window->WndProc;
+            Ret = Wnd->WndProc;
         }
         else
         {
             CallProc = UserFindCallProc(Wnd->Class,
-                                        Window->WndProc,
+                                        Wnd->WndProc,
                                         Wnd->Unicode);
             if (CallProc == NULL)
             {
                 CallProc = CreateCallProc(NULL,
-                                          Window->WndProc,
+                                          Wnd->WndProc,
                                           Wnd->Unicode,
                                           Wnd->ti->kpi);
                 if (CallProc == NULL)
@@ -3639,9 +3639,9 @@
                                        CallProc);
             }
 
-            Window->CallProc = CallProc;
-
-            Ret = GetCallProcHandle(Window->CallProc);
+            Wnd->CallProc = CallProc;
+
+            Ret = GetCallProcHandle(Wnd->CallProc);
         }
     }
 
@@ -3649,22 +3649,22 @@
     {
         /* check if the new procedure matches with the one in the
            window class. If so, we need to restore both procedures! */
-        Window->IsSystem = (NewWndProc == Wnd->Class->WndProc ||
-                            NewWndProc == Wnd->Class->WndProcExtra);
-
-        if (Window->IsSystem)
+        Wnd->IsSystem = (NewWndProc == Wnd->Class->WndProc ||
+                         NewWndProc == Wnd->Class->WndProcExtra);
+
+        if (Wnd->IsSystem)
         {
-            Window->WndProc = Wnd->Class->WndProc;
-            Window->WndProcExtra = Wnd->Class->WndProcExtra;
+            Wnd->WndProc = Wnd->Class->WndProc;
+            Wnd->WndProcExtra = Wnd->Class->WndProcExtra;
             Wnd->Unicode = !Ansi;
             return Ret;
         }
     }
 
-    ASSERT(!Window->IsSystem);
+    ASSERT(!Wnd->IsSystem);
 
     /* update the window procedure */
-    Window->WndProc = NewWndProc;
+    Wnd->WndProc = NewWndProc;
     Wnd->Unicode = !Ansi;
 
     return Ret;




More information about the Ros-diffs mailing list