Recovery of release 990110 after disk crash.
[wine.git] / windows / hook.c
blob5261b6b8ad7c79aa538de82ed3a064af0cb49a75
1 /*
2 * Windows hook functions
4 * Copyright 1994, 1995 Alexandre Julliard
5 * 1996 Andrew Lewycky
7 * Based on investigations by Alex Korobka
8 */
11 * Warning!
12 * A HHOOK is a 32-bit handle for compatibility with Windows 3.0 where it was
13 * a pointer to the next function. Now it is in fact composed of a USER heap
14 * handle in the low 16 bits and of a HOOK_MAGIC value in the high 16 bits.
17 #include "windows.h"
18 #include "hook.h"
19 #include "queue.h"
20 #include "task.h"
21 #include "user.h"
22 #include "heap.h"
23 #include "struct32.h"
24 #include "winproc.h"
25 #include "debug.h"
27 #pragma pack(1)
29 /* Hook data (pointed to by a HHOOK) */
30 typedef struct
32 HANDLE16 next; /* 00 Next hook in chain */
33 HOOKPROC32 proc WINE_PACKED; /* 02 Hook procedure */
34 INT16 id; /* 06 Hook id (WH_xxx) */
35 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
36 HMODULE16 ownerModule; /* 0a Owner module */
37 WORD flags; /* 0c flags */
38 } HOOKDATA;
40 #pragma pack(4)
42 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
44 /* This should probably reside in USER heap */
45 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
47 typedef VOID (*HOOK_MapFunc)(INT32, INT32, WPARAM32 *, LPARAM *);
48 typedef VOID (*HOOK_UnMapFunc)(INT32, INT32, WPARAM32, LPARAM, WPARAM32,
49 LPARAM);
51 /***********************************************************************
52 * HOOK_Map16To32Common
54 static void HOOK_Map16To32Common(INT32 id, INT32 code, WPARAM32 *pwParam,
55 LPARAM *plParam, BOOL32 bA )
58 switch( id )
60 case WH_MSGFILTER:
61 case WH_SYSMSGFILTER:
62 case WH_GETMESSAGE:
63 case WH_JOURNALRECORD:
65 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
66 LPMSG32 lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
68 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
69 *plParam = (LPARAM)lpmsg32;
70 break;
73 case WH_JOURNALPLAYBACK:
75 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
76 LPEVENTMSG32 lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
78 lpem32->message = lpem16->message;
79 lpem32->paramL = lpem16->paramL;
80 lpem32->paramH = lpem16->paramH;
81 lpem32->time = lpem16->time;
82 lpem32->hwnd = 0; /* FIXME */
84 *plParam = (LPARAM)lpem32;
85 break;
88 case WH_CALLWNDPROC:
90 LPCWPSTRUCT16 lpcwp16 = PTR_SEG_TO_LIN(*plParam);
91 LPCWPSTRUCT32 lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
93 lpcwp32->hwnd = lpcwp16->hwnd;
94 lpcwp32->lParam = lpcwp16->lParam;
96 if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam,
97 &lpcwp32->message, &lpcwp32->wParam,
98 &lpcwp32->lParam );
99 else WINPROC_MapMsg16To32W( lpcwp16->hwnd,lpcwp16->message, lpcwp16->wParam,
100 &lpcwp32->message, &lpcwp32->wParam,
101 &lpcwp32->lParam );
102 *plParam = (LPARAM)lpcwp32;
103 break;
106 case WH_CBT:
107 switch (code)
109 case HCBT_CREATEWND:
111 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
112 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
113 LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
114 sizeof(*lpcbtcw32) );
115 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
116 sizeof(*lpcbtcw32->lpcs) );
118 STRUCT32_CREATESTRUCT16to32A( lpcs16,
119 (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
121 if (HIWORD(lpcs16->lpszName))
122 lpcbtcw32->lpcs->lpszName =
123 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
124 : HEAP_strdupAtoW( SystemHeap, 0,
125 PTR_SEG_TO_LIN(lpcs16->lpszName) );
126 else
127 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
129 if (HIWORD(lpcs16->lpszClass))
130 lpcbtcw32->lpcs->lpszClass =
131 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
132 : HEAP_strdupAtoW( SystemHeap, 0,
133 PTR_SEG_TO_LIN(lpcs16->lpszClass) );
134 else
135 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
137 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
139 *plParam = (LPARAM)lpcbtcw32;
140 break;
142 case HCBT_ACTIVATE:
144 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
145 LPCBTACTIVATESTRUCT32 lpcas32 = HeapAlloc( SystemHeap, 0,
146 sizeof(*lpcas32) );
147 lpcas32->fMouse = lpcas16->fMouse;
148 lpcas32->hWndActive = lpcas16->hWndActive;
149 *plParam = (LPARAM)lpcas32;
150 break;
152 case HCBT_CLICKSKIPPED:
154 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
155 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
156 sizeof(*lpms32) );
158 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
160 /* wHitTestCode may be negative, so convince compiler to do
161 correct sign extension. Yay. :| */
162 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
164 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
165 lpms32->hwnd = lpms16->hwnd;
166 *plParam = (LPARAM)lpms32;
167 break;
169 case HCBT_MOVESIZE:
171 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
172 LPRECT32 lprect32 = HeapAlloc( SystemHeap, 0,
173 sizeof(*lprect32) );
175 CONV_RECT16TO32( lprect16, lprect32 );
176 *plParam = (LPARAM)lprect32;
177 break;
180 break;
182 case WH_MOUSE:
184 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
185 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
186 sizeof(*lpms32) );
188 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
190 /* wHitTestCode may be negative, so convince compiler to do
191 correct sign extension. Yay. :| */
192 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
193 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
194 lpms32->hwnd = lpms16->hwnd;
195 *plParam = (LPARAM)lpms32;
196 break;
199 case WH_DEBUG:
201 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
202 LPDEBUGHOOKINFO32 lpdh32 = HeapAlloc( SystemHeap, 0,
203 sizeof(*lpdh32) );
205 lpdh32->idThread = 0; /* FIXME */
206 lpdh32->idThreadInstaller = 0; /* FIXME */
207 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
208 lpdh32->wParam = lpdh16->wParam;
209 lpdh32->code = lpdh16->code;
211 /* do sign extension if it was WH_MSGFILTER */
212 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
214 *plParam = (LPARAM)lpdh32;
215 break;
218 case WH_SHELL:
219 case WH_KEYBOARD:
220 break;
222 case WH_HARDWARE:
223 case WH_FOREGROUNDIDLE:
224 case WH_CALLWNDPROCRET:
225 FIXME(hook, "\t[%i] 16to32 translation unimplemented\n", id);
230 /***********************************************************************
231 * HOOK_Map16To32A
233 static void HOOK_Map16To32A(INT32 id, INT32 code, WPARAM32 *pwParam,
234 LPARAM *plParam)
236 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
240 /***********************************************************************
241 * HOOK_Map16To32W
243 static void HOOK_Map16To32W(INT32 id, INT32 code, WPARAM32 *pwParam,
244 LPARAM *plParam)
246 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
250 /***********************************************************************
251 * HOOK_UnMap16To32Common
253 static void HOOK_UnMap16To32Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
254 LPARAM lParamOrig, WPARAM32 wParam,
255 LPARAM lParam, BOOL32 bA)
257 switch (id)
259 case WH_MSGFILTER:
260 case WH_SYSMSGFILTER:
261 case WH_JOURNALRECORD:
262 case WH_JOURNALPLAYBACK:
264 HeapFree( SystemHeap, 0, (LPVOID)lParam );
265 break;
267 case WH_CALLWNDPROC:
269 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)lParam;
270 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
271 lpcwp32->lParam, 0 );
272 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
273 lpcwp32->lParam, 0 );
274 HeapFree( SystemHeap, 0, lpcwp32 );
275 break;
278 case WH_GETMESSAGE:
280 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
281 STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
282 HeapFree( SystemHeap, 0, (LPVOID)lParam );
283 break;
286 case WH_MOUSE:
287 case WH_DEBUG:
289 HeapFree( SystemHeap, 0, (LPVOID)lParam );
290 break;
292 case WH_CBT:
293 switch (code)
295 case HCBT_CREATEWND:
297 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
298 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
300 if( !bA )
302 if (HIWORD(lpcbtcw32->lpcs->lpszName))
303 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
304 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
305 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
308 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
310 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
311 } /* fall through */
313 case HCBT_ACTIVATE:
314 case HCBT_CLICKSKIPPED:
315 case HCBT_MOVESIZE:
317 HeapFree( SystemHeap, 0, (LPVOID)lParam);
318 break;
320 break;
322 case WH_SHELL:
323 case WH_KEYBOARD:
324 break;
326 case WH_HARDWARE:
327 case WH_FOREGROUNDIDLE:
328 case WH_CALLWNDPROCRET:
329 FIXME(hook, "\t[%i] skipping unmap\n", id);
330 break;
335 /***********************************************************************
336 * HOOK_UnMap16To32A
338 static void HOOK_UnMap16To32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
339 LPARAM lParamOrig, WPARAM32 wParam,
340 LPARAM lParam)
342 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
343 lParam, TRUE );
347 /***********************************************************************
348 * HOOK_UnMap16To32W
350 static void HOOK_UnMap16To32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
351 LPARAM lParamOrig, WPARAM32 wParam,
352 LPARAM lParam)
354 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
355 lParam, FALSE );
359 /***********************************************************************
360 * HOOK_Map32To16Common
362 static void HOOK_Map32To16Common(INT32 id, INT32 code, WPARAM32 *pwParam,
363 LPARAM *plParam, BOOL32 bA)
365 switch (id)
367 case WH_MSGFILTER:
368 case WH_SYSMSGFILTER:
369 case WH_GETMESSAGE:
370 case WH_JOURNALRECORD:
372 LPMSG32 lpmsg32 = (LPMSG32)*plParam;
373 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
375 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
377 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
378 break;
381 case WH_JOURNALPLAYBACK:
383 LPEVENTMSG32 lpem32 = (LPEVENTMSG32)*plParam;
384 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
386 lpem16->message = lpem32->message;
387 lpem16->paramL = lpem32->paramL;
388 lpem16->paramH = lpem32->paramH;
389 lpem16->time = lpem32->time;
391 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
392 break;
395 case WH_CALLWNDPROC:
397 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)*plParam;
398 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
400 lpcwp16->hwnd = lpcwp32->hwnd;
401 lpcwp16->lParam = lpcwp32->lParam;
403 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
404 lpcwp32->wParam, &lpcwp16->message,
405 &lpcwp16->wParam, &lpcwp16->lParam );
406 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
407 lpcwp32->wParam, &lpcwp16->message,
408 &lpcwp16->wParam, &lpcwp16->lParam );
409 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
410 break;
413 case WH_CBT:
414 switch (code)
416 case HCBT_ACTIVATE:
418 LPCBTACTIVATESTRUCT32 lpcas32 = (LPCBTACTIVATESTRUCT32)*plParam;
419 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
421 lpcas16->fMouse = lpcas32->fMouse;
422 lpcas16->hWndActive = lpcas32->hWndActive;
424 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
425 break;
428 case HCBT_CLICKSKIPPED:
430 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
431 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
433 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
435 lpms16->hwnd = lpms32->hwnd;
436 lpms16->wHitTestCode = lpms32->wHitTestCode;
437 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
439 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
440 break;
443 case HCBT_MOVESIZE:
445 LPRECT32 lprect32 = (LPRECT32)*plParam;
446 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
448 CONV_RECT32TO16( lprect32, lprect16 );
450 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
451 break;
454 break;
456 case WH_MOUSE:
458 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
459 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
461 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
463 lpms16->hwnd = lpms32->hwnd;
464 lpms16->wHitTestCode = lpms32->wHitTestCode;
465 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
467 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
468 break;
471 case WH_DEBUG:
473 LPDEBUGHOOKINFO32 lpdh32 = (LPDEBUGHOOKINFO32)*plParam;
474 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
476 lpdh16->hModuleHook = 0; /* FIXME */
477 lpdh16->reserved = 0;
478 lpdh16->lParam = lpdh32->lParam;
479 lpdh16->wParam = lpdh32->wParam;
480 lpdh16->code = lpdh32->code;
482 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
483 break;
486 case WH_SHELL:
487 case WH_KEYBOARD:
488 break;
490 case WH_HARDWARE:
491 case WH_FOREGROUNDIDLE:
492 case WH_CALLWNDPROCRET:
493 FIXME(hook,"\t[%i] 32to16 translation unimplemented\n", id);
498 /***********************************************************************
499 * HOOK_Map32ATo16
501 static void HOOK_Map32ATo16(INT32 id, INT32 code, WPARAM32 *pwParam,
502 LPARAM *plParam)
504 if (id == WH_CBT && code == HCBT_CREATEWND)
506 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)*plParam;
507 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
508 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
510 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
511 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
513 if (HIWORD(lpcbtcw32->lpcs->lpszName))
514 lpcs16->lpszName =
515 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
516 else
517 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
519 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
520 lpcs16->lpszClass =
521 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
522 else
523 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
525 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
527 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
529 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
533 /***********************************************************************
534 * HOOK_Map32WTo16
536 static void HOOK_Map32WTo16(INT32 id, INT32 code, WPARAM32 *pwParam,
537 LPARAM *plParam)
539 if (id == WH_CBT && code == HCBT_CREATEWND)
541 LPSTR name, cls;
542 LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
543 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
544 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
546 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
547 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
548 lpcs16 );
550 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
551 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
552 lpcs16->lpszName = SEGPTR_GET( name );
553 lpcs16->lpszClass = SEGPTR_GET( cls );
554 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
556 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
558 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
562 /***********************************************************************
563 * HOOK_UnMap32To16Common
565 static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
566 LPARAM lParamOrig, WPARAM32 wParam,
567 LPARAM lParam, BOOL32 bA)
569 switch (id)
571 case WH_MSGFILTER:
572 case WH_SYSMSGFILTER:
573 case WH_JOURNALRECORD:
574 case WH_JOURNALPLAYBACK:
575 case WH_MOUSE:
576 case WH_DEBUG:
577 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
578 break;
580 case WH_CALLWNDPROC:
582 LPCWPSTRUCT16 lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
583 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)lParamOrig;
584 MSGPARAM16 mp16 = { lpcwp16->wParam, lpcwp16->lParam, 0 };
586 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
587 lpcwp32->lParam, &mp16 );
588 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
589 lpcwp32->lParam, &mp16 );
590 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
591 break;
594 case WH_GETMESSAGE:
596 LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
598 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
599 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
600 break;
603 case WH_CBT:
604 switch (code)
606 case HCBT_CREATEWND:
608 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)(lParamOrig);
609 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
610 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
612 if (HIWORD(lpcs16->lpszName))
613 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
615 if (HIWORD(lpcs16->lpszClass))
616 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
618 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
620 SEGPTR_FREE( lpcs16 );
621 } /* fall through */
623 case HCBT_ACTIVATE:
624 case HCBT_CLICKSKIPPED:
625 case HCBT_MOVESIZE:
627 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
628 break;
630 break;
632 case WH_SHELL:
633 case WH_KEYBOARD:
634 break;
636 case WH_HARDWARE:
637 case WH_FOREGROUNDIDLE:
638 case WH_CALLWNDPROCRET:
639 FIXME(hook, "\t[%i] skipping unmap\n", id);
644 /***********************************************************************
645 * HOOK_UnMap32ATo16
647 static void HOOK_UnMap32ATo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
648 LPARAM lParamOrig, WPARAM32 wParam,
649 LPARAM lParam)
651 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
652 lParam, TRUE );
656 /***********************************************************************
657 * HOOK_UnMap32WTo16
659 static void HOOK_UnMap32WTo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
660 LPARAM lParamOrig, WPARAM32 wParam,
661 LPARAM lParam)
663 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
664 lParam, FALSE );
668 /***********************************************************************
669 * HOOK_Map32ATo32W
671 static void HOOK_Map32ATo32W(INT32 id, INT32 code, WPARAM32 *pwParam,
672 LPARAM *plParam)
674 if (id == WH_CBT && code == HCBT_CREATEWND)
676 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)*plParam;
677 LPCBT_CREATEWND32W lpcbtcwW = HeapAlloc( SystemHeap, 0,
678 sizeof(*lpcbtcwW) );
679 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
681 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
682 *lpcbtcwW->lpcs = *(LPCREATESTRUCT32W)lpcbtcwA->lpcs;
684 if (HIWORD(lpcbtcwA->lpcs->lpszName))
686 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
687 lpcbtcwA->lpcs->lpszName );
689 else
690 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
692 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
694 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
695 lpcbtcwA->lpcs->lpszClass );
697 else
698 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
699 *plParam = (LPARAM)lpcbtcwW;
701 return;
705 /***********************************************************************
706 * HOOK_UnMap32ATo32W
708 static void HOOK_UnMap32ATo32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
709 LPARAM lParamOrig, WPARAM32 wParam,
710 LPARAM lParam)
712 if (id == WH_CBT && code == HCBT_CREATEWND)
714 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
715 if (HIWORD(lpcbtcwW->lpcs->lpszName))
716 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
717 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
718 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
719 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
720 HeapFree( SystemHeap, 0, lpcbtcwW );
722 return;
726 /***********************************************************************
727 * HOOK_Map32WTo32A
729 static void HOOK_Map32WTo32A(INT32 id, INT32 code, WPARAM32 *pwParam,
730 LPARAM *plParam)
732 if (id == WH_CBT && code == HCBT_CREATEWND)
734 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)*plParam;
735 LPCBT_CREATEWND32A lpcbtcwA = HeapAlloc( SystemHeap, 0,
736 sizeof(*lpcbtcwA) );
737 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
739 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
740 *lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
742 if (HIWORD(lpcbtcwW->lpcs->lpszName))
743 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
744 lpcbtcwW->lpcs->lpszName );
745 else
746 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
748 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
749 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
750 lpcbtcwW->lpcs->lpszClass );
751 else
752 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
753 *plParam = (LPARAM)lpcbtcwA;
755 return;
759 /***********************************************************************
760 * HOOK_UnMap32WTo32A
762 static void HOOK_UnMap32WTo32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
763 LPARAM lParamOrig, WPARAM32 wParam,
764 LPARAM lParam)
766 if (id == WH_CBT && code == HCBT_CREATEWND)
768 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
769 if (HIWORD(lpcbtcwA->lpcs->lpszName))
770 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
771 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
772 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
773 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
774 HeapFree( SystemHeap, 0, lpcbtcwA );
776 return;
780 /***********************************************************************
781 * Map Function Tables
783 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
785 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
786 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
787 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
790 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
792 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
793 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
794 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
798 /***********************************************************************
799 * Internal Functions
802 /***********************************************************************
803 * HOOK_GetNextHook
805 * Get the next hook of a given hook.
807 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
809 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
811 if (!data || !hook) return 0;
812 if (data->next) return data->next;
813 if (!data->ownerQueue) return 0; /* Already system hook */
815 /* Now start enumerating the system hooks */
816 return HOOK_systemHooks[data->id - WH_MINHOOK];
820 /***********************************************************************
821 * HOOK_GetHook
823 * Get the first hook for a given type.
825 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
827 MESSAGEQUEUE *queue;
828 HANDLE16 hook = 0;
830 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
831 hook = queue->hooks[id - WH_MINHOOK];
832 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
833 return hook;
837 /***********************************************************************
838 * HOOK_SetHook
840 * Install a given hook.
842 static HANDLE16 HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
843 HINSTANCE16 hInst, HTASK16 hTask )
845 HOOKDATA *data;
846 HANDLE16 handle;
847 HQUEUE16 hQueue = 0;
849 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
851 TRACE(hook, "Setting hook %d: %08x %04x %04x\n",
852 id, (UINT32)proc, hInst, hTask );
854 if (!hInst && (type!=HOOK_WIN16))
855 hInst = GetModuleHandle32A(NULL);/*FIXME: correct? probably not */
857 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
859 if (hTask) /* Task-specific hook */
861 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
862 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
863 if (!(hQueue = GetTaskQueue( hTask )))
865 /* FIXME: shouldn't this be done somewhere else? */
866 if (hTask != GetCurrentTask()) return 0;
867 if (!(hQueue = GetFastQueue())) return 0;
871 /* Create the hook structure */
873 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
874 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
875 data->proc = proc;
876 data->id = id;
877 data->ownerQueue = hQueue;
878 data->ownerModule = hInst;
879 data->flags = type;
881 /* Insert it in the correct linked list */
883 if (hQueue)
885 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
886 data->next = queue->hooks[id - WH_MINHOOK];
887 queue->hooks[id - WH_MINHOOK] = handle;
889 else
891 data->next = HOOK_systemHooks[id - WH_MINHOOK];
892 HOOK_systemHooks[id - WH_MINHOOK] = handle;
894 TRACE(hook, "Setting hook %d: ret=%04x [next=%04x]\n",
895 id, handle, data->next );
896 return handle;
900 /***********************************************************************
901 * HOOK_RemoveHook
903 * Remove a hook from the list.
905 static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
907 HOOKDATA *data;
908 HANDLE16 *prevHook;
910 TRACE(hook, "Removing hook %04x\n", hook );
912 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
913 if (data->flags & HOOK_INUSE)
915 /* Mark it for deletion later on */
916 WARN(hook, "Hook still running, deletion delayed\n" );
917 data->proc = (HOOKPROC32)0;
918 return TRUE;
921 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
923 /* Remove it from the linked list */
925 if (data->ownerQueue)
927 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
928 if (!queue) return FALSE;
929 prevHook = &queue->hooks[data->id - WH_MINHOOK];
931 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
933 while (*prevHook && *prevHook != hook)
934 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
936 if (!*prevHook) return FALSE;
937 *prevHook = data->next;
938 USER_HEAP_FREE( hook );
939 return TRUE;
943 /***********************************************************************
944 * HOOK_FindValidHook
946 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
948 HOOKDATA *data;
950 for (;;)
952 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
953 if (data->proc) return hook;
954 hook = data->next;
959 /***********************************************************************
960 * HOOK_CallHook
962 * Call a hook procedure.
964 static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
965 WPARAM32 wParam, LPARAM lParam )
967 MESSAGEQUEUE *queue;
968 HANDLE16 prevHook;
969 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
970 LRESULT ret;
972 WPARAM32 wParamOrig = wParam;
973 LPARAM lParamOrig = lParam;
974 HOOK_MapFunc MapFunc;
975 HOOK_UnMapFunc UnMapFunc;
977 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
978 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
980 if (MapFunc)
981 MapFunc( data->id, code, &wParam, &lParam );
983 /* Now call it */
985 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetThreadQueue(0) ))) return 0;
986 prevHook = queue->hCurHook;
987 queue->hCurHook = hook;
988 data->flags |= HOOK_INUSE;
990 TRACE(hook, "Calling hook %04x: %d %08x %08lx\n",
991 hook, code, wParam, lParam );
993 ret = data->proc(code, wParam, lParam);
995 TRACE(hook, "Ret hook %04x = %08lx\n", hook, ret );
997 data->flags &= ~HOOK_INUSE;
998 queue->hCurHook = prevHook;
1000 if (UnMapFunc)
1001 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
1003 if (!data->proc) HOOK_RemoveHook( hook );
1005 return ret;
1008 /***********************************************************************
1009 * Exported Functions & APIs
1012 /***********************************************************************
1013 * HOOK_GetProc16
1015 * Don't call this unless you are the if1632/thunk.c.
1017 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
1019 HOOKDATA *data;
1020 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
1021 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
1022 if ((data->flags & HOOK_MAPTYPE) != HOOK_WIN16) return NULL;
1023 return (HOOKPROC16)data->proc;
1027 /***********************************************************************
1028 * HOOK_IsHooked
1030 * Replacement for calling HOOK_GetHook from other modules.
1032 BOOL32 HOOK_IsHooked( INT16 id )
1034 return HOOK_GetHook( id, GetThreadQueue(0) ) != 0;
1038 /***********************************************************************
1039 * HOOK_CallHooks16
1041 * Call a hook chain.
1043 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1044 LPARAM lParam )
1046 HANDLE16 hook;
1048 if (!(hook = HOOK_GetHook( id , GetThreadQueue(0) ))) return 0;
1049 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1050 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1053 /***********************************************************************
1054 * HOOK_CallHooks32A
1056 * Call a hook chain.
1058 LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
1059 LPARAM lParam )
1061 HANDLE16 hook;
1063 if (!(hook = HOOK_GetHook( id , GetThreadQueue(0) ))) return 0;
1064 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1065 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1068 /***********************************************************************
1069 * HOOK_CallHooks32W
1071 * Call a hook chain.
1073 LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
1074 LPARAM lParam )
1076 HANDLE16 hook;
1078 if (!(hook = HOOK_GetHook( id , GetThreadQueue(0) ))) return 0;
1079 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1080 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1081 lParam );
1085 /***********************************************************************
1086 * HOOK_ResetQueueHooks
1088 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1090 MESSAGEQUEUE *queue;
1092 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
1094 HOOKDATA* data;
1095 HHOOK hook;
1096 int id;
1097 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1099 hook = queue->hooks[id - WH_MINHOOK];
1100 while( hook )
1102 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1104 data->ownerQueue = hQueue;
1105 hook = data->next;
1106 } else break;
1112 /***********************************************************************
1113 * HOOK_FreeModuleHooks
1115 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1117 /* remove all system hooks registered by this module */
1119 HOOKDATA* hptr;
1120 HHOOK hook, next;
1121 int id;
1123 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1125 hook = HOOK_systemHooks[id - WH_MINHOOK];
1126 while( hook )
1127 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1129 next = hptr->next;
1130 if( hptr->ownerModule == hModule )
1132 hptr->flags &= HOOK_MAPTYPE;
1133 HOOK_RemoveHook(hook);
1135 hook = next;
1137 else hook = 0;
1141 /***********************************************************************
1142 * HOOK_FreeQueueHooks
1144 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1146 /* remove all hooks registered by this queue */
1148 HOOKDATA* hptr = NULL;
1149 HHOOK hook, next;
1150 int id;
1152 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1154 hook = HOOK_GetHook( id, hQueue );
1155 while( hook )
1157 next = HOOK_GetNextHook(hook);
1159 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1160 if( hptr && hptr->ownerQueue == hQueue )
1162 hptr->flags &= HOOK_MAPTYPE;
1163 HOOK_RemoveHook(hook);
1165 hook = next;
1171 /***********************************************************************
1172 * SetWindowsHook16 (USER.121)
1174 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1176 HANDLE16 handle;
1177 HINSTANCE16 hInst = FarGetOwner( HIWORD(proc) );
1179 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1180 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1182 if (id == WH_DEBUG)
1184 FIXME(hook, "WH_DEBUG is broken in 16-bit Windows.\n");
1185 return 0;
1188 handle = HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), hTask );
1189 return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
1193 /***********************************************************************
1194 * SetWindowsHook32A (USER32.525)
1196 * FIXME: I don't know if this is correct
1198 HHOOK WINAPI SetWindowsHook32A( INT32 id, HOOKPROC32 proc )
1200 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1201 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1203 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, 0, hTask );
1204 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1208 /***********************************************************************
1209 * SetWindowsHook32W (USER32.528)
1211 * FIXME: I don't know if this is correct
1213 HHOOK WINAPI SetWindowsHook32W( INT32 id, HOOKPROC32 proc )
1215 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1216 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1218 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, 0, hTask );
1219 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1223 /***********************************************************************
1224 * SetWindowsHookEx16 (USER.291)
1226 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1227 HTASK16 hTask )
1229 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), hTask );
1230 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1234 /***********************************************************************
1235 * SetWindowsHookEx32A (USER32.526)
1237 HHOOK WINAPI SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1238 DWORD dwThreadID )
1240 HANDLE16 handle;
1241 HTASK16 hTask;
1243 if (dwThreadID == GetCurrentThreadId())
1244 hTask = GetCurrentTask();
1245 else
1246 hTask = LOWORD(dwThreadID); /* FIXME! */
1248 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, hTask );
1249 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1253 /***********************************************************************
1254 * SetWindowsHookEx32W (USER32.527)
1256 HHOOK WINAPI SetWindowsHookEx32W( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1257 DWORD dwThreadID )
1259 HANDLE16 handle;
1260 HTASK16 hTask;
1262 if (dwThreadID == GetCurrentThreadId())
1263 hTask = GetCurrentTask();
1264 else
1265 hTask = LOWORD(dwThreadID); /* FIXME! */
1267 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, hTask );
1268 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1272 /***********************************************************************
1273 * UnhookWindowsHook16 (USER.234)
1275 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1277 HANDLE16 hook = HOOK_GetHook( id, GetThreadQueue(0) );
1279 TRACE(hook, "%d %08lx\n", id, (DWORD)proc );
1281 while (hook)
1283 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1284 if (data->proc == (HOOKPROC32)proc) break;
1285 hook = HOOK_GetNextHook( hook );
1287 if (!hook) return FALSE;
1288 return HOOK_RemoveHook( hook );
1292 /***********************************************************************
1293 * UnhookWindowsHook32 (USER32.557)
1295 BOOL32 WINAPI UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
1297 HANDLE16 hook = HOOK_GetHook( id, GetThreadQueue(0) );
1299 TRACE(hook, "%d %08lx\n", id, (DWORD)proc );
1301 while (hook)
1303 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1304 if (data->proc == proc) break;
1305 hook = HOOK_GetNextHook( hook );
1307 if (!hook) return FALSE;
1308 return HOOK_RemoveHook( hook );
1312 /***********************************************************************
1313 * UnhookWindowHookEx16 (USER.292)
1315 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1317 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1318 return HOOK_RemoveHook( LOWORD(hhook) );
1322 /***********************************************************************
1323 * UnhookWindowHookEx32 (USER32.558)
1325 BOOL32 WINAPI UnhookWindowsHookEx32( HHOOK hhook )
1327 return UnhookWindowsHookEx16( hhook );
1331 /***********************************************************************
1332 * CallNextHookEx16 (USER.293)
1334 * I wouldn't have separated this into 16 and 32 bit versions, but I
1335 * need a way to figure out if I need to do a mapping or not.
1337 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1338 LPARAM lParam )
1340 HANDLE16 next;
1342 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1343 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1345 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1349 /***********************************************************************
1350 * CallNextHookEx32 (USER32.17)
1352 * There aren't ANSI and UNICODE versions of this.
1354 LRESULT WINAPI CallNextHookEx32( HHOOK hhook, INT32 code, WPARAM32 wParam,
1355 LPARAM lParam )
1357 HANDLE16 next;
1358 INT32 fromtype; /* figure out Ansi/Unicode */
1359 HOOKDATA *oldhook;
1361 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1362 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1364 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1365 fromtype = oldhook->flags & HOOK_MAPTYPE;
1367 if (fromtype == HOOK_WIN16)
1368 ERR(hook, "called from 16bit hook!\n");
1370 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1374 /***********************************************************************
1375 * DefHookProc16 (USER.235)
1377 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1378 HHOOK *hhook )
1380 /* Note: the *hhook parameter is never used, since we rely on the
1381 * current hook value from the task queue to find the next hook. */
1382 MESSAGEQUEUE *queue;
1384 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetThreadQueue(0) ))) return 0;
1385 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1389 /***********************************************************************
1390 * CallMsgFilter16 (USER.123)
1392 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1394 if (GetSysModalWindow16()) return FALSE;
1395 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1396 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1400 /***********************************************************************
1401 * CallMsgFilter32A (USER32.15)
1404 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1405 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1407 BOOL32 WINAPI CallMsgFilter32A( LPMSG32 msg, INT32 code )
1409 if (GetSysModalWindow16()) return FALSE; /* ??? */
1410 if (HOOK_CallHooks32A( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1411 return TRUE;
1412 return HOOK_CallHooks32A( WH_MSGFILTER, code, 0, (LPARAM)msg );
1416 /***********************************************************************
1417 * CallMsgFilter32W (USER32.16)
1419 BOOL32 WINAPI CallMsgFilter32W( LPMSG32 msg, INT32 code )
1421 if (GetSysModalWindow16()) return FALSE; /* ??? */
1422 if (HOOK_CallHooks32W( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1423 return TRUE;
1424 return HOOK_CallHooks32W( WH_MSGFILTER, code, 0, (LPARAM)msg );