ReactOS  0.4.11-dev-195-gef016bf
hook.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*
20  *
21  * PROJECT: ReactOS user32.dll
22  * FILE: win32ss/user/user32/windows/hook.c
23  * PURPOSE: Hooks
24  * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25  * UPDATE HISTORY:
26  * 09-05-2001 CSH Created
27  */
28 
29 #include <user32.h>
30 
32 
33 typedef struct _NOTIFYEVENT
34 {
35  DWORD event;
36  LONG idObject;
37  LONG idChild;
38  DWORD flags;
40 
41 /* PRIVATE FUNCTIONS *********************************************************/
42 
43 static
44 DWORD
47 {
48  DWORD Ret = 0;
49 
50  if ( Event > EVENT_OBJECT_STATECHANGE )
51  {
52  if ( Event == EVENT_OBJECT_LOCATIONCHANGE ) return SRV_EVENT_LOCATIONCHANGE;
53  if ( Event == EVENT_OBJECT_NAMECHANGE ) return SRV_EVENT_NAMECHANGE;
54  if ( Event == EVENT_OBJECT_VALUECHANGE ) return SRV_EVENT_VALUECHANGE;
55  return SRV_EVENT_CREATE;
56  }
57 
58  if ( Event == EVENT_OBJECT_STATECHANGE ) return SRV_EVENT_STATECHANGE;
59 
60  Ret = SRV_EVENT_RUNNING;
61 
62  if ( Event < EVENT_SYSTEM_MENUSTART ) return SRV_EVENT_CREATE;
63 
64  if ( Event <= EVENT_SYSTEM_MENUPOPUPEND )
65  {
66  Ret = SRV_EVENT_MENU;
67  }
68  else
69  {
70  if ( Event <= EVENT_CONSOLE_CARET-1 ) return SRV_EVENT_CREATE;
71  if ( Event <= EVENT_CONSOLE_END_APPLICATION ) return SRV_EVENT_END_APPLICATION;
72  if ( Event != EVENT_OBJECT_FOCUS ) return SRV_EVENT_CREATE;
73  }
74  return Ret;
75 }
76 
77 static
78 HHOOK
81  int idHook,
82  HOOKPROC lpfn,
83  HINSTANCE hMod,
85  BOOL bAnsi)
86 {
88  UNICODE_STRING USModuleName;
89 
90  if (NULL != hMod)
91  {
92  if (0 == GetModuleFileNameW(hMod, ModuleName, MAX_PATH))
93  {
94  return NULL;
95  }
96  RtlInitUnicodeString(&USModuleName, ModuleName);
97  }
98  else
99  {
100  RtlInitUnicodeString(&USModuleName, NULL);
101  }
102 
103  return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi);
104 }
105 
106 /*
107  Since ReactOS uses User32 as the main message source this was needed.
108  Base on the funny rules from the wine tests it left it with this option.
109  8^(
110  */
111 VOID
112 FASTCALL
114  DWORD event,
115  HWND hwnd,
116  LONG idObject,
117  LONG idChild,
118  DWORD flags
119  )
120 {
121  NOTIFYEVENT ne;
122  ne.event = event;
123  ne.idObject = idObject;
124  ne.idChild = idChild;
125  ne.flags = flags;
127  NtUserxNotifyWinEvent(hwnd, &ne);
128 }
129 
130 /* FUNCTIONS *****************************************************************/
131 
132 #if 0
133 BOOL
134 WINAPI
136  LPMSG lpMsg,
137  int nCode)
138 {
140  return FALSE;
141 }
142 #endif
143 
144 /*
145  * @implemented
146  */
147 BOOL
148 WINAPI
150  LPMSG lpMsg,
151  int nCode)
152 {
153  MSG Msg;
154  if ( NtCurrentTeb()->Win32ThreadInfo &&
156  {
157  if ( lpMsg->message & ~WM_MAXIMUM )
158  {
160  return FALSE;
161  }
162  RtlCopyMemory(&Msg, lpMsg, sizeof(MSG));
163  return NtUserCallMsgFilter( &Msg, nCode);
164  }
165  return FALSE;
166 }
167 
168 
169 /*
170  * @implemented
171  */
172 BOOL
173 WINAPI
175  LPMSG lpMsg,
176  int nCode)
177 {
178  MSG Msg;
179  if ( NtCurrentTeb()->Win32ThreadInfo &&
181  {
182  if ( lpMsg->message & ~WM_MAXIMUM )
183  {
185  return FALSE;
186  }
187  RtlCopyMemory(&Msg, lpMsg, sizeof(MSG));
188  return NtUserCallMsgFilter( &Msg, nCode);
189  }
190  return FALSE;
191 }
192 
193 
194 /*
195  * @implemented
196  */
197 LRESULT
198 WINAPI
200  HHOOK Hook, // Windows NT/XP/2003: Ignored.
201  int Code,
202  WPARAM wParam,
203  LPARAM lParam)
204 {
206  DWORD Flags, Save;
207  PHOOK pHook, phkNext;
208  LRESULT lResult = 0;
209 
210  ClientInfo = GetWin32ClientInfo();
211 
212  if (!ClientInfo->phkCurrent) return 0;
213 
214  pHook = DesktopPtrToUser(ClientInfo->phkCurrent);
215 
216  if (!pHook->phkNext) return 0; // Nothing to do....
217 
218  phkNext = DesktopPtrToUser(pHook->phkNext);
219 
220  if ( phkNext->HookId == WH_CALLWNDPROC ||
221  phkNext->HookId == WH_CALLWNDPROCRET)
222  {
223  Save = ClientInfo->dwHookData;
224  Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK;
225 // wParam: If the message was sent by the current thread/process, it is
226 // nonzero; otherwise, it is zero.
227  if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK;
228  else ClientInfo->CI_flags &= ~CI_CURTHPRHOOK;
229 
230  if (phkNext->HookId == WH_CALLWNDPROC)
231  {
232  PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam;
233 
234  NtUserMessageCall( pCWP->hwnd,
235  pCWP->message,
236  pCWP->wParam,
237  pCWP->lParam,
238  (ULONG_PTR)&lResult,
240  phkNext->Ansi);
241  }
242  else
243  {
244  PCWPRETSTRUCT pCWPR = (PCWPRETSTRUCT)lParam;
245 
246  ClientInfo->dwHookData = pCWPR->lResult;
247 
248  NtUserMessageCall( pCWPR->hwnd,
249  pCWPR->message,
250  pCWPR->wParam,
251  pCWPR->lParam,
252  (ULONG_PTR)&lResult,
254  phkNext->Ansi);
255  }
256  ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK);
257  ClientInfo->dwHookData = Save;
258  }
259  else
260  lResult = NtUserCallNextHookEx(Code, wParam, lParam, pHook->Ansi);
261 
262  return lResult;
263 }
264 
265 
266 /*
267  * @implemented
268  */
269 HHOOK
270 WINAPI
271 SetWindowsHookW(int idHook, HOOKPROC lpfn)
272 {
274  return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, FALSE);
275 // return NtUserSetWindowsHookAW(idHook, lpfn, FALSE);
276 }
277 
278 /*
279  * @implemented
280  */
281 HHOOK
282 WINAPI
283 SetWindowsHookA(int idHook, HOOKPROC lpfn)
284 {
286  return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, TRUE);
287 // return NtUserSetWindowsHookAW(idHook, lpfn, TRUE);
288 }
289 
290 /*
291  * @unimplemented
292  */
293 BOOL
294 WINAPI
296 {
298 }
299 
300 /*
301  * @unimplemented
302  */
303 BOOL
304 WINAPI
306 {
307  return NtUserxRegisterShellHookWindow(hWnd);
308 }
309 
310 /*
311  * @implemented
312  */
313 BOOL
314 WINAPI
315 UnhookWindowsHook ( int nCode, HOOKPROC pfnFilterProc )
316 {
317  return NtUserxUnhookWindowsHook(nCode, pfnFilterProc);
318 }
319 
320 /*
321  * @implemented
322  */
323 VOID
324 WINAPI
326  DWORD event,
327  HWND hwnd,
328  LONG idObject,
329  LONG idChild
330  )
331 {
332 // "Servers call NotifyWinEvent to announce the event to the system after the
333 // event has occurred; they must never notify the system of an event before
334 // the event has occurred." msdn on NotifyWinEvent.
335  if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(event)) // Check to see.
336  NtUserNotifyWinEvent(event, hwnd, idObject, idChild);
337 }
338 
339 /*
340  * @implemented
341  */
343 WINAPI
345  UINT eventMin,
346  UINT eventMax,
347  HMODULE hmodWinEventProc,
348  WINEVENTPROC pfnWinEventProc,
349  DWORD idProcess,
350  DWORD idThread,
351  UINT dwFlags
352  )
353 {
355  UNICODE_STRING USModuleName;
356  PUNICODE_STRING pusmodName;
357 
358  RtlInitUnicodeString(&USModuleName, NULL);
359 
360  if ((hmodWinEventProc != NULL) && (dwFlags & WINEVENT_INCONTEXT))
361  {
362  if (0 == GetModuleFileNameW(hmodWinEventProc, ModuleName, MAX_PATH))
363  {
364  return NULL;
365  }
366  RtlInitUnicodeString(&USModuleName, ModuleName);
367  pusmodName = &USModuleName;
368  }
369  else
370  {
371  pusmodName = NULL;
372  }
373 
374  return NtUserSetWinEventHook(eventMin,
375  eventMax,
376  hmodWinEventProc,
377  pusmodName,
378  pfnWinEventProc,
379  idProcess,
380  idThread,
381  dwFlags);
382 }
383 
384 /*
385  * @implemented
386  */
387 BOOL
388 WINAPI
390  DWORD event)
391 {
392  if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo)
393  {
394  return (gpsi->dwInstalledEventHooks & GetMaskFromEvent(event)) != 0;
395  }
396  return FALSE;
397 }
398 
399 /*
400  * @implemented
401  */
402 HHOOK
403 WINAPI
405  int idHook,
406  HOOKPROC lpfn,
407  HINSTANCE hMod,
409 {
410  return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, TRUE);
411 }
412 
413 
414 /*
415  * @implemented
416  */
417 HHOOK
418 WINAPI
420  int idHook,
421  HOOKPROC lpfn,
422  HINSTANCE hMod,
424 {
425  return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
426 }
427 
428 static
429 BOOL
431  PUNICODE_STRING pstrLibName,
432  PUNICODE_STRING pstrInitFunc,
433  BOOL bUnload,
434  BOOL bApiHook)
435 {
437  PVOID pInitFunction;
439  ANSI_STRING InitFuncName;
440  BOOL bResult = FALSE;
441 
442  TRACE("ClientLoadLibrary: pid: %d, strLibraryName: %S, "
443  "strInitFuncName: %S, bUnload: %d, bApiHook:%d\n",
445  pstrLibName->Buffer,
446  pstrInitFunc->Buffer,
447  bUnload,
448  bApiHook);
449 
450  /* Check if we have to load the module */
451  if (bUnload == FALSE)
452  {
453  ASSERT(pstrLibName->Buffer != NULL);
454 
455  /* Load it */
456  hLibrary = LoadLibrary(pstrLibName->Buffer);
457  if (hLibrary == 0)
458  {
459  return FALSE;
460  }
461 
462  if (!bApiHook)
463  {
464  /* There is nothing more to do for a global hook*/
465  return TRUE;
466  }
467 
468  /* Initialize the user api hook */
469  ASSERT(pstrInitFunc->Buffer);
470  Status = RtlUnicodeStringToAnsiString(&InitFuncName,
471  pstrInitFunc,
472  TRUE);
473  if (!NT_SUCCESS(Status))
474  {
475  FreeLibrary(hLibrary);
476  return FALSE;
477  }
478 
479  /* Get the address of the initialization routine */
480  pInitFunction = GetProcAddress(hLibrary, InitFuncName.Buffer);
481  if (pInitFunction)
482  {
483  /* Call the initialization routine */
484  bResult = InitUserApiHook(hLibrary, (USERAPIHOOKPROC)pInitFunction);
485  }
486 
487  RtlFreeAnsiString(&InitFuncName);
488 
489  /* In case of error unload the library */
490  if (bResult == FALSE)
491  {
492  FreeLibrary(hLibrary);
493  }
494  }
495  else
496  {
497  /* Cleanup user api hook before unloading */
498  if (bApiHook)
499  {
500  hLibrary = ghmodUserApiHook;
502 
503  /* Check if we can we unload it now */
504  if (!bResult)
505  {
506  /* Return success because we are going to free
507  the library in EndUserApiHook*/
508  return TRUE;
509  }
510  }
511  else
512  {
513  /* Get the library handle from the name */
514  hLibrary = GetModuleHandle(pstrLibName->Buffer);
515  if (hLibrary == NULL)
516  {
517  return FALSE;
518  }
519  }
520 
521  bResult = FreeLibrary(hLibrary);
522  }
523 
524  return bResult;
525 }
526 
529 {
530  BOOL bResult;
532 
533  /* Retireve the callback parameters */
534  Argument = (PCLIENT_LOAD_LIBRARY_ARGUMENTS)Arguments;
535  if(Argument->strLibraryName.Buffer != NULL)
536  {
537  Argument->strLibraryName.Buffer = (PWCHAR)((ULONG_PTR)Argument->strLibraryName.Buffer + (ULONG_PTR)Argument);
538  }
539  if(Argument->strInitFuncName.Buffer != NULL)
540  {
541  Argument->strInitFuncName.Buffer = (PWCHAR)((ULONG_PTR)Argument->strInitFuncName.Buffer + (ULONG_PTR)Argument);
542  }
543 
544  /* Call the implementation of the callback */
545  bResult = ClientLoadLibrary(&Argument->strLibraryName,
546  &Argument->strInitFuncName,
547  Argument->Unload,
548  Argument->ApiHook);
549 
550  return ZwCallbackReturn(&bResult, sizeof(HINSTANCE), STATUS_SUCCESS);
551 }
552 
554 User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
555 {
557  CREATESTRUCTW Csw;
558  CBT_CREATEWNDW CbtCreatewndw;
559  PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL;
560  KBDLLHOOKSTRUCT KeyboardLlData, *pKeyboardLlData;
561  MSLLHOOKSTRUCT MouseLlData, *pMouseLlData;
562  MSG *pcMsg, *pMsg;
563  PMOUSEHOOKSTRUCT pMHook;
564  CWPSTRUCT *pCWP;
565  CWPRETSTRUCT *pCWPR;
566  PRECTL prl;
567  LPCBTACTIVATESTRUCT pcbtas;
568  HOOKPROC Proc;
569  WPARAM wParam = 0;
570  LPARAM lParam = 0;
571  LRESULT Result = 0;
572  BOOL Hit = FALSE, Loaded = FALSE;
573  HMODULE mod = NULL;
575 
576  Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
577 
578  Proc = Common->Proc;
579  // HookProc Justin Case module is from another process.
580  if (Common->offPfn && Common->Mod)
581  {
582  if (!(mod = GetModuleHandleW((LPCWSTR)Common->ModuleName)))
583  {
584  TRACE("Reloading Hook Module.\n");
586  {
587  ERR("Failed to load Hook Module.\n");
588  }
589  else
590  {
591  Loaded = TRUE; // Free it only when loaded.
592  }
593  }
594  if (mod)
595  {
596  TRACE("Loading Hook Module. %S\n",Common->ModuleName);
597  Proc = (HOOKPROC)((char *)mod + Common->offPfn);
598  }
599  }
600 
601  switch(Common->HookId)
602  {
603  case WH_CBT:
604  {
605  //ERR("WH_CBT: Code %d\n", Common->Code);
606  switch(Common->Code)
607  {
608  case HCBT_CREATEWND:
609  CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS)
610  ((PCHAR) Common + Common->lParam);
611  RtlCopyMemory(&Csw, &CbtCreatewndExtra->Cs, sizeof(CREATESTRUCTW));
612  CbtCreatewndw.lpcs = &Csw;
613  CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
614  wParam = Common->wParam;
615  lParam = (LPARAM) &CbtCreatewndw;
616  //ERR("HCBT_CREATEWND: hWnd 0x%x Name 0x%x Class 0x%x\n", Common->wParam, Csw.lpszName, Csw.lpszClass);
617  break;
618  case HCBT_CLICKSKIPPED:
619  pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
620  lParam = (LPARAM) pMHook;
621  wParam = Common->wParam;
622  break;
623  case HCBT_MOVESIZE:
624  prl = (PRECTL)((PCHAR) Common + Common->lParam);
625  lParam = (LPARAM) prl;
626  wParam = Common->wParam;
627  break;
628  case HCBT_ACTIVATE:
629  //ERR("HCBT_ACTIVATE: hwnd %p\n",Common->wParam);
630  pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam);
631  lParam = (LPARAM) pcbtas;
632  wParam = Common->wParam;
633  break;
634  case HCBT_KEYSKIPPED: /* The rest SEH support */
635  case HCBT_MINMAX:
636  case HCBT_SETFOCUS:
637  case HCBT_SYSCOMMAND:
638  case HCBT_DESTROYWND:
639  case HCBT_QS:
640  wParam = Common->wParam;
641  lParam = Common->lParam;
642  break;
643  default:
644  if (Loaded) FreeLibrary(mod);
645  ERR("HCBT_ not supported = %d\n", Common->Code);
647  }
648 
649  if (Proc)
650  {
651  _SEH2_TRY
652  {
653  Result = Proc(Common->Code, wParam, lParam);
654  }
656  {
657  Hit = TRUE;
658  }
659  _SEH2_END;
660  }
661  else
662  {
663  ERR("Null Proc! Common = 0x%x, Proc = 0x%x\n",Common,Proc);
664  }
665  switch(Common->Code)
666  {
667  case HCBT_CREATEWND:
668  CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter;
669  CbtCreatewndExtra->Cs.x = CbtCreatewndw.lpcs->x;
670  CbtCreatewndExtra->Cs.y = CbtCreatewndw.lpcs->y;
671  CbtCreatewndExtra->Cs.cx = CbtCreatewndw.lpcs->cx;
672  CbtCreatewndExtra->Cs.cy = CbtCreatewndw.lpcs->cy;
673  break;
674  }
675  break;
676  }
677  case WH_KEYBOARD_LL:
678  //ERR("WH_KEYBOARD_LL: Code %d, wParam %d\n",Common->Code,Common->wParam);
679  pKeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
680  RtlCopyMemory(&KeyboardLlData, pKeyboardLlData, sizeof(KBDLLHOOKSTRUCT));
681  Result = Proc(Common->Code, Common->wParam, (LPARAM) &KeyboardLlData);
682  break;
683  case WH_MOUSE_LL:
684  //ERR("WH_MOUSE_LL: Code %d, wParam %d\n",Common->Code,Common->wParam);
685  pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
686  RtlCopyMemory(&MouseLlData, pMouseLlData, sizeof(MSLLHOOKSTRUCT));
687  Result = Proc(Common->Code, Common->wParam, (LPARAM) &MouseLlData);
688  break;
689  case WH_MOUSE: /* SEH support */
690  pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
691  _SEH2_TRY
692  {
693  Result = Proc(Common->Code, Common->wParam, (LPARAM) pMHook);
694  }
696  {
697  Hit = TRUE;
698  }
699  _SEH2_END;
700  break;
701  case WH_CALLWNDPROC:
702 // ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam);
703  pCWP = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
704  RtlCopyMemory(pCWP, (PCHAR) Common + Common->lParam, sizeof(CWPSTRUCT));
705  /* If more memory is reserved, then lParam is a pointer.
706  * Size of the buffer is stocked in the lParam member, and its content
707  * is at the end of the argument buffer */
708  if(ArgumentLength > (sizeof(CWPSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
709  {
710  RtlCopyMemory((PCHAR)pCWP + sizeof(CWPSTRUCT),
711  (PCHAR)Common + Common->lParam + sizeof(CWPSTRUCT),
712  pCWP->lParam);
713  pCWP->lParam = (LPARAM)((PCHAR)pCWP + sizeof(CWPSTRUCT));
714  }
715  Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
716  HeapFree(GetProcessHeap(), 0, pCWP);
717  break;
718  case WH_CALLWNDPROCRET:
719  /* Almost the same as WH_CALLWNDPROC */
720  pCWPR = HeapAlloc(GetProcessHeap(), 0, ArgumentLength - sizeof(HOOKPROC_CALLBACK_ARGUMENTS));
721  RtlCopyMemory(pCWPR, (PCHAR) Common + Common->lParam, sizeof(CWPRETSTRUCT));
722  if(ArgumentLength > (sizeof(CWPRETSTRUCT) + sizeof(HOOKPROC_CALLBACK_ARGUMENTS)))
723  {
724  RtlCopyMemory((PCHAR)pCWPR + sizeof(CWPRETSTRUCT),
725  (PCHAR)Common + Common->lParam + sizeof(CWPRETSTRUCT),
726  pCWPR->lParam);
727  pCWPR->lParam = (LPARAM)((PCHAR)pCWPR + sizeof(CWPRETSTRUCT));
728  }
729  Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
730  HeapFree(GetProcessHeap(), 0, pCWPR);
731  break;
732  case WH_MSGFILTER: /* All SEH support */
733  case WH_SYSMSGFILTER:
734  case WH_GETMESSAGE:
735  pMsg = (PMSG)((PCHAR) Common + Common->lParam);
736  pcMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSG));
737  RtlCopyMemory(pcMsg, pMsg, sizeof(MSG));
738 // ERR("pMsg %d pcMsg %d\n",pMsg->message, pcMsg->message);
739  _SEH2_TRY
740  {
741  Result = Proc(Common->Code, Common->wParam, (LPARAM) pcMsg);
742  }
744  {
745  Hit = TRUE;
746  }
747  _SEH2_END;
748  if (!Hit && Common->HookId == WH_GETMESSAGE)
749  RtlCopyMemory(pMsg, pcMsg, sizeof(MSG));
750  HeapFree( GetProcessHeap(), 0, pcMsg );
751  break;
752  case WH_KEYBOARD:
753  case WH_SHELL:
754  Result = Proc(Common->Code, Common->wParam, Common->lParam);
755  break;
756  case WH_FOREGROUNDIDLE: /* <-- SEH support */
757  _SEH2_TRY
758  {
759  Result = Proc(Common->Code, Common->wParam, Common->lParam);
760  }
762  {
763  Hit = TRUE;
764  }
765  _SEH2_END;
766  break;
767  default:
768  if (Loaded) FreeLibrary(mod);
769  ERR("WH_ not supported = %d\n", Common->HookId);
771  }
772  if (Hit)
773  {
774  ERR("Hook Exception! Id: %d, Code %d, Proc 0x%x\n",Common->HookId,Common->Code,Proc);
775  Status = STATUS_UNSUCCESSFUL;
776  }
777  if (Loaded) FreeLibrary(mod);
778  Common->Result = Result;
779  return ZwCallbackReturn(Arguments, ArgumentLength, Status);
780 }
781 
783 User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
784 {
786  WINEVENTPROC Proc;
788  DWORD len;
789  HMODULE mod = NULL;
790  BOOL Loaded = FALSE;
791 
792  Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Arguments;
793 
794  Proc = Common->Proc;
795 
796  if (Common->offPfn && Common->Mod)
797  { // Validate the module again.
798  if (!(len = GetModuleFileNameW((HINSTANCE)Common->Mod, module, MAX_PATH)) || len >= MAX_PATH)
799  {
800  ERR("Error check for module!\n");
801  Common->Mod = 0;
802  }
803 
804  if (Common->Mod && !(mod = GetModuleHandleW(module)))
805  {
806  TRACE("Reloading Event Module.\n");
807  if (!(mod = LoadLibraryExW(module, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)))
808  {
809  ERR("Failed to load Event Module.\n");
810  }
811  else
812  {
813  Loaded = TRUE; // Free it only when loaded.
814  }
815  }
816 
817  if (mod)
818  {
819  TRACE("Loading Event Module. %S\n",module);
820  Proc = (WINEVENTPROC)((char *)mod + Common->offPfn);
821  }
822  }
823 
824  Proc(Common->hook,
825  Common->event,
826  Common->hwnd,
827  Common->idObject,
828  Common->idChild,
829  Common->dwEventThread,
830  Common->dwmsEventTime);
831 
832  if (Loaded) FreeLibrary(mod);
833 
835 }
836 
837 
838 
BOOL WINAPI DeregisterShellHookWindow(HWND hWnd)
Definition: hook.c:295
DWORD *typedef PVOID
Definition: winlogon.h:61
#define WH_MOUSE
Definition: winuser.h:37
struct tagCWPSTRUCT * PCWPSTRUCT
signed char * PCHAR
Definition: retypes.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define HCBT_CLICKSKIPPED
Definition: winuser.h:61
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 const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1256
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:607
struct tagCWPSTRUCT CWPSTRUCT
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define HCBT_SYSCOMMAND
Definition: winuser.h:63
HHOOK WINAPI SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
Definition: hook.c:404
struct _EVENTPROC_CALLBACK_ARGUMENTS * PEVENTPROC_CALLBACK_ARGUMENTS
#define PtrToUint(p)
Definition: basetsd.h:85
WPARAM wParam
Definition: winuser.h:2972
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct @1570 Msg[]
#define WH_GETMESSAGE
Definition: winuser.h:33
#define HCBT_CREATEWND
Definition: winuser.h:58
LONG idChild
Definition: hook.h:39
WINE_DEFAULT_DEBUG_CHANNEL(user32)
struct RECTL * PRECTL
#define LoadLibrary
Definition: winbase.h:3676
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
__wchar_t WCHAR
Definition: xmlstorage.h:180
LPCREATESTRUCTW lpcs
Definition: winuser.h:2928
BOOL NTAPI NtUserCallMsgFilter(LPMSG msg, INT code)
Definition: message.c:2218
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:286
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define WH_MSGFILTER
Definition: winuser.h:29
struct _HOOKPROC_CALLBACK_ARGUMENTS * PHOOKPROC_CALLBACK_ARGUMENTS
struct tagHOOK * phkNext
Definition: ntuser.h:218
HHOOK WINAPI SetWindowsHookW(int idHook, HOOKPROC lpfn)
Definition: hook.c:271
ULONG_PTR CI_flags
Definition: ntuser.h:287
BOOL WINAPI ClearUserApiHook(HINSTANCE hInstance)
Definition: usrapihk.c:193
HWND hWnd
Definition: settings.c:17
#define WH_SHELL
Definition: winuser.h:40
HANDLE HWND
Definition: compat.h:13
struct tagCWPRETSTRUCT * PCWPRETSTRUCT
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
VOID(CALLBACK * WINEVENTPROC)(HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD)
Definition: winable.h:68
LPARAM lParam
Definition: winuser.h:2971
NTSTATUS WINAPI User32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: hook.c:528
#define SRV_EVENT_STATECHANGE
Definition: ntuser.h:1039
VOID FASTCALL IntNotifyWinEvent(DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD flags)
Definition: hook.c:113
#define GetWin32ClientInfo()
Definition: ntuser.h:320
#define HCBT_SETFOCUS
Definition: winuser.h:64
VOID WINAPI NotifyWinEvent(DWORD event, HWND hwnd, LONG idObject, LONG idChild)
Definition: hook.c:325
_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
uint16_t * PWCHAR
Definition: typedefs.h:54
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:339
BOOL(CALLBACK * USERAPIHOOKPROC)(UAPIHK State, PUSERAPIHOOK puah)
Definition: undocuser.h:362
EXTINLINE BOOL NtUserxDeregisterShellHookWindow(HWND hWnd)
Definition: ntwrapper.h:726
static HWINEVENTHOOK(WINAPI *pSetWinEventHook)(DWORD
#define FASTCALL
Definition: nt_native.h:50
HHOOK WINAPI SetWindowsHookA(int idHook, HOOKPROC lpfn)
Definition: hook.c:283
BOOL WINAPI UnhookWindowsHook(int nCode, HOOKPROC pfnFilterProc)
Definition: hook.c:315
PSERVERINFO gpsi
Definition: main.c:27
LRESULT APIENTRY NtUserCallNextHookEx(int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi)
Definition: hook.c:1357
DWORD DWORD
Definition: winlogon.h:84
Definition: fs_rec.h:186
_SEH2_TRY
Definition: create.c:4250
UINT_PTR WPARAM
Definition: windef.h:207
UNICODE_STRING strInitFuncName
Definition: callback.h:107
#define HCBT_KEYSKIPPED
Definition: winuser.h:62
HWND hwndInsertAfter
Definition: winuser.h:2929
uint32_t ULONG_PTR
Definition: typedefs.h:63
EXTINLINE BOOL NtUserxRegisterShellHookWindow(HWND hWnd)
Definition: ntwrapper.h:731
#define WH_FOREGROUNDIDLE
Definition: winuser.h:41
NTSYSAPI NTSTATUS NTAPI ZwCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS Status)
struct tagCWPRETSTRUCT CWPRETSTRUCT
#define SRV_EVENT_CREATE
Definition: ntuser.h:1041
CLIENT_DATA ClientInfo
#define WH_MOUSE_LL
Definition: winuser.h:44
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static __inline PVOID DesktopPtrToUser(PVOID Ptr)
Definition: user_x.h:12
#define FALSE
Definition: types.h:117
#define SRV_EVENT_NAMECHANGE
Definition: ntuser.h:1037
LRESULT(CALLBACK * HOOKPROC)(int, WPARAM, LPARAM)
Definition: winuser.h:2852
long LONG
Definition: pedump.c:60
LONG_PTR LPARAM
Definition: windef.h:208
#define HCBT_DESTROYWND
Definition: winuser.h:59
#define SRV_EVENT_MENU
Definition: ntuser.h:1034
HINSTANCE ghmodUserApiHook
Definition: usrapihk.c:37
BOOL WINAPI IsWinEventHookInstalled(DWORD event)
Definition: hook.c:389
LRESULT WINAPI CallNextHookEx(HHOOK Hook, int Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:199
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static int Save(const char **args)
Definition: vfdcmd.c:1851
#define SRV_EVENT_END_APPLICATION
Definition: ntuser.h:1035
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI InitUserApiHook(HINSTANCE hInstance, USERAPIHOOKPROC pfn)
Definition: usrapihk.c:255
#define WH_CBT
Definition: winuser.h:35
HWINEVENTHOOK NTAPI NtUserSetWinEventHook(UINT eventMin, UINT eventMax, HMODULE hmodWinEventProc, PUNICODE_STRING puString, WINEVENTPROC lpfnWinEventProc, DWORD idProcess, DWORD idThread, UINT dwflags)
Definition: event.c:287
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
struct tagMOUSEHOOKSTRUCT * PMOUSEHOOKSTRUCT
#define WH_CALLWNDPROCRET
Definition: winuser.h:42
BOOL WINAPI CallMsgFilterW(LPMSG lpMsg, int nCode)
Definition: hook.c:174
static BOOL ClientLoadLibrary(PUNICODE_STRING pstrLibName, PUNICODE_STRING pstrInitFunc, BOOL bUnload, BOOL bApiHook)
Definition: hook.c:430
EXTINLINE VOID NtUserxNotifyWinEvent(HWND hWnd, PVOID ne)
Definition: ntwrapper.h:716
HWINEVENTHOOK WINAPI SetWinEventHook(UINT eventMin, UINT eventMax, HMODULE hmodWinEventProc, WINEVENTPROC pfnWinEventProc, DWORD idProcess, DWORD idThread, UINT dwFlags)
Definition: hook.c:344
#define Code
Definition: deflate.h:80
#define FNID_CALLWNDPROCRET
Definition: ntuser.h:839
int HookId
Definition: ntuser.h:219
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
unsigned int BOOL
Definition: ntddk_ex.h:94
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN Ansi
Definition: ntuser.h:228
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
UINT WPARAM wParam
Definition: precomp.h:45
#define ISITHOOKED(HookId)
Definition: hook.h:6
HHOOK APIENTRY NtUserSetWindowsHookEx(HINSTANCE Mod, PUNICODE_STRING UnsafeModuleName, DWORD ThreadId, int HookId, HOOKPROC HookProc, BOOL Ansi)
Definition: hook.c:1427
#define MAX_PATH
Definition: compat.h:26
#define SRV_EVENT_RUNNING
Definition: ntuser.h:1036
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
static HHOOK FASTCALL IntSetWindowsHook(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId, BOOL bAnsi)
Definition: hook.c:80
PHOOK phkCurrent
Definition: ntuser.h:295
LPARAM lParam
Definition: winuser.h:2978
NTSTATUS WINAPI User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: hook.c:554
#define SetLastError(x)
Definition: compat.h:409
BOOL WINAPI RegisterShellHookWindow(HWND hWnd)
Definition: hook.c:305
WPARAM wParam
Definition: winuser.h:2979
struct _NOTIFYEVENT NOTIFYEVENT
GLbitfield flags
Definition: glext.h:7161
HANDLE UniqueThread
Definition: compat.h:475
#define HCBT_QS
Definition: winuser.h:57
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
HANDLE HINSTANCE
Definition: typedefs.h:75
#define WINEVENT_INCONTEXT
Definition: winable.h:35
DWORD dwThreadId
Definition: fdebug.c:31
UINT message
Definition: winuser.h:2980
DWORD event
Definition: hook.h:37
#define WH_CALLWNDPROC
Definition: winuser.h:34
#define CI_CURTHPRHOOK
Definition: ntuser.h:281
static DWORD FASTCALL GetMaskFromEvent(DWORD Event)
Definition: hook.c:46
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
BOOL WINAPI CallMsgFilterA(LPMSG lpMsg, int nCode)
Definition: hook.c:149
HMODULE hLibrary
Definition: odbccp32.c:12
struct tagCBTACTIVATESTRUCT * LPCBTACTIVATESTRUCT
GLenum GLsizei len
Definition: glext.h:6722
#define WM_MAXIMUM
Definition: undocuser.h:62
struct _cl_event * event
Definition: glext.h:7739
BOOL NTAPI NtUserMessageCall(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL Ansi)
Definition: message.c:2325
struct _CLIENT_LOAD_LIBRARY_ARGUMENTS * PCLIENT_LOAD_LIBRARY_ARGUMENTS
#define WINAPI
Definition: msvc.h:20
#define FNID_CALLWNDPROC
Definition: ntuser.h:838
ULONG_PTR dwHookData
Definition: ntuser.h:301
Status
Definition: gdiplustypes.h:24
#define HCBT_MINMAX
Definition: winuser.h:56
#define ERR(fmt,...)
Definition: debug.h:109
DWORD dwInstalledEventHooks
Definition: ntuser.h:1024
_SEH2_END
Definition: create.c:4424
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define GetModuleHandle
Definition: winbase.h:3641
struct tagMSG * PMSG
UINT WPARAM LPARAM lParam
Definition: precomp.h:45
#define SRV_EVENT_LOCATIONCHANGE
Definition: ntuser.h:1040
unsigned int UINT
Definition: ndis.h:50
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define SRV_EVENT_VALUECHANGE
Definition: ntuser.h:1038
HANDLE HMODULE
Definition: typedefs.h:75
#define HCBT_MOVESIZE
Definition: winuser.h:55
#define WH_KEYBOARD
Definition: winuser.h:32
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
struct tagMSLLHOOKSTRUCT * PMSLLHOOKSTRUCT
unsigned int ULONG
Definition: retypes.h:1
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define ULONG_PTR
Definition: config.h:101
#define CallMsgFilter
Definition: winuser.h:5600
#define GetProcAddress(x, y)
Definition: compat.h:410
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
VOID NTAPI NtUserNotifyWinEvent(DWORD Event, HWND hWnd, LONG idObject, LONG idChild)
Definition: event.c:255
LONG_PTR LRESULT
Definition: windef.h:209
UNICODE_STRING strLibraryName
Definition: callback.h:106
UINT message
Definition: winuser.h:3068
return STATUS_SUCCESS
Definition: btrfs.c:2710
LRESULT lResult
Definition: winuser.h:2970
#define WH_SYSMSGFILTER
Definition: winuser.h:36
DWORD flags
Definition: hook.h:40
struct tagKBDLLHOOKSTRUCT * PKBDLLHOOKSTRUCT
#define HeapFree(x, y, z)
Definition: compat.h:394
NTSTATUS WINAPI User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: hook.c:783
struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS * PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
LONG idObject
Definition: hook.h:38
EXTINLINE BOOL NtUserxUnhookWindowsHook(int nCode, HOOKPROC pfnFilterProc)
Definition: ntwrapper.h:696
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1215
UINT WPARAM LPARAM LRESULT & lResult
Definition: precomp.h:45
HHOOK WINAPI SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
Definition: hook.c:419
#define LPARAM
Definition: msvc.h:38
static int mod
Definition: i386-dis.c:1273
struct _NOTIFYEVENT * PNOTIFYEVENT