Release 970824
[wine.git] / windows / hook.c
blob7166bad5d0ad7a853a7333d1ac763603efd5b931
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 "stackframe.h"
21 #include "user.h"
22 #include "heap.h"
23 #include "struct32.h"
24 #include "winproc.h"
25 #include "stddebug.h"
26 #include "debug.h"
28 #pragma pack(1)
30 /* Hook data (pointed to by a HHOOK) */
31 typedef struct
33 HANDLE16 next; /* 00 Next hook in chain */
34 HOOKPROC32 proc WINE_PACKED; /* 02 Hook procedure */
35 INT16 id; /* 06 Hook id (WH_xxx) */
36 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
37 HMODULE16 ownerModule; /* 0a Owner module */
38 WORD flags; /* 0c flags */
39 } HOOKDATA;
41 #pragma pack(4)
43 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
45 /* This should probably reside in USER heap */
46 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
48 typedef VOID (*HOOK_MapFunc)(INT32, INT32, WPARAM32 *, LPARAM *);
49 typedef VOID (*HOOK_UnMapFunc)(INT32, INT32, WPARAM32, LPARAM, WPARAM32,
50 LPARAM);
52 /***********************************************************************
53 * HOOK_Map16To32Common
55 static void HOOK_Map16To32Common(INT32 id, INT32 code, WPARAM32 *pwParam,
56 LPARAM *plParam, BOOL32 bA )
59 switch( id )
61 case WH_MSGFILTER:
62 case WH_SYSMSGFILTER:
63 case WH_GETMESSAGE:
64 case WH_JOURNALRECORD:
66 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
67 LPMSG32 lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
69 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
70 *plParam = (LPARAM)lpmsg32;
71 break;
74 case WH_JOURNALPLAYBACK:
76 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
77 LPEVENTMSG32 lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
79 lpem32->message = lpem16->message;
80 lpem32->paramL = lpem16->paramL;
81 lpem32->paramH = lpem16->paramH;
82 lpem32->time = lpem16->time;
83 lpem32->hwnd = 0; /* FIXME */
85 *plParam = (LPARAM)lpem32;
86 break;
89 case WH_CALLWNDPROC:
91 INT32 (*localMap)(UINT16, WPARAM16, UINT32*, WPARAM32*, LPARAM*)
92 = (bA) ? WINPROC_MapMsg16To32A : WINPROC_MapMsg16To32W;
93 LPCWPSTRUCT16 lpcwp16 = PTR_SEG_TO_LIN(*plParam);
94 LPCWPSTRUCT32 lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
96 lpcwp32->hwnd = lpcwp16->hwnd;
97 lpcwp32->lParam = lpcwp16->lParam;
99 (*localMap)(lpcwp16->message, lpcwp16->wParam,
100 &lpcwp32->message, &lpcwp32->wParam, &lpcwp32->lParam );
101 break;
104 case WH_CBT:
105 switch (code)
107 case HCBT_CREATEWND:
109 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
110 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
111 LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
112 sizeof(*lpcbtcw32) );
113 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
114 sizeof(*lpcbtcw32->lpcs) );
116 STRUCT32_CREATESTRUCT16to32A( lpcs16,
117 (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
119 if (HIWORD(lpcs16->lpszName))
120 lpcbtcw32->lpcs->lpszName =
121 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
122 : HEAP_strdupAtoW( SystemHeap, 0,
123 PTR_SEG_TO_LIN(lpcs16->lpszName) );
124 else
125 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
127 if (HIWORD(lpcs16->lpszClass))
128 lpcbtcw32->lpcs->lpszClass =
129 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
130 : HEAP_strdupAtoW( SystemHeap, 0,
131 PTR_SEG_TO_LIN(lpcs16->lpszClass) );
132 else
133 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
135 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
137 *plParam = (LPARAM)lpcbtcw32;
138 break;
140 case HCBT_ACTIVATE:
142 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
143 LPCBTACTIVATESTRUCT32 lpcas32 = HeapAlloc( SystemHeap, 0,
144 sizeof(*lpcas32) );
145 lpcas32->fMouse = lpcas16->fMouse;
146 lpcas32->hWndActive = lpcas16->hWndActive;
147 *plParam = (LPARAM)lpcas32;
148 break;
150 case HCBT_CLICKSKIPPED:
152 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
153 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
154 sizeof(*lpms32) );
156 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
158 /* wHitTestCode may be negative, so convince compiler to do
159 correct sign extension. Yay. :| */
160 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
162 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
163 lpms32->hwnd = lpms16->hwnd;
164 *plParam = (LPARAM)lpms32;
165 break;
167 case HCBT_MOVESIZE:
169 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
170 LPRECT32 lprect32 = HeapAlloc( SystemHeap, 0,
171 sizeof(*lprect32) );
173 CONV_RECT16TO32( lprect16, lprect32 );
174 *plParam = (LPARAM)lprect32;
175 break;
178 break;
180 case WH_MOUSE:
182 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
183 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
184 sizeof(*lpms32) );
186 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
188 /* wHitTestCode may be negative, so convince compiler to do
189 correct sign extension. Yay. :| */
190 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
191 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
192 lpms32->hwnd = lpms16->hwnd;
193 *plParam = (LPARAM)lpms32;
194 break;
197 case WH_DEBUG:
199 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
200 LPDEBUGHOOKINFO32 lpdh32 = HeapAlloc( SystemHeap, 0,
201 sizeof(*lpdh32) );
203 lpdh32->idThread = 0; /* FIXME */
204 lpdh32->idThreadInstaller = 0; /* FIXME */
205 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
206 lpdh32->wParam = lpdh16->wParam;
207 lpdh32->code = lpdh16->code;
209 /* do sign extension if it was WH_MSGFILTER */
210 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
212 *plParam = (LPARAM)lpdh32;
213 break;
216 case WH_SHELL:
217 case WH_KEYBOARD:
218 break;
220 case WH_HARDWARE:
221 case WH_FOREGROUNDIDLE:
222 case WH_CALLWNDPROCRET:
223 fprintf(stderr, "\t[%i] 16to32 translation unimplemented\n", id);
228 /***********************************************************************
229 * HOOK_Map16To32A
231 static void HOOK_Map16To32A(INT32 id, INT32 code, WPARAM32 *pwParam,
232 LPARAM *plParam)
234 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
238 /***********************************************************************
239 * HOOK_Map16To32W
241 static void HOOK_Map16To32W(INT32 id, INT32 code, WPARAM32 *pwParam,
242 LPARAM *plParam)
244 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
248 /***********************************************************************
249 * HOOK_UnMap16To32Common
251 static void HOOK_UnMap16To32Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
252 LPARAM lParamOrig, WPARAM32 wParam,
253 LPARAM lParam, BOOL32 bA)
255 switch (id)
257 case WH_MSGFILTER:
258 case WH_SYSMSGFILTER:
259 case WH_JOURNALRECORD:
260 case WH_JOURNALPLAYBACK:
262 HeapFree( SystemHeap, 0, (LPVOID)lParam );
263 break;
265 case WH_CALLWNDPROC:
267 void (*localUnMap)(UINT32, WPARAM32, LPARAM)
268 = (bA) ? WINPROC_UnmapMsg16To32A : WINPROC_UnmapMsg16To32W;
269 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)lParam;
271 (*localUnMap)(lpcwp32->message, lpcwp32->wParam, lpcwp32->lParam );
272 HeapFree( SystemHeap, 0, lpcwp32 );
273 break;
276 case WH_GETMESSAGE:
278 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
279 STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
280 HeapFree( SystemHeap, 0, (LPVOID)lParam );
281 break;
284 case WH_MOUSE:
285 case WH_DEBUG:
287 HeapFree( SystemHeap, 0, (LPVOID)lParam );
288 break;
290 case WH_CBT:
291 switch (code)
293 case HCBT_CREATEWND:
295 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
296 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
298 if( !bA )
300 if (HIWORD(lpcbtcw32->lpcs->lpszName))
301 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
302 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
303 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
306 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
308 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
309 } /* fall through */
311 case HCBT_ACTIVATE:
312 case HCBT_CLICKSKIPPED:
313 case HCBT_MOVESIZE:
315 HeapFree( SystemHeap, 0, (LPVOID)lParam);
316 break;
318 break;
320 case WH_SHELL:
321 case WH_KEYBOARD:
322 break;
324 case WH_HARDWARE:
325 case WH_FOREGROUNDIDLE:
326 case WH_CALLWNDPROCRET:
327 fprintf(stderr, "\t[%i] skipping unmap\n", id);
328 break;
333 /***********************************************************************
334 * HOOK_UnMap16To32A
336 static void HOOK_UnMap16To32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
337 LPARAM lParamOrig, WPARAM32 wParam,
338 LPARAM lParam)
340 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
341 lParam, TRUE );
345 /***********************************************************************
346 * HOOK_UnMap16To32W
348 static void HOOK_UnMap16To32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
349 LPARAM lParamOrig, WPARAM32 wParam,
350 LPARAM lParam)
352 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
353 lParam, FALSE );
357 /***********************************************************************
358 * HOOK_Map32To16Common
360 static void HOOK_Map32To16Common(INT32 id, INT32 code, WPARAM32 *pwParam,
361 LPARAM *plParam, BOOL32 bA)
363 switch (id)
365 case WH_MSGFILTER:
366 case WH_SYSMSGFILTER:
367 case WH_GETMESSAGE:
368 case WH_JOURNALRECORD:
370 LPMSG32 lpmsg32 = (LPMSG32)*plParam;
371 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
373 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
375 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
376 break;
379 case WH_JOURNALPLAYBACK:
381 LPEVENTMSG32 lpem32 = (LPEVENTMSG32)*plParam;
382 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
384 lpem16->message = lpem32->message;
385 lpem16->paramL = lpem32->paramL;
386 lpem16->paramH = lpem32->paramH;
387 lpem16->time = lpem32->time;
389 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
390 break;
393 case WH_CALLWNDPROC:
395 INT32 (*localMap)(UINT32, WPARAM32, UINT16*, WPARAM16*, LPARAM*)
396 = (bA) ? WINPROC_MapMsg32ATo16 : WINPROC_MapMsg32WTo16;
397 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)*plParam;
398 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
400 lpcwp16->hwnd = lpcwp32->hwnd;
401 lpcwp16->lParam = lpcwp32->lParam;
403 (*localMap)(lpcwp32->message, lpcwp32->wParam,
404 &lpcwp16->message, &lpcwp16->wParam, &lpcwp16->lParam );
405 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
406 break;
409 case WH_CBT:
410 switch (code)
412 case HCBT_ACTIVATE:
414 LPCBTACTIVATESTRUCT32 lpcas32 = (LPCBTACTIVATESTRUCT32)*plParam;
415 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
417 lpcas16->fMouse = lpcas32->fMouse;
418 lpcas16->hWndActive = lpcas32->hWndActive;
420 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
421 break;
424 case HCBT_CLICKSKIPPED:
426 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
427 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
429 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
431 lpms16->hwnd = lpms32->hwnd;
432 lpms16->wHitTestCode = lpms32->wHitTestCode;
433 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
435 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
436 break;
439 case HCBT_MOVESIZE:
441 LPRECT32 lprect32 = (LPRECT32)*plParam;
442 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
444 CONV_RECT32TO16( lprect32, lprect16 );
446 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
447 break;
450 break;
452 case WH_MOUSE:
454 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
455 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
457 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
459 lpms16->hwnd = lpms32->hwnd;
460 lpms16->wHitTestCode = lpms32->wHitTestCode;
461 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
463 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
464 break;
467 case WH_DEBUG:
469 LPDEBUGHOOKINFO32 lpdh32 = (LPDEBUGHOOKINFO32)*plParam;
470 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
472 lpdh16->hModuleHook = 0; /* FIXME */
473 lpdh16->reserved = 0;
474 lpdh16->lParam = lpdh32->lParam;
475 lpdh16->wParam = lpdh32->wParam;
476 lpdh16->code = lpdh32->code;
478 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
479 break;
482 case WH_SHELL:
483 case WH_KEYBOARD:
484 break;
486 case WH_HARDWARE:
487 case WH_FOREGROUNDIDLE:
488 case WH_CALLWNDPROCRET:
489 fprintf(stderr,"\t[%i] 32to16 translation unimplemented\n", id);
494 /***********************************************************************
495 * HOOK_Map32ATo16
497 static void HOOK_Map32ATo16(INT32 id, INT32 code, WPARAM32 *pwParam,
498 LPARAM *plParam)
500 if (id == WH_CBT && code == HCBT_CREATEWND)
502 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)*plParam;
503 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
504 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
506 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
507 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
509 if (HIWORD(lpcbtcw32->lpcs->lpszName))
510 lpcs16->lpszName =
511 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
512 else
513 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
515 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
516 lpcs16->lpszClass =
517 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
518 else
519 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
521 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
523 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
525 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
529 /***********************************************************************
530 * HOOK_Map32WTo16
532 static void HOOK_Map32WTo16(INT32 id, INT32 code, WPARAM32 *pwParam,
533 LPARAM *plParam)
535 if (id == WH_CBT && code == HCBT_CREATEWND)
537 LPSTR name, cls;
538 LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
539 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
540 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
542 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
543 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
544 lpcs16 );
546 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
547 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
548 lpcs16->lpszName = SEGPTR_GET( name );
549 lpcs16->lpszClass = SEGPTR_GET( cls );
550 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
552 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
554 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
558 /***********************************************************************
559 * HOOK_UnMap32To16Common
561 static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
562 LPARAM lParamOrig, WPARAM32 wParam,
563 LPARAM lParam, BOOL32 bA)
565 switch (id)
567 case WH_MSGFILTER:
568 case WH_SYSMSGFILTER:
569 case WH_JOURNALRECORD:
570 case WH_JOURNALPLAYBACK:
571 case WH_MOUSE:
572 case WH_DEBUG:
573 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
574 break;
576 case WH_CALLWNDPROC:
578 void (*localUnMap)(UINT32, WPARAM32, LPARAM, MSGPARAM16* )
579 = (bA) ? WINPROC_UnmapMsg32ATo16 : WINPROC_UnmapMsg32WTo16;
580 LPCWPSTRUCT16 lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
581 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)lParamOrig;
582 MSGPARAM16 mp16 = { lpcwp16->wParam, lpcwp16->lParam, 0 };
584 (*localUnMap)(lpcwp32->message, lpcwp32->wParam, lpcwp32->lParam, &mp16 );
585 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
586 break;
589 case WH_GETMESSAGE:
591 LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
593 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
594 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
595 break;
598 case WH_CBT:
599 switch (code)
601 case HCBT_CREATEWND:
603 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)(lParamOrig);
604 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
605 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
607 if (HIWORD(lpcs16->lpszName))
608 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
610 if (HIWORD(lpcs16->lpszClass))
611 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
613 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
615 SEGPTR_FREE( lpcs16 );
616 } /* fall through */
618 case HCBT_ACTIVATE:
619 case HCBT_CLICKSKIPPED:
620 case HCBT_MOVESIZE:
622 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
623 break;
625 break;
627 case WH_SHELL:
628 case WH_KEYBOARD:
629 break;
631 case WH_HARDWARE:
632 case WH_FOREGROUNDIDLE:
633 case WH_CALLWNDPROCRET:
634 fprintf(stderr, "\t[%i] skipping unmap\n", id);
639 /***********************************************************************
640 * HOOK_UnMap32ATo16
642 static void HOOK_UnMap32ATo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
643 LPARAM lParamOrig, WPARAM32 wParam,
644 LPARAM lParam)
646 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
647 lParam, TRUE );
651 /***********************************************************************
652 * HOOK_UnMap32WTo16
654 static void HOOK_UnMap32WTo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
655 LPARAM lParamOrig, WPARAM32 wParam,
656 LPARAM lParam)
658 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
659 lParam, FALSE );
663 /***********************************************************************
664 * HOOK_Map32ATo32W
666 static void HOOK_Map32ATo32W(INT32 id, INT32 code, WPARAM32 *pwParam,
667 LPARAM *plParam)
669 if (id == WH_CBT && code == HCBT_CREATEWND)
671 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)*plParam;
672 LPCBT_CREATEWND32W lpcbtcwW = HeapAlloc( SystemHeap, 0,
673 sizeof(*lpcbtcwW) );
674 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
676 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
677 *lpcbtcwW->lpcs = *(LPCREATESTRUCT32W)lpcbtcwA->lpcs;
679 if (HIWORD(lpcbtcwA->lpcs->lpszName))
681 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
682 lpcbtcwA->lpcs->lpszName );
684 else
685 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
687 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
689 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
690 lpcbtcwA->lpcs->lpszClass );
692 else
693 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
695 return;
699 /***********************************************************************
700 * HOOK_UnMap32ATo32W
702 static void HOOK_UnMap32ATo32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
703 LPARAM lParamOrig, WPARAM32 wParam,
704 LPARAM lParam)
706 if (id == WH_CBT && code == HCBT_CREATEWND)
708 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
709 if (HIWORD(lpcbtcwW->lpcs->lpszName))
710 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
711 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
712 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
713 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
714 HeapFree( SystemHeap, 0, lpcbtcwW );
716 return;
720 /***********************************************************************
721 * HOOK_Map32WTo32A
723 static void HOOK_Map32WTo32A(INT32 id, INT32 code, WPARAM32 *pwParam,
724 LPARAM *plParam)
726 if (id == WH_CBT && code == HCBT_CREATEWND)
728 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)*plParam;
729 LPCBT_CREATEWND32A lpcbtcwA = HeapAlloc( SystemHeap, 0,
730 sizeof(*lpcbtcwA) );
731 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
733 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
734 *lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
736 if (HIWORD(lpcbtcwW->lpcs->lpszName))
737 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
738 lpcbtcwW->lpcs->lpszName );
739 else
740 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
742 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
743 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
744 lpcbtcwW->lpcs->lpszClass );
745 else
746 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
748 return;
752 /***********************************************************************
753 * HOOK_UnMap32WTo32A
755 static void HOOK_UnMap32WTo32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
756 LPARAM lParamOrig, WPARAM32 wParam,
757 LPARAM lParam)
759 if (id == WH_CBT && code == HCBT_CREATEWND)
761 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
762 if (HIWORD(lpcbtcwA->lpcs->lpszName))
763 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
764 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
765 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
766 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
767 HeapFree( SystemHeap, 0, lpcbtcwA );
769 return;
773 /***********************************************************************
774 * Map Function Tables
776 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
778 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
779 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
780 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
783 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
785 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
786 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
787 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
791 /***********************************************************************
792 * Internal Functions
795 /***********************************************************************
796 * HOOK_GetNextHook
798 * Get the next hook of a given hook.
800 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
802 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
804 if (!data || !hook) return 0;
805 if (data->next) return data->next;
806 if (!data->ownerQueue) return 0; /* Already system hook */
808 /* Now start enumerating the system hooks */
809 return HOOK_systemHooks[data->id - WH_MINHOOK];
813 /***********************************************************************
814 * HOOK_GetHook
816 * Get the first hook for a given type.
818 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
820 MESSAGEQUEUE *queue;
821 HANDLE16 hook = 0;
823 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
824 hook = queue->hooks[id - WH_MINHOOK];
825 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
826 return hook;
830 /***********************************************************************
831 * HOOK_SetHook
833 * Install a given hook.
835 static HANDLE16 HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
836 HINSTANCE16 hInst, HTASK16 hTask )
838 HOOKDATA *data;
839 HANDLE16 handle;
840 HQUEUE16 hQueue = 0;
842 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
843 if (!(hInst = GetExePtr( hInst ))) return 0;
845 dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
846 id, (UINT32)proc, hInst, hTask );
848 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
850 if (hTask) /* Task-specific hook */
852 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
853 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
854 if (!(hQueue = GetTaskQueue( hTask ))) return 0;
857 /* Create the hook structure */
859 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
860 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
861 data->proc = proc;
862 data->id = id;
863 data->ownerQueue = hQueue;
864 data->ownerModule = hInst;
865 data->flags = type;
867 /* Insert it in the correct linked list */
869 if (hQueue)
871 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
872 data->next = queue->hooks[id - WH_MINHOOK];
873 queue->hooks[id - WH_MINHOOK] = handle;
875 else
877 data->next = HOOK_systemHooks[id - WH_MINHOOK];
878 HOOK_systemHooks[id - WH_MINHOOK] = handle;
880 dprintf_hook( stddeb, "Setting hook %d: ret=%04x [next=%04x]\n",
881 id, handle, data->next );
882 return handle;
886 /***********************************************************************
887 * HOOK_RemoveHook
889 * Remove a hook from the list.
891 static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
893 HOOKDATA *data;
894 HANDLE16 *prevHook;
896 dprintf_hook( stddeb, "Removing hook %04x\n", hook );
898 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
899 if (data->flags & HOOK_INUSE)
901 /* Mark it for deletion later on */
902 dprintf_hook( stddeb, "Hook still running, deletion delayed\n" );
903 data->proc = (HOOKPROC32)0;
904 return TRUE;
907 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
909 /* Remove it from the linked list */
911 if (data->ownerQueue)
913 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
914 if (!queue) return FALSE;
915 prevHook = &queue->hooks[data->id - WH_MINHOOK];
917 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
919 while (*prevHook && *prevHook != hook)
920 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
922 if (!*prevHook) return FALSE;
923 *prevHook = data->next;
924 USER_HEAP_FREE( hook );
925 return TRUE;
929 /***********************************************************************
930 * HOOK_FindValidHook
932 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
934 HOOKDATA *data;
936 for (;;)
938 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
939 if (data->proc) return hook;
940 hook = data->next;
945 /***********************************************************************
946 * HOOK_CallHook
948 * Call a hook procedure.
950 static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
951 WPARAM32 wParam, LPARAM lParam )
953 MESSAGEQUEUE *queue;
954 HANDLE16 prevHook;
955 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
956 LRESULT ret;
957 WORD old_ds;
959 WPARAM32 wParamOrig = wParam;
960 LPARAM lParamOrig = lParam;
961 HOOK_MapFunc MapFunc;
962 HOOK_UnMapFunc UnMapFunc;
964 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
965 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
967 if (MapFunc)
968 MapFunc( data->id, code, &wParam, &lParam );
970 /* Now call it */
972 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
973 prevHook = queue->hCurHook;
974 queue->hCurHook = hook;
975 data->flags |= HOOK_INUSE;
977 dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
978 hook, code, wParam, lParam );
980 /* Set DS = SS to call hook procedure */
981 old_ds = CURRENT_DS;
982 CURRENT_DS = SELECTOROF(IF1632_Saved16_ss_sp);
983 ret = data->proc(code, wParam, lParam);
984 CURRENT_DS = old_ds;
986 dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
988 data->flags &= ~HOOK_INUSE;
989 queue->hCurHook = prevHook;
991 if (UnMapFunc)
992 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
994 if (!data->proc) HOOK_RemoveHook( hook );
996 return ret;
999 /***********************************************************************
1000 * Exported Functions & APIs
1003 /***********************************************************************
1004 * HOOK_GetProc16
1006 * Don't call this unless you are the if1632/thunk.c.
1008 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
1010 HOOKDATA *data;
1011 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
1012 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
1013 if ((data->flags & HOOK_MAPTYPE) != HOOK_WIN16) return NULL;
1014 return (HOOKPROC16)data->proc;
1018 /***********************************************************************
1019 * HOOK_IsHooked
1021 * Replacement for calling HOOK_GetHook from other modules.
1023 BOOL32 HOOK_IsHooked( INT16 id )
1025 return HOOK_GetHook( id, GetTaskQueue(0) ) != 0;
1029 /***********************************************************************
1030 * HOOK_CallHooks16
1032 * Call a hook chain.
1034 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1035 LPARAM lParam )
1037 HANDLE16 hook;
1039 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1040 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1041 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1044 /***********************************************************************
1045 * HOOK_CallHooks32A
1047 * Call a hook chain.
1049 LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
1050 LPARAM lParam )
1052 HANDLE16 hook;
1054 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1055 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1056 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1059 /***********************************************************************
1060 * HOOK_CallHooks32W
1062 * Call a hook chain.
1064 LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
1065 LPARAM lParam )
1067 HANDLE16 hook;
1069 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1070 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1071 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1072 lParam );
1076 /***********************************************************************
1077 * HOOK_ResetQueueHooks
1079 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1081 MESSAGEQUEUE *queue;
1083 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
1085 HOOKDATA* data;
1086 HHOOK hook;
1087 int id;
1088 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1090 hook = queue->hooks[id - WH_MINHOOK];
1091 while( hook )
1093 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1095 data->ownerQueue = hQueue;
1096 hook = data->next;
1097 } else break;
1103 /***********************************************************************
1104 * HOOK_FreeModuleHooks
1106 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1108 /* remove all system hooks registered by this module */
1110 HOOKDATA* hptr;
1111 HHOOK hook, next;
1112 int id;
1114 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1116 hook = HOOK_systemHooks[id - WH_MINHOOK];
1117 while( hook )
1118 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1120 next = hptr->next;
1121 if( hptr->ownerModule == hModule )
1123 hptr->flags &= HOOK_MAPTYPE;
1124 HOOK_RemoveHook(hook);
1126 hook = next;
1128 else hook = 0;
1132 /***********************************************************************
1133 * HOOK_FreeQueueHooks
1135 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1137 /* remove all hooks registered by this queue */
1139 HOOKDATA* hptr = NULL;
1140 HHOOK hook, next;
1141 int id;
1143 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1145 hook = HOOK_GetHook( id, hQueue );
1146 while( hook )
1148 next = HOOK_GetNextHook(hook);
1150 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1151 if( hptr && hptr->ownerQueue == hQueue )
1153 hptr->flags &= HOOK_MAPTYPE;
1154 HOOK_RemoveHook(hook);
1156 hook = next;
1162 /***********************************************************************
1163 * SetWindowsHook16 (USER.121)
1165 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1167 HANDLE16 handle;
1168 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1170 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1171 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1173 if (id == WH_DEBUG)
1175 fprintf( stdnimp, "WH_DEBUG is broken in 16-bit Windows.\n");
1176 return 0;
1179 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
1180 return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
1184 /***********************************************************************
1185 * SetWindowsHook32A (USER32.524)
1187 * FIXME: I don't know if this is correct
1189 HHOOK WINAPI SetWindowsHook32A( INT32 id, HOOKPROC32 proc )
1191 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1193 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1194 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1196 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, hTask );
1197 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1201 /***********************************************************************
1202 * SetWindowsHook32W (USER32.527)
1204 * FIXME: I don't know if this is correct
1206 HHOOK WINAPI SetWindowsHook32W( INT32 id, HOOKPROC32 proc )
1208 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1210 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1211 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1213 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, hTask );
1214 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1218 /***********************************************************************
1219 * SetWindowsHookEx16 (USER.291)
1221 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1222 HTASK16 hTask )
1224 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
1225 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1229 /***********************************************************************
1230 * SetWindowsHookEx32A (USER32.525)
1232 HHOOK WINAPI SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1233 DWORD dwThreadID )
1235 HANDLE16 handle;
1236 HTASK16 hTask;
1238 if (dwThreadID == GetCurrentThreadId())
1239 hTask = GetCurrentTask();
1240 else
1241 hTask = LOWORD(dwThreadID);
1243 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, hTask );
1244 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1248 /***********************************************************************
1249 * SetWindowsHookEx32W (USER32.526)
1251 HHOOK WINAPI SetWindowsHookEx32W( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1252 DWORD dwThreadID )
1254 HANDLE16 handle;
1255 HTASK16 hTask;
1257 if (dwThreadID == GetCurrentThreadId())
1258 hTask = GetCurrentTask();
1259 else
1260 hTask = LOWORD(dwThreadID);
1262 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, hTask );
1263 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1267 /***********************************************************************
1268 * UnhookWindowsHook16 (USER.234)
1270 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1272 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1274 dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
1276 while (hook)
1278 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1279 if (data->proc == (HOOKPROC32)proc) break;
1280 hook = HOOK_GetNextHook( hook );
1282 if (!hook) return FALSE;
1283 return HOOK_RemoveHook( hook );
1287 /***********************************************************************
1288 * UnhookWindowsHook32 (USER32.556)
1290 BOOL32 WINAPI UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
1292 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1294 dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
1296 while (hook)
1298 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1299 if (data->proc == proc) break;
1300 hook = HOOK_GetNextHook( hook );
1302 if (!hook) return FALSE;
1303 return HOOK_RemoveHook( hook );
1307 /***********************************************************************
1308 * UnhookWindowHookEx16 (USER.292)
1310 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1312 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1313 return HOOK_RemoveHook( LOWORD(hhook) );
1317 /***********************************************************************
1318 * UnhookWindowHookEx32 (USER32.557)
1320 BOOL32 WINAPI UnhookWindowsHookEx32( HHOOK hhook )
1322 return UnhookWindowsHookEx16( hhook );
1326 /***********************************************************************
1327 * CallNextHookEx16 (USER.293)
1329 * I wouldn't have separated this into 16 and 32 bit versions, but I
1330 * need a way to figure out if I need to do a mapping or not.
1332 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1333 LPARAM lParam )
1335 HANDLE16 next;
1337 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1338 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1340 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1344 /***********************************************************************
1345 * CallNextHookEx32 (USER32.16)
1347 * There aren't ANSI and UNICODE versions of this.
1349 LRESULT WINAPI CallNextHookEx32( HHOOK hhook, INT32 code, WPARAM32 wParam,
1350 LPARAM lParam )
1352 HANDLE16 next;
1353 INT32 fromtype; /* figure out Ansi/Unicode */
1354 HOOKDATA *oldhook;
1356 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1357 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1359 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1360 fromtype = oldhook->flags & HOOK_MAPTYPE;
1362 if (fromtype == HOOK_WIN16)
1363 fprintf(stderr, "CallNextHookEx32: called from 16bit hook!\n");
1365 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1369 /***********************************************************************
1370 * DefHookProc16 (USER.235)
1372 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1373 HHOOK *hhook )
1375 /* Note: the *hhook parameter is never used, since we rely on the
1376 * current hook value from the task queue to find the next hook. */
1377 MESSAGEQUEUE *queue;
1379 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
1380 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1384 /***********************************************************************
1385 * CallMsgFilter16 (USER.123)
1387 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1389 if (GetSysModalWindow16()) return FALSE;
1390 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1391 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1395 /***********************************************************************
1396 * CallMsgFilter32A (USER32.14)
1399 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1400 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1402 BOOL32 WINAPI CallMsgFilter32A( LPMSG32 msg, INT32 code )
1404 if (GetSysModalWindow16()) return FALSE; /* ??? */
1405 if (HOOK_CallHooks32A( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1406 return TRUE;
1407 return HOOK_CallHooks32A( WH_MSGFILTER, code, 0, (LPARAM)msg );
1411 /***********************************************************************
1412 * CallMsgFilter32W (USER32.15)
1414 BOOL32 WINAPI CallMsgFilter32W( LPMSG32 msg, INT32 code )
1416 if (GetSysModalWindow16()) return FALSE; /* ??? */
1417 if (HOOK_CallHooks32W( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1418 return TRUE;
1419 return HOOK_CallHooks32W( WH_MSGFILTER, code, 0, (LPARAM)msg );