From 965305ebc8d2948d6c38af4fd0259808a7fc8153 Mon Sep 17 00:00:00 2001 From: Andrew Munger Date: Wed, 3 May 2006 04:17:50 +0000 Subject: [PATCH] Move callproc code into own file and reduce unneccessary system calls to dereference them. It doesn't fix any bugs but improves performance a bit. Patch from w3seek, bug 1445. svn path=/trunk/; revision=21779 --- reactos/dll/win32/user32/windows/message.c | 13 +- .../subsystems/win32/win32k/include/class.h | 9 +- .../subsystems/win32/win32k/main/dllmain.c | 7 - .../subsystems/win32/win32k/ntuser/callproc.c | 156 ++++++++++++++++++ .../subsystems/win32/win32k/ntuser/class.c | 132 +-------------- .../subsystems/win32/win32k/ntuser/window.c | 6 +- reactos/subsystems/win32/win32k/win32k.rbuild | 1 + 7 files changed, 176 insertions(+), 148 deletions(-) create mode 100644 reactos/subsystems/win32/win32k/ntuser/callproc.c diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index add13934440..276077788a7 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -1001,6 +1001,13 @@ IntCallWindowProcA(BOOL IsAnsiProc, } } +static BOOL __inline +IsCallProcHandle(IN WNDPROC lpWndProc) +{ + /* FIXME - check for 64 bit architectures... */ + return ((ULONG_PTR)lpWndProc & 0xFFFF0000) == 0xFFFF0000; +} + /* * @implemented @@ -1018,7 +1025,8 @@ CallWindowProcA(WNDPROC lpPrevWndFunc, if (lpPrevWndFunc == NULL) lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, TRUE); - if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc, + if (!IsCallProcHandle(lpPrevWndFunc) || + !NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc, &wpInfo)) { return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam); @@ -1047,7 +1055,8 @@ CallWindowProcW(WNDPROC lpPrevWndFunc, if (lpPrevWndFunc == NULL) lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE); - if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc, + if (!IsCallProcHandle(lpPrevWndFunc) || + !NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc, &wpInfo)) { return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam); diff --git a/reactos/subsystems/win32/win32k/include/class.h b/reactos/subsystems/win32/win32k/include/class.h index 3b13b34148c..8ec33fb768b 100644 --- a/reactos/subsystems/win32/win32k/include/class.h +++ b/reactos/subsystems/win32/win32k/include/class.h @@ -4,6 +4,9 @@ #define IS_ATOM(x) \ (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) +WNDPROC +GetCallProcHandle(IN PCALLPROC CallProc); + VOID DestroyCallProc(IN PDESKTOP Desktop, IN OUT PCALLPROC CallProc); @@ -18,12 +21,6 @@ CreateCallProc(IN PDESKTOP Desktop, IN BOOL Unicode, IN PW32PROCESSINFO pi); -NTSTATUS FASTCALL -InitClassImpl(VOID); - -NTSTATUS FASTCALL -CleanupClassImpl(VOID); - BOOL UserGetCallProcInfo(IN HANDLE hCallProc, OUT PWNDPROC_INFO wpInfo); diff --git a/reactos/subsystems/win32/win32k/main/dllmain.c b/reactos/subsystems/win32/win32k/main/dllmain.c index b112b396c85..567c2a3ca56 100644 --- a/reactos/subsystems/win32/win32k/main/dllmain.c +++ b/reactos/subsystems/win32/win32k/main/dllmain.c @@ -425,13 +425,6 @@ DriverEntry ( return STATUS_UNSUCCESSFUL; } - Status = InitClassImpl(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to initialize window class implementation!\n"); - return STATUS_UNSUCCESSFUL; - } - Status = InitDesktopImpl(); if (!NT_SUCCESS(Status)) { diff --git a/reactos/subsystems/win32/win32k/ntuser/callproc.c b/reactos/subsystems/win32/win32k/ntuser/callproc.c new file mode 100644 index 00000000000..c1de8ea78a8 --- /dev/null +++ b/reactos/subsystems/win32/win32k/ntuser/callproc.c @@ -0,0 +1,156 @@ +/* + * ReactOS W32 Subsystem + * Copyright (C) 1998 - 2006 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: class.c 21596 2006-04-15 10:41:58Z greatlrd $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Window classes + * FILE: subsys/win32k/ntuser/class.c + * PROGRAMER: Thomas Weidenmueller + * REVISION HISTORY: + * 06-06-2001 CSH Created + */ +/* INCLUDES ******************************************************************/ + +#include + +#define NDEBUG +#include + +/* CALLPROC ******************************************************************/ + +WNDPROC +GetCallProcHandle(IN PCALLPROC CallProc) +{ + /* FIXME - check for 64 bit architectures... */ + return (WNDPROC)((ULONG_PTR)ObmObjectToHandle(CallProc) | 0xFFFF0000); +} + +VOID +DestroyCallProc(IN PDESKTOP Desktop, + IN OUT PCALLPROC CallProc) +{ + /* FIXME - use new object manager! */ + HANDLE Handle = ObmObjectToHandle(CallProc); + + ObmDeleteObject(Handle, + otCallProc); +} + +PCALLPROC +CloneCallProc(IN PDESKTOP Desktop, + IN PCALLPROC CallProc) +{ + PCALLPROC NewCallProc; + HANDLE Handle; + + /* FIXME - use new object manager! */ + NewCallProc = (PCALLPROC)ObmCreateObject(gHandleTable, + &Handle, + otCallProc, + sizeof(CALLPROC)); + if (NewCallProc != NULL) + { + NewCallProc->pi = CallProc->pi; + NewCallProc->WndProc = CallProc->WndProc; + NewCallProc->Unicode = CallProc->Unicode; + } + + return NewCallProc; +} + +PCALLPROC +CreateCallProc(IN PDESKTOP Desktop, + IN WNDPROC WndProc, + IN BOOL Unicode, + IN PW32PROCESSINFO pi) +{ + PCALLPROC NewCallProc; + HANDLE Handle; + + /* FIXME - use new object manager! */ + NewCallProc = (PCALLPROC)ObmCreateObject(gHandleTable, + &Handle, + otCallProc, + sizeof(CALLPROC)); + if (NewCallProc != NULL) + { + NewCallProc->pi = pi; + NewCallProc->WndProc = WndProc; + NewCallProc->Unicode = Unicode; + } + + return NewCallProc; +} + +BOOL +UserGetCallProcInfo(IN HANDLE hCallProc, + OUT PWNDPROC_INFO wpInfo) +{ + PCALLPROC CallProc; + + /* NOTE: Accessing the WNDPROC_INFO structure may raise an exception! */ + + /* FIXME - use new object manager! */ + CallProc = UserGetObject(gHandleTable, + hCallProc, + otCallProc); + if (CallProc == NULL) + { + return FALSE; + } + + if (CallProc->pi != GetW32ProcessInfo()) + { + return FALSE; + } + + wpInfo->WindowProc = CallProc->WndProc; + wpInfo->IsUnicode = CallProc->Unicode; + + return TRUE; +} + +BOOL NTAPI +NtUserDereferenceWndProcHandle(IN HANDLE wpHandle, + OUT PWNDPROC_INFO wpInfo) +{ + BOOL Ret = FALSE; + + UserEnterShared(); + + _SEH_TRY + { + ProbeForWrite(wpInfo, + sizeof(WNDPROC_INFO), + sizeof(ULONG)); + + Ret = UserGetCallProcInfo(wpHandle, + wpInfo); + } + _SEH_HANDLE + { + SetLastWin32Error(_SEH_GetExceptionCode()); + } + _SEH_END; + + UserLeave(); + + return Ret; +} diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index 9bb2753d8b6..afa9d2e8144 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -33,107 +33,8 @@ #define NDEBUG #include -/* CALLPROC ******************************************************************/ - -VOID -DestroyCallProc(IN PDESKTOP Desktop, - IN OUT PCALLPROC CallProc) -{ - /* FIXME - use new object manager! */ - HANDLE Handle = ObmObjectToHandle(CallProc); - - ObmDeleteObject(Handle, - otCallProc); -} - -PCALLPROC -CloneCallProc(IN PDESKTOP Desktop, - IN PCALLPROC CallProc) -{ - PCALLPROC NewCallProc; - HANDLE Handle; - - /* FIXME - use new object manager! */ - NewCallProc = (PCALLPROC)ObmCreateObject(gHandleTable, - &Handle, - otCallProc, - sizeof(CALLPROC)); - if (NewCallProc != NULL) - { - NewCallProc->pi = CallProc->pi; - NewCallProc->WndProc = CallProc->WndProc; - NewCallProc->Unicode = CallProc->Unicode; - } - - return NewCallProc; -} - -PCALLPROC -CreateCallProc(IN PDESKTOP Desktop, - IN WNDPROC WndProc, - IN BOOL Unicode, - IN PW32PROCESSINFO pi) -{ - PCALLPROC NewCallProc; - HANDLE Handle; - - /* FIXME - use new object manager! */ - NewCallProc = (PCALLPROC)ObmCreateObject(gHandleTable, - &Handle, - otCallProc, - sizeof(CALLPROC)); - if (NewCallProc != NULL) - { - NewCallProc->pi = pi; - NewCallProc->WndProc = WndProc; - NewCallProc->Unicode = Unicode; - } - - return NewCallProc; -} - -BOOL -UserGetCallProcInfo(IN HANDLE hCallProc, - OUT PWNDPROC_INFO wpInfo) -{ - PCALLPROC CallProc; - - /* NOTE: Accessing the WNDPROC_INFO structure may raise an exception! */ - - /* FIXME - use new object manager! */ - CallProc = UserGetObject(gHandleTable, - hCallProc, - otCallProc); - if (CallProc == NULL) - { - return FALSE; - } - - if (CallProc->pi != GetW32ProcessInfo()) - { - return FALSE; - } - - wpInfo->WindowProc = CallProc->WndProc; - wpInfo->IsUnicode = CallProc->Unicode; - - return TRUE; -} - /* WINDOWCLASS ***************************************************************/ -NTSTATUS FASTCALL -InitClassImpl(VOID) -{ - return(STATUS_SUCCESS); -} - -NTSTATUS FASTCALL -CleanupClassImpl(VOID) -{ - return(STATUS_SUCCESS); -} - static VOID IntFreeClassMenuName(IN OUT PWINDOWCLASS Class) { @@ -345,7 +246,7 @@ IntGetClassWndProc(IN PWINDOWCLASS Class, if (*CallProcPtr != NULL) { - return (WNDPROC)ObmObjectToHandle(*CallProcPtr); + return GetCallProcHandle(*CallProcPtr); } else { @@ -392,7 +293,7 @@ IntGetClassWndProc(IN PWINDOWCLASS Class, Class = Class->Next; } - return (WNDPROC)ObmObjectToHandle(NewCallProc); + return GetCallProcHandle(NewCallProc); } } } @@ -2510,33 +2411,4 @@ NtUserGetWOWClass(DWORD Unknown0, return(0); } - -BOOL NTAPI -NtUserDereferenceWndProcHandle(IN HANDLE wpHandle, - OUT PWNDPROC_INFO wpInfo) -{ - BOOL Ret = FALSE; - - UserEnterShared(); - - _SEH_TRY - { - ProbeForWrite(wpInfo, - sizeof(WNDPROC_INFO), - sizeof(ULONG)); - - Ret = UserGetCallProcInfo(wpHandle, - wpInfo); - } - _SEH_HANDLE - { - SetLastWin32Error(_SEH_GetExceptionCode()); - } - _SEH_END; - - UserLeave(); - - return Ret; -} - /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 1d0ef87ca2e..2fec86b9a83 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -509,7 +509,7 @@ IntGetWindowProc(IN PWINDOW_OBJECT Window, { if (Window->CallProc != NULL) { - return (WNDPROC)ObmObjectToHandle(Window->CallProc); + return GetCallProcHandle(Window->CallProc); } else { @@ -536,7 +536,7 @@ IntGetWindowProc(IN PWINDOW_OBJECT Window, NewCallProc); } - return (WNDPROC)ObmObjectToHandle((CallProc == NULL ? NewCallProc : CallProc)); + return GetCallProcHandle((CallProc == NULL ? NewCallProc : CallProc)); } } } @@ -3464,7 +3464,7 @@ IntSetWindowProc(PWINDOW_OBJECT Window, } } - Ret = (WNDPROC)ObmObjectToHandle(Window->CallProc2); + Ret = GetCallProcHandle(Window->CallProc2); } } diff --git a/reactos/subsystems/win32/win32k/win32k.rbuild b/reactos/subsystems/win32/win32k/win32k.rbuild index e4b7bd68e07..7ae8dce920d 100644 --- a/reactos/subsystems/win32/win32k/win32k.rbuild +++ b/reactos/subsystems/win32/win32k/win32k.rbuild @@ -84,6 +84,7 @@ accelerator.c callback.c + callproc.c caret.c class.c clipboard.c