Adding support for Event hooks. Start using the server info structure and pass the pointer to the user with kernel to user correction.

svn path=/trunk/; revision=32993
This commit is contained in:
James Tabor 2008-04-17 01:48:34 +00:00
parent cbd1d50bb1
commit 76dd22c3e5
12 changed files with 275 additions and 105 deletions

View file

@ -8,6 +8,7 @@ PUSER_HANDLE_TABLE gHandleTable = NULL;
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 @@ Init(VOID)
(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);

View file

@ -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 @@ NotifyWinEvent(
// "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 @@ IsWinEventHookInstalled(
{
if ((PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo)
{
return (Bogus_SrvEventActivity & GetMaskFromEvent(event)) != 0;
return (g_psi->SrvEventActivity & GetMaskFromEvent(event)) != 0;
}
return FALSE;
}
@ -454,3 +453,24 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
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);
}

View file

@ -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 @@ typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
/* 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 @@ NTSTATUS STDCALL
User32SetupDefaultCursors(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL
User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
NTSTATUS STDCALL
User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength);
#endif /* __INCLUDE_USER32_CALLBACK_H */

View file

@ -1679,7 +1679,7 @@ NtUserNotifyProcessCreate(
DWORD dwUnknown3,
DWORD dwUnknown4);
DWORD
VOID
NTAPI
NtUserNotifyWinEvent(
DWORD Event,
@ -2345,7 +2345,7 @@ NTAPI
NtUserUnhookWindowsHookEx(
HHOOK Hook);
DWORD
BOOL
NTAPI
NtUserUnhookWinEvent(
HWINEVENTHOOK hWinEventHook);

View file

@ -35,6 +35,16 @@ co_IntCallHookProc(INT HookId,
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);

View file

@ -23,7 +23,27 @@ typedef struct tagHOOKTABLE
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);

View file

@ -465,4 +465,69 @@ co_IntCallHookProc(INT HookId,
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 */

View file

@ -0,0 +1,124 @@
#include <w32k.h>
#define NDEBUG
#include <debug.h>
extern PSERVERINFO gpsi;
//static PEVENTTABLE GlobalEvents;
/* 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;
}
static
DWORD
FASTCALL
TimeStamp(VOID)
{
return (DWORD)((ULONGLONG)SharedUserData->TickCountLowDeprecated * SharedUserData->TickCountMultiplier / 16777216);
}
/* FUNCTIONS *****************************************************************/
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;
}
VOID
STDCALL
NtUserNotifyWinEvent(
DWORD Event,
HWND hWnd,
LONG idObject,
LONG idChild)
{
UNIMPLEMENTED
}
HWINEVENTHOOK
STDCALL
NtUserSetWinEventHook(
UINT eventMin,
UINT eventMax,
HMODULE hmodWinEventProc,
PUNICODE_STRING puString,
WINEVENTPROC lpfnWinEventProc,
DWORD idProcess,
DWORD idThread,
UINT dwflags)
{
gpsi->SrvEventActivity |= GetMaskFromEvent(eventMin);
gpsi->SrvEventActivity &= ~GetMaskFromEvent(eventMin);
UNIMPLEMENTED
return 0;
}
BOOL
STDCALL
NtUserUnhookWinEvent(
HWINEVENTHOOK hWinEventHook)
{
UNIMPLEMENTED
return FALSE;
}
/* EOF */

View file

@ -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 @@ CLEANUP:
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 @@ CLEANUP:
UserLeave();
END_CLEANUP;
}
DWORD
STDCALL
NtUserUnhookWinEvent(
HWINEVENTHOOK hWinEventHook)
{
UNIMPLEMENTED
return 0;
}
/* EOF */

View file

@ -426,19 +426,6 @@ NtUserNotifyIMEStatus(
return 0;
}
DWORD
STDCALL
NtUserNotifyWinEvent(
DWORD Event,
HWND hWnd,
LONG idObject,
LONG idChild)
{
UNIMPLEMENTED
return 0;
}
DWORD
STDCALL
NtUserQueryUserCounters(

View file

@ -2056,7 +2056,7 @@ AllocErr:
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 @@ AllocErr:
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))
{

View file

@ -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>