Author: jimtabor Date: Wed Apr 16 20:48:34 2008 New Revision: 32993
URL: http://svn.reactos.org/svn/reactos?rev=32993&view=rev Log: Adding support for Event hooks. Start using the server info structure and pass the pointer to the user with kernel to user correction.
Added: trunk/reactos/subsystems/win32/win32k/ntuser/event.c - copied, changed from r32946, trunk/reactos/subsystems/win32/win32k/ntuser/hook.c Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c trunk/reactos/dll/win32/user32/windows/hook.c trunk/reactos/include/reactos/win32k/callback.h trunk/reactos/include/reactos/win32k/ntuser.h trunk/reactos/subsystems/win32/win32k/include/callback.h trunk/reactos/subsystems/win32/win32k/include/hook.h trunk/reactos/subsystems/win32/win32k/ntuser/callback.c trunk/reactos/subsystems/win32/win32k/ntuser/hook.c trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c trunk/reactos/subsystems/win32/win32k/ntuser/window.c trunk/reactos/subsystems/win32/win32k/win32k.rbuild
Modified: trunk/reactos/dll/win32/user32/misc/dllmain.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/misc/dllma... ============================================================================== --- trunk/reactos/dll/win32/user32/misc/dllmain.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/misc/dllmain.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -8,6 +8,7 @@ PUSER_HANDLE_ENTRY gHandleEntries = NULL; PW32PROCESSINFO g_pi = NULL; /* User Mode Pointer */ PW32PROCESSINFO g_kpi = NULL; /* Kernel Mode Pointer */ +PSERVERINFO g_psi = NULL;
PW32PROCESSINFO GetW32ProcessInfo(VOID); @@ -56,9 +57,12 @@ (PVOID)User32SetupDefaultCursors; NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_HOOKPROC] = (PVOID)User32CallHookProcFromKernel; + NtCurrentTeb()->ProcessEnvironmentBlock->KernelCallbackTable[USER32_CALLBACK_EVENTPROC] = + (PVOID)User32CallEventProcFromKernel;
g_pi = GetW32ProcessInfo(); g_kpi = SharedPtrToKernel(g_pi); + g_psi = SharedPtrToUser(g_pi->psi); gHandleTable = SharedPtrToUser(g_pi->UserHandleTable); gHandleEntries = SharedPtrToUser(gHandleTable->handles);
Modified: trunk/reactos/dll/win32/user32/windows/hook.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/ho... ============================================================================== --- trunk/reactos/dll/win32/user32/windows/hook.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/user32/windows/hook.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -33,8 +33,7 @@ #include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32); - -DWORD Bogus_SrvEventActivity = 0; // Fixme, need to ref to share data. +extern PSERVERINFO g_psi;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -263,7 +262,7 @@ // "Servers call NotifyWinEvent to announce the event to the system after the // event has occurred; they must never notify the system of an event before // the event has occurred." msdn on NotifyWinEvent. - if (Bogus_SrvEventActivity & GetMaskFromEvent(event)) // Check to see. + if (g_psi->SrvEventActivity & GetMaskFromEvent(event)) // Check to see. NtUserNotifyWinEvent(event, hwnd, idObject, idChild); }
@@ -318,7 +317,7 @@ { if ((PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo) { - return (Bogus_SrvEventActivity & GetMaskFromEvent(event)) != 0; + return (g_psi->SrvEventActivity & GetMaskFromEvent(event)) != 0; } return FALSE; } @@ -454,3 +453,24 @@
return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS); } + +NTSTATUS STDCALL +User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PEVENTPROC_CALLBACK_ARGUMENTS Common; + + Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Arguments; + + Common->Proc(Common->hook, + Common->event, + Common->hwnd, + Common->idObject, + Common->idChild, + Common->dwEventThread, + Common->dwmsEventTime); + + return ZwCallbackReturn(NULL, 0, STATUS_SUCCESS); +} + + +
Modified: trunk/reactos/include/reactos/win32k/callback.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/call... ============================================================================== --- trunk/reactos/include/reactos/win32k/callback.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/win32k/callback.h [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -6,7 +6,8 @@ #define USER32_CALLBACK_LOADSYSMENUTEMPLATE (2) #define USER32_CALLBACK_LOADDEFAULTCURSORS (3) #define USER32_CALLBACK_HOOKPROC (4) -#define USER32_CALLBACK_MAXIMUM (4) +#define USER32_CALLBACK_EVENTPROC (5) +#define USER32_CALLBACK_MAXIMUM (5)
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS { @@ -50,6 +51,23 @@ /* WCHAR szClass[] */ } HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS, *PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS;
+typedef VOID (*WINEVENTPROC)(HWINEVENTHOOK,DWORD,HWND,LONG,LONG,DWORD,DWORD); + +typedef struct _EVENTPROC_CALLBACK_ARGUMENTS +{ + HWINEVENTHOOK hook; + DWORD event; + HWND hwnd; + LONG idObject; + LONG idChild; + DWORD dwEventThread; + DWORD dwmsEventTime; + WINEVENTPROC Proc; + BOOLEAN Ansi; + UINT ModuleNameLength; + WCHAR ModuleName[1]; +} EVENTPROC_CALLBACK_ARGUMENTS, *PEVENTPROC_CALLBACK_ARGUMENTS; + NTSTATUS STDCALL User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS STDCALL @@ -60,5 +78,7 @@ User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength); NTSTATUS STDCALL User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength); +NTSTATUS STDCALL +User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */
Modified: trunk/reactos/include/reactos/win32k/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntus... ============================================================================== --- trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/win32k/ntuser.h [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -1679,7 +1679,7 @@ DWORD dwUnknown3, DWORD dwUnknown4);
-DWORD +VOID NTAPI NtUserNotifyWinEvent( DWORD Event, @@ -2345,7 +2345,7 @@ NtUserUnhookWindowsHookEx( HHOOK Hook);
-DWORD +BOOL NTAPI NtUserUnhookWinEvent( HWINEVENTHOOK hWinEventHook);
Modified: trunk/reactos/subsystems/win32/win32k/include/callback.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/callback.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/callback.h [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -35,6 +35,16 @@ BOOLEAN Ansi, PUNICODE_STRING ModuleName);
+LRESULT STDCALL +co_IntCallEventProc(HWINEVENTHOOK hook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD dwEventThread, + DWORD dwmsEventTime, + WINEVENTPROC Proc); + VOID FASTCALL IntCleanupThreadCallbacks(PW32THREAD W32Thread);
Modified: trunk/reactos/subsystems/win32/win32k/include/hook.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/hook.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/hook.h [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -23,7 +23,27 @@ UINT Counts[NB_HOOKS]; /* use counts for each hook chain */ } HOOKTABLE, *PHOOKTABLE;
+typedef struct tagEVENTHOOK +{ + LIST_ENTRY Chain; /* Event chain entry */ + HWINEVENTHOOK Self; /* user handle for this event */ + PETHREAD Thread; /* Thread owning the event */ + UINT eventMin; + UINT eventMax; + WINEVENTPROC Proc; /* Event function */ + BOOLEAN Ansi; /* Is it an Ansi event? */ + ULONG Flags; /* Some internal flags */ + UNICODE_STRING ModuleName; /* Module name for global events */ +} EVENTHOOK, *PEVENTHOOK; + +typedef struct tagEVENTTABLE +{ + LIST_ENTRY Events; + UINT Counts; +} EVENTTABLE, *PEVENTTABLE; + LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam); +LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, LONG, LONG); VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread); PHOOK FASTCALL IntGetHookObject(HHOOK);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/callback.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -465,4 +465,69 @@ return Result; }
+LRESULT +STDCALL +co_IntCallEventProc(HWINEVENTHOOK hook, + DWORD event, + HWND hWnd, + LONG idObject, + LONG idChild, + DWORD dwEventThread, + DWORD dwmsEventTime, + WINEVENTPROC Proc) +{ + LRESULT Result; + NTSTATUS Status; + PEVENTPROC_CALLBACK_ARGUMENTS Common; + ULONG ArgumentLength, ResultLength; + PVOID Argument, ResultPointer, pWnd; + + ArgumentLength = sizeof(EVENTPROC_CALLBACK_ARGUMENTS); + + Argument = IntCbAllocateMemory(ArgumentLength); + if (NULL == Argument) + { + DPRINT1("EventProc callback failed: out of memory\n"); + return 0; + } + Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Argument; + Common->hook = hook; + Common->event = event; + Common->hwnd = hWnd; + Common->idObject = idObject; + Common->idChild = idChild; + Common->dwEventThread = dwEventThread; + Common->dwmsEventTime = dwmsEventTime; + Common->Proc = Proc; + + ResultPointer = NULL; + ResultLength = sizeof(LRESULT); + + IntSetTebWndCallback (&hWnd, &pWnd); + + UserLeaveCo(); + + Status = KeUserModeCallback(USER32_CALLBACK_EVENTPROC, + Argument, + ArgumentLength, + &ResultPointer, + &ResultLength); + + /* Simulate old behaviour: copy into our local buffer */ + Result = *(LRESULT*)ResultPointer; + + UserEnterCo(); + + IntRestoreTebWndCallback (hWnd, pWnd); + + IntCbFreeMemory(Argument); + + if (!NT_SUCCESS(Status)) + { + return 0; + } + + return Result; +} + /* EOF */
Copied: trunk/reactos/subsystems/win32/win32k/ntuser/event.c (from r32946, trunk/reactos/subsystems/win32/win32k/ntuser/hook.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/event.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -1,43 +1,11 @@ -/* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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. - */ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Window hooks - * FILE: subsys/win32k/ntuser/hook.c - * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * REVISION HISTORY: - * 06-06-2001 CSH Created - * NOTE: Most of this code was adapted from Wine, - * Copyright (C) 2002 Alexandre Julliard - */
#include <w32k.h>
#define NDEBUG #include <debug.h>
-#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK) -#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) - -static PHOOKTABLE GlobalHooks; -DWORD Bogus_SrvEventActivity = 0; +extern PSERVERINFO gpsi; +//static PEVENTTABLE GlobalEvents;
/* PRIVATE FUNCTIONS *********************************************************/ @@ -76,662 +44,50 @@ return Ret; }
-/* create a new hook table */ -static PHOOKTABLE -IntAllocHookTable(void) + +static +DWORD +FASTCALL +TimeStamp(VOID) { - PHOOKTABLE Table; - UINT i; + return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216); +}
- Table = ExAllocatePoolWithTag(PagedPool, sizeof(HOOKTABLE), TAG_HOOK); - if (NULL != Table) - { - for (i = 0; i < NB_HOOKS; i++) - { - InitializeListHead(&Table->Hooks[i]); - Table->Counts[i] = 0; - } - } +/* FUNCTIONS *****************************************************************/
- return Table; +LRESULT +FASTCALL +co_EVENT_CallEvents( DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild) +{ + + PEVENTHOOK peh = UserHeapAlloc(sizeof(EVENTHOOK)); + + if ((gpsi->SrvEventActivity & GetMaskFromEvent(event))) return 0; // No events to run. + + LRESULT Result = co_IntCallEventProc(peh->Self, + event, + hwnd, + idObject, + idChild, + (DWORD)(NtCurrentTeb()->Cid).UniqueThread, + TimeStamp(), + peh->Proc); + return Result; }
-PHOOK FASTCALL IntGetHookObject(HHOOK hHook) +VOID +STDCALL +NtUserNotifyWinEvent( + DWORD Event, + HWND hWnd, + LONG idObject, + LONG idChild) { - PHOOK Hook; - - if (!hHook) - { - SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); - return NULL; - } - - Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook); - if (!Hook) - { - SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); - return NULL; - } - - ASSERT(USER_BODY_TO_HEADER(Hook)->RefCount >= 0); - - USER_BODY_TO_HEADER(Hook)->RefCount++; - - return Hook; -} - - - -/* create a new hook and add it to the specified table */ -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; - - if (NULL == Table) - { - Table = IntAllocHookTable(); - if (NULL == Table) - { - return NULL; - } - if (Global) - { - GlobalHooks = Table; - } - else - { - MsqSetHooks(((PW32THREAD)Thread->Tcb.Win32Thread)->MessageQueue, Table); - } - } - - Hook = UserCreateObject(gHandleTable, &Handle, otHook, sizeof(HOOK)); - if (NULL == Hook) - { - return NULL; - } - - 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); - - return Hook; -} - -/* get the hook table that a given hook belongs to */ -static PHOOKTABLE FASTCALL -IntGetTable(PHOOK Hook) -{ - if (NULL == Hook->Thread || WH_KEYBOARD_LL == Hook->HookId || - WH_MOUSE_LL == Hook->HookId) - { - return GlobalHooks; - } - - return MsqGetHooks(((PW32THREAD)Hook->Thread->Tcb.Win32Thread)->MessageQueue); -} - -/* get the first hook in the chain */ -static PHOOK FASTCALL -IntGetFirstHook(PHOOKTABLE Table, int HookId) -{ - PLIST_ENTRY Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink; - return Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)] - ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain); -} - -/* find the first non-deleted hook in the chain */ -static PHOOK FASTCALL -IntGetFirstValidHook(PHOOKTABLE Table, int HookId) -{ - PHOOK Hook; - PLIST_ENTRY Elem; - - Hook = IntGetFirstHook(Table, HookId); - while (NULL != Hook && NULL == Hook->Proc) - { - Elem = Hook->Chain.Flink; - Hook = (Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)] - ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain)); - } - - return Hook; -} - -/* find the next hook in the chain, skipping the deleted ones */ -static PHOOK FASTCALL -IntGetNextHook(PHOOK Hook) -{ - PHOOKTABLE Table = IntGetTable(Hook); - int HookId = Hook->HookId; - PLIST_ENTRY Elem; - - Elem = Hook->Chain.Flink; - while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)]) - { - Hook = CONTAINING_RECORD(Elem, HOOK, Chain); - if (NULL != Hook->Proc) - { - return Hook; - } - } - - if (NULL != GlobalHooks && Table != GlobalHooks) /* now search through the global table */ - { - return IntGetFirstValidHook(GlobalHooks, HookId); - } - - return NULL; -} - -/* free a hook, removing it from its chain */ -static VOID FASTCALL -IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj) -{ - RemoveEntryList(&Hook->Chain); - RtlFreeUnicodeString(&Hook->ModuleName); - - /* Dereference thread if required */ - if (Hook->Flags & HOOK_THREAD_REFERENCED) - { - ObDereferenceObject(Hook->Thread); - } - - /* Close handle */ - UserDeleteObject(Hook->Self, otHook); -} - -/* remove a hook, freeing it if the chain is not in use */ -static VOID -IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj, BOOL TableAlreadyLocked) -{ - PW32THREAD W32Thread; - PHOOKTABLE Table = IntGetTable(Hook); - - ASSERT(NULL != Table); - if (NULL == Table) - { - 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)]) - { - Hook->Proc = NULL; /* chain is in use, just mark it and return */ - } - else - { - IntFreeHook(Table, Hook, WinStaObj); - } -} - -/* release a hook chain, removing deleted hooks if the use count drops to 0 */ -static VOID FASTCALL -IntReleaseHookChain(PHOOKTABLE Table, int HookId, PWINSTATION_OBJECT WinStaObj) -{ - PLIST_ENTRY Elem; - PHOOK HookObj; - - if (NULL == Table) - { - return; - } - - /* use count shouldn't already be 0 */ - ASSERT(0 != Table->Counts[HOOKID_TO_INDEX(HookId)]); - if (0 == Table->Counts[HOOKID_TO_INDEX(HookId)]) - { - return; - } - if (0 == --Table->Counts[HOOKID_TO_INDEX(HookId)]) - { - Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink; - while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)]) - { - HookObj = CONTAINING_RECORD(Elem, HOOK, Chain); - Elem = Elem->Flink; - if (NULL == HookObj->Proc) - { - IntFreeHook(Table, HookObj, WinStaObj); - } - } - } -} - -static LRESULT FASTCALL -IntCallLowLevelHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam, PHOOK Hook) -{ - NTSTATUS Status; - ULONG_PTR uResult; - - /* FIXME should get timeout from - * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage(((PW32THREAD)Hook->Thread->Tcb.Win32Thread)->MessageQueue, (HWND) Code, HookId, - wParam, lParam, 5000, TRUE, TRUE, &uResult); - - return NT_SUCCESS(Status) ? uResult : 0; -} - -LRESULT FASTCALL -co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) -{ - PHOOK Hook; - PW32THREAD Win32Thread; - PHOOKTABLE Table; - LRESULT Result; - PWINSTATION_OBJECT WinStaObj; - NTSTATUS Status; - - ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK); - - Win32Thread = PsGetCurrentThreadWin32Thread(); - if (NULL == Win32Thread) - { - Table = NULL; - } - else - { - Table = MsqGetHooks(Win32Thread->MessageQueue); - } - - if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId))) - { - /* try global table */ - Table = GlobalHooks; - if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId))) - { - return 0; /* no hook set */ - } - } - - if (Hook->Thread != PsGetCurrentThread() - && (WH_KEYBOARD_LL == HookId || WH_MOUSE_LL == HookId)) - { - DPRINT("Calling hook in owning thread\n"); - return IntCallLowLevelHook(HookId, Code, wParam, lParam, Hook); - } - - if (Hook->Thread != PsGetCurrentThread()) - { - DPRINT1("Calling hooks in other threads not implemented yet"); - return 0; - } - - Table->Counts[HOOKID_TO_INDEX(HookId)]++; - if (Table != GlobalHooks && GlobalHooks != NULL) - { - GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++; - } - - Result = co_IntCallHookProc(HookId, Code, wParam, lParam, Hook->Proc, - Hook->Ansi, &Hook->ModuleName); - - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (! NT_SUCCESS(Status)) - { - DPRINT1("Invalid window station????\n"); - } - else - { - IntReleaseHookChain(MsqGetHooks(PsGetCurrentThreadWin32Thread()->MessageQueue), HookId, WinStaObj); - IntReleaseHookChain(GlobalHooks, HookId, WinStaObj); - ObDereferenceObject(WinStaObj); - } - - return Result; -} - -VOID FASTCALL -HOOK_DestroyThreadHooks(PETHREAD Thread) -{ - int HookId; - PLIST_ENTRY Elem; - PHOOK HookObj; - PWINSTATION_OBJECT WinStaObj; - NTSTATUS Status; - - if (NULL != GlobalHooks) - { - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (! NT_SUCCESS(Status)) - { - DPRINT1("Invalid window station????\n"); - return; - } - - for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++) - { - /* only low-level keyboard/mouse global hooks can be owned by a thread */ - switch(HookId) - { - case WH_KEYBOARD_LL: - case WH_MOUSE_LL: - Elem = GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)].Flink; - while (Elem != &GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)]) - { - HookObj = CONTAINING_RECORD(Elem, HOOK, Chain); - Elem = Elem->Flink; - if (HookObj->Thread == Thread) - { - IntRemoveHook(HookObj, WinStaObj, TRUE); - } - } - break; - } - } - - ObDereferenceObject(WinStaObj); - } -} - -LRESULT -STDCALL -NtUserCallNextHookEx( - HHOOK Hook, - int Code, - WPARAM wParam, - LPARAM lParam) -{ - PHOOK HookObj, NextObj; - PWINSTATION_OBJECT WinStaObj; - NTSTATUS Status; - DECLARE_RETURN(LRESULT); - - DPRINT("Enter NtUserCallNextHookEx\n"); - UserEnterExclusive(); - - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( FALSE); - } - - //Status = UserReferenceObjectByHandle(gHandleTable, Hook, - // otHookProc, (PVOID *) &HookObj); - ObDereferenceObject(WinStaObj); - - // if (! NT_SUCCESS(Status)) - // { - // DPRINT1("Invalid handle passed to NtUserCallNextHookEx\n"); - // SetLastNtError(Status); - // RETURN( 0); - // } - - if (!(HookObj = IntGetHookObject(Hook))) - { - RETURN(0); - } - - ASSERT(Hook == HookObj->Self); - - if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread())) - { - DPRINT1("Thread mismatch\n"); - UserDereferenceObject(HookObj); - SetLastWin32Error(ERROR_INVALID_HANDLE); - RETURN( 0); - } - - NextObj = IntGetNextHook(HookObj); - UserDereferenceObject(HookObj); - if (NULL != NextObj) - { - DPRINT1("Calling next hook not implemented\n"); - UNIMPLEMENTED - SetLastWin32Error(ERROR_NOT_SUPPORTED); - RETURN( 0); - } - - RETURN( 0); - -CLEANUP: - DPRINT("Leave NtUserCallNextHookEx, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -HHOOK -STDCALL -NtUserSetWindowsHookAW( - int idHook, - HOOKPROC lpfn, - BOOL Ansi) -{ - UNICODE_STRING USModuleName; - RtlInitUnicodeString(&USModuleName, NULL); - return NtUserSetWindowsHookEx(NULL, &USModuleName, 0, idHook, lpfn, Ansi); -} - -HHOOK -STDCALL -NtUserSetWindowsHookEx( - HINSTANCE Mod, - PUNICODE_STRING UnsafeModuleName, - DWORD ThreadId, - int HookId, - HOOKPROC HookProc, - BOOL Ansi) -{ - PWINSTATION_OBJECT WinStaObj; - BOOLEAN Global; - PETHREAD Thread; - PHOOK Hook; - UNICODE_STRING ModuleName; - NTSTATUS Status; - HHOOK Handle; - DECLARE_RETURN(HHOOK); - - DPRINT("Enter NtUserSetWindowsHookEx\n"); - UserEnterExclusive(); - - if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId || NULL == HookProc) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } - - if (ThreadId) /* thread-local hook */ - { - if (HookId == WH_JOURNALRECORD || - HookId == WH_JOURNALPLAYBACK || - HookId == WH_KEYBOARD_LL || - HookId == WH_MOUSE_LL || - HookId == WH_SYSMSGFILTER) - { - /* these can only be global */ - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } - Mod = NULL; - Global = FALSE; - if (! NT_SUCCESS(PsLookupThreadByThreadId((HANDLE) ThreadId, &Thread))) - { - DPRINT1("Invalid thread id 0x%x\n", ThreadId); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } - if (Thread->ThreadsProcess != PsGetCurrentProcess()) - { - ObDereferenceObject(Thread); - DPRINT1("Can't specify thread belonging to another process\n"); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } - } - else /* system-global hook */ - { - if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL) - { - Mod = NULL; - Thread = PsGetCurrentThread(); - Status = ObReferenceObjectByPointer(Thread, - THREAD_ALL_ACCESS, - PsThreadType, - KernelMode); - - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( (HANDLE) NULL); - } - } - else if (NULL == Mod) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } - else - { - Thread = NULL; - } - Global = TRUE; - } - - /* We only (partially) support local WH_CBT hooks and - * WH_KEYBOARD_LL/WH_MOUSE_LL hooks for now */ - if ((WH_CBT != HookId || Global) - && WH_KEYBOARD_LL != HookId && WH_MOUSE_LL != HookId) - { -#if 0 /* Removed to get winEmbed working again */ - UNIMPLEMENTED -#else - DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE"); -#endif - - if (NULL != Thread) - { - ObDereferenceObject(Thread); - } - SetLastWin32Error(ERROR_NOT_SUPPORTED); - RETURN( NULL); - } - - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (! NT_SUCCESS(Status)) - { - if (NULL != Thread) - { - ObDereferenceObject(Thread); - } - SetLastNtError(Status); - RETURN( (HANDLE) NULL); - } - - Hook = IntAddHook(Thread, HookId, Global, WinStaObj); - if (NULL == Hook) - { - if (NULL != Thread) - { - ObDereferenceObject(Thread); - } - ObDereferenceObject(WinStaObj); - RETURN( NULL); - } - - if (NULL != Thread) - { - Hook->Flags |= HOOK_THREAD_REFERENCED; - } - - if (NULL != Mod) - { - Status = MmCopyFromCaller(&ModuleName, UnsafeModuleName, sizeof(UNICODE_STRING)); - if (! NT_SUCCESS(Status)) - { - UserDereferenceObject(Hook); - IntRemoveHook(Hook, WinStaObj, FALSE); - if (NULL != Thread) - { - ObDereferenceObject(Thread); - } - ObDereferenceObject(WinStaObj); - SetLastNtError(Status); - RETURN( NULL); - } - Hook->ModuleName.Buffer = ExAllocatePoolWithTag(PagedPool, - ModuleName.MaximumLength, - TAG_HOOK); - if (NULL == Hook->ModuleName.Buffer) - { - UserDereferenceObject(Hook); - IntRemoveHook(Hook, WinStaObj, FALSE); - if (NULL != Thread) - { - ObDereferenceObject(Thread); - } - ObDereferenceObject(WinStaObj); - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - RETURN( NULL); - } - Hook->ModuleName.MaximumLength = ModuleName.MaximumLength; - Status = MmCopyFromCaller(Hook->ModuleName.Buffer, - ModuleName.Buffer, - ModuleName.MaximumLength); - if (! NT_SUCCESS(Status)) - { - ExFreePool(Hook->ModuleName.Buffer); - UserDereferenceObject(Hook); - IntRemoveHook(Hook, WinStaObj, FALSE); - if (NULL != Thread) - { - ObDereferenceObject(Thread); - } - ObDereferenceObject(WinStaObj); - SetLastNtError(Status); - RETURN( NULL); - } - Hook->ModuleName.Length = ModuleName.Length; - } - - Hook->Proc = HookProc; - Hook->Ansi = Ansi; - Handle = Hook->Self; - - UserDereferenceObject(Hook); - ObDereferenceObject(WinStaObj); - - RETURN( Handle); - -CLEANUP: - DPRINT("Leave NtUserSetWindowsHookEx, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; + UNIMPLEMENTED }
HWINEVENTHOOK @@ -746,70 +102,23 @@ DWORD idThread, UINT dwflags) { + gpsi->SrvEventActivity |= GetMaskFromEvent(eventMin); + gpsi->SrvEventActivity &= ~GetMaskFromEvent(eventMin);
- Bogus_SrvEventActivity |= GetMaskFromEvent(eventMin); // Fake it out for now. - Bogus_SrvEventActivity &= ~GetMaskFromEvent(eventMin); UNIMPLEMENTED
return 0; }
+ BOOL -STDCALL -NtUserUnhookWindowsHookEx( - HHOOK Hook) -{ - PWINSTATION_OBJECT WinStaObj; - PHOOK HookObj; - NTSTATUS Status; - DECLARE_RETURN(BOOL); - - DPRINT("Enter NtUserUnhookWindowsHookEx\n"); - UserEnterExclusive(); - - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( FALSE); - } - - // Status = UserReferenceObjectByHandle(gHandleTable, Hook, - // otHookProc, (PVOID *) &HookObj); - if (!(HookObj = IntGetHookObject(Hook))) - { - DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n"); - ObDereferenceObject(WinStaObj); - // SetLastNtError(Status); - RETURN( FALSE); - } - ASSERT(Hook == HookObj->Self); - - IntRemoveHook(HookObj, WinStaObj, FALSE); - - UserDereferenceObject(HookObj); - ObDereferenceObject(WinStaObj); - - RETURN( TRUE); - -CLEANUP: - DPRINT("Leave NtUserUnhookWindowsHookEx, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -DWORD STDCALL NtUserUnhookWinEvent( HWINEVENTHOOK hWinEventHook) { UNIMPLEMENTED
- return 0; + return FALSE; }
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -1,26 +1,8 @@ -/* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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. - */ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Window hooks - * FILE: subsys/win32k/ntuser/hook.c + * FILE: subsystem/win32/win32k/ntuser/hook.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * REVISION HISTORY: * 06-06-2001 CSH Created @@ -37,44 +19,10 @@ #define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
static PHOOKTABLE GlobalHooks; -DWORD Bogus_SrvEventActivity = 0;
/* PRIVATE FUNCTIONS *********************************************************/
-static -DWORD -FASTCALL -GetMaskFromEvent(DWORD Event) -{ - DWORD Ret = 0; - - if ( Event > EVENT_OBJECT_STATECHANGE ) - { - if ( Event == EVENT_OBJECT_LOCATIONCHANGE ) return SRV_EVENT_LOCATIONCHANGE; - if ( Event == EVENT_OBJECT_NAMECHANGE ) return SRV_EVENT_NAMECHANGE; - if ( Event == EVENT_OBJECT_VALUECHANGE ) return SRV_EVENT_VALUECHANGE; - return SRV_EVENT_CREATE; - } - - if ( Event == EVENT_OBJECT_STATECHANGE ) return SRV_EVENT_STATECHANGE; - - Ret = SRV_EVENT_RUNNING; - - if ( Event < EVENT_SYSTEM_MENUSTART ) return SRV_EVENT_CREATE; - - if ( Event <= EVENT_SYSTEM_MENUPOPUPEND ) - { - Ret = SRV_EVENT_MENU; - } - else - { - if ( Event <= EVENT_CONSOLE_CARET-1 ) return SRV_EVENT_CREATE; - if ( Event <= EVENT_CONSOLE_END_APPLICATION ) return SRV_EVENT_END_APPLICATION; - if ( Event != EVENT_OBJECT_FOCUS ) return SRV_EVENT_CREATE; - } - return Ret; -}
/* create a new hook table */ static PHOOKTABLE @@ -734,25 +682,6 @@ END_CLEANUP; }
-HWINEVENTHOOK -STDCALL -NtUserSetWinEventHook( - UINT eventMin, - UINT eventMax, - HMODULE hmodWinEventProc, - PUNICODE_STRING puString, - WINEVENTPROC lpfnWinEventProc, - DWORD idProcess, - DWORD idThread, - UINT dwflags) -{ - - Bogus_SrvEventActivity |= GetMaskFromEvent(eventMin); // Fake it out for now. - Bogus_SrvEventActivity &= ~GetMaskFromEvent(eventMin); - UNIMPLEMENTED - - return 0; -}
BOOL STDCALL @@ -801,15 +730,5 @@ UserLeave(); END_CLEANUP; } - -DWORD -STDCALL -NtUserUnhookWinEvent( - HWINEVENTHOOK hWinEventHook) -{ - UNIMPLEMENTED - - return 0; -} - + /* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -428,19 +428,6 @@
DWORD STDCALL -NtUserNotifyWinEvent( - DWORD Event, - HWND hWnd, - LONG idObject, - LONG idChild) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserQueryUserCounters( DWORD Unknown0, DWORD Unknown1,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -2056,7 +2056,7 @@ IntUnlinkWindow(Window); RETURN((HWND)0); } -#if 0 + Result = co_EVENT_CallEvents(EVENT_OBJECT_CREATE, Window->hSelf, OBJID_WINDOW, 0);
if (Result == (LRESULT)-1) @@ -2065,7 +2065,7 @@ DPRINT1("IntCreateWindowEx(): event CREATE hook failed. No cleanup performed!\n"); RETURN((HWND)0); } -#endif + /* Send move and size messages. */ if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE)) {
Modified: trunk/reactos/subsystems/win32/win32k/win32k.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/win... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/win32k.rbuild [iso-8859-1] Wed Apr 16 20:48:34 2008 @@ -112,6 +112,7 @@ <file>csr.c</file> <file>cursoricon.c</file> <file>desktop.c</file> + <file>event.c</file> <file>focus.c</file> <file>guicheck.c</file> <file>hook.c</file>