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

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

disabled global system hooks

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