ReactOS 0.4.15-dev-7907-g95bf896
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 * PROGRAMER: James Tabor <james.tabor@reactos.org>
6 */
7
8#include <win32k.h>
10
11typedef struct _EVENTPACK
12{
18
20
21/* PRIVATE FUNCTIONS *********************************************************/
22
23static
27{
28 DWORD Ret = 0;
29
30 if ( Event > EVENT_OBJECT_STATECHANGE )
31 {
32 if ( Event == EVENT_OBJECT_LOCATIONCHANGE ) return SRV_EVENT_LOCATIONCHANGE;
33 if ( Event == EVENT_OBJECT_NAMECHANGE ) return SRV_EVENT_NAMECHANGE;
34 if ( Event == EVENT_OBJECT_VALUECHANGE ) return SRV_EVENT_VALUECHANGE;
35 return SRV_EVENT_CREATE;
36 }
37
38 if ( Event == EVENT_OBJECT_STATECHANGE ) return SRV_EVENT_STATECHANGE;
39
41
42 if ( Event < EVENT_SYSTEM_MENUSTART ) return SRV_EVENT_CREATE;
43
44 if ( Event <= EVENT_SYSTEM_MENUPOPUPEND )
45 {
46 Ret = SRV_EVENT_MENU;
47 }
48 else
49 {
50 if ( Event <= EVENT_CONSOLE_CARET-1 ) return SRV_EVENT_CREATE;
51 if ( Event <= EVENT_CONSOLE_END_APPLICATION ) return SRV_EVENT_END_APPLICATION;
52 if ( Event != EVENT_OBJECT_FOCUS ) return SRV_EVENT_CREATE;
53 }
54 return Ret;
55}
56
57static
58VOID
60IntSetSrvEventMask( UINT EventMin, UINT EventMax)
61{
62 UINT event;
63 TRACE("SetSrvEventMask 1\n");
64 for ( event = EventMin; event <= EventMax; event++)
65 {
66 if ((event >= EVENT_SYSTEM_SOUND && event <= EVENT_SYSTEM_MINIMIZEEND) ||
67 (event >= EVENT_CONSOLE_CARET && event <= EVENT_CONSOLE_END_APPLICATION) ||
68 (event >= EVENT_OBJECT_CREATE && event <= EVENT_OBJECT_ACCELERATORCHANGE))
69 {
71 }
72 if (event > EVENT_SYSTEM_MINIMIZEEND && event < EVENT_CONSOLE_CARET)
73 {
74 event = EVENT_CONSOLE_CARET-1;
76 }
77 if (event > EVENT_CONSOLE_END_APPLICATION && event < EVENT_OBJECT_CREATE )
78 {
79 event = EVENT_OBJECT_CREATE-1;
81 }
82 if (event > EVENT_OBJECT_ACCELERATORCHANGE && event < EVENT_MAX)
83 {
84 event = EVENT_MAX-1;
86 break;
87 }
88 }
90 gpsi->dwInstalledEventHooks |= SRV_EVENT_RUNNING; // Set something.
91 TRACE("SetSrvEventMask 2 : %x\n", gpsi->dwInstalledEventHooks);
92}
93
94static
99 HWND hwnd,
100 LONG idObject,
101 LONG idChild,
102 LONG idThread)
103{
104 PEVENTPACK pEP;
105 MSG Msg;
106
108 if (!pEP) return 0;
109
110 pEP->pEH = pEH;
111 pEP->idObject = idObject;
112 pEP->idChild = idChild;
113 pEP->idThread = idThread;
114
115 Msg.message = event;
116 Msg.hwnd = hwnd;
117 Msg.wParam = 0;
118 Msg.lParam = POSTEVENT_NWE;
119 Msg.time = 0;
120
122 return 0;
123}
124
127{
128 PEVENTHOOK pEH = Object;
129 if (pEH)
130 {
131 TRACE("IntRemoveEvent pEH %p\n", pEH);
133 RemoveEntryList(&pEH->Chain);
138 return TRUE;
139 }
140 return FALSE;
141}
142
143/* FUNCTIONS *****************************************************************/
144
145//
146// Dispatch MsgQueue Event Call processor!
147//
151 HWND hwnd,
152 UINT_PTR idObject,
153 LONG_PTR idChild)
154{
155 PEVENTHOOK pEH;
157 PEVENTPACK pEP = (PEVENTPACK)idChild;
158
159 pEH = pEP->pEH;
160 TRACE("Dispatch Event 0x%lx, idObject %uI hwnd %p\n", event, idObject, hwnd);
162 event,
163 hwnd,
164 pEP->idObject,
165 pEP->idChild,
166 pEP->idThread,
168 pEH->Proc,
169 pEH->ihmod,
170 pEH->offPfn);
171
173 return Result;
174}
175
176VOID
179 DWORD Event,
180 PWND pWnd,
181 LONG idObject,
182 LONG idChild,
183 DWORD flags)
184{
185 PEVENTHOOK pEH;
186 PLIST_ENTRY ListEntry;
187 PTHREADINFO pti, ptiCurrent;
189
190 TRACE("IntNotifyWinEvent GlobalEvents = %p pWnd %p\n", GlobalEvents, pWnd);
191
192 if (!GlobalEvents || !GlobalEvents->Counts) return;
193
194 if (pWnd && pWnd->state & WNDS_DESTROYED) return;
195
196 ptiCurrent = PsGetCurrentThreadWin32Thread();
197
198 if (pWnd && flags & WEF_SETBYWNDPTI)
199 pti = pWnd->head.pti;
200 else
201 pti = ptiCurrent;
202
203 ListEntry = GlobalEvents->Events.Flink;
204 ASSERT(ListEntry != &GlobalEvents->Events);
205 while (ListEntry != &GlobalEvents->Events)
206 {
207 pEH = CONTAINING_RECORD(ListEntry, EVENTHOOK, Chain);
208 ListEntry = ListEntry->Flink;
209
210 // Must be inside the event window.
211 if ( Event >= pEH->eventMin && Event <= pEH->eventMax )
212 {
213 // if all process || all thread || other thread same process
214 // if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
215 if (!( (pEH->idProcess && pEH->idProcess != PtrToUint(pti->pEThread->Cid.UniqueProcess)) ||
216 (pEH->Flags & WINEVENT_SKIPOWNPROCESS && pEH->head.pti->ppi == pti->ppi) ||
217 (pEH->idThread && pEH->idThread != PtrToUint(pti->pEThread->Cid.UniqueThread)) ||
218 (pEH->Flags & WINEVENT_SKIPOWNTHREAD && pEH->head.pti == pti) ||
219 pEH->head.pti->rpdesk != ptiCurrent->rpdesk ) ) // Same as hooks.
220 {
221 UserRefObjectCo(pEH, &Ref);
222 if (pEH->Flags & WINEVENT_INCONTEXT)
223 {
224 TRACE("In Event 0x%x, idObject %d hwnd %p\n", Event, idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
226 Event,
227 pWnd ? UserHMGetHandle(pWnd) : NULL,
228 idObject,
229 idChild,
232 pEH->Proc,
233 pEH->ihmod,
234 pEH->offPfn);
235 }
236 else
237 {
238 TRACE("Out Event 0x%x, idObject %d hwnd %p\n", Event, idObject, pWnd ? UserHMGetHandle(pWnd) : NULL);
240 Event,
241 pWnd ? UserHMGetHandle(pWnd) : NULL,
242 idObject,
243 idChild,
245 }
247 }
248 }
249 }
250}
251
252VOID
255 DWORD Event,
256 HWND hWnd,
257 LONG idObject,
258 LONG idChild)
259{
260 PWND Window = NULL;
263
264 /* Validate input */
265 if (hWnd && (hWnd != INVALID_HANDLE_VALUE))
266 {
268 if (!Window)
269 {
270 UserLeave();
271 return;
272 }
273 }
274
276 {
277 if (Window) UserRefObjectCo(Window, &Ref);
278 IntNotifyWinEvent( Event, Window, idObject, idChild, WEF_SETBYWNDPTI);
280 }
281 UserLeave();
282}
283
287 UINT eventMin,
288 UINT eventMax,
289 HMODULE hmodWinEventProc,
290 PUNICODE_STRING puString,
291 WINEVENTPROC lpfnWinEventProc,
292 DWORD idProcess,
293 DWORD idThread,
295{
296 PEVENTHOOK pEH;
297 HWINEVENTHOOK Ret = NULL;
300 PTHREADINFO pti;
301
302 TRACE("NtUserSetWinEventHook hmod %p, pfn %p\n", hmodWinEventProc, lpfnWinEventProc);
303
305
306 if ( !GlobalEvents )
307 {
309 if (GlobalEvents == NULL)
310 {
312 goto SetEventExit;
313 }
314 GlobalEvents->Counts = 0;
316 }
317
318 if (eventMin > eventMax)
319 {
321 goto SetEventExit;
322 }
323
324 if (!lpfnWinEventProc)
325 {
327 goto SetEventExit;
328 }
329
331 {
332 if (!hmodWinEventProc)
333 {
334 ERR("Hook needs a module\n");
336 goto SetEventExit;
337 }
338 if (puString == NULL)
339 {
340 ERR("Dll not found\n");
342 goto SetEventExit;
343 }
344 }
345 else
346 {
347 TRACE("Out of Context\n");
348 hmodWinEventProc = 0;
349 }
350
351 if (idThread)
352 {
355 if (!NT_SUCCESS(Status))
356 {
358 goto SetEventExit;
359 }
362 }
363 else
364 {
366 }
367 // Creator, pti is set here.
369 if (pEH)
370 {
373
375 pEH->eventMin = eventMin;
376 pEH->eventMax = eventMax;
377 pEH->idProcess = idProcess; // These are cmp'ed
378 pEH->idThread = idThread; // "
379 pEH->Flags = dwflags;
380 /*
381 If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from
382 the atom index table where the hmod data is saved to be recalled later
383 if fSync set by WINEVENT_INCONTEXT.
384 If WINEVENT_OUTOFCONTEXT just use proc..
385 Do this instead....
386 */
387 if (hmodWinEventProc != NULL)
388 {
389 pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);
390 pEH->ihmod = (INT_PTR)hmodWinEventProc;
391 pEH->Proc = lpfnWinEventProc;
392 }
393 else
394 {
395 pEH->Proc = lpfnWinEventProc;
396 pEH->offPfn = 0;
397 pEH->ihmod = (INT_PTR)hmodWinEventProc;
398 }
399
401
402 Ret = Handle;
403 IntSetSrvEventMask( eventMin, eventMax);
404 }
405
406SetEventExit:
407 UserLeave();
408 return Ret;
409}
410
411BOOL
414 HWINEVENTHOOK hWinEventHook)
415{
416 PEVENTHOOK pEH;
417 BOOL Ret = FALSE;
418
420
422 if (pEH)
423 {
424 Ret = IntRemoveEvent(pEH);
425 }
426
427 UserLeave();
428 return Ret;
429}
430
431/* 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 @1632 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:636
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define SRV_EVENT_VALUECHANGE
Definition: ntuser.h:1085
#define SRV_EVENT_NAMECHANGE
Definition: ntuser.h:1084
#define SRV_EVENT_MENU
Definition: ntuser.h:1081
#define SRV_EVENT_END_APPLICATION
Definition: ntuser.h:1082
#define SRV_EVENT_LOCATIONCHANGE
Definition: ntuser.h:1087
#define SRV_EVENT_CREATE
Definition: ntuser.h:1088
@ TYPE_WINEVENTHOOK
Definition: ntuser.h:55
#define WEF_SETBYWNDPTI
Definition: ntuser.h:236
#define SRV_EVENT_STATECHANGE
Definition: ntuser.h:1086
#define UserHMSetHandle(obj, handle)
Definition: ntuser.h:231
#define SRV_EVENT_RUNNING
Definition: ntuser.h:1083
#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:1109
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:251
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
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:14
LONG idChild
Definition: event.c:15
PEVENTHOOK pEH
Definition: event.c:13
LONG idThread
Definition: event.c:16
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:694
THRDESKHEAD head
Definition: ntuser.h:695
DWORD state
Definition: ntuser.h:701
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:1071
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:122
_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:254
static DWORD FASTCALL GetMaskFromEvent(DWORD Event)
Definition: event.c:26
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:178
BOOLEAN IntRemoveEvent(PVOID Object)
Definition: event.c:126
static PEVENTTABLE GlobalEvents
Definition: event.c:19
static LRESULT FASTCALL IntCallLowLevelEvent(PEVENTHOOK pEH, DWORD event, HWND hwnd, LONG idObject, LONG idChild, LONG idThread)
Definition: event.c:97
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:286
LRESULT APIENTRY co_EVENT_CallEvents(DWORD event, HWND hwnd, UINT_PTR idObject, LONG_PTR idChild)
Definition: event.c:150
BOOL APIENTRY NtUserUnhookWinEvent(HWINEVENTHOOK hWinEventHook)
Definition: event.c:413
struct _EVENTPACK * PEVENTPACK
static VOID FASTCALL IntSetSrvEventMask(UINT EventMin, UINT EventMax)
Definition: event.c:60
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:22
_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:409
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
#define ObDereferenceObject
Definition: obfuncs.h:203