7 typedef struct _EVENTPACK
12 } EVENTPACK
, *PEVENTPACK
;
14 static PEVENTTABLE GlobalEvents
= NULL
;
16 /* PRIVATE FUNCTIONS *********************************************************/
21 GetMaskFromEvent(DWORD Event
)
25 if ( Event
> EVENT_OBJECT_STATECHANGE
)
27 if ( Event
== EVENT_OBJECT_LOCATIONCHANGE
) return SRV_EVENT_LOCATIONCHANGE
;
28 if ( Event
== EVENT_OBJECT_NAMECHANGE
) return SRV_EVENT_NAMECHANGE
;
29 if ( Event
== EVENT_OBJECT_VALUECHANGE
) return SRV_EVENT_VALUECHANGE
;
30 return SRV_EVENT_CREATE
;
33 if ( Event
== EVENT_OBJECT_STATECHANGE
) return SRV_EVENT_STATECHANGE
;
35 Ret
= SRV_EVENT_RUNNING
;
37 if ( Event
< EVENT_SYSTEM_MENUSTART
) return SRV_EVENT_CREATE
;
39 if ( Event
<= EVENT_SYSTEM_MENUPOPUPEND
)
45 if ( Event
<= EVENT_CONSOLE_CARET
-1 ) return SRV_EVENT_CREATE
;
46 if ( Event
<= EVENT_CONSOLE_END_APPLICATION
) return SRV_EVENT_END_APPLICATION
;
47 if ( Event
!= EVENT_OBJECT_FOCUS
) return SRV_EVENT_CREATE
;
55 IntSetSrvEventMask( UINT EventMin
, UINT EventMax
)
58 DPRINT("SetSrvEventMask 1\n");
59 for ( event
= EventMin
; event
<= EventMax
; event
++)
61 if ((event
>= EVENT_SYSTEM_SOUND
&& event
<= EVENT_SYSTEM_MINIMIZEEND
) ||
62 (event
>= EVENT_CONSOLE_CARET
&& event
<= EVENT_CONSOLE_END_APPLICATION
) ||
63 (event
>= EVENT_OBJECT_CREATE
&& event
<= EVENT_OBJECT_ACCELERATORCHANGE
))
65 gpsi
->SrvEventActivity
|= GetMaskFromEvent(event
);
67 if (event
> EVENT_SYSTEM_MINIMIZEEND
&& event
< EVENT_CONSOLE_CARET
)
69 event
= EVENT_CONSOLE_CARET
-1;
70 gpsi
->SrvEventActivity
|= GetMaskFromEvent(event
);
72 if (event
> EVENT_CONSOLE_END_APPLICATION
&& event
< EVENT_OBJECT_CREATE
)
74 event
= EVENT_OBJECT_CREATE
-1;
75 gpsi
->SrvEventActivity
|= GetMaskFromEvent(event
);
77 if (event
> EVENT_OBJECT_ACCELERATORCHANGE
&& event
< EVENT_MAX
)
80 gpsi
->SrvEventActivity
|= GetMaskFromEvent(event
);
84 if (!gpsi
->SrvEventActivity
)
85 gpsi
->SrvEventActivity
|= SRV_EVENT_RUNNING
; // Set something.
86 DPRINT("SetSrvEventMask 2 : %x\n", gpsi
->SrvEventActivity
);
92 IntCallLowLevelEvent( PEVENTHOOK pEH
,
103 EP
.idObject
= idObject
;
104 EP
.idChild
= idChild
;
106 /* FIXME should get timeout from
107 * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
108 Status
= co_MsqSendMessage(((PTHREADINFO
)pEH
->Thread
->Tcb
.Win32Thread
)->MessageQueue
,
118 return NT_SUCCESS(Status
) ? uResult
: 0;
125 IntRemoveEvent(PEVENTHOOK pEH
)
129 RemoveEntryList(&pEH
->Chain
);
130 GlobalEvents
->Counts
--;
131 if (!GlobalEvents
->Counts
) gpsi
->SrvEventActivity
= 0;
132 UserDeleteObject(pEH
->Self
, otEvent
);
138 /* FUNCTIONS *****************************************************************/
142 co_EVENT_CallEvents( DWORD event
,
149 PEVENTPACK pEP
= (PEVENTPACK
)idChild
;
153 Result
= co_IntCallEventProc( pEH
->Self
,
158 (DWORD
)(NtCurrentTeb()->ClientId
).UniqueThread
,
159 (DWORD
)EngGetTickCount(),
168 PWINDOW_OBJECT Window
,
175 if (!GlobalEvents
->Counts
) return;
177 pEH
= (PEVENTHOOK
)GlobalEvents
->Events
.Flink
;
181 UserReferenceObject(pEH
);
182 // Must be inside the event window.
183 if ( (pEH
->eventMin
<= Event
) && (pEH
->eventMax
>= Event
))
185 if ((pEH
->Thread
!= PsGetCurrentThread()) && (pEH
->Thread
!= NULL
))
186 { // if all process || all thread || other thread same process
187 if (!(pEH
->idProcess
) || !(pEH
->idThread
) ||
188 (NtCurrentTeb()->ClientId
.UniqueProcess
== (PVOID
)pEH
->idProcess
))
190 Result
= IntCallLowLevelEvent(pEH
, Event
, Window
->hSelf
, idObject
, idChild
);
192 }// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
193 else if ( !(pEH
->Flags
& WINEVENT_SKIPOWNTHREAD
) &&
194 ( ((pEH
->idProcess
&&
195 NtCurrentTeb()->ClientId
.UniqueProcess
== (PVOID
)pEH
->idProcess
) &&
196 !(pEH
->Flags
& WINEVENT_SKIPOWNPROCESS
)) ||
199 Result
= co_IntCallEventProc( pEH
->Self
,
204 PtrToUint(NtCurrentTeb()->ClientId
.UniqueThread
),
205 (DWORD
)EngGetTickCount(),
209 UserDereferenceObject(pEH
);
211 pEH
= (PEVENTHOOK
)pEH
->Chain
.Flink
;
212 } while (pEH
!= (PEVENTHOOK
)&GlobalEvents
->Events
.Flink
);
217 NtUserNotifyWinEvent(
223 PWINDOW_OBJECT Window
= NULL
;
224 USER_REFERENCE_ENTRY Ref
;
225 UserEnterExclusive();
228 if (hWnd
&& (hWnd
!= INVALID_HANDLE_VALUE
) && !(Window
= UserGetWindowObject(hWnd
)))
234 if (gpsi
->SrvEventActivity
& GetMaskFromEvent(Event
))
236 UserRefObjectCo(Window
, &Ref
);
237 IntNotifyWinEvent( Event
, Window
, idObject
, idChild
);
238 UserDerefObjectCo(Window
);
245 NtUserSetWinEventHook(
248 HMODULE hmodWinEventProc
,
249 PUNICODE_STRING puString
,
250 WINEVENTPROC lpfnWinEventProc
,
256 HWINEVENTHOOK Ret
= NULL
;
257 UNICODE_STRING ModuleName
;
260 PETHREAD Thread
= NULL
;
262 UserEnterExclusive();
266 GlobalEvents
= ExAllocatePoolWithTag(PagedPool
, sizeof(EVENTTABLE
), TAG_HOOK
);
267 if (GlobalEvents
== NULL
)
269 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
272 GlobalEvents
->Counts
= 0;
273 InitializeListHead(&GlobalEvents
->Events
);
276 if (eventMin
> eventMax
)
278 SetLastWin32Error(ERROR_INVALID_HOOK_FILTER
);
282 if (!lpfnWinEventProc
)
284 SetLastWin32Error(ERROR_INVALID_FILTER_PROC
);
288 if ((dwflags
& WINEVENT_INCONTEXT
) && !hmodWinEventProc
)
290 SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD
);
296 Status
= PsLookupThreadByThreadId((HANDLE
)(DWORD_PTR
)idThread
, &Thread
);
297 if (!NT_SUCCESS(Status
))
299 SetLastWin32Error(ERROR_INVALID_THREAD_ID
);
304 pEH
= UserCreateObject(gHandleTable
, &Handle
, otEvent
, sizeof(EVENTHOOK
));
307 InsertTailList(&GlobalEvents
->Events
, &pEH
->Chain
);
308 GlobalEvents
->Counts
++;
312 pEH
->Thread
= Thread
;
314 pEH
->Thread
= PsGetCurrentThread();
315 pEH
->eventMin
= eventMin
;
316 pEH
->eventMax
= eventMax
;
317 pEH
->idProcess
= idProcess
;
318 pEH
->idThread
= idThread
;
320 pEH
->Flags
= dwflags
;
323 if (NULL
!= hmodWinEventProc
)
325 Status
= MmCopyFromCaller(&ModuleName
,
327 sizeof(UNICODE_STRING
));
329 if (! NT_SUCCESS(Status
))
331 UserDereferenceObject(pEH
);
333 SetLastNtError(Status
);
337 pEH
->ModuleName
.Buffer
= ExAllocatePoolWithTag(PagedPool
,
338 ModuleName
.MaximumLength
,
341 if (NULL
== pEH
->ModuleName
.Buffer
)
343 UserDereferenceObject(pEH
);
345 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
349 pEH
->ModuleName
.MaximumLength
= ModuleName
.MaximumLength
;
351 Status
= MmCopyFromCaller(pEH
->ModuleName
.Buffer
,
353 ModuleName
.MaximumLength
);
355 if (! NT_SUCCESS(Status
))
357 ExFreePoolWithTag(pEH
->ModuleName
.Buffer
, TAG_HOOK
);
358 UserDereferenceObject(pEH
);
360 SetLastNtError(Status
);
364 pEH
->ModuleName
.Length
= ModuleName
.Length
;
366 pEH
->Proc
= (void *)((char *)lpfnWinEventProc
- (char *)hmodWinEventProc
);
369 pEH
->Proc
= lpfnWinEventProc
;
371 UserDereferenceObject(pEH
);
374 IntSetSrvEventMask( eventMin
, eventMax
);
378 if (Thread
) ObDereferenceObject(Thread
);
385 NtUserUnhookWinEvent(
386 HWINEVENTHOOK hWinEventHook
)
391 UserEnterExclusive();
393 pEH
= (PEVENTHOOK
)UserGetObject(gHandleTable
, hWinEventHook
, otEvent
);
396 Ret
= IntRemoveEvent(pEH
);