Implement WH_MOUSE_LL hook
[reactos.git] / reactos / lib / user32 / windows / hook.c
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 /* $Id$
20 *
21 * PROJECT: ReactOS user32.dll
22 * FILE: lib/user32/windows/input.c
23 * PURPOSE: Input
24 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * UPDATE HISTORY:
26 * 09-05-2001 CSH Created
27 */
28
29 /* INCLUDES ******************************************************************/
30
31 #include "user32.h"
32 #include <user32/callback.h>
33 #define NDEBUG
34 #include <debug.h>
35
36 /* FUNCTIONS *****************************************************************/
37
38 /*
39 * @implemented
40 */
41 BOOL
42 STDCALL
43 UnhookWindowsHookEx(
44 HHOOK Hook)
45 {
46 return NtUserUnhookWindowsHookEx(Hook);
47 }
48 #if 0
49 BOOL
50 STDCALL
51 CallMsgFilter(
52 LPMSG lpMsg,
53 int nCode)
54 {
55 UNIMPLEMENTED;
56 return FALSE;
57 }
58 #endif
59
60
61 /*
62 * @unimplemented
63 */
64 BOOL
65 STDCALL
66 CallMsgFilterA(
67 LPMSG lpMsg,
68 int nCode)
69 {
70 UNIMPLEMENTED;
71 return FALSE;
72 }
73
74
75 /*
76 * @unimplemented
77 */
78 BOOL
79 STDCALL
80 CallMsgFilterW(
81 LPMSG lpMsg,
82 int nCode)
83 {
84 UNIMPLEMENTED;
85 return FALSE;
86 }
87
88
89 /*
90 * @unimplemented
91 */
92 LRESULT
93 STDCALL
94 CallNextHookEx(
95 HHOOK Hook,
96 int Code,
97 WPARAM wParam,
98 LPARAM lParam)
99 {
100 return NtUserCallNextHookEx(Hook, Code, wParam, lParam);
101 }
102
103 STATIC
104 HHOOK
105 FASTCALL
106 IntSetWindowsHook(
107 int idHook,
108 HOOKPROC lpfn,
109 HINSTANCE hMod,
110 DWORD dwThreadId,
111 BOOL bAnsi)
112 {
113 WCHAR ModuleName[MAX_PATH];
114 UNICODE_STRING USModuleName;
115
116 if (NULL != hMod)
117 {
118 if (0 == GetModuleFileNameW(hMod, ModuleName, MAX_PATH))
119 {
120 return NULL;
121 }
122 RtlInitUnicodeString(&USModuleName, ModuleName);
123 }
124 else
125 {
126 RtlInitUnicodeString(&USModuleName, NULL);
127 }
128
129 return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi);
130 }
131
132 /*
133 * @unimplemented
134 */
135 HHOOK
136 STDCALL
137 SetWindowsHookW(int idHook, HOOKPROC lpfn)
138 {
139 return IntSetWindowsHook(idHook, lpfn, NULL, 0, FALSE);
140 }
141
142 /*
143 * @unimplemented
144 */
145 HHOOK
146 STDCALL
147 SetWindowsHookA(int idHook, HOOKPROC lpfn)
148 {
149 return IntSetWindowsHook(idHook, lpfn, NULL, 0, TRUE);
150 }
151
152 /*
153 * @unimplemented
154 */
155 BOOL
156 STDCALL
157 DeregisterShellHookWindow(HWND hWnd)
158 {
159 return NtUserCallHwnd(HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW, (DWORD)hWnd);
160 }
161
162 /*
163 * @unimplemented
164 */
165 BOOL
166 STDCALL
167 RegisterShellHookWindow(HWND hWnd)
168 {
169 return NtUserCallHwnd(HWND_ROUTINE_REGISTERSHELLHOOKWINDOW, (DWORD)hWnd);
170 }
171
172 /*
173 * @unimplemented
174 */
175 BOOL
176 STDCALL
177 UnhookWindowsHook ( int nCode, HOOKPROC pfnFilterProc )
178 {
179 UNIMPLEMENTED;
180 return FALSE;
181 }
182
183 /*
184 * @unimplemented
185 */
186 VOID
187 STDCALL
188 NotifyWinEvent(
189 DWORD event,
190 HWND hwnd,
191 LONG idObject,
192 LONG idChild
193 )
194 {
195 UNIMPLEMENTED;
196 }
197
198 /*
199 * @unimplemented
200 */
201 HWINEVENTHOOK
202 STDCALL
203 SetWinEventHook(
204 UINT eventMin,
205 UINT eventMax,
206 HMODULE hmodWinEventProc,
207 WINEVENTPROC pfnWinEventProc,
208 DWORD idProcess,
209 DWORD idThread,
210 UINT dwFlags
211 )
212 {
213 UNIMPLEMENTED;
214 return FALSE;
215 }
216
217 /*
218 * @unimplemented
219 */
220 BOOL
221 STDCALL
222 UnhookWinEvent ( HWINEVENTHOOK hWinEventHook )
223 {
224 UNIMPLEMENTED;
225 return FALSE;
226 }
227
228 /*
229 * @unimplemented
230 */
231 BOOL
232 STDCALL
233 IsWinEventHookInstalled(
234 DWORD event)
235 {
236 UNIMPLEMENTED;
237 return FALSE;
238 }
239
240
241 /*
242 * @unimplemented
243 */
244 HHOOK
245 STDCALL
246 SetWindowsHookExA(
247 int idHook,
248 HOOKPROC lpfn,
249 HINSTANCE hMod,
250 DWORD dwThreadId)
251 {
252 return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, TRUE);
253 }
254
255
256 /*
257 * @unimplemented
258 */
259 HHOOK
260 STDCALL
261 SetWindowsHookExW(
262 int idHook,
263 HOOKPROC lpfn,
264 HINSTANCE hMod,
265 DWORD dwThreadId)
266 {
267 return IntSetWindowsHook(idHook, lpfn, hMod, dwThreadId, FALSE);
268 }
269
270 NTSTATUS STDCALL
271 User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
272 {
273 PHOOKPROC_CALLBACK_ARGUMENTS Common;
274 LRESULT Result;
275 CREATESTRUCTW Csw;
276 CBT_CREATEWNDW CbtCreatewndw;
277 UNICODE_STRING UString;
278 CREATESTRUCTA Csa;
279 CBT_CREATEWNDA CbtCreatewnda;
280 ANSI_STRING AString;
281 PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra;
282 WPARAM wParam;
283 LPARAM lParam;
284 PKBDLLHOOKSTRUCT KeyboardLlData;
285 PMSLLHOOKSTRUCT MouseLlData;
286
287 Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments;
288
289 switch(Common->HookId)
290 {
291 case WH_CBT:
292 switch(Common->Code)
293 {
294 case HCBT_CREATEWND:
295 CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS)
296 ((PCHAR) Common + Common->lParam);
297 Csw = CbtCreatewndExtra->Cs;
298 if (NULL != CbtCreatewndExtra->Cs.lpszName)
299 {
300 Csw.lpszName = (LPCWSTR)((PCHAR) CbtCreatewndExtra
301 + (ULONG) CbtCreatewndExtra->Cs.lpszName);
302 }
303 if (0 != HIWORD(CbtCreatewndExtra->Cs.lpszClass))
304 {
305 Csw.lpszClass = (LPCWSTR)((PCHAR) CbtCreatewndExtra
306 + LOWORD((ULONG) CbtCreatewndExtra->Cs.lpszClass));
307 }
308 wParam = Common->wParam;
309 if (Common->Ansi)
310 {
311 memcpy(&Csa, &Csw, sizeof(CREATESTRUCTW));
312 if (NULL != Csw.lpszName)
313 {
314 RtlInitUnicodeString(&UString, Csw.lpszName);
315 RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
316 Csa.lpszName = AString.Buffer;
317 }
318 if (0 != HIWORD(Csw.lpszClass))
319 {
320 RtlInitUnicodeString(&UString, Csw.lpszClass);
321 RtlUnicodeStringToAnsiString(&AString, &UString, TRUE);
322 Csa.lpszClass = AString.Buffer;
323 }
324 CbtCreatewnda.lpcs = &Csa;
325 CbtCreatewnda.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
326 lParam = (LPARAM) &CbtCreatewnda;
327 }
328 else
329 {
330 CbtCreatewndw.lpcs = &Csw;
331 CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter;
332 lParam = (LPARAM) &CbtCreatewndw;
333 }
334 break;
335 default:
336 return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
337 }
338
339 Result = Common->Proc(Common->Code, wParam, lParam);
340
341 switch(Common->Code)
342 {
343 case HCBT_CREATEWND:
344 if (Common->Ansi)
345 {
346 if (0 != HIWORD(Csa.lpszClass))
347 {
348 RtlFreeHeap(GetProcessHeap(), 0, (LPSTR) Csa.lpszClass);
349 }
350 if (NULL != Csa.lpszName)
351 {
352 RtlFreeHeap(GetProcessHeap(), 0, (LPSTR) Csa.lpszName);
353 }
354 }
355 break;
356 }
357 break;
358 case WH_KEYBOARD_LL:
359 KeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
360 Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData);
361 break;
362 case WH_MOUSE_LL:
363 MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam);
364 Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData);
365 break;
366 default:
367 return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED);
368 }
369
370 return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
371 }