2 * Windows hook functions
4 * Copyright 1994 Alexandre Julliard
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.
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
);
30 data
= PTR_SEG_TO_LIN(data
->next
);
39 /***********************************************************************
40 * UnhookWindowsHook (USER.234)
42 BOOL
UnhookWindowsHook( short id
, FARPROC hproc
)
44 HHOOK
*prevHook
,hhook
;
46 prevHook
= &TASK_HOOK(id
);
48 HOOKDATA
*data
= (HOOKDATA
*)PTR_SEG_TO_LIN(*prevHook
);
50 if (data
->proc
== hproc
) {
52 *prevHook
= data
->next
;
53 USER_HEAP_FREE(LOWORD(hhook
));
57 prevHook
= &SYSTEM_HOOK(id
);
59 HOOKDATA
*data
= (HOOKDATA
*)PTR_SEG_TO_LIN(*prevHook
);
60 if (data
->proc
== hproc
) {
62 *prevHook
= data
->next
;
63 USER_HEAP_FREE(LOWORD(hhook
));
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
)
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
;
119 *prevHook
= USER_HEAP_SEG_ADDR(handle
);
124 /***********************************************************************
125 * UnhookWindowHookEx (USER.292)
127 BOOL
UnhookWindowsHookEx( HHOOK hhook
)
129 HOOKDATA
*data
= (HOOKDATA
*)PTR_SEG_TO_LIN(hhook
);
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 );
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
);