Release 950319
[wine.git] / windows / hook.c
blobe91a22b52eca1ca1318874164ac6aaebf44c2be5
1 /*
2 * Windows hook functions
4 * Copyright 1994 Alexandre Julliard
5 */
7 /* Warning!
8 * HHOOK is not a real handle, but a 32-bit pointer to a HOOKDATA structure.
9 * This is for compatibility with Windows 3.0 where HHOOK was a HOOKPROC.
12 #include "hook.h"
13 #include "user.h"
16 HHOOK systemHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
18 /* Task-specific hooks should probably be in the task structure */
19 HHOOK taskHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
23 /***********************************************************************
24 * SetWindowsHook (USER.121)
26 HHOOK SetWindowsHook( short id, HOOKPROC proc )
28 return SetWindowsHookEx( id, proc, 0, 0 );
32 /***********************************************************************
33 * UnhookWindowsHook (USER.234)
35 BOOL UnhookWindowsHook( short id, HHOOK hhook )
37 return UnhookWindowsHookEx( hhook );
41 /***********************************************************************
42 * DefHookProc (USER.235)
44 DWORD DefHookProc( short code, WORD wParam, DWORD lParam, HHOOK *hhook )
46 return CallNextHookEx( *hhook, code, wParam, lParam );
50 /***********************************************************************
51 * CallMsgFilter (USER.123)
53 BOOL CallMsgFilter( SEGPTR msg, short code )
55 if (CALL_SYSTEM_HOOK( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
56 else return CALL_TASK_HOOK( WH_MSGFILTER, code, 0, (LPARAM)msg );
60 /***********************************************************************
61 * SetWindowsHookEx (USER.291)
63 HHOOK SetWindowsHookEx( short id, HOOKPROC proc, HINSTANCE hinst, HTASK htask )
65 HOOKDATA *data;
66 HANDLE handle;
67 HHOOK *prevHook;
69 if ((id < FIRST_HOOK) || (id > LAST_HOOK)) return 0;
70 if (htask) /* Task-specific hook */
72 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
73 (id == WH_SYSMSGFILTER)) return 0;
74 prevHook = &TASK_HOOK( id );
76 else /* System-wide hook */
78 prevHook = &SYSTEM_HOOK( id );
81 handle = (HANDLE) USER_HEAP_ALLOC( sizeof(*data) );
82 if (!handle) return 0;
83 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
85 data->next = *prevHook;
86 data->proc = proc;
87 data->id = id;
88 data->htask = htask;
89 *prevHook = USER_HEAP_SEG_ADDR(handle);
90 return *prevHook;
94 /***********************************************************************
95 * UnhookWindowHookEx (USER.292)
97 BOOL UnhookWindowsHookEx( HHOOK hhook )
99 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
100 HHOOK *prevHook;
102 if (!data) return FALSE;
103 prevHook = data->htask ? &TASK_HOOK(data->id) : &SYSTEM_HOOK(data->id);
104 while (*prevHook && (*prevHook != hhook))
105 prevHook = &((HOOKDATA *)*prevHook)->next;
106 if (!*prevHook) return FALSE;
107 *prevHook = data->next;
108 USER_HEAP_FREE( hhook & 0xffff );
109 return TRUE;
113 /***********************************************************************
114 * CallNextHookEx (USER.293)
116 DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
118 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
119 if (!data->next) return 0;
120 else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );