ReactOS  0.4.15-dev-316-g938df97
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;
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 
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  {
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 {
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  {
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  {
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  {
493  }
494  }
495  else
496  {
497  /* Cleanup user api hook before unloading */
498  if (bApiHook)
499  {
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 *pCsw = NULL;
558  CBT_CREATEWNDW *pCbtCreatewndw = NULL;
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 
612  pCbtCreatewndw = (CBT_CREATEWNDW*)HeapAlloc(GetProcessHeap(), 0, sizeof(CBT_CREATEWNDW));
613  RtlCopyMemory(pCbtCreatewndw, CbtCreatewndExtra, sizeof(CBT_CREATEWNDW));
614 
615  pCsw = (CREATESTRUCTW*)HeapAlloc(GetProcessHeap(), 0, sizeof(CREATESTRUCTW));
616  RtlCopyMemory(pCsw, &CbtCreatewndExtra->Cs, sizeof(CREATESTRUCTW));
617 
618  pCbtCreatewndw->lpcs = pCsw;
619  pCbtCreatewndw->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
620  wParam = Common->wParam;
621  lParam = (LPARAM) pCbtCreatewndw;
622  //ERR("HCBT_CREATEWND: hWnd %p Csw %p Name %p Class %p\n", Common->wParam, pCsw, pCsw->lpszName, pCsw->lpszClass);
623  break;
624  case HCBT_CLICKSKIPPED:
625  pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
626  lParam = (LPARAM) pMHook;
627  wParam = Common->wParam;
628  break;
629  case HCBT_MOVESIZE:
630  prl = (PRECTL)((PCHAR) Common + Common->lParam);
631  lParam = (LPARAM) prl;
632  wParam = Common->wParam;
633  break;
634  case HCBT_ACTIVATE:
635  //ERR("HCBT_ACTIVATE: hwnd %p\n",Common->wParam);
636  pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam);
637  lParam = (LPARAM) pcbtas;
638  wParam = Common->wParam;
639  break;
640  case HCBT_KEYSKIPPED: /* The rest SEH support */
641  case HCBT_MINMAX:
642  case HCBT_SETFOCUS:
643  case HCBT_SYSCOMMAND:
644  case HCBT_DESTROYWND:
645  case HCBT_QS:
646  wParam = Common->wParam;
647  lParam = Common->lParam;
648  break;
649  default:
650  if (Loaded) FreeLibrary(mod);
651  ERR("HCBT_ not supported = %d\n", Common->Code);
653  }
654 
655  if (Proc)
656  {
657  _SEH2_TRY
658  {
659  Result = Proc(Common->Code, wParam, lParam);
660  }
662  {
663  Hit = TRUE;
664  }
665  _SEH2_END;
666  }
667  else
668  {
669  ERR("Null Proc! Common = 0x%x, Proc = 0x%x\n",Common,Proc);
670  }
671  switch(Common->Code)
672  {
673  case HCBT_CREATEWND:
674  CbtCreatewndExtra->WndInsertAfter = pCbtCreatewndw->hwndInsertAfter;
675  CbtCreatewndExtra->Cs.x = pCbtCreatewndw->lpcs->x;
676  CbtCreatewndExtra->Cs.y = pCbtCreatewndw->lpcs->y;
677  CbtCreatewndExtra->Cs.cx = pCbtCreatewndw->lpcs->cx;
678  CbtCreatewndExtra->Cs.cy = pCbtCreatewndw->lpcs->cy;
679  HeapFree(GetProcessHeap(), 0, pCsw);
680  HeapFree(GetProcessHeap(), 0, pCbtCreatewndw);
681  break;
682  }
683  break;
684  }
685  case WH_KEYBOARD_LL:
686  //ERR("WH_KEYBOARD_LL: Code %d, wParam %d\n",Common->Code,Common->wParam);
687  pKeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
688  RtlCopyMemory(&KeyboardLlData, pKeyboardLlData, sizeof(KBDLLHOOKSTRUCT));
689  Result = Proc(Common->Code, Common->wParam, (LPARAM) &KeyboardLlData);
690  break;
691  case WH_MOUSE_LL:
692  //ERR("WH_MOUSE_LL: Code %d, wParam %d\n",Common->Code,Common->wParam);
693  pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
694  RtlCopyMemory(&MouseLlData, pMouseLlData, sizeof(MSLLHOOKSTRUCT));
695  Result = Proc(Common->Code, Common->wParam, (LPARAM) &MouseLlData);
696  break;
697  case WH_MOUSE: /* SEH support */
698  pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam);
699  _SEH2_TRY
700  {
701  Result = Proc(Common->Code, Common->wParam, (LPARAM) pMHook);
702  }
704  {
705  Hit = TRUE;
706  }
707  _SEH2_END;
708  break;
709  case WH_CALLWNDPROC:
710  {
711  PCWP_Struct pcwps = (PCWP_Struct)Common;
712  CWPSTRUCT *pCWPT = &pcwps->cwps;
713  pCWP = HeapAlloc(GetProcessHeap(), 0, Common->lParamSize + sizeof(CWPSTRUCT));
714  RtlCopyMemory(pCWP, pCWPT, sizeof(CWPSTRUCT));
715 // ERR("WH_CALLWNDPROC: Code %d, wParam %d msg %d\n",Common->Code,Common->wParam,pCWP->message);
716  /* If more memory is reserved, then lParam is a pointer.
717  * Size of the buffer is stocked in the lParam member, and its content
718  * is at the end of the argument buffer */
719  if ( Common->lParamSize )
720  {
721  pCWP->lParam = (LPARAM)((PCHAR)pCWP + sizeof(CWPSTRUCT));
722  RtlCopyMemory( (PCHAR)pCWP + sizeof(CWPSTRUCT), &pcwps->Extra, Common->lParamSize );
723  }
724  Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWP);
725  HeapFree(GetProcessHeap(), 0, pCWP);
726  }
727  break;
728  case WH_CALLWNDPROCRET:
729  /* Almost the same as WH_CALLWNDPROC */
730  {
731  PCWPR_Struct pcwprs = (PCWPR_Struct)Common;
732  CWPRETSTRUCT *pCWPRT = &pcwprs->cwprs;
733  pCWPR = HeapAlloc(GetProcessHeap(), 0, Common->lParamSize + sizeof(CWPRETSTRUCT));
734  RtlCopyMemory(pCWPR, pCWPRT, sizeof(CWPSTRUCT));
735  if ( Common->lParamSize )
736  {
737  pCWPR->lParam = (LPARAM)((PCHAR)pCWPR + sizeof(CWPRETSTRUCT));
738  RtlCopyMemory( (PCHAR)pCWPR + sizeof(CWPRETSTRUCT), &pcwprs->Extra, Common->lParamSize );
739  }
740  Result = Proc(Common->Code, Common->wParam, (LPARAM) pCWPR);
741  HeapFree(GetProcessHeap(), 0, pCWPR);
742  }
743  break;
744  case WH_MSGFILTER: /* All SEH support */
745  case WH_SYSMSGFILTER:
746  case WH_GETMESSAGE:
747  pMsg = (PMSG)((PCHAR) Common + Common->lParam);
748  pcMsg = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MSG));
749  RtlCopyMemory(pcMsg, pMsg, sizeof(MSG));
750 // ERR("pMsg %d pcMsg %d\n",pMsg->message, pcMsg->message);
751  _SEH2_TRY
752  {
753  Result = Proc(Common->Code, Common->wParam, (LPARAM) pcMsg);
754  }
756  {
757  Hit = TRUE;
758  }
759  _SEH2_END;
760  if (!Hit && Common->HookId == WH_GETMESSAGE)
761  RtlCopyMemory(pMsg, pcMsg, sizeof(MSG));
762  HeapFree( GetProcessHeap(), 0, pcMsg );
763  break;
764  case WH_KEYBOARD:
765  case WH_SHELL:
766  Result = Proc(Common->Code, Common->wParam, Common->lParam);
767  break;
768  case WH_FOREGROUNDIDLE: /* <-- SEH support */
769  _SEH2_TRY
770  {
771  Result = Proc(Common->Code, Common->wParam, Common->lParam);
772  }
774  {
775  Hit = TRUE;
776  }
777  _SEH2_END;
778  break;
779  default:
780  if (Loaded) FreeLibrary(mod);
781  ERR("WH_ not supported = %d\n", Common->HookId);
783  }
784  if (Hit)
785  {
786  ERR("Hook Exception! Id: %d, Code %d, Proc 0x%x\n",Common->HookId,Common->Code,Proc);
788  }
789  if (Loaded) FreeLibrary(mod);
790  Common->Result = Result;
791  return ZwCallbackReturn(Arguments, ArgumentLength, Status);
792 }
793 
795 User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
796 {
798  WINEVENTPROC Proc;
800  DWORD len;
801  HMODULE mod = NULL;
802  BOOL Loaded = FALSE;
803 
804  Common = (PEVENTPROC_CALLBACK_ARGUMENTS) Arguments;
805 
806  Proc = Common->Proc;
807 
808  if (Common->offPfn && Common->Mod)
809  { // Validate the module again.
810  if (!(len = GetModuleFileNameW((HINSTANCE)Common->Mod, module, MAX_PATH)) || len >= MAX_PATH)
811  {
812  ERR("Error check for module!\n");
813  Common->Mod = 0;
814  }
815 
816  if (Common->Mod && !(mod = GetModuleHandleW(module)))
817  {
818  TRACE("Reloading Event Module.\n");
820  {
821  ERR("Failed to load Event Module.\n");
822  }
823  else
824  {
825  Loaded = TRUE; // Free it only when loaded.
826  }
827  }
828 
829  if (mod)
830  {
831  TRACE("Loading Event Module. %S\n",module);
832  Proc = (WINEVENTPROC)((char *)mod + Common->offPfn);
833  }
834  }
835 
836  Proc(Common->hook,
837  Common->event,
838  Common->hwnd,
839  Common->idObject,
840  Common->idChild,
841  Common->dwEventThread,
842  Common->dwmsEventTime);
843 
844  if (Loaded) FreeLibrary(mod);
845 
847 }
848 
849 
850 
BOOL WINAPI DeregisterShellHookWindow(HWND hWnd)
Definition: hook.c:295
struct @1608 Msg[]
#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
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
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:2994
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#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:3702
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
LPCREATESTRUCTW lpcs
Definition: winuser.h:2950
BOOL NTAPI NtUserCallMsgFilter(LPMSG msg, INT code)
Definition: message.c:2379
struct tagCWP_Struct * PCWP_Struct
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
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
LONG NTSTATUS
Definition: precomp.h:26
struct tagHOOK * phkNext
Definition: ntuser.h:218
HHOOK WINAPI SetWindowsHookW(int idHook, HOOKPROC lpfn)
Definition: hook.c:271
BOOL WINAPI ClearUserApiHook(HINSTANCE hInstance)
Definition: usrapihk.c:193
HWND hWnd
Definition: settings.c:17
#define WH_SHELL
Definition: winuser.h:40
CWPSTRUCT cwps
Definition: callback.h:79
struct tagCWPRETSTRUCT * PCWPRETSTRUCT
LPARAM lParam
Definition: winuser.h:2993
struct tagCBT_CREATEWNDW CBT_CREATEWNDW
NTSTATUS WINAPI User32CallClientLoadLibraryFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: hook.c:528
#define SRV_EVENT_STATECHANGE
Definition: ntuser.h:1039
UINT_PTR WPARAM
Definition: windef.h:207
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:1274
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
uint16_t * PWCHAR
Definition: typedefs.h:55
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:339
EXTINLINE BOOL NtUserxDeregisterShellHookWindow(HWND hWnd)
Definition: ntwrapper.h:731
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:1371
WPARAM wParam
Definition: combotst.c:138
LRESULT(CALLBACK * HOOKPROC)(int, WPARAM, LPARAM)
Definition: winuser.h:2874
Definition: fs_rec.h:186
_SEH2_TRY
Definition: create.c:4250
UNICODE_STRING strInitFuncName
Definition: callback.h:123
#define HCBT_KEYSKIPPED
Definition: winuser.h:62
HWND hwndInsertAfter
Definition: winuser.h:2951
uint32_t ULONG_PTR
Definition: typedefs.h:64
EXTINLINE BOOL NtUserxRegisterShellHookWindow(HWND hWnd)
Definition: ntwrapper.h:736
#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
BOOL(CALLBACK * USERAPIHOOKPROC)(UAPIHK State, PUSERAPIHOOK puah)
Definition: undocuser.h:362
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static __inline PVOID DesktopPtrToUser(PVOID Ptr)
Definition: user_x.h:12
#define SRV_EVENT_NAMECHANGE
Definition: ntuser.h:1037
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#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
PBYTE Extra[4]
Definition: callback.h:80
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
_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
LONG_PTR LPARAM
Definition: windef.h:208
struct tagCREATESTRUCTW CREATESTRUCTW
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
CWPRETSTRUCT cwprs
Definition: callback.h:86
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:721
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
VOID(CALLBACK * WINEVENTPROC)(HWINEVENTHOOK, DWORD, HWND, LONG, LONG, DWORD, DWORD)
Definition: winable.h:68
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:414
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
BOOLEAN Ansi
Definition: ntuser.h:228
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define WH_KEYBOARD_LL
Definition: winuser.h:43
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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:1441
#define MAX_PATH
Definition: compat.h:26
#define SRV_EVENT_RUNNING
Definition: ntuser.h:1036
#define WINAPI
Definition: msvc.h:6
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
unsigned long DWORD
Definition: ntddk_ex.h:95
static HHOOK FASTCALL IntSetWindowsHook(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId, BOOL bAnsi)
Definition: hook.c:80
LPARAM lParam
Definition: winuser.h:3000
NTSTATUS WINAPI User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: hook.c:554
#define SetLastError(x)
Definition: compat.h:418
BOOL WINAPI RegisterShellHookWindow(HWND hWnd)
Definition: hook.c:305
WPARAM wParam
Definition: winuser.h:3001
PBYTE Extra[4]
Definition: callback.h:87
struct _NOTIFYEVENT NOTIFYEVENT
GLbitfield flags
Definition: glext.h:7161
HANDLE UniqueThread
Definition: compat.h:484
#define HCBT_QS
Definition: winuser.h:57
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WINEVENT_INCONTEXT
Definition: winable.h:35
DWORD dwThreadId
Definition: fdebug.c:31
UINT message
Definition: winuser.h:3002
DWORD event
Definition: hook.h:37
struct tagCWPR_Struct * PCWPR_Struct
#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
GLenum GLsizei len
Definition: glext.h:6722
struct tagCBTACTIVATESTRUCT * LPCBTACTIVATESTRUCT
#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:2486
struct _CLIENT_LOAD_LIBRARY_ARGUMENTS * PCLIENT_LOAD_LIBRARY_ARGUMENTS
#define FNID_CALLWNDPROC
Definition: ntuser.h:838
Status
Definition: gdiplustypes.h:24
#define HCBT_MINMAX
Definition: winuser.h:56
#define ERR(fmt,...)
Definition: debug.h:110
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:3667
struct tagMSG * PMSG
#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
#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:838
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:115
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define ULONG_PTR
Definition: config.h:101
#define CallMsgFilter
Definition: winuser.h:5709
#define GetProcAddress(x, y)
Definition: compat.h:419
#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:122
UINT message
Definition: winuser.h:3090
return STATUS_SUCCESS
Definition: btrfs.c:3014
LRESULT lResult
Definition: winuser.h:2992
#define WH_SYSMSGFILTER
Definition: winuser.h:36
DWORD flags
Definition: hook.h:40
LPARAM lParam
Definition: combotst.c:139
struct tagKBDLLHOOKSTRUCT * PKBDLLHOOKSTRUCT
#define HeapFree(x, y, z)
Definition: compat.h:403
NTSTATUS WINAPI User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: hook.c:795
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:701
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
HHOOK WINAPI SetWindowsHookExW(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId)
Definition: hook.c:419
static int mod
Definition: i386-dis.c:1273
struct _NOTIFYEVENT * PNOTIFYEVENT