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

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

temporary workaround added for opera crash

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