ReactOS 0.4.15-dev-5853-gcb454ef
hook.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 hooks
5 * FILE: win32ss/user/ntuser/hook.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * James Tabor (james.tabor@rectos.org)
8 * Rafal Harabien (rafalh@reactos.org)
9 * NOTE: Most of this code was adapted from Wine,
10 * Copyright (C) 2002 Alexandre Julliard
11 */
12
13#include <win32k.h>
15
16typedef struct _HOOKPACK
17{
22
26
27/* PRIVATE FUNCTIONS *********************************************************/
28
29/* Calls ClientLoadLibrary in user32 in order to load or unload a module */
30BOOL
31IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
32{
33 PPROCESSINFO ppi;
34 BOOL bResult;
35
37
38 TRACE("IntLoadHookModule. Client PID: %p\n", PsGetProcessId(ppi->peProcess));
39
40 /* Check if this is the api hook */
41 if(iHookID == WH_APIHOOK)
42 {
43 if(!Unload && !(ppi->W32PF_flags & W32PF_APIHOOKLOADED))
44 {
45 /* A callback in user mode can trigger UserLoadApiHook to be called and
46 as a result IntLoadHookModule will be called recursively.
47 To solve this we set the flag that means that the appliaction has
48 loaded the api hook before the callback and in case of error we remove it */
49 ppi->W32PF_flags |= W32PF_APIHOOKLOADED;
50
51 /* Call ClientLoadLibrary in user32 */
53 TRACE("co_IntClientLoadLibrary returned %d\n", bResult );
54 if (!bResult)
55 {
56 /* Remove the flag we set before */
57 ppi->W32PF_flags &= ~W32PF_APIHOOKLOADED;
58 }
59 return bResult;
60 }
61 else if(Unload && (ppi->W32PF_flags & W32PF_APIHOOKLOADED))
62 {
63 /* Call ClientLoadLibrary in user32 */
65 if (bResult)
66 {
67 ppi->W32PF_flags &= ~W32PF_APIHOOKLOADED;
68 }
69 return bResult;
70 }
71
72 return TRUE;
73 }
74
75 STUB;
76
77 return FALSE;
78}
79
80/*
81IntHookModuleUnloaded:
82Sends a internal message to all threads of the requested desktop
83and notifies them that a global hook was destroyed
84and an injected module must be unloaded.
85As a result, IntLoadHookModule will be called for all the threads that
86will receive the special purpose internal message.
87*/
88BOOL
89IntHookModuleUnloaded(PDESKTOP pdesk, int iHookID, HHOOK hHook)
90{
91 PTHREADINFO ptiCurrent;
92 PLIST_ENTRY ListEntry;
93 PPROCESSINFO ppiCsr;
94
95 TRACE("IntHookModuleUnloaded: iHookID=%d\n", iHookID);
96
98
99 ListEntry = pdesk->PtiList.Flink;
100 while(ListEntry != &pdesk->PtiList)
101 {
102 ptiCurrent = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
103
104 /* FIXME: Do some more security checks here */
105
106 /* FIXME: HACK: The first check is a reactos specific hack for system threads */
107 if(!PsIsSystemProcess(ptiCurrent->ppi->peProcess) &&
108 ptiCurrent->ppi != ppiCsr)
109 {
110 if(ptiCurrent->ppi->W32PF_flags & W32PF_APIHOOKLOADED)
111 {
112 TRACE("IntHookModuleUnloaded: sending message to PID %p, ppi=%p\n", PsGetProcessId(ptiCurrent->ppi->peProcess), ptiCurrent->ppi);
113 co_MsqSendMessageAsync( ptiCurrent,
114 0,
115 iHookID,
116 TRUE,
117 (LPARAM)hHook,
118 NULL,
119 0,
120 FALSE,
122 }
123 }
124 ListEntry = ListEntry->Flink;
125 }
126
127 return TRUE;
128}
129
130BOOL
133{
135}
136
137BOOL
140 PUNICODE_STRING pstrDllName,
141 PUNICODE_STRING pstrFuncName)
142{
143 PTHREADINFO pti, ptiCurrent;
144 HWND *List;
145 PWND DesktopWindow, pwndCurrent;
146 ULONG i;
147 PPROCESSINFO ppiCsr;
148
151
152 /* Fail if the api hook is already registered */
154 {
155 return FALSE;
156 }
157
158 TRACE("UserRegisterUserApiHook. Server PID: %p\n", PsGetProcessId(pti->ppi->peProcess));
159
160 /* Register the api hook */
162
163 strUahModule = *pstrDllName;
164 strUahInitFunc = *pstrFuncName;
165 ppiUahServer = pti->ppi;
166
167 /* Broadcast an internal message to every top level window */
170
171 if (List != NULL)
172 {
173 for (i = 0; List[i]; i++)
174 {
175 pwndCurrent = UserGetWindowObject(List[i]);
176 if(pwndCurrent == NULL)
177 {
178 continue;
179 }
180 ptiCurrent = pwndCurrent->head.pti;
181
182 /* FIXME: The first check is a reactos specific hack for system threads */
183 if(PsIsSystemProcess(ptiCurrent->ppi->peProcess) ||
184 ptiCurrent->ppi == ppiCsr)
185 {
186 continue;
187 }
188
189 co_MsqSendMessageAsync( ptiCurrent,
190 0,
192 FALSE, /* Load the module */
193 0,
194 NULL,
195 0,
196 FALSE,
198 }
200 }
201
202 return TRUE;
203}
204
205BOOL
208{
209 PTHREADINFO pti;
210
212
213 /* Fail if the api hook is not registered */
215 {
216 return FALSE;
217 }
218
219 /* Only the process that registered the api hook can uregister it */
221 {
222 return FALSE;
223 }
224
225 TRACE("UserUnregisterUserApiHook. Server PID: %p\n", PsGetProcessId(pti->ppi->peProcess));
226
227 /* Unregister the api hook */
228 gpsi->dwSRVIFlags &= ~SRVINFO_APIHOOK;
232
233 /* Notify all applications that the api hook module must be unloaded */
234 return IntHookModuleUnloaded(pti->rpdesk, WH_APIHOOK, 0);
235}
236
237static
241 INT Code,
244{
246 PTHREADINFO pti;
247 PHOOKPACK pHP;
248 INT Size = 0;
249 UINT uTimeout = 300;
250 BOOL Block = FALSE;
251 ULONG_PTR uResult = 0;
252
253 if (Hook->ptiHooked)
254 pti = Hook->ptiHooked;
255 else
256 pti = Hook->head.pti;
257
259 if (!pHP) return 0;
260
261 pHP->pHk = Hook;
262 pHP->lParam = lParam;
263 pHP->pHookStructs = NULL;
264
265// This prevents stack corruption from the caller.
266 switch(Hook->HookId)
267 {
269 case WH_JOURNALRECORD:
270 uTimeout = 0;
271 Size = sizeof(EVENTMSG);
272 break;
273 case WH_KEYBOARD_LL:
274 Size = sizeof(KBDLLHOOKSTRUCT);
275 break;
276 case WH_MOUSE_LL:
277 Size = sizeof(MSLLHOOKSTRUCT);
278 break;
279 case WH_MOUSE:
280 uTimeout = 200;
281 Block = TRUE;
282 Size = sizeof(MOUSEHOOKSTRUCT);
283 break;
284 case WH_KEYBOARD:
285 uTimeout = 200;
286 Block = TRUE;
287 break;
288 }
289
290 if (Size)
291 {
294 }
295
296 /* FIXME: Should get timeout from
297 * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */
299 IntToPtr(Code), // hWnd
300 Hook->HookId, // Msg
301 wParam,
302 (LPARAM)pHP,
303 uTimeout,
304 Block,
306 &uResult);
307 if (!NT_SUCCESS(Status))
308 {
309 ERR("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status);
312 }
313 return NT_SUCCESS(Status) ? uResult : 0;
314}
315
316
317//
318// Dispatch MsgQueue Hook Call processor!
319//
323 INT Code,
326{
327 LRESULT Result = 0;
328 PHOOK phk;
330
331 phk = pHP->pHk;
332 lParam = pHP->lParam;
333
334 switch(HookId)
335 {
337 case WH_JOURNALRECORD:
338 case WH_KEYBOARD_LL:
339 case WH_MOUSE_LL:
340 case WH_MOUSE:
341 lParam = (LPARAM)pHP->pHookStructs;
342 case WH_KEYBOARD:
343 break;
344 }
345
347 {
348 /* The odds are high for this to be a Global call. */
349 Result = co_IntCallHookProc( HookId,
350 Code,
351 wParam,
352 lParam,
353 phk->Proc,
354 phk->ihmod,
355 phk->offPfn,
356 phk->Ansi,
357 &phk->ModuleName);
358 }
359 /* The odds so high, no one is waiting for the results. */
362 return Result;
363}
364
365static
369 INT Code,
372{
373 TRACE("Calling Next HOOK %d\n", Hook->HookId);
374
375 return co_IntCallHookProc( Hook->HookId,
376 Code,
377 wParam,
378 lParam,
379 Hook->Proc,
380 Hook->ihmod,
381 Hook->offPfn,
382 Hook->Ansi,
383 &Hook->ModuleName);
384}
385
386static
390 int Code,
393 BOOL Ansi)
394{
395 LRESULT lResult = 0;
396 ULONG Size;
397 DEBUGHOOKINFO Debug;
398 PVOID HooklParam = NULL;
399 BOOL BadChk = FALSE;
400
401 if (lParam)
402 {
404 {
406 sizeof(DEBUGHOOKINFO),
407 1);
408
409 RtlCopyMemory(&Debug,
410 (PVOID)lParam,
411 sizeof(DEBUGHOOKINFO));
412 }
414 {
415 BadChk = TRUE;
416 }
417 _SEH2_END;
418
419 if (BadChk)
420 {
421 ERR("HOOK WH_DEBUG read from lParam ERROR!\n");
422 return lResult;
423 }
424 }
425 else
426 return lResult; /* Need lParam! */
427
428 switch (wParam)
429 {
430 case WH_CBT:
431 {
432 switch (Debug.code)
433 {
435 Size = sizeof(MOUSEHOOKSTRUCTEX);
436 break;
437
438 case HCBT_MOVESIZE:
439 Size = sizeof(RECT);
440 break;
441
442 case HCBT_ACTIVATE:
443 Size = sizeof(CBTACTIVATESTRUCT);
444 break;
445
446 case HCBT_CREATEWND: /* Handle ANSI? */
447 Size = sizeof(CBT_CREATEWND);
448 /* What shall we do? Size += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS); same as CREATESTRUCTEX */
449 break;
450
451 default:
452 Size = sizeof(LPARAM);
453 }
454 }
455 break;
456
457 case WH_MOUSE_LL:
458 Size = sizeof(MSLLHOOKSTRUCT);
459 break;
460
461 case WH_KEYBOARD_LL:
462 Size = sizeof(KBDLLHOOKSTRUCT);
463 break;
464
465 case WH_MSGFILTER:
466 case WH_SYSMSGFILTER:
467 case WH_GETMESSAGE:
468 Size = sizeof(MSG);
469 break;
470
472 case WH_JOURNALRECORD:
473 Size = sizeof(EVENTMSG);
474 break;
475
477 case WH_KEYBOARD:
478 case WH_SHELL:
479 default:
480 Size = sizeof(LPARAM);
481 }
482
483 if (Size > sizeof(LPARAM))
485
486 if (HooklParam)
487 {
489 {
491 Size,
492 1);
493
494 RtlCopyMemory(HooklParam,
495 (PVOID)Debug.lParam,
496 Size);
497 }
499 {
500 BadChk = TRUE;
501 }
502 _SEH2_END;
503
504 if (BadChk)
505 {
506 ERR("HOOK WH_DEBUG read from Debug.lParam ERROR!\n");
507 ExFreePoolWithTag(HooklParam, TAG_HOOK);
508 return lResult;
509 }
510 }
511
512 if (HooklParam) Debug.lParam = (LPARAM)HooklParam;
513 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Debug);
514 if (HooklParam) ExFreePoolWithTag(HooklParam, TAG_HOOK);
515
516 return lResult;
517}
518
519static
523 int Code,
526 BOOL Ansi)
527{
528 LRESULT lResult = 0;
529 BOOL BadChk = FALSE;
530
531 /* Handle this one first. */
532 if ((Hook->HookId == WH_MOUSE) ||
533 (Hook->HookId == WH_CBT && Code == HCBT_CLICKSKIPPED))
534 {
535 MOUSEHOOKSTRUCTEX Mouse;
536 if (lParam)
537 {
539 {
541 sizeof(MOUSEHOOKSTRUCTEX),
542 1);
543
545 (PVOID)lParam,
546 sizeof(MOUSEHOOKSTRUCTEX));
547 }
549 {
550 BadChk = TRUE;
551 }
552 _SEH2_END;
553
554 if (BadChk)
555 {
556 ERR("HOOK WH_MOUSE read from lParam ERROR!\n");
557 }
558 }
559
560 if (!BadChk)
561 {
562 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Mouse);
563 }
564
565 return lResult;
566 }
567
568 switch(Hook->HookId)
569 {
570 case WH_MOUSE_LL:
571 {
573
574 if (lParam)
575 {
577 {
579 sizeof(MSLLHOOKSTRUCT),
580 1);
581
583 (PVOID)lParam,
584 sizeof(MSLLHOOKSTRUCT));
585 }
587 {
588 BadChk = TRUE;
589 }
590 _SEH2_END;
591
592 if (BadChk)
593 {
594 ERR("HOOK WH_MOUSE_LL read from lParam ERROR!\n");
595 }
596 }
597
598 if (!BadChk)
599 {
600 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Mouse);
601 }
602 break;
603 }
604
605 case WH_KEYBOARD_LL:
606 {
608
609 if (lParam)
610 {
612 {
614 sizeof(KBDLLHOOKSTRUCT),
615 1);
616
618 (PVOID)lParam,
619 sizeof(KBDLLHOOKSTRUCT));
620 }
622 {
623 BadChk = TRUE;
624 }
625 _SEH2_END;
626
627 if (BadChk)
628 {
629 ERR("HOOK WH_KEYBORD_LL read from lParam ERROR!\n");
630 }
631 }
632
633 if (!BadChk)
634 {
635 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Keyboard);
636 }
637 break;
638 }
639
640 case WH_MSGFILTER:
641 case WH_SYSMSGFILTER:
642 case WH_GETMESSAGE:
643 {
644 MSG Msg;
645
646 if (lParam)
647 {
649 {
651 sizeof(MSG),
652 1);
653
655 (PVOID)lParam,
656 sizeof(MSG));
657 }
659 {
660 BadChk = TRUE;
661 }
662 _SEH2_END;
663
664 if (BadChk)
665 {
666 ERR("HOOK WH_XMESSAGEX read from lParam ERROR!\n");
667 }
668 }
669
670 if (!BadChk)
671 {
672 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&Msg);
673
674 if (lParam && (Hook->HookId == WH_GETMESSAGE))
675 {
677 {
679 sizeof(MSG),
680 1);
681
683 &Msg,
684 sizeof(MSG));
685 }
687 {
688 BadChk = TRUE;
689 }
690 _SEH2_END;
691
692 if (BadChk)
693 {
694 ERR("HOOK WH_GETMESSAGE write to lParam ERROR!\n");
695 }
696 }
697 }
698 break;
699 }
700
701 case WH_CBT:
702 TRACE("HOOK WH_CBT!\n");
703 switch (Code)
704 {
705 case HCBT_CREATEWND:
706 {
708
709 TRACE("HOOK HCBT_CREATEWND\n");
711 {
712 if (Ansi)
713 {
714 ProbeForRead( pcbtcww,
715 sizeof(CBT_CREATEWNDA),
716 1);
717 ProbeForWrite(pcbtcww->lpcs,
718 sizeof(CREATESTRUCTA),
719 1);
720 ProbeForRead( pcbtcww->lpcs->lpszName,
721 sizeof(CHAR),
722 1);
723
724 if (!IS_ATOM(pcbtcww->lpcs->lpszClass))
725 {
726 _Analysis_assume_(pcbtcww->lpcs->lpszClass != NULL);
727 ProbeForRead(pcbtcww->lpcs->lpszClass,
728 sizeof(CHAR),
729 1);
730 }
731 }
732 else
733 {
734 ProbeForRead( pcbtcww,
735 sizeof(CBT_CREATEWNDW),
736 1);
737 ProbeForWrite(pcbtcww->lpcs,
738 sizeof(CREATESTRUCTW),
739 1);
740 ProbeForRead( pcbtcww->lpcs->lpszName,
741 sizeof(WCHAR),
742 1);
743
744 if (!IS_ATOM(pcbtcww->lpcs->lpszClass))
745 {
746 _Analysis_assume_(pcbtcww->lpcs->lpszClass != NULL);
747 ProbeForRead(pcbtcww->lpcs->lpszClass,
748 sizeof(WCHAR),
749 1);
750 }
751 }
752 }
754 {
755 BadChk = TRUE;
756 }
757 _SEH2_END;
758
759 if (BadChk)
760 {
761 ERR("HOOK HCBT_CREATEWND write ERROR!\n");
762 }
763 /* The next call handles the structures. */
764 if (!BadChk && Hook->Proc)
765 {
766 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
767 }
768 break;
769 }
770
771 case HCBT_MOVESIZE:
772 {
773 RECTL rt;
774
775 TRACE("HOOK HCBT_MOVESIZE\n");
776
777 if (lParam)
778 {
780 {
782 sizeof(RECT),
783 1);
784
785 RtlCopyMemory(&rt,
786 (PVOID)lParam,
787 sizeof(RECT));
788 }
790 {
791 BadChk = TRUE;
792 }
793 _SEH2_END;
794
795 if (BadChk)
796 {
797 ERR("HOOK HCBT_MOVESIZE read from lParam ERROR!\n");
798 }
799 }
800
801 if (!BadChk)
802 {
803 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&rt);
804 }
805 break;
806 }
807
808 case HCBT_ACTIVATE:
809 {
811
812 TRACE("HOOK HCBT_ACTIVATE\n");
813 if (lParam)
814 {
816 {
818 sizeof(CBTACTIVATESTRUCT),
819 1);
820
821 RtlCopyMemory(&CbAs,
822 (PVOID)lParam,
823 sizeof(CBTACTIVATESTRUCT));
824 }
826 {
827 BadChk = TRUE;
828 }
829 _SEH2_END;
830
831 if (BadChk)
832 {
833 ERR("HOOK HCBT_ACTIVATE read from lParam ERROR!\n");
834 }
835 }
836
837 if (!BadChk)
838 {
839 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)&CbAs);
840 }
841 break;
842 }
843
844 /* The rest just use default. */
845 default:
846 TRACE("HOOK HCBT_ %d\n",Code);
847 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
848 break;
849 }
850 break;
851/*
852 Note WH_JOURNALPLAYBACK,
853 "To have the system wait before processing the message, the return value
854 must be the amount of time, in clock ticks, that the system should wait."
855 */
857 case WH_JOURNALRECORD:
858 {
859 EVENTMSG EventMsg;
860
861 if (lParam)
862 {
864 {
866 sizeof(EVENTMSG),
867 1);
868
869 RtlCopyMemory(&EventMsg,
870 (PVOID)lParam,
871 sizeof(EVENTMSG));
872 }
874 {
875 BadChk = TRUE;
876 }
877 _SEH2_END;
878
879 if (BadChk)
880 {
881 ERR("HOOK WH_JOURNAL read from lParam ERROR!\n");
882 }
883 }
884
885 if (!BadChk)
886 {
887 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, (LPARAM)(lParam ? &EventMsg : NULL));
888
889 if (lParam)
890 {
892 {
894 sizeof(EVENTMSG),
895 1);
896
898 &EventMsg,
899 sizeof(EVENTMSG));
900 }
902 {
903 BadChk = TRUE;
904 }
905 _SEH2_END;
906
907 if (BadChk)
908 {
909 ERR("HOOK WH_JOURNAL write to lParam ERROR!\n");
910 }
911 }
912 }
913 break;
914 }
915
916 case WH_DEBUG:
917 lResult = co_IntCallDebugHook(Hook, Code, wParam, lParam, Ansi);
918 break;
919
920 /*
921 * Default the rest like, WH_FOREGROUNDIDLE, WH_KEYBOARD and WH_SHELL.
922 */
924 case WH_KEYBOARD:
925 case WH_SHELL:
926 lResult = co_HOOK_CallHookNext(Hook, Code, wParam, lParam);
927 break;
928
929 default:
930 ERR("Unsupported HOOK Id -> %d\n",Hook->HookId);
931 break;
932 }
933 return lResult;
934}
935
936PHOOK
939{
940 PHOOK Hook;
941
942 if (!hHook)
943 {
945 return NULL;
946 }
947
948 Hook = (PHOOK)UserGetObject(gHandleTable, hHook, TYPE_HOOK);
949 if (!Hook)
950 {
952 return NULL;
953 }
954
956
957 return Hook;
958}
959
960static
961HHOOK*
964{
965 PLIST_ENTRY pLastHead, pElem;
966 unsigned i = 0;
967 unsigned cHooks = 0;
968 HHOOK *pList;
969 PHOOK pHook;
970
971 pLastHead = &pdo->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
972 for (pElem = pLastHead->Flink; pElem != pLastHead; pElem = pElem->Flink)
973 ++cHooks;
974
975 pList = ExAllocatePoolWithTag(PagedPool, (cHooks + 1) * sizeof(HHOOK), TAG_HOOK);
976 if (!pList)
977 {
979 return NULL;
980 }
981
982 for (pElem = pLastHead->Flink; pElem != pLastHead; pElem = pElem->Flink)
983 {
984 pHook = CONTAINING_RECORD(pElem, HOOK, Chain);
985 NT_ASSERT(i < cHooks);
986 pList[i++] = pHook->head.h;
987 }
988 pList[i] = NULL;
989
990 return pList;
991}
992
993/* Find the next hook in the chain */
994PHOOK
997{
998 int HookId = Hook->HookId;
999 PLIST_ENTRY pLastHead, pElem;
1000 PTHREADINFO pti;
1001
1002 if (Hook->ptiHooked)
1003 {
1004 pti = Hook->ptiHooked;
1005 pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
1006 }
1007 else
1008 {
1010 pLastHead = &pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)];
1011 }
1012
1013 pElem = Hook->Chain.Flink;
1014 if (pElem != pLastHead)
1015 return CONTAINING_RECORD(pElem, HOOK, Chain);
1016 return NULL;
1017}
1018
1019/* Free a hook, removing it from its chain */
1020static
1021VOID
1024{
1025 RemoveEntryList(&Hook->Chain);
1026 if (Hook->ModuleName.Buffer)
1027 {
1029 Hook->ModuleName.Buffer = NULL;
1030 }
1031 /* Close handle */
1033}
1034
1035/* Remove a hook, freeing it from the chain */
1036BOOLEAN
1038{
1039 INT HookId;
1040 PTHREADINFO ptiHook, pti;
1041 PDESKTOP pdo;
1042 PHOOK Hook = Object;
1043
1045
1046 HookId = Hook->HookId;
1048
1049 if (Hook->ptiHooked) // Local
1050 {
1051 ptiHook = Hook->ptiHooked;
1052
1053 IntFreeHook(Hook);
1054
1055 if (IsListEmpty(&ptiHook->aphkStart[HOOKID_TO_INDEX(HookId)]))
1056 {
1057 BOOL bOtherProcess;
1059
1060 ptiHook->fsHooks &= ~HOOKID_TO_FLAG(HookId);
1061 bOtherProcess = (ptiHook->ppi != pti->ppi);
1062
1063 if (bOtherProcess)
1064 KeStackAttachProcess(&ptiHook->ppi->peProcess->Pcb, &ApcState);
1065
1066 _SEH2_TRY
1067 {
1068 ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
1069 }
1071 {
1072 /* Do nothing */
1073 (void)0;
1074 }
1075 _SEH2_END;
1076
1077 if (bOtherProcess)
1079 }
1080 }
1081 else // Global
1082 {
1083 IntFreeHook(Hook);
1084
1085 pdo = IntGetActiveDesktop();
1086
1087 if (pdo &&
1088 pdo->pDeskInfo &&
1090 {
1091 pdo->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId);
1092 }
1093 }
1094
1095 return TRUE;
1096}
1097
1098/*
1099 Win32k Kernel Space Hook Caller.
1100 */
1101LRESULT
1104 INT Code,
1105 WPARAM wParam,
1106 LPARAM lParam)
1107{
1108 PHOOK Hook, SaveHook;
1109 PTHREADINFO pti;
1111 PLIST_ENTRY pLastHead;
1112 PDESKTOP pdo;
1113 BOOL Local = FALSE, Global = FALSE;
1114 LRESULT Result = 0;
1116
1117 ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
1118
1120 if (!pti || !pti->rpdesk || !pti->rpdesk->pDeskInfo)
1121 {
1122 pdo = IntGetActiveDesktop();
1123 /* If KeyboardThread|MouseThread|(RawInputThread or RIT) aka system threads,
1124 pti->fsHooks most likely, is zero. So process KbT & MsT to "send" the message.
1125 */
1126 if ( !pti || !pdo || (!(HookId == WH_KEYBOARD_LL) && !(HookId == WH_MOUSE_LL)) )
1127 {
1128 TRACE("No PDO %d\n", HookId);
1129 goto Exit;
1130 }
1131 }
1132 else
1133 {
1134 pdo = pti->rpdesk;
1135 }
1136
1138 {
1139 TRACE("Hook Thread dead %d\n", HookId);
1140 goto Exit;
1141 }
1142
1143 if ( ISITHOOKED(HookId) )
1144 {
1145 TRACE("Local Hooker %d\n", HookId);
1146 Local = TRUE;
1147 }
1148
1149 if ( pdo->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId) )
1150 {
1151 TRACE("Global Hooker %d\n", HookId);
1152 Global = TRUE;
1153 }
1154
1155 if ( !Local && !Global ) goto Exit; // No work!
1156
1157 Hook = NULL;
1158
1159 /* SetWindowHookEx sorts out the Thread issue by placing the Hook to
1160 the correct Thread if not NULL.
1161 */
1162 if ( Local )
1163 {
1164 pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
1165 if (IsListEmpty(pLastHead))
1166 {
1167 ERR("No Local Hook Found!\n");
1168 goto Exit;
1169 }
1170
1171 Hook = CONTAINING_RECORD(pLastHead->Flink, HOOK, Chain);
1172 ObReferenceObject(pti->pEThread);
1174 UserRefObjectCo(Hook, &Ref);
1175
1176 ClientInfo = pti->pClientInfo;
1177 SaveHook = pti->sphkCurrent;
1178 /* Note: Setting pti->sphkCurrent will also lock the next hook to this
1179 * hook ID. So, the CallNextHookEx will only call to that hook ID
1180 * chain anyway. For Thread Hooks....
1181 */
1182
1183 /* Load it for the next call. */
1184 pti->sphkCurrent = Hook;
1185 Hook->phkNext = IntGetNextHook(Hook);
1186 if (ClientInfo)
1187 {
1188 _SEH2_TRY
1189 {
1190 ClientInfo->phkCurrent = Hook;
1191 }
1193 {
1194 ClientInfo = NULL; // Don't bother next run.
1195 }
1196 _SEH2_END;
1197 }
1198 Result = co_IntCallHookProc( HookId,
1199 Code,
1200 wParam,
1201 lParam,
1202 Hook->Proc,
1203 Hook->ihmod,
1204 Hook->offPfn,
1205 Hook->Ansi,
1206 &Hook->ModuleName);
1207 if (ClientInfo)
1208 {
1209 _SEH2_TRY
1210 {
1211 ClientInfo->phkCurrent = SaveHook;
1212 }
1214 {
1215 /* Do nothing */
1216 (void)0;
1217 }
1218 _SEH2_END;
1219 }
1220 pti->sphkCurrent = SaveHook;
1221 Hook->phkNext = NULL;
1222 UserDerefObjectCo(Hook);
1224 ObDereferenceObject(pti->pEThread);
1225 }
1226
1227 if ( Global )
1228 {
1229 PTHREADINFO ptiHook;
1230 HHOOK *pHookHandles;
1231 unsigned i;
1232
1233 /* Keep hooks in array because hooks can be destroyed in user world */
1234 pHookHandles = IntGetGlobalHookHandles(pdo, HookId);
1235 if(!pHookHandles)
1236 goto Exit;
1237
1238 /* Performance goes down the drain. If more hooks are associated to this
1239 * hook ID, this will have to post to each of the thread message queues
1240 * or make a direct call.
1241 */
1242 for(i = 0; pHookHandles[i]; ++i)
1243 {
1244 Hook = (PHOOK)UserGetObject(gHandleTable, pHookHandles[i], TYPE_HOOK);
1245 if(!Hook)
1246 {
1247 ERR("Invalid hook!\n");
1248 continue;
1249 }
1250
1251 /* Hook->Thread is null, we hax around this with Hook->head.pti. */
1252 ptiHook = Hook->head.pti;
1253
1254 if ( (pti->TIF_flags & TIF_DISABLEHOOKS) || (ptiHook->TIF_flags & TIF_INCLEANUP))
1255 {
1256 TRACE("Next Hook %p, %p\n", ptiHook->rpdesk, pdo);
1257 continue;
1258 }
1259 UserRefObjectCo(Hook, &Ref);
1260
1261 if (ptiHook != pti )
1262 {
1263 // Block | TimeOut
1264 if ( HookId == WH_JOURNALPLAYBACK || // 1 | 0
1265 HookId == WH_JOURNALRECORD || // 1 | 0
1266 HookId == WH_KEYBOARD || // 1 | 200
1267 HookId == WH_MOUSE || // 1 | 200
1268 HookId == WH_KEYBOARD_LL || // 0 | 300
1269 HookId == WH_MOUSE_LL ) // 0 | 300
1270 {
1271 TRACE("\nGlobal Hook posting to another Thread! %d\n",HookId );
1273 }
1274 else if (ptiHook->ppi == pti->ppi)
1275 {
1276 TRACE("\nGlobal Hook calling to another Thread! %d\n",HookId );
1277 ObReferenceObject(ptiHook->pEThread);
1278 IntReferenceThreadInfo(ptiHook);
1279 Result = co_IntCallHookProc( HookId,
1280 Code,
1281 wParam,
1282 lParam,
1283 Hook->Proc,
1284 Hook->ihmod,
1285 Hook->offPfn,
1286 Hook->Ansi,
1287 &Hook->ModuleName);
1288 IntDereferenceThreadInfo(ptiHook);
1289 ObDereferenceObject(ptiHook->pEThread);
1290 }
1291 }
1292 else
1293 { /* Make the direct call. */
1294 TRACE("Global going Local Hook calling to Thread! %d\n",HookId );
1295 ObReferenceObject(pti->pEThread);
1297 Result = co_IntCallHookProc( HookId,
1298 Code,
1299 wParam,
1300 lParam,
1301 Hook->Proc,
1302 Hook->ihmod,
1303 Hook->offPfn,
1304 Hook->Ansi,
1305 &Hook->ModuleName);
1307 ObDereferenceObject(pti->pEThread);
1308 }
1309 UserDerefObjectCo(Hook);
1310 }
1311 ExFreePoolWithTag(pHookHandles, TAG_HOOK);
1312 TRACE("Ret: Global HookId %d Result 0x%x\n", HookId,Result);
1313 }
1314Exit:
1315 return Result;
1316}
1317
1318BOOL
1320IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
1321{
1322 PHOOK Hook;
1323 PLIST_ENTRY pLastHead, pElement;
1325
1326 if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
1327 {
1329 return FALSE;
1330 }
1331
1332 if (pti->fsHooks)
1333 {
1334 pLastHead = &pti->aphkStart[HOOKID_TO_INDEX(HookId)];
1335
1336 pElement = pLastHead->Flink;
1337 while (pElement != pLastHead)
1338 {
1339 Hook = CONTAINING_RECORD(pElement, HOOK, Chain);
1340
1341 /* Get the next element now, we might free the hook in what follows */
1342 pElement = Hook->Chain.Flink;
1343
1344 if (Hook->Proc == pfnFilterProc)
1345 {
1346 if (Hook->head.pti == pti)
1347 {
1348 IntRemoveHook(Hook);
1349 return TRUE;
1350 }
1351 else
1352 {
1354 return FALSE;
1355 }
1356 }
1357 }
1358 }
1359 return FALSE;
1360}
1361
1362/*
1363 * Support for compatibility only? Global hooks are processed in kernel space.
1364 * This is very thread specific! Never seeing applications with more than one
1365 * hook per thread installed. Most of the applications are Global hookers and
1366 * associated with just one hook Id. Maybe it's for diagnostic testing or a
1367 * throw back to 3.11?
1368 */
1369LRESULT
1372 WPARAM wParam,
1373 LPARAM lParam,
1374 BOOL Ansi)
1375{
1376 PTHREADINFO pti;
1377 PHOOK HookObj, NextObj;
1379 LRESULT lResult = 0;
1381
1382 TRACE("Enter NtUserCallNextHookEx\n");
1384
1385 pti = GetW32ThreadInfo();
1386
1387 HookObj = pti->sphkCurrent;
1388
1389 if (!HookObj) RETURN( 0);
1390
1391 NextObj = HookObj->phkNext;
1392
1393 pti->sphkCurrent = NextObj;
1394 ClientInfo = pti->pClientInfo;
1395 _SEH2_TRY
1396 {
1397 ClientInfo->phkCurrent = NextObj;
1398 }
1400 {
1401 ClientInfo = NULL;
1402 }
1403 _SEH2_END;
1404
1405 /* Now in List run down. */
1406 if (ClientInfo && NextObj)
1407 {
1408 NextObj->phkNext = IntGetNextHook(NextObj);
1409 lResult = co_UserCallNextHookEx( NextObj, Code, wParam, lParam, NextObj->Ansi);
1410 }
1411 RETURN( lResult);
1412
1413CLEANUP:
1414 TRACE("Leave NtUserCallNextHookEx, ret=%i\n",_ret_);
1415 UserLeave();
1417}
1418
1419HHOOK
1422 HOOKPROC lpfn,
1423 BOOL Ansi)
1424{
1425 DWORD ThreadId;
1426 UNICODE_STRING USModuleName;
1427
1428 RtlInitUnicodeString(&USModuleName, NULL);
1430
1432 &USModuleName,
1433 ThreadId,
1434 idHook,
1435 lpfn,
1436 Ansi);
1437}
1438
1439HHOOK
1442 PUNICODE_STRING UnsafeModuleName,
1443 DWORD ThreadId,
1444 int HookId,
1445 HOOKPROC HookProc,
1446 BOOL Ansi)
1447{
1448 PWINSTATION_OBJECT WinStaObj;
1449 PHOOK Hook = NULL;
1452 HHOOK Handle;
1453 PTHREADINFO pti, ptiHook = NULL;
1454 DECLARE_RETURN(HHOOK);
1455
1456 TRACE("Enter NtUserSetWindowsHookEx\n");
1458
1460
1461 if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId )
1462 {
1464 RETURN( NULL);
1465 }
1466
1467 if (!HookProc)
1468 {
1470 RETURN( NULL);
1471 }
1472
1473 if (ThreadId) /* thread-local hook */
1474 {
1475 if ( HookId == WH_JOURNALRECORD ||
1476 HookId == WH_JOURNALPLAYBACK ||
1477 HookId == WH_KEYBOARD_LL ||
1478 HookId == WH_MOUSE_LL ||
1479 HookId == WH_SYSMSGFILTER)
1480 {
1481 TRACE("Local hook installing Global HookId: %d\n",HookId);
1482 /* these can only be global */
1484 RETURN( NULL);
1485 }
1486
1487 if ( !(ptiHook = IntTID2PTI( UlongToHandle(ThreadId) )))
1488 {
1489 ERR("Invalid thread id 0x%x\n", ThreadId);
1491 RETURN( NULL);
1492 }
1493
1494 if ( ptiHook->rpdesk != pti->rpdesk) // gptiCurrent->rpdesk)
1495 {
1496 ERR("Local hook wrong desktop HookId: %d\n",HookId);
1498 RETURN( NULL);
1499 }
1500
1501 if (ptiHook->ppi != pti->ppi)
1502 {
1503 if ( !Mod &&
1504 (HookId == WH_GETMESSAGE ||
1505 HookId == WH_CALLWNDPROC ||
1506 HookId == WH_CBT ||
1507 HookId == WH_HARDWARE ||
1508 HookId == WH_DEBUG ||
1509 HookId == WH_SHELL ||
1510 HookId == WH_FOREGROUNDIDLE ||
1511 HookId == WH_CALLWNDPROCRET) )
1512 {
1513 ERR("Local hook needs hMod HookId: %d\n",HookId);
1515 RETURN( NULL);
1516 }
1517
1518 if ( (ptiHook->TIF_flags & (TIF_CSRSSTHREAD|TIF_SYSTEMTHREAD)) &&
1519 (HookId == WH_GETMESSAGE ||
1520 HookId == WH_CALLWNDPROC ||
1521 HookId == WH_CBT ||
1522 HookId == WH_HARDWARE ||
1523 HookId == WH_DEBUG ||
1524 HookId == WH_SHELL ||
1525 HookId == WH_FOREGROUNDIDLE ||
1526 HookId == WH_CALLWNDPROCRET) )
1527 {
1529 RETURN( NULL);
1530 }
1531 }
1532 }
1533 else /* System-global hook */
1534 {
1535 ptiHook = pti; // gptiCurrent;
1536 if ( !Mod &&
1537 (HookId == WH_GETMESSAGE ||
1538 HookId == WH_CALLWNDPROC ||
1539 HookId == WH_CBT ||
1540 HookId == WH_SYSMSGFILTER ||
1541 HookId == WH_HARDWARE ||
1542 HookId == WH_DEBUG ||
1543 HookId == WH_SHELL ||
1544 HookId == WH_FOREGROUNDIDLE ||
1545 HookId == WH_CALLWNDPROCRET) )
1546 {
1547 ERR("Global hook needs hMod HookId: %d\n",HookId);
1549 RETURN( NULL);
1550 }
1551 }
1552
1554 UserMode,
1555 0,
1556 &WinStaObj,
1557 0);
1558
1559 if (!NT_SUCCESS(Status))
1560 {
1562 RETURN( NULL);
1563 }
1564 ObDereferenceObject(WinStaObj);
1565
1566 Hook = UserCreateObject(gHandleTable, NULL, ptiHook, (PHANDLE)&Handle, TYPE_HOOK, sizeof(HOOK));
1567
1568 if (!Hook)
1569 {
1570 RETURN( NULL);
1571 }
1572
1573 Hook->ihmod = (INT_PTR)Mod; // Module Index from atom table, Do this for now.
1574 Hook->HookId = HookId;
1575 Hook->rpdesk = ptiHook->rpdesk;
1576 Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */
1577 Hook->Proc = HookProc;
1578 Hook->Ansi = Ansi;
1579
1580 TRACE("Set Hook Desk %p DeskInfo %p Handle Desk %p\n", pti->rpdesk, pti->pDeskInfo, Hook->head.rpdesk);
1581
1582 if (ThreadId) /* Thread-local hook */
1583 {
1584 InsertHeadList(&ptiHook->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
1585 ptiHook->sphkCurrent = NULL;
1586 Hook->ptiHooked = ptiHook;
1587 ptiHook->fsHooks |= HOOKID_TO_FLAG(HookId);
1588
1589 if (ptiHook->pClientInfo)
1590 {
1591 if ( ptiHook->ppi == pti->ppi) /* gptiCurrent->ppi) */
1592 {
1593 _SEH2_TRY
1594 {
1595 ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
1596 ptiHook->pClientInfo->phkCurrent = NULL;
1597 }
1599 {
1600 ERR("Problem writing to Local ClientInfo!\n");
1601 }
1602 _SEH2_END;
1603 }
1604 else
1605 {
1607
1608 KeStackAttachProcess(&ptiHook->ppi->peProcess->Pcb, &ApcState);
1609 _SEH2_TRY
1610 {
1611 ptiHook->pClientInfo->fsHooks = ptiHook->fsHooks;
1612 ptiHook->pClientInfo->phkCurrent = NULL;
1613 }
1615 {
1616 ERR("Problem writing to Remote ClientInfo!\n");
1617 }
1618 _SEH2_END;
1620 }
1621 }
1622 }
1623 else
1624 {
1625 InsertHeadList(&ptiHook->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain);
1626 Hook->ptiHooked = NULL;
1627 //gptiCurrent->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
1628 ptiHook->rpdesk->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId);
1629 ptiHook->sphkCurrent = NULL;
1630 ptiHook->pClientInfo->phkCurrent = NULL;
1631 }
1632
1634
1635 if (Mod)
1636 {
1638 UnsafeModuleName,
1639 sizeof(UNICODE_STRING));
1640 if (!NT_SUCCESS(Status))
1641 {
1642 IntRemoveHook(Hook);
1644 RETURN( NULL);
1645 }
1646
1648 ModuleName.MaximumLength,
1649 TAG_HOOK);
1650 if (NULL == Hook->ModuleName.Buffer)
1651 {
1652 IntRemoveHook(Hook);
1654 RETURN( NULL);
1655 }
1656
1657 Hook->ModuleName.MaximumLength = ModuleName.MaximumLength;
1659 ModuleName.Buffer,
1660 ModuleName.MaximumLength);
1661 if (!NT_SUCCESS(Status))
1662 {
1664 Hook->ModuleName.Buffer = NULL;
1665 IntRemoveHook(Hook);
1667 RETURN( NULL);
1668 }
1669
1673 FIXME("NtUserSetWindowsHookEx Setting process hMod instance addressing.\n");
1674 /* Make proc relative to the module base */
1675 Hook->offPfn = (ULONG_PTR)((char *)HookProc - (char *)Mod);
1676 }
1677 else
1678 Hook->offPfn = 0;
1679
1680 TRACE("Installing: HookId %d Global %s\n", HookId, !ThreadId ? "TRUE" : "FALSE");
1681 RETURN( Handle);
1682
1683CLEANUP:
1684 if (Hook)
1686 TRACE("Leave NtUserSetWindowsHookEx, ret=%p\n", _ret_);
1687 UserLeave();
1689}
1690
1691BOOL
1694{
1695 PHOOK HookObj;
1697
1698 TRACE("Enter NtUserUnhookWindowsHookEx\n");
1700
1701 if (!(HookObj = IntGetHookObject(Hook)))
1702 {
1703 ERR("Invalid handle passed to NtUserUnhookWindowsHookEx\n");
1704 /* SetLastNtError(Status); */
1705 RETURN( FALSE);
1706 }
1707
1708 ASSERT(Hook == UserHMGetHandle(HookObj));
1709
1710 IntRemoveHook(HookObj);
1711
1712 UserDereferenceObject(HookObj);
1713
1714 RETURN( TRUE);
1715
1716CLEANUP:
1717 TRACE("Leave NtUserUnhookWindowsHookEx, ret=%i\n",_ret_);
1718 UserLeave();
1720}
1721
1722BOOL
1725 PUNICODE_STRING m_dllname1,
1726 PUNICODE_STRING m_funname1,
1727 DWORD dwUnknown3,
1728 DWORD dwUnknown4)
1729{
1730 BOOL ret;
1731 UNICODE_STRING strDllNameSafe;
1732 UNICODE_STRING strFuncNameSafe;
1734
1735 /* Probe and capture parameters */
1736 Status = ProbeAndCaptureUnicodeString(&strDllNameSafe, UserMode, m_dllname1);
1737 if(!NT_SUCCESS(Status))
1738 {
1740 return FALSE;
1741 }
1742
1743 Status = ProbeAndCaptureUnicodeString(&strFuncNameSafe, UserMode, m_funname1);
1744 if(!NT_SUCCESS(Status))
1745 {
1746 ReleaseCapturedUnicodeString(&strDllNameSafe, UserMode);
1748 return FALSE;
1749 }
1750
1752
1753 /* Call internal function */
1754 ret = UserRegisterUserApiHook(&strDllNameSafe, &strFuncNameSafe);
1755
1756 UserLeave();
1757
1758 /* Cleanup only in case of failure */
1759 if(ret == FALSE)
1760 {
1761 ReleaseCapturedUnicodeString(&strDllNameSafe, UserMode);
1762 ReleaseCapturedUnicodeString(&strFuncNameSafe, UserMode);
1763 }
1764
1765 return ret;
1766}
1767
1768BOOL
1771{
1772 BOOL ret;
1773
1776 UserLeave();
1777
1778 return ret;
1779}
1780
1781/* EOF */
#define RETURN(x)
#define MSG
Definition: Mailslot.c:11
unsigned char BOOLEAN
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
LONG NTSTATUS
Definition: precomp.h:26
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define PtrToUint(p)
Definition: basetsd.h:85
#define IntToPtr(i)
Definition: basetsd.h:89
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
#define IS_ATOM(x)
Definition: class.h:3
WPARAM wParam
Definition: combotst.c:138
struct @1609 Msg[]
LPARAM lParam
Definition: combotst.c:139
PEPROCESS gpepCSRSS
Definition: csr.c:15
#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 ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
PSERVERINFO gpsi
Definition: imm.c:18
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
Definition: floppy.c:377
FxChildList * pList
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define HOOKID_TO_INDEX(HookId)
Definition: hook.h:4
#define ISITHOOKED(HookId)
Definition: hook.h:6
#define WH_APIHOOK
Definition: hook.h:12
#define HOOKID_TO_FLAG(HookId)
Definition: hook.h:5
@ Keyboard
Definition: i8042prt.h:115
@ Mouse
Definition: i8042prt.h:116
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define TIF_CSRSSTHREAD
Definition: ntuser.h:265
#define TIF_INCLEANUP
Definition: ntuser.h:262
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct tagHOOK * PHOOK
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:801
@ TYPE_HOOK
Definition: ntuser.h:45
#define SRVINFO_APIHOOK
Definition: ntuser.h:945
#define TIF_SYSTEMTHREAD
Definition: ntuser.h:264
#define TIF_DISABLEHOOKS
Definition: ntuser.h:290
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
CLIENT_DATA ClientInfo
#define NtCurrentTeb
#define STUB
Definition: kernel32.h:27
UNICODE_STRING Global
Definition: symlink.c:37
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
NTSTATUS FASTCALL co_MsqSendMessage(PTHREADINFO ptirec, HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult)
Definition: msgqueue.c:1056
BOOL FASTCALL co_MsqSendMessageAsync(PTHREADINFO ptiReceiver, HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, BOOL HasPackedLParam, INT HookMessage)
Definition: msgqueue.c:1014
#define MSQ_ISHOOK
Definition: msgqueue.h:5
#define MSQ_INJECTMODULE
Definition: msgqueue.h:6
unsigned int UINT
Definition: ndis.h:50
#define UserMode
Definition: asm.h:35
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
BOOLEAN NTAPI PsIsSystemProcess(IN PEPROCESS Process)
Definition: process.c:1223
PVOID NTAPI PsGetProcessWin32Process(PEPROCESS Process)
Definition: process.c:1193
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
HANDLE NTAPI PsGetProcessId(PEPROCESS Process)
Definition: process.c:1063
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
static HHOOK *FASTCALL IntGetGlobalHookHandles(PDESKTOP pdo, int HookId)
Definition: hook.c:963
LRESULT APIENTRY co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:322
struct _HOOKPACK HOOKPACK
UNICODE_STRING strUahModule
Definition: hook.c:23
static LRESULT APIENTRY co_HOOK_CallHookNext(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:368
static LRESULT FASTCALL co_IntCallLowLevelHook(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:240
BOOL FASTCALL UserUnregisterUserApiHook(VOID)
Definition: hook.c:207
UNICODE_STRING strUahInitFunc
Definition: hook.c:24
BOOL APIENTRY NtUserUnregisterUserApiHook(VOID)
Definition: hook.c:1770
BOOL APIENTRY NtUserRegisterUserApiHook(PUNICODE_STRING m_dllname1, PUNICODE_STRING m_funname1, DWORD dwUnknown3, DWORD dwUnknown4)
Definition: hook.c:1724
LRESULT APIENTRY NtUserCallNextHookEx(int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: hook.c:1371
PHOOK FASTCALL IntGetNextHook(PHOOK Hook)
Definition: hook.c:996
struct _HOOKPACK * PHOOKPACK
BOOL IntHookModuleUnloaded(PDESKTOP pdesk, int iHookID, HHOOK hHook)
Definition: hook.c:89
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1103
BOOL APIENTRY NtUserUnhookWindowsHookEx(HHOOK Hook)
Definition: hook.c:1693
BOOL FASTCALL UserLoadApiHook(VOID)
Definition: hook.c:132
HHOOK APIENTRY NtUserSetWindowsHookEx(HINSTANCE Mod, PUNICODE_STRING UnsafeModuleName, DWORD ThreadId, int HookId, HOOKPROC HookProc, BOOL Ansi)
Definition: hook.c:1441
static LRESULT FASTCALL co_IntCallDebugHook(PHOOK Hook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: hook.c:389
HHOOK APIENTRY NtUserSetWindowsHookAW(int idHook, HOOKPROC lpfn, BOOL Ansi)
Definition: hook.c:1421
static VOID FASTCALL IntFreeHook(PHOOK Hook)
Definition: hook.c:1023
static LRESULT APIENTRY co_UserCallNextHookEx(PHOOK Hook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: hook.c:522
PHOOK FASTCALL IntGetHookObject(HHOOK hHook)
Definition: hook.c:938
PPROCESSINFO ppiUahServer
Definition: hook.c:25
BOOLEAN IntRemoveHook(PVOID Object)
Definition: hook.c:1037
BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
Definition: hook.c:31
BOOL FASTCALL IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc)
Definition: hook.c:1320
BOOL FASTCALL UserRegisterUserApiHook(PUNICODE_STRING pstrDllName, PUNICODE_STRING pstrFuncName)
Definition: hook.c:139
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:232
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:254
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
BOOL FASTCALL UserIsEnteredExclusive(VOID)
Definition: ntuser.c:227
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
#define MmCopyFromCaller
Definition: polytest.cpp:29
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
Implementation of the Explorer desktop window.
Definition: desktop.h:52
HANDLE UniqueThread
Definition: compat.h:826
DWORD fsHooks
Definition: ntuser.h:138
LIST_ENTRY aphkStart[NB_HOOKS]
Definition: ntuser.h:139
LIST_ENTRY PtiList
Definition: desktop.h:25
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
Definition: hook.c:17
PVOID pHookStructs
Definition: hook.c:20
PHOOK pHk
Definition: hook.c:18
LPARAM lParam
Definition: hook.c:19
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
PPROCESSINFO ppi
Definition: win32.h:88
struct _DESKTOPINFO * pDeskInfo
Definition: win32.h:93
struct tagHOOK * sphkCurrent
Definition: win32.h:118
ULONG fsHooks
Definition: win32.h:117
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
LIST_ENTRY aphkStart[NB_HOOKS]
FIXME!
Definition: win32.h:143
FLONG TIF_flags
Definition: win32.h:95
struct _DESKTOP * rpdesk
Definition: win32.h:92
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: object.h:4
Definition: ntuser.h:689
THRDESKHEAD head
Definition: ntuser.h:690
ACPI_SIZE Length
Definition: actypes.h:1053
LPCREATESTRUCTW lpcs
Definition: winuser.h:2965
LPCWSTR lpszClass
Definition: winuser.h:2955
LPCWSTR lpszName
Definition: winuser.h:2954
INT_PTR ihmod
Definition: ntuser.h:244
struct tagHOOK * phkNext
Definition: ntuser.h:240
THRDESKHEAD head
Definition: ntuser.h:239
HOOKPROC Proc
Definition: ntuser.h:249
LIST_ENTRY Chain
Definition: ntuser.h:248
ULONG_PTR offPfn
Definition: ntuser.h:242
int HookId
Definition: ntuser.h:241
struct _THREADINFO * ptiHooked
Definition: ntuser.h:245
struct _DESKTOP * rpdesk
Definition: ntuser.h:246
BOOLEAN Ansi
Definition: ntuser.h:250
UNICODE_STRING ModuleName
Definition: ntuser.h:251
DWORD dwSRVIFlags
Definition: ntuser.h:1046
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define CLEANUP
Definition: ntuser.h:5
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
#define END_CLEANUP
Definition: ntuser.h:6
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:134
int ret
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1701
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:171
#define IntReferenceThreadInfo(pti)
Definition: win32.h:166
#define W32PF_APIHOOKLOADED
Definition: win32.h:35
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:37
#define RECT
Definition: precomp.h:26
BOOL NTAPI co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName, PUNICODE_STRING pstrInitFunc, BOOL Unload, BOOL ApiHook)
Definition: callback.c:136
LRESULT APIENTRY co_IntCallHookProc(INT HookId, INT Code, WPARAM wParam, LPARAM lParam, HOOKPROC Proc, INT Mod, ULONG_PTR offPfn, BOOLEAN Ansi, PUNICODE_STRING ModuleName)
Definition: callback.c:508
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1262
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1374
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42
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
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:703
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:731
#define USERTAG_WINDOWLIST
Definition: tags.h:298
#define TAG_HOOK
Definition: tags.h:5
HWND *FASTCALL IntWinListChildren(PWND Window)
Definition: window.c:286
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define ERROR_HOOK_TYPE_NOT_ALLOWED
Definition: winerror.h:939
#define ERROR_INVALID_FILTER_PROC
Definition: winerror.h:908
#define ERROR_HOOK_NEEDS_HMOD
Definition: winerror.h:909
#define ERROR_INVALID_HOOK_FILTER
Definition: winerror.h:907
#define ERROR_INVALID_HOOK_HANDLE
Definition: winerror.h:885
#define ERROR_GLOBAL_ONLY_HOOK
Definition: winerror.h:910
#define WH_KEYBOARD
Definition: winuser.h:32
LRESULT(CALLBACK * HOOKPROC)(int, WPARAM, LPARAM)
Definition: winuser.h:2889
#define WH_CALLWNDPROCRET
Definition: winuser.h:42
struct tagEVENTMSG EVENTMSG
struct tagMOUSEHOOKSTRUCT MOUSEHOOKSTRUCT
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define WH_MSGFILTER
Definition: winuser.h:29
#define WH_MINHOOK
Definition: winuser.h:46
#define WH_MAXHOOK
Definition: winuser.h:47
struct tagCBTACTIVATESTRUCT CBTACTIVATESTRUCT
#define WH_SHELL
Definition: winuser.h:40
CBT_CREATEWNDA CBT_CREATEWND
Definition: winuser.h:5717
#define WH_CBT
Definition: winuser.h:35
#define WH_JOURNALPLAYBACK
Definition: winuser.h:31
#define HCBT_CREATEWND
Definition: winuser.h:58
#define WH_MOUSE_LL
Definition: winuser.h:44
#define WH_DEBUG
Definition: winuser.h:39
#define WH_MOUSE
Definition: winuser.h:37
#define WH_HARDWARE
Definition: winuser.h:38
#define HCBT_CLICKSKIPPED
Definition: winuser.h:61
#define HCBT_MOVESIZE
Definition: winuser.h:55
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define WH_GETMESSAGE
Definition: winuser.h:33
#define WH_SYSMSGFILTER
Definition: winuser.h:36
struct tagMSLLHOOKSTRUCT MSLLHOOKSTRUCT
struct tagKBDLLHOOKSTRUCT KBDLLHOOKSTRUCT
#define WH_FOREGROUNDIDLE
Definition: winuser.h:41
struct tagCBT_CREATEWNDW * LPCBT_CREATEWNDW
#define WH_JOURNALRECORD
Definition: winuser.h:30
#define WH_CALLWNDPROC
Definition: winuser.h:34
_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
KAPC_STATE
Definition: ketypes.h:1285
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define NT_ASSERT
Definition: rtlfuncs.h:3310
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175