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/u…
==============================================================================
--- 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/m…
==============================================================================
--- 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/ntu…
==============================================================================
--- 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/in…
==============================================================================
--- 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/in…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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;