source: trunk/src/user32/HOOK.CPP@ 4658

Last change on this file since 4658 was 4658, checked in by sandervl, 25 years ago

Updates for TEB changes

File size: 20.6 KB
Line 
1/* $Id: HOOK.CPP,v 1.16 2000-11-21 11:36:07 sandervl Exp $ */
2
3/*
4 * Windows hook functions
5 *
6 * Copyright 1999 Sander van Leeuwen (OS/2 Port)
7 *
8 * Port of Wine code (windows\hook.c; dated 990920)
9 * All 16 bits code removed
10 *
11 * Copyright 1994, 1995 Alexandre Julliard
12 * 1996 Andrew Lewycky
13 *
14 * Based on investigations by Alex Korobka
15 *
16 *
17 * Project Odin Software License can be found in LICENSE.TXT
18 */
19
20/*
21 * Warning!
22 * A HHOOK is a 32-bit handle for compatibility with Windows 3.0 where it was
23 * a pointer to the next function. Now it is in fact composed of a USER heap
24 * handle in the low 16 bits and of a HOOK_MAGIC value in the high 16 bits.
25 */
26
27#include <os2win.h>
28#include "hook.h"
29#include "queue.h"
30#include "task.h"
31#include "winproc.h"
32#include "debugtools.h"
33#include <misc.h>
34#include <heapstring.h>
35#include <vmutex.h>
36#include <wprocess.h>
37
38#define DBG_LOCALLOG DBG_hook
39#include "dbglocal.h"
40
41DEFAULT_DEBUG_CHANNEL(hook)
42
43#include "pshpack1.h"
44
45 /* Hook data (pointed to by a HHOOK) */
46typedef struct
47{
48 HANDLE next; /* 00 Next hook in chain */
49 HOOKPROC proc; /* 04 Hook procedure (original) */
50 INT id; /* 08 Hook id (WH_xxx) */
51 DWORD ownerThread; /* 0C Owner thread (0 for system hook) */
52 HMODULE ownerModule; /* 10 Owner module */
53 DWORD flags; /* 14 flags */
54 DWORD magic; /* 18 magic dword */
55} HOOKDATA;
56
57#include "poppack.h"
58
59#define HOOK_MAGIC1 ((int)'H' | (int)'K' << 8) /* 'HK' */
60#define HOOK_MAGIC ((HOOK_MAGIC1<<16)|HOOK_MAGIC1) // 'HKHK'
61
62#define CHECK_MAGIC(a) ((a != 0) && (((HOOKDATA *)a)->magic == HOOK_MAGIC))
63
64//NOTE: This must be in the local data segment -> if a shared semaphore was
65// created by a different process, the handle returned by DosOpenMutexSem
66// will be returned in hGlobalHookMutex
67static HMTX hGlobalHookMutex = 0;
68
69//Global DLL Data
70#pragma data_seg(_GLOBALDATA)
71static HANDLE HOOK_systemHooks[WH_NB_HOOKS] = { 0 };
72static VMutex systemHookMutex(VMUTEX_SHARED, &hGlobalHookMutex);
73#pragma data_seg()
74static HANDLE HOOK_threadHooks[WH_NB_HOOKS] = { 0 };
75static VMutex threadHookMutex;
76
77typedef VOID (*HOOK_MapFunc)(INT, INT, WPARAM *, LPARAM *);
78typedef VOID (*HOOK_UnMapFunc)(INT, INT, WPARAM, LPARAM, WPARAM,
79 LPARAM);
80
81/***********************************************************************
82 * HOOK_Map32ATo32W
83 */
84static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
85 LPARAM *plParam)
86{
87 if (id == WH_CBT && code == HCBT_CREATEWND)
88 {
89 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
90 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)HeapAlloc(GetProcessHeap(), 0,
91 sizeof(*lpcbtcwW) );
92 lpcbtcwW->lpcs = (CREATESTRUCTW*)HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwW->lpcs) );
93
94 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
95 *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
96
97 if (HIWORD(lpcbtcwA->lpcs->lpszName))
98 {
99 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
100 lpcbtcwA->lpcs->lpszName );
101 }
102 else
103 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
104
105 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
106 {
107 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
108 lpcbtcwA->lpcs->lpszClass );
109 }
110 else
111 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
112 *plParam = (LPARAM)lpcbtcwW;
113 }
114 return;
115}
116
117
118/***********************************************************************
119 * HOOK_UnMap32ATo32W
120 */
121static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
122 LPARAM lParamOrig, WPARAM wParam,
123 LPARAM lParam)
124{
125 if (id == WH_CBT && code == HCBT_CREATEWND)
126 {
127 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
128 if (HIWORD(lpcbtcwW->lpcs->lpszName))
129 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
130 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
131 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
132 HeapFree( GetProcessHeap(), 0, lpcbtcwW->lpcs );
133 HeapFree( GetProcessHeap(), 0, lpcbtcwW );
134 }
135 return;
136}
137
138
139/***********************************************************************
140 * HOOK_Map32WTo32A
141 */
142static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
143 LPARAM *plParam)
144{
145 if (id == WH_CBT && code == HCBT_CREATEWND)
146 {
147 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
148 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)HeapAlloc(GetProcessHeap(), 0,
149 sizeof(*lpcbtcwA) );
150 lpcbtcwA->lpcs = (CREATESTRUCTA*)HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwA->lpcs) );
151
152 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
153 *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
154
155 if (HIWORD(lpcbtcwW->lpcs->lpszName))
156 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
157 lpcbtcwW->lpcs->lpszName );
158 else
159 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
160
161 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
162 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
163 lpcbtcwW->lpcs->lpszClass );
164 else
165 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
166 *plParam = (LPARAM)lpcbtcwA;
167 }
168 return;
169}
170
171
172/***********************************************************************
173 * HOOK_UnMap32WTo32A
174 */
175static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
176 LPARAM lParamOrig, WPARAM wParam,
177 LPARAM lParam)
178{
179 if (id == WH_CBT && code == HCBT_CREATEWND)
180 {
181 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
182 if (HIWORD(lpcbtcwA->lpcs->lpszName))
183 HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
184 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
185 HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
186 HeapFree( GetProcessHeap(), 0, lpcbtcwA->lpcs );
187 HeapFree( GetProcessHeap(), 0, lpcbtcwA );
188 }
189 return;
190}
191
192
193/***********************************************************************
194 * Map Function Tables
195 */
196static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
197{
198 { NULL, NULL, NULL },
199 { NULL, NULL, HOOK_Map32ATo32W },
200 { NULL, HOOK_Map32WTo32A, NULL }
201};
202
203static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
204{
205 { NULL, NULL, NULL },
206 { NULL, NULL, HOOK_UnMap32ATo32W },
207 { NULL, HOOK_UnMap32WTo32A, NULL }
208};
209
210
211/***********************************************************************
212 * Internal Functions
213 */
214
215/***********************************************************************
216 * HOOK_GetNextHook
217 *
218 * Get the next hook of a given hook.
219 */
220static HANDLE HOOK_GetNextHook( HANDLE hook )
221{
222 HOOKDATA *data = (HOOKDATA *)hook;
223
224 if (!data || !hook) return 0;
225 if (data->next) return data->next;
226 if (!data->ownerThread) return 0; /* Already system hook */
227
228 /* Now start enumerating the system hooks */
229 return HOOK_systemHooks[data->id - WH_MINHOOK];
230}
231
232
233/***********************************************************************
234 * HOOK_GetHook
235 *
236 * Get the first hook for a given type.
237 */
238static HANDLE HOOK_GetHook( INT id, DWORD threadId )
239{
240 MESSAGEQUEUE *queue;
241 HANDLE hook = 0;
242 TEB *teb;
243
244 teb = GetTEBFromThreadId(threadId);
245 if(teb) {
246 hook = teb->o.odin.hooks[id - WH_MINHOOK];
247 }
248 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
249
250 return hook;
251}
252
253
254/***********************************************************************
255 * HOOK_SetHook
256 *
257 * Install a given hook.
258 */
259static HHOOK HOOK_SetHook( INT id, LPVOID proc, INT type,
260 HMODULE hModule, DWORD dwThreadId )
261{
262 HOOKDATA *data;
263 TEB *teb;
264
265 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK) || !proc )
266 {
267 SetLastError(ERROR_INVALID_PARAMETER);
268 return 0;
269 }
270
271 dprintf(("Setting hook %d: %08x %04x %08lx\n", id, (UINT)proc, hModule, dwThreadId ));
272
273#ifndef __WIN32OS2__
274 /* Create task queue if none present */
275 GetFastQueue16();
276
277 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput16(FALSE);
278#endif
279
280
281 if (dwThreadId) /* Task-specific hook */
282 {
283 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
284 (id == WH_SYSMSGFILTER)) {
285 SetLastError(ERROR_INVALID_PARAMETER);
286 return 0; /* System-only hooks */
287 }
288 }
289
290 /* Create the hook structure */
291
292 data = (HOOKDATA *) HeapAlloc(GetProcessHeap(), 0, sizeof(HOOKDATA));
293 data->proc = (HOOKPROC)proc;
294 data->id = id;
295 data->ownerThread = dwThreadId;
296 data->ownerModule = hModule;
297 data->flags = type;
298 data->magic = HOOK_MAGIC;
299
300 /* Insert it in the correct linked list */
301 if(dwThreadId)
302 {
303 teb = GetTEBFromThreadId(dwThreadId);
304 if(!teb) {
305 dprintf(("HOOK_SetHook: can't find thread database for thread %x", dwThreadId));
306 return 0;
307 }
308 threadHookMutex.enter();
309 data->next = teb->o.odin.hooks[id - WH_MINHOOK];
310 teb->o.odin.hooks[id - WH_MINHOOK] = (DWORD)data;
311 threadHookMutex.leave();
312 }
313 else
314 {
315 systemHookMutex.enter(VMUTEX_WAIT_FOREVER, &hGlobalHookMutex);
316 data->next = HOOK_systemHooks[id - WH_MINHOOK];
317 HOOK_systemHooks[id - WH_MINHOOK] = (HANDLE)data;
318 systemHookMutex.leave(&hGlobalHookMutex);
319 }
320
321 return (HHOOK)data;
322}
323
324
325/***********************************************************************
326 * HOOK_RemoveHook
327 *
328 * Remove a hook from the list.
329 */
330static BOOL HOOK_RemoveHook( HOOKDATA *data )
331{
332 HOOKDATA **prevHook;
333 TEB *teb;
334
335 dprintf(("Removing hook %08x\n", data));
336
337 if (data->flags & HOOK_INUSE)
338 {
339 /* Mark it for deletion later on */
340 dprintf(("Hook still running, deletion delayed\n" ));
341 data->flags |= HOOK_DELAYED_DELETE;
342 return TRUE;
343 }
344
345#ifndef __WIN32OS2__
346 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput16(TRUE);
347#endif
348
349 /* Remove it from the linked list */
350
351 if (data->ownerThread)
352 {
353 teb = GetTEBFromThreadId(data->ownerThread);
354 if(!teb) {
355 dprintf(("HOOK_RemoveHook: can't find thread database for thread %x", data->ownerThread));
356 return FALSE;
357 }
358 threadHookMutex.enter();
359 prevHook = (HOOKDATA **)&teb->o.odin.hooks[data->id - WH_MINHOOK];
360 }
361 else {
362 systemHookMutex.enter(VMUTEX_WAIT_FOREVER, &hGlobalHookMutex);
363 prevHook = (HOOKDATA **)&HOOK_systemHooks[data->id - WH_MINHOOK];
364 }
365 while (*prevHook && *prevHook != data)
366 prevHook = (HOOKDATA **)&(*prevHook)->next;
367
368 if (!prevHook) {
369 if (data->ownerThread) {
370 threadHookMutex.leave();
371 }
372 else systemHookMutex.leave(&hGlobalHookMutex);
373
374 return FALSE;
375 }
376 *prevHook = (HOOKDATA *)data->next;
377
378 if (data->ownerThread) {
379 threadHookMutex.leave();
380 }
381 else systemHookMutex.leave(&hGlobalHookMutex);
382
383 HeapFree(GetProcessHeap(), 0, (LPVOID)data );
384 return TRUE;
385}
386
387
388/***********************************************************************
389 * HOOK_FindValidHook
390 */
391static HANDLE HOOK_FindValidHook( HANDLE hook )
392{
393 HOOKDATA *data;
394
395 for (;;)
396 {
397 if (!(data = (HOOKDATA *)hook)) return 0;
398 if (data->proc) return hook;
399 hook = data->next;
400 }
401}
402
403
404/***********************************************************************
405 * HOOK_CallHook
406 *
407 * Call a hook procedure.
408 */
409static LRESULT HOOK_CallHook( HANDLE hook, INT fromtype, INT code,
410 WPARAM wParam, LPARAM lParam )
411{
412 MESSAGEQUEUE *queue;
413 HANDLE prevHook;
414 HOOKDATA *data = (HOOKDATA *)hook;
415 LRESULT ret;
416
417 WPARAM wParamOrig = wParam;
418 LPARAM lParamOrig = lParam;
419 HOOK_MapFunc MapFunc;
420 HOOK_UnMapFunc UnMapFunc;
421
422 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
423 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
424
425 if (MapFunc)
426 MapFunc( data->id, code, &wParam, &lParam );
427
428 /* Now call it */
429
430 data->flags |= HOOK_INUSE;
431
432 dprintf2(("Calling hook %04x: %d %08x %08lx\n", hook, code, wParam, lParam ));
433
434 ret = data->proc(code, wParam, lParam);
435
436 data->flags &= ~HOOK_INUSE;
437
438 if (UnMapFunc)
439 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
440
441 if(data->flags & HOOK_DELAYED_DELETE) HOOK_RemoveHook( data );
442
443 return ret;
444}
445
446/***********************************************************************
447 * Exported Functions & APIs
448 */
449
450/***********************************************************************
451 * HOOK_IsHooked
452 *
453 * Replacement for calling HOOK_GetHook from other modules.
454 */
455BOOL HOOK_IsHooked( INT id )
456{
457 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
458 avoid queue being created if someone wants to merely check ... */
459
460 return HOOK_GetHook( id, GetCurrentThreadId() ) != 0;
461}
462
463/***********************************************************************
464 * HOOK_CallHooks32A
465 *
466 * Call a hook chain.
467 */
468LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
469 LPARAM lParam )
470{
471 HANDLE hook;
472
473 if (!(hook = HOOK_GetHook( id, GetCurrentThreadId() ))) return 0;
474 if (!(hook = HOOK_FindValidHook(hook))) return 0;
475 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
476}
477
478/***********************************************************************
479 * HOOK_CallHooks32W
480 *
481 * Call a hook chain.
482 */
483LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
484 LPARAM lParam )
485{
486 HANDLE hook;
487
488 if (!(hook = HOOK_GetHook( id, GetCurrentThreadId() ))) return 0;
489 if (!(hook = HOOK_FindValidHook(hook))) return 0;
490 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
491 lParam );
492}
493
494
495#if 0
496/***********************************************************************
497 * HOOK_ResetQueueHooks
498 */
499void HOOK_ResetQueueHooks( HQUEUE hQueue )
500{
501 MESSAGEQUEUE *queue;
502
503 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
504 {
505 HOOKDATA* data;
506 HHOOK hook;
507 int id;
508 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
509 {
510 hook = queue->hooks[id - WH_MINHOOK];
511 while( hook )
512 {
513 if( (data = (HOOKDATA *)hook) )
514 {
515 data->ownerQueue = hQueue;
516 hook = data->next;
517 } else break;
518 }
519 }
520
521 QUEUE_Unlock( queue );
522 }
523}
524#endif
525
526/***********************************************************************
527 * HOOK_FreeModuleHooks
528 */
529void HOOK_FreeModuleHooks( HMODULE hModule )
530{
531 /* remove all system hooks registered by this module */
532
533 HOOKDATA* hptr;
534 HHOOK hook, next;
535 int id;
536
537 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
538 {
539 hook = HOOK_systemHooks[id - WH_MINHOOK];
540 while( hook )
541 {
542 hptr = (HOOKDATA *)hook;
543 if (hptr)
544 {
545 next = hptr->next;
546 if( hptr->ownerModule == hModule )
547 {
548 hptr->flags &= HOOK_MAPTYPE;
549 HOOK_RemoveHook(hptr);
550 }
551 hook = next;
552 }
553 else hook = 0;
554 }
555 }
556}
557
558/***********************************************************************
559 * HOOK_FreeQueueHooks
560 */
561void HOOK_FreeQueueHooks( DWORD threadId )
562{
563 /* remove all hooks registered by this queue */
564
565 HOOKDATA* hptr = NULL;
566 HHOOK hook, next;
567 int id;
568
569 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
570 {
571 hook = HOOK_GetHook( id, threadId );
572 while( hook )
573 {
574 next = HOOK_GetNextHook(hook);
575
576 hptr = (HOOKDATA *)hook;
577 if( hptr && hptr->ownerThread == threadId )
578 {
579 hptr->flags &= HOOK_MAPTYPE;
580 HOOK_RemoveHook(hptr);
581 }
582 hook = next;
583 }
584 }
585}
586
587
588/***********************************************************************
589 * SetWindowsHook32A (USER32.525)
590 */
591HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
592{
593 return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
594}
595
596/***********************************************************************
597 * SetWindowsHook32W (USER32.528)
598 */
599HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
600{
601 return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
602}
603
604/***********************************************************************
605 * SetWindowsHookEx32A (USER32.526)
606 */
607HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
608 DWORD dwThreadId )
609{
610 return HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, dwThreadId );
611}
612
613/***********************************************************************
614 * SetWindowsHookEx32W (USER32.527)
615 */
616HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
617 DWORD dwThreadId )
618{
619 return HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, dwThreadId );
620}
621
622/***********************************************************************
623 * UnhookWindowsHook32 (USER32.557)
624 */
625BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
626{
627 HANDLE hook = HOOK_GetHook( id, GetCurrentThreadId() );
628
629 dprintf(("UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc ));
630
631 while (hook)
632 {
633 HOOKDATA *data = (HOOKDATA *)hook;
634 if (data->proc == proc) break;
635 hook = HOOK_GetNextHook( hook );
636 }
637 if (!hook) return FALSE;
638 return HOOK_RemoveHook( (HOOKDATA *)hook );
639}
640
641
642/***********************************************************************
643 * UnhookWindowHookEx32 (USER32.558)
644 */
645BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
646{
647 if (CHECK_MAGIC(hhook) == FALSE) {
648 dprintf(("ERROR: UnhookWindowsHookEx invalid hook %x", hhook));
649 return FALSE;
650 }
651
652 return HOOK_RemoveHook( (HOOKDATA *)hhook );
653}
654
655/***********************************************************************
656 * CallNextHookEx32 (USER32.17)
657 *
658 * There aren't ANSI and UNICODE versions of this.
659 */
660LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
661 LPARAM lParam )
662{
663 HANDLE next;
664 INT fromtype; /* figure out Ansi/Unicode */
665 HOOKDATA *oldhook;
666
667 if (CHECK_MAGIC(hhook) == FALSE) {
668 dprintf(("ERROR: CallNextHookEx invalid hook %x", hhook));
669 return FALSE;
670 }
671 if (!(next = HOOK_GetNextHook( hhook ))) return 0;
672
673 oldhook = (HOOKDATA *)hhook ;
674 fromtype = oldhook->flags & HOOK_MAPTYPE;
675
676 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
677}
678
679
680/***********************************************************************
681 * CallMsgFilter32A (USER32.15)
682 */
683/*
684 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
685 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
686 */
687BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
688{
689#if 0 //CB: not a Win32 API and unimplemented
690 if (GetSysModalWindow()) return FALSE; /* ??? */
691#endif
692 if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
693 return TRUE;
694 return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
695}
696
697
698/***********************************************************************
699 * CallMsgFilter32W (USER32.16)
700 */
701BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
702{
703#if 0 //CB: not a Win32 API and unimplemented
704 if (GetSysModalWindow()) return FALSE; /* ??? */
705#endif
706 if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
707 return TRUE;
708 return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );
709}
710
711
712BOOL ProcessKbdHook(LPMSG msg, BOOL remove )
713{
714 return (HOOK_CallHooksA( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
715 LOWORD (msg->wParam), msg->lParam )
716 ? TRUE : FALSE);
717}
Note: See TracBrowser for help on using the repository browser.