mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
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:
parent
cbd1d50bb1
commit
76dd22c3e5
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
124
reactos/subsystems/win32/win32k/ntuser/event.c
Normal file
124
reactos/subsystems/win32/win32k/ntuser/event.c
Normal 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 */
|
|
@ -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 */
|
||||
|
|
|
@ -426,19 +426,6 @@ NtUserNotifyIMEStatus(
|
|||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserNotifyWinEvent(
|
||||
DWORD Event,
|
||||
HWND hWnd,
|
||||
LONG idObject,
|
||||
LONG idChild)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserQueryUserCounters(
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue