Release 950918
[wine/dcerpc.git] / windows / hook.c
blobd4fe2ebd511c43ea6b67a247786e3415435777cb
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"
14 #include "stddebug.h"
15 #include "debug.h"
17 HHOOK systemHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
19 /* Task-specific hooks should probably be in the task structure */
20 HHOOK taskHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
24 /***********************************************************************
25 * SetWindowsHook (USER.121)
27 FARPROC SetWindowsHook( short id, HOOKPROC proc )
29 HHOOK hhook = SetWindowsHookEx( id, proc, 0, 0 );
30 HOOKDATA *data = PTR_SEG_TO_LIN(hhook);
31 if (data != NULL) {
32 data = PTR_SEG_TO_LIN(data->next);
33 if (data != NULL) {
34 return data->proc;
37 return 0;
41 /***********************************************************************
42 * UnhookWindowsHook (USER.234)
44 BOOL UnhookWindowsHook( short id, FARPROC hproc )
46 HHOOK *prevHook,hhook;
48 prevHook = &TASK_HOOK(id);
49 while (*prevHook) {
50 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(*prevHook);
52 if (data->proc == hproc) {
53 hhook = *prevHook;
54 *prevHook = data->next;
55 USER_HEAP_FREE(LOWORD(hhook));
56 return TRUE;
59 prevHook = &SYSTEM_HOOK(id);
60 while (*prevHook) {
61 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(*prevHook);
62 if (data->proc == hproc) {
63 hhook = *prevHook;
64 *prevHook = data->next;
65 USER_HEAP_FREE(LOWORD(hhook));
66 return TRUE;
69 return FALSE;
73 /***********************************************************************
74 * DefHookProc (USER.235)
76 DWORD DefHookProc( short code, WORD wParam, DWORD lParam, HHOOK *hhook )
78 return CallNextHookEx( *hhook, code, wParam, lParam );
82 /***********************************************************************
83 * CallMsgFilter (USER.123)
85 BOOL CallMsgFilter( SEGPTR msg, short code )
87 if (CALL_SYSTEM_HOOK( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
88 else return CALL_TASK_HOOK( WH_MSGFILTER, code, 0, (LPARAM)msg );
92 /***********************************************************************
93 * SetWindowsHookEx (USER.291)
95 HHOOK SetWindowsHookEx( short id, HOOKPROC proc, HINSTANCE hinst, HTASK htask )
97 HOOKDATA *data;
98 HANDLE handle;
99 HHOOK *prevHook;
101 if ((id < FIRST_HOOK) || (id > LAST_HOOK)) return 0;
102 if (id != WH_GETMESSAGE && id != WH_CALLWNDPROC) {
103 fprintf( stdnimp, "Unimplemented hook set: %d!\n", id );
105 if (htask) /* Task-specific hook */
107 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
108 (id == WH_SYSMSGFILTER)) return 0;
109 prevHook = &TASK_HOOK( id );
111 else /* System-wide hook */
113 prevHook = &SYSTEM_HOOK( id );
116 handle = (HANDLE) USER_HEAP_ALLOC( sizeof(*data) );
117 if (!handle) return 0;
118 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
120 data->next = *prevHook;
121 data->proc = proc;
122 data->id = id;
123 data->htask = htask;
124 *prevHook = USER_HEAP_SEG_ADDR(handle);
125 return *prevHook;
129 /***********************************************************************
130 * UnhookWindowHookEx (USER.292)
132 BOOL UnhookWindowsHookEx( HHOOK hhook )
134 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
135 HHOOK *prevHook;
137 if (!data) return FALSE;
138 prevHook = data->htask ? &TASK_HOOK(data->id) : &SYSTEM_HOOK(data->id);
139 while (*prevHook && (*prevHook != hhook)) {
140 prevHook = &((HOOKDATA *)*prevHook)->next;
142 if (!*prevHook) return FALSE;
143 *prevHook = data->next;
144 USER_HEAP_FREE( hhook & 0xffff );
145 return TRUE;
149 /***********************************************************************
150 * CallNextHookEx (USER.293)
152 DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
154 HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
155 if (data == NULL || !data->next) return 0;
156 else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );