3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
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.
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.
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.
21 * PROJECT: ReactOS user32.dll
22 * FILE: lib/user32/windows/input.c
24 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * 09-05-2001 CSH Created
29 /* INCLUDES ******************************************************************/
33 #include <wine/debug.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
37 /* PRIVATE FUNCTIONS *********************************************************/
42 GetMaskFromEvent(DWORD Event
)
46 if ( Event
> EVENT_OBJECT_STATECHANGE
)
48 if ( Event
== EVENT_OBJECT_LOCATIONCHANGE
) return SRV_EVENT_LOCATIONCHANGE
;
49 if ( Event
== EVENT_OBJECT_NAMECHANGE
) return SRV_EVENT_NAMECHANGE
;
50 if ( Event
== EVENT_OBJECT_VALUECHANGE
) return SRV_EVENT_VALUECHANGE
;
51 return SRV_EVENT_CREATE
;
54 if ( Event
== EVENT_OBJECT_STATECHANGE
) return SRV_EVENT_STATECHANGE
;
56 Ret
= SRV_EVENT_RUNNING
;
58 if ( Event
< EVENT_SYSTEM_MENUSTART
) return SRV_EVENT_CREATE
;
60 if ( Event
<= EVENT_SYSTEM_MENUPOPUPEND
)
66 if ( Event
<= EVENT_CONSOLE_CARET
-1 ) return SRV_EVENT_CREATE
;
67 if ( Event
<= EVENT_CONSOLE_END_APPLICATION
) return SRV_EVENT_END_APPLICATION
;
68 if ( Event
!= EVENT_OBJECT_FOCUS
) return SRV_EVENT_CREATE
;
83 WCHAR ModuleName
[MAX_PATH
];
84 UNICODE_STRING USModuleName
;
88 if (0 == GetModuleFileNameW(hMod
, ModuleName
, MAX_PATH
))
92 RtlInitUnicodeString(&USModuleName
, ModuleName
);
96 RtlInitUnicodeString(&USModuleName
, NULL
);
99 return NtUserSetWindowsHookEx(hMod
, &USModuleName
, dwThreadId
, idHook
, lpfn
, bAnsi
);
103 /* FUNCTIONS *****************************************************************/
128 if (nCode
!= HCBT_CREATEWND
) ret
= NtUserCallMsgFilter((LPMSG
) lpMsg
, nCode
);
131 UNICODE_STRING usBuffer
;
132 CBT_CREATEWNDA
*cbtcwA
= (CBT_CREATEWNDA
*)lpMsg
->lParam
;
133 CBT_CREATEWNDW cbtcwW
;
137 Msg
.hwnd
= lpMsg
->hwnd
;
138 Msg
.message
= lpMsg
->message
;
139 Msg
.time
= lpMsg
->time
;
141 Msg
.wParam
= lpMsg
->wParam
;
144 cbtcwW
.hwndInsertAfter
= cbtcwA
->hwndInsertAfter
;
145 csW
= *(CREATESTRUCTW
*)cbtcwA
->lpcs
;
147 if (HIWORD(cbtcwA
->lpcs
->lpszName
))
149 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,cbtcwA
->lpcs
->lpszName
);
150 csW
.lpszName
= usBuffer
.Buffer
;
152 if (HIWORD(cbtcwA
->lpcs
->lpszClass
))
154 RtlCreateUnicodeStringFromAsciiz(&usBuffer
,cbtcwA
->lpcs
->lpszClass
);
155 csW
.lpszClass
= usBuffer
.Buffer
;
157 Msg
.lParam
=(LPARAM
) &cbtcwW
;
159 ret
= NtUserCallMsgFilter((LPMSG
)&Msg
, nCode
);
161 lpMsg
->time
= Msg
.time
;
164 cbtcwA
->hwndInsertAfter
= cbtcwW
.hwndInsertAfter
;
165 if (HIWORD(csW
.lpszName
)) HeapFree( GetProcessHeap(), 0, (LPWSTR
)csW
.lpszName
);
166 if (HIWORD(csW
.lpszClass
)) HeapFree( GetProcessHeap(), 0, (LPWSTR
)csW
.lpszClass
);
181 return NtUserCallMsgFilter((LPMSG
) lpMsg
, nCode
);
191 HHOOK Hook
, // Windows NT/XP/2003: Ignored.
196 PCLIENTINFO ClientInfo
;
203 ClientInfo
= GetWin32ClientInfo();
205 if (!ClientInfo
->phkCurrent
) return 0;
207 pHook
= SharedPtrToUser(ClientInfo
->phkCurrent
);
209 if (pHook
->HookId
== WH_CALLWNDPROC
|| pHook
->HookId
== WH_CALLWNDPROCRET
)
211 Save
= ClientInfo
->dwHookData
;
212 Flags
= ClientInfo
->CI_flags
& CI_CURTHPRHOOK
;
213 // wParam: If the message was sent by the current thread/process, it is
214 // nonzero; otherwise, it is zero.
215 if (wParam
) ClientInfo
->CI_flags
|= CI_CURTHPRHOOK
;
216 else ClientInfo
->CI_flags
&= ~CI_CURTHPRHOOK
;
218 if (pHook
->HookId
== WH_CALLWNDPROC
)
220 PCWPSTRUCT pCWP
= (PCWPSTRUCT
)lParam
;
222 NtUserMessageCall( pCWP
->hwnd
,
232 PCWPRETSTRUCT pCWPR
= (PCWPRETSTRUCT
)lParam
;
234 ClientInfo
->dwHookData
= pCWPR
->lResult
;
236 NtUserMessageCall( pCWPR
->hwnd
,
244 ClientInfo
->CI_flags
^= ((ClientInfo
->CI_flags
^ Flags
) & CI_CURTHPRHOOK
);
245 ClientInfo
->dwHookData
= Save
;
248 lResult
= NtUserCallNextHookEx(Code
, wParam
, lParam
, pHook
->Ansi
);
259 SetWindowsHookW(int idHook
, HOOKPROC lpfn
)
261 return IntSetWindowsHook(idHook
, lpfn
, NULL
, 0, FALSE
);
269 SetWindowsHookA(int idHook
, HOOKPROC lpfn
)
271 return IntSetWindowsHook(idHook
, lpfn
, NULL
, 0, TRUE
);
279 DeregisterShellHookWindow(HWND hWnd
)
281 return NtUserCallHwnd(hWnd
, HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW
);
289 RegisterShellHookWindow(HWND hWnd
)
291 return NtUserCallHwnd(hWnd
, HWND_ROUTINE_REGISTERSHELLHOOKWINDOW
);
299 UnhookWindowsHook ( int nCode
, HOOKPROC pfnFilterProc
)
301 return NtUserCallTwoParam(nCode
, (DWORD_PTR
)pfnFilterProc
, TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK
);
316 // "Servers call NotifyWinEvent to announce the event to the system after the
317 // event has occurred; they must never notify the system of an event before
318 // the event has occurred." msdn on NotifyWinEvent.
319 if (gpsi
->dwInstalledEventHooks
& GetMaskFromEvent(event
)) // Check to see.
320 NtUserNotifyWinEvent(event
, hwnd
, idObject
, idChild
);
331 HMODULE hmodWinEventProc
,
332 WINEVENTPROC pfnWinEventProc
,
338 WCHAR ModuleName
[MAX_PATH
];
339 UNICODE_STRING USModuleName
;
341 if ((hmodWinEventProc
!= NULL
) && (dwFlags
& WINEVENT_INCONTEXT
))
343 if (0 == GetModuleFileNameW(hmodWinEventProc
, ModuleName
, MAX_PATH
))
347 RtlInitUnicodeString(&USModuleName
, ModuleName
);
351 RtlInitUnicodeString(&USModuleName
, NULL
);
354 return NtUserSetWinEventHook(eventMin
,
369 IsWinEventHookInstalled(
372 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
)
374 return (gpsi
->dwInstalledEventHooks
& GetMaskFromEvent(event
)) != 0;
390 return IntSetWindowsHook(idHook
, lpfn
, hMod
, dwThreadId
, TRUE
);
405 return IntSetWindowsHook(idHook
, lpfn
, hMod
, dwThreadId
, FALSE
);
409 User32CallHookProcFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
411 PHOOKPROC_CALLBACK_ARGUMENTS Common
;
414 CBT_CREATEWNDW CbtCreatewndw
;
416 CBT_CREATEWNDA CbtCreatewnda
;
417 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra
= NULL
;
420 PKBDLLHOOKSTRUCT KeyboardLlData
;
421 PMSLLHOOKSTRUCT MouseLlData
;
423 PMOUSEHOOKSTRUCT MHook
;
427 LPCBTACTIVATESTRUCT pcbtas
;
429 Common
= (PHOOKPROC_CALLBACK_ARGUMENTS
) Arguments
;
431 switch(Common
->HookId
)
438 CbtCreatewndExtra
= (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS
)
439 ((PCHAR
) Common
+ Common
->lParam
);
440 Csw
= CbtCreatewndExtra
->Cs
;
441 if (NULL
!= CbtCreatewndExtra
->Cs
.lpszName
)
443 Csw
.lpszName
= (LPCWSTR
)((PCHAR
) CbtCreatewndExtra
444 + (ULONG
) CbtCreatewndExtra
->Cs
.lpszName
);
446 if (0 != HIWORD(CbtCreatewndExtra
->Cs
.lpszClass
))
448 Csw
.lpszClass
= (LPCWSTR
)((PCHAR
) CbtCreatewndExtra
449 + LOWORD((ULONG
) CbtCreatewndExtra
->Cs
.lpszClass
));
451 wParam
= Common
->wParam
;
454 memcpy(&Csa
, &Csw
, sizeof(CREATESTRUCTW
));
455 CbtCreatewnda
.lpcs
= &Csa
;
456 CbtCreatewnda
.hwndInsertAfter
= CbtCreatewndExtra
->WndInsertAfter
;
457 lParam
= (LPARAM
) &CbtCreatewnda
;
461 CbtCreatewndw
.lpcs
= &Csw
;
462 CbtCreatewndw
.hwndInsertAfter
= CbtCreatewndExtra
->WndInsertAfter
;
463 lParam
= (LPARAM
) &CbtCreatewndw
;
466 case HCBT_CLICKSKIPPED
:
467 MHook
= (PMOUSEHOOKSTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
468 lParam
= (LPARAM
) MHook
;
471 prl
= (PRECTL
)((PCHAR
) Common
+ Common
->lParam
);
472 lParam
= (LPARAM
) prl
;
475 pcbtas
= (LPCBTACTIVATESTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
476 lParam
= (LPARAM
) pcbtas
;
478 case HCBT_KEYSKIPPED
:
481 case HCBT_SYSCOMMAND
:
482 case HCBT_DESTROYWND
:
484 wParam
= Common
->wParam
;
485 lParam
= Common
->lParam
;
488 ERR("HCBT_ not supported = %d\n", Common
->Code
);
489 return ZwCallbackReturn(NULL
, 0, STATUS_NOT_SUPPORTED
);
493 Result
= Common
->Proc(Common
->Code
, wParam
, lParam
);
496 ERR("Common = 0x%x, Proc = 0x%x\n",Common
,Common
->Proc
);
501 CbtCreatewndExtra
->WndInsertAfter
= CbtCreatewndw
.hwndInsertAfter
;
507 KeyboardLlData
= (PKBDLLHOOKSTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
508 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, (LPARAM
) KeyboardLlData
);
511 MouseLlData
= (PMSLLHOOKSTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
512 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, (LPARAM
) MouseLlData
);
515 MHook
= (PMOUSEHOOKSTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
516 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, (LPARAM
) MHook
);
519 CWP
= (PCWPSTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
520 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, (LPARAM
) CWP
);
522 case WH_CALLWNDPROCRET
:
523 CWPR
= (PCWPRETSTRUCT
)((PCHAR
) Common
+ Common
->lParam
);
524 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, (LPARAM
) CWPR
);
527 case WH_SYSMSGFILTER
:
529 Msg
= (PMSG
)((PCHAR
) Common
+ Common
->lParam
);
530 // FIXME("UHOOK Memory: %x: %x\n",Common, Msg);
531 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, (LPARAM
) Msg
);
533 case WH_FOREGROUNDIDLE
:
536 Result
= Common
->Proc(Common
->Code
, Common
->wParam
, Common
->lParam
);
539 return ZwCallbackReturn(NULL
, 0, STATUS_NOT_SUPPORTED
);
542 return ZwCallbackReturn(&Result
, sizeof(LRESULT
), STATUS_SUCCESS
);
546 User32CallEventProcFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
548 PEVENTPROC_CALLBACK_ARGUMENTS Common
;
550 Common
= (PEVENTPROC_CALLBACK_ARGUMENTS
) Arguments
;
552 Common
->Proc(Common
->hook
,
557 Common
->dwEventThread
,
558 Common
->dwmsEventTime
);
560 return ZwCallbackReturn(NULL
, 0, STATUS_SUCCESS
);