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

Last change on this file since 5655 was 5606, checked in by sandervl, 24 years ago

mouse message translation + dc reset after resize fixes

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