ReactOS 0.4.15-dev-5667-ged97270
event.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Window event handlers
5 * FILE: win32ss/user/ntuser/event.c
6 * PROGRAMER: James Tabor (james.tabor@rectos.org)
7 */
8
9#include <win32k.h>
11
12typedef struct _EVENTPACK
13{
19
21
22/* PRIVATE FUNCTIONS *********************************************************/
23
24static
28{
29 DWORD Ret = 0;
30
31 if ( Event > EVENT_OBJECT_STATECHANGE )
32 {
33 if ( Event == EVENT_OBJECT_LOCATIONCHANGE ) return SRV_EVENT_LOCATIONCHANGE;
34 if ( Event == EVENT_OBJECT_NAMECHANGE ) return SRV_EVENT_NAMECHANGE;
35 if ( Event == EVENT_OBJECT_VALUECHANGE ) return SRV_EVENT_VALUECHANGE;
36 return SRV_EVENT_CREATE;
37 }
38
39 if ( Event == EVENT_OBJECT_STATECHANGE ) return SRV_EVENT_STATECHANGE;
40
42
43 if ( Event < EVENT_SYSTEM_MENUSTART ) return SRV_EVENT_CREATE;
44
45 if ( Event <= EVENT_SYSTEM_MENUPOPUPEND )
46 {
47 Ret = SRV_EVENT_MENU;
48 }
49 else
50 {
51 if ( Event <= EVENT_CONSOLE_CARET-1 ) return SRV_EVENT_CREATE;
52 if ( Event <= EVENT_CONSOLE_END_APPLICATION ) return SRV_EVENT_END_APPLICATION;
53 if ( Event != EVENT_OBJECT_FOCUS ) return SRV_EVENT_CREATE;
54 }
55 return Ret;
56}
57
58static
59VOID
61IntSetSrvEventMask( UINT EventMin, UINT EventMax)
62{
63 UINT event;
64 TRACE("SetSrvEventMask 1\n");
65 for ( event = EventMin; event <= EventMax; event++)
66 {
67 if ((event >= EVENT_SYSTEM_SOUND && event <= EVENT_SYSTEM_MINIMIZEEND) ||
68 (event >= EVENT_CONSOLE_CARET && event <= EVENT_CONSOLE_END_APPLICATION) ||
69 (event >= EVENT_OBJECT_CREATE && event <= EVENT_OBJECT_ACCELERATORCHANGE))
70 {
72 }
73 if (event > EVENT_SYSTEM_MINIMIZEEND && event < EVENT_CONSOLE_CARET)
74 {
75 event = EVENT_CONSOLE_CARET-1;
77 }
78 if (event > EVENT_CONSOLE_END_APPLICATION && event < EVENT_OBJECT_CREATE )
79 {
80 event = EVENT_OBJECT_CREATE-1;
82 }
83 if (event > EVENT_OBJECT_ACCELERATORCHANGE && event < EVENT_MAX)
84 {
85 event = EVENT_MAX-1;
87 break;
88 }
89 }
91 gpsi->dwInstalledEventHooks |= SRV_EVENT_RUNNING; // Set something.
92 TRACE("SetSrvEventMask 2 : %x\n", gpsi->dwInstalledEventHooks);
93}
94
95static
100 HWND hwnd,
101 LONG idObject,
102 LONG idChild,
103 LONG idThread)
104{
105 PEVENTPACK pEP;
106 MSG Msg;
107
109 if (!pEP) return 0;
110
111 pEP->pEH = pEH;
112 pEP->idObject = idObject;
113 pEP->idChild = idChild;
114 pEP->idThread = idThread;
115
116 Msg.message = event;
117 Msg.hwnd = hwnd;
118 Msg.wParam = 0;
119 Msg.lParam = POSTEVENT_NWE;
120 Msg.time = 0;
121
123 return 0;
124}
125
128{
129 PEVENTHOOK pEH = Object;
130 if (pEH)
131 {
132 TRACE("IntRemoveEvent pEH %p\n", pEH);
134 RemoveEntryList(&pEH->Chain);
139 return TRUE;
140 }
141 return FALSE;
142}
143
144/* FUNCTIONS *****************************************************************/
145
146//
147// Dispatch MsgQueue Event Call processor!
148//
152 HWND hwnd,
153 UINT_PTR idObject,
154 LONG_PTR idChild)
155{
156 PEVENTHOOK pEH;
158 PEVENTPACK pEP = (PEVENTPACK)idChild;
159
160 pEH = pEP->pEH;
161 TRACE("Dispatch Event 0x%lx, idObject %uI hwnd %p\n", event, idObject, hwnd);
163 event,
164 hwnd,
165 pEP->idObject,
166 pEP->idChild,
167 pEP->idThread,
169 pEH->Proc,
170 pEH->ihmod,
171 pEH->offPfn);
172
174 return Result;
175}
176
177VOID
180 DWORD Event,
181 PWND pWnd,
182 LONG idObject,
183 LONG idChild,
184 DWORD flags)
185{
186 PEVENTHOOK pEH;
187 PLIST_ENTRY ListEntry;
188 PTHREADINFO pti, ptiCurrent;
190
191 TRACE("IntNotifyWinEvent GlobalEvents = %p pWnd %p\n", GlobalEvents, pWnd);
192
193 if (!GlobalEvents || !GlobalEvents->Counts) return;
194
195 if (pWnd && pWnd->state & WNDS_DESTROYED) return;
196
197 ptiCurrent = PsGetCurrentThreadWin32Thread();
198
199 if (pWnd && flags & WEF_SETBYWNDPTI)
200 pti = pWnd->head.pti;
201 else
202 pti = ptiCurrent;
203
204 ListEntry = GlobalEvents->Events.Flink;
205 ASSERT(ListEntry != &GlobalEvents->Events);
206 while (ListEntry != &GlobalEvents->Events)
207 {
208 pEH = CONTAINING_RECORD(ListEntry, EVENTHOOK, Chain);
209 ListEntry = ListEntry->Flink;
210
211 // Must be inside the event window.
212 if ( Event >= pEH->eventMin && Event <= pEH->eventMax )
213 {
214 // if all process || all thread || other thread same process
215 // if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
216 if (!( (pEH->idProcess && pEH->idProcess != PtrToUint(pti->pEThread->Cid.UniqueProcess)) ||
217 (pEH->Flags & WINEVENT_SKIPOWNPROCESS && pEH->head.pti->ppi == pti->ppi) ||
218 (pEH->idThread && pEH->idThread != PtrToUint(pti->pEThread->Cid.UniqueThread)) ||
219 (pEH->Flags & WINEVENT_SKIPOWNTHREAD && pEH->head.pti == pti) ||
220 pEH->head.pti->rpdesk != ptiCurrent->rpdesk ) ) // Same as hooks.
221 {
222 UserRefObjectCo(pEH, &Ref);
223 if (pEH->Flags & WINEVENT_INCONTEXT)
224 {
225 TRACE("In Event 0x%x, idObject %d hwnd %p\n", Event, idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
227 Event,
228 pWnd ? UserHMGetHandle(pWnd) : NULL,
229 idObject,
230 idChild,
233 pEH->Proc,
234 pEH->ihmod,
235 pEH->offPfn);
236 }
237 else
238 {
239 TRACE("Out Event 0x%x, idObject %d hwnd %p\n", Event, idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
241 Event,
242 pWnd ? UserHMGetHandle(pWnd) : NULL,
243 idObject,
244 idChild,
246 }
248 }
249 }
250 }
251}
252
253VOID
256 DWORD Event,
257 HWND hWnd,
258 LONG idObject,
259 LONG idChild)
260{
261 PWND Window = NULL;
264
265 /* Validate input */
266 if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
267 {
269 if (!Window)
270 {
271 UserLeave();
272 return;
273 }
274 }
275
277 {
278 if (Window) UserRefObjectCo(Window, &Ref);
279 IntNotifyWinEvent( Event, Window, idObject, idChild, WEF_SETBYWNDPTI);
281 }
282 UserLeave();
283}
284
288 UINT eventMin,
289 UINT eventMax,
290 HMODULE hmodWinEventProc,
291 PUNICODE_STRING puString,
292 WINEVENTPROC lpfnWinEventProc,
293 DWORD idProcess,
294 DWORD idThread,
296{
297 PEVENTHOOK pEH;
298 HWINEVENTHOOK Ret = NULL;
301 PTHREADINFO pti;
302
303 TRACE("NtUserSetWinEventHook hmod %p, pfn %p\n", hmodWinEventProc, lpfnWinEventProc);
304
306
307 if ( !GlobalEvents )
308 {
310 if (GlobalEvents == NULL)
311 {
313 goto SetEventExit;
314 }
315 GlobalEvents->Counts = 0;
317 }
318
319 if (eventMin > eventMax)
320 {
322 goto SetEventExit;
323 }
324
325 if (!lpfnWinEventProc)
326 {
328 goto SetEventExit;
329 }
330
332 {
333 if (!hmodWinEventProc)
334 {
335 ERR("Hook needs a module\n");
337 goto SetEventExit;
338 }
339 if (puString == NULL)
340 {
341 ERR("Dll not found\n");
343 goto SetEventExit;
344 }
345 }
346 else
347 {
348 TRACE("Out of Context\n");
349 hmodWinEventProc = 0;
350 }
351
352 if (idThread)
353 {
356 if (!NT_SUCCESS(Status))
357 {
359 goto SetEventExit;
360 }
363 }
364 else
365 {
367 }
368 // Creator, pti is set here.
370 if (pEH)
371 {
374
375 UserHMGetHandle(pEH) = Handle;
376 pEH->eventMin = eventMin;
377 pEH->eventMax = eventMax;
378 pEH->idProcess = idProcess; // These are cmp'ed
379 pEH->idThread = idThread; // "
380 pEH->Flags = dwflags;
381 /*
382 If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from
383 the atom index table where the hmod data is saved to be recalled later
384 if fSync set by WINEVENT_INCONTEXT.
385 If WINEVENT_OUTOFCONTEXT just use proc..
386 Do this instead....
387 */
388 if (hmodWinEventProc != NULL)
389 {
390 pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);
391 pEH->ihmod = (INT_PTR)hmodWinEventProc;
392 pEH->Proc = lpfnWinEventProc;
393 }
394 else
395 {
396 pEH->Proc = lpfnWinEventProc;
397 pEH->offPfn = 0;
398 pEH->ihmod = (INT_PTR)hmodWinEventProc;
399 }
400
402
403 Ret = Handle;
404 IntSetSrvEventMask( eventMin, eventMax);
405 }
406
407SetEventExit:
408 UserLeave();
409 return Ret;
410}
411
412BOOL
415 HWINEVENTHOOK hWinEventHook)
416{
417 PEVENTHOOK pEH;
418 BOOL Ret = FALSE;
419
421
423 if (pEH)
424 {
425 Ret = IntRemoveEvent(pEH);
426 }
427
428 UserLeave();
429 return Ret;
430}
431
432/* EOF */
unsigned char BOOLEAN
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
#define PtrToUint(p)
Definition: basetsd.h:85
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
struct @1609 Msg[]
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define APIENTRY
Definition: api.h:79
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
PSERVERINFO gpsi
Definition: imm.c:18
#define ULONG_PTR
Definition: config.h:101
#define EngGetTickCount32()
Definition: eng.h:43
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
struct _cl_event * event
Definition: glext.h:7739
GLbitfield flags
Definition: glext.h:7161
struct tagEVENTHOOK * PEVENTHOOK
#define WNDS_DESTROYED
Definition: ntuser.h:631
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define SRV_EVENT_VALUECHANGE
Definition: ntuser.h:1080
#define SRV_EVENT_NAMECHANGE
Definition: ntuser.h:1079
#define SRV_EVENT_MENU
Definition: ntuser.h:1076
#define SRV_EVENT_END_APPLICATION
Definition: ntuser.h:1077
#define SRV_EVENT_LOCATIONCHANGE
Definition: ntuser.h:1082
#define SRV_EVENT_CREATE
Definition: ntuser.h:1083
@ TYPE_WINEVENTHOOK
Definition: ntuser.h:55
#define WEF_SETBYWNDPTI
Definition: ntuser.h:235
#define SRV_EVENT_STATECHANGE
Definition: ntuser.h:1081
#define SRV_EVENT_RUNNING
Definition: ntuser.h:1078
#define NtCurrentTeb
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static _In_ DWORD dwflags
Definition: dispmode.c:64
static HWINEVENTHOOK(WINAPI *pSetWinEventHook)(DWORD
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1337
#define POSTEVENT_NWE
Definition: msgqueue.h:125
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define FASTCALL
Definition: nt_native.h:50
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
Definition: thread.c:643
PVOID NTAPI PsGetThreadWin32Thread(IN PETHREAD Thread)
Definition: thread.c:795
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:254
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
long LONG
Definition: pedump.c:60
#define TRACE(s)
Definition: solgame.cpp:4
Definition: window.c:28
HANDLE UniqueThread
Definition: compat.h:826
LONG idObject
Definition: event.c:15
LONG idChild
Definition: event.c:16
PEVENTHOOK pEH
Definition: event.c:14
LONG idThread
Definition: event.c:17
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PPROCESSINFO ppi
Definition: win32.h:88
struct _DESKTOP * rpdesk
Definition: win32.h:92
struct _THREADINFO * pti
Definition: ntuser.h:188
Definition: object.h:4
Definition: ntuser.h:689
THRDESKHEAD head
Definition: ntuser.h:690
DWORD state
Definition: ntuser.h:696
UINT eventMax
Definition: hook.h:20
DWORD idThread
Definition: hook.h:22
WINEVENTPROC Proc
Definition: hook.h:23
ULONG_PTR offPfn
Definition: hook.h:25
INT_PTR ihmod
Definition: hook.h:26
LIST_ENTRY Chain
Definition: hook.h:18
UINT eventMin
Definition: hook.h:19
THROBJHEAD head
Definition: hook.h:17
ULONG Flags
Definition: hook.h:24
DWORD idProcess
Definition: hook.h:21
UINT Counts
Definition: hook.h:32
LIST_ENTRY Events
Definition: hook.h:31
DWORD dwInstalledEventHooks
Definition: ntuser.h:1066
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define QS_EVENT
Definition: undocuser.h:97
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:134
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
LRESULT APIENTRY co_IntCallEventProc(HWINEVENTHOOK hook, DWORD event, HWND hWnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime, WINEVENTPROC Proc, INT Mod, ULONG_PTR offPfn)
Definition: callback.c:838
VOID APIENTRY NtUserNotifyWinEvent(DWORD Event, HWND hWnd, LONG idObject, LONG idChild)
Definition: event.c:255
static DWORD FASTCALL GetMaskFromEvent(DWORD Event)
Definition: event.c:27
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:179
BOOLEAN IntRemoveEvent(PVOID Object)
Definition: event.c:127
static PEVENTTABLE GlobalEvents
Definition: event.c:20
static LRESULT FASTCALL IntCallLowLevelEvent(PEVENTHOOK pEH, DWORD event, HWND hwnd, LONG idObject, LONG idChild, LONG idThread)
Definition: event.c:98
struct _EVENTPACK EVENTPACK
HWINEVENTHOOK APIENTRY NtUserSetWinEventHook(UINT eventMin, UINT eventMax, HMODULE hmodWinEventProc, PUNICODE_STRING puString, WINEVENTPROC lpfnWinEventProc, DWORD idProcess, DWORD idThread, UINT dwflags)
Definition: event.c:287
LRESULT APIENTRY co_EVENT_CallEvents(DWORD event, HWND hwnd, UINT_PTR idObject, LONG_PTR idChild)
Definition: event.c:151
BOOL APIENTRY NtUserUnhookWinEvent(HWINEVENTHOOK hWinEventHook)
Definition: event.c:414
struct _EVENTPACK * PEVENTPACK
static VOID FASTCALL IntSetSrvEventMask(UINT EventMin, UINT EventMax)
Definition: event.c:61
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:495
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568
#define TAG_HOOK
Definition: tags.h:5
VOID(CALLBACK * WINEVENTPROC)(HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD)
Definition: winable.h:68
#define WINEVENT_INCONTEXT
Definition: winable.h:35
#define WINEVENT_SKIPOWNPROCESS
Definition: winable.h:34
#define WINEVENT_SKIPOWNTHREAD
Definition: winable.h:33
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LRESULT
Definition: windef.h:209
#define ERROR_INVALID_FILTER_PROC
Definition: winerror.h:908
#define ERROR_INVALID_THREAD_ID
Definition: winerror.h:925
#define ERROR_HOOK_NEEDS_HMOD
Definition: winerror.h:909
#define ERROR_DLL_NOT_FOUND
Definition: winerror.h:679
#define ERROR_INVALID_HOOK_FILTER
Definition: winerror.h:907
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165
#define ObDereferenceObject
Definition: obfuncs.h:203