Release 950522
[wine.git] / windows / hook.c
blob2110dd960ab0c98ab955e769fbabe51d5584c3bf
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"
15 HHOOK systemHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
17 /* Task-specific hooks should probably be in the task structure */
18 HHOOK taskHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
22 /***********************************************************************
23 * SetWindowsHook (USER.121)
25 FARPROC SetWindowsHook( short id, HOOKPROC proc )
27 HHOOK hhook = SetWindowsHookEx( id, proc, 0, 0 );
28 HOOKDATA *data = PTR_SEG_TO_LIN(hhook);
29 if (data != NULL) {
30 data = PTR_SEG_TO_LIN(data->next);
31 if (data != NULL) {
32 return data->proc;
35 return 0;
39 /***********************************************************************
40 * UnhookWindowsHook (USER.234)
42 BOOL UnhookWindowsHook( short id, FARPROC hproc )
44 HHOOK *prevHook,hhook;
46 prevHook = &TASK_HOOK(id);
47 while (*prevHook) {
48 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(*prevHook);
50 if (data->proc == hproc) {
51 hhook = *prevHook;
52 *prevHook = data->next;
53 USER_HEAP_FREE(LOWORD(hhook));
54 return TRUE;
57 prevHook = &SYSTEM_HOOK(id);
58 while (*prevHook) {
59 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(*prevHook);
60 if (data->proc == hproc) {
61 hhook = *prevHook;
62 *prevHook = data->next;
63 USER_HEAP_FREE(LOWORD(hhook));
64 return TRUE;
67 return FALSE;
71 /***********************************************************************
72 * DefHookProc (USER.235)
74 DWORD DefHookProc( short code, WORD wParam, DWORD lParam, HHOOK *hhook )
76 return CallNextHookEx( *hhook, code, wParam, lParam );
80 /***********************************************************************
81 * CallMsgFilter (USER.123)
83 BOOL CallMsgFilter( SEGPTR msg, short code )
85 if (CALL_SYSTEM_HOOK( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
86 else return CALL_TASK_HOOK( WH_MSGFILTER, code, 0, (LPARAM)msg );
90 /***********************************************************************
91 * SetWindowsHookEx (USER.291)
93 HHOOK SetWindowsHookEx( short id, HOOKPROC proc, HINSTANCE hinst, HTASK htask )
95 HOOKDATA *data;
96 HANDLE handle;
97 HHOOK *prevHook;
99 if ((id < FIRST_HOOK) || (id > LAST_HOOK)) return 0;
100 if (htask) /* Task-specific hook */
102 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
103 (id == WH_SYSMSGFILTER)) return 0;
104 prevHook = &TASK_HOOK( id );
106 else /* System-wide hook */
108 prevHook = &SYSTEM_HOOK( id );
111 handle = (HANDLE) USER_HEAP_ALLOC( sizeof(*data) );
112 if (!handle) return 0;
113 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
115 data->next = *prevHook;
116 data->proc = proc;
117 data->id = id;
118 data->htask = htask;
119 *prevHook = USER_HEAP_SEG_ADDR(handle);
120 return *prevHook;
124 /***********************************************************************
125 * UnhookWindowHookEx (USER.292)
127 BOOL UnhookWindowsHookEx( HHOOK hhook )
129 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
130 HHOOK *prevHook;
132 if (!data) return FALSE;
133 prevHook = data->htask ? &TASK_HOOK(data->id) : &SYSTEM_HOOK(data->id);
134 while (*prevHook && (*prevHook != hhook)) {
135 prevHook = &((HOOKDATA *)*prevHook)->next;
137 if (!*prevHook) return FALSE;
138 *prevHook = data->next;
139 USER_HEAP_FREE( hhook & 0xffff );
140 return TRUE;
144 /***********************************************************************
145 * CallNextHookEx (USER.293)
147 DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
149 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
150 if (!data->next) return 0;
151 else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );