Release 961208
[wine/multimedia.git] / windows / hook.c
bloba64db7c7e9aec5d4c8890e9a99b306fbeb4006c7
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 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
18 #include "windows.h"
19 #include "hook.h"
20 #include "queue.h"
21 #include "user.h"
22 #include "heap.h"
23 #include "struct32.h"
24 #include "string32.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 inHookProc; /* 0c TRUE if in this->proc */
39 INT32 flags;
40 } HOOKDATA;
42 #pragma pack(4)
44 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
46 /* This should probably reside in USER heap */
47 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
49 typedef VOID (*HOOK_MapFunc)(INT32, INT32, WPARAM32 *, LPARAM *);
50 typedef VOID (*HOOK_UnMapFunc)(INT32, INT32, WPARAM32, LPARAM, WPARAM32,
51 LPARAM);
54 /***********************************************************************
55 * Hook Mapping Functions
59 /***********************************************************************
60 * HOOK_Map16To32Common
62 static void HOOK_Map16To32Common(INT32 id, INT32 code, WPARAM32 *pwParam,
63 LPARAM *plParam)
65 switch (id)
67 case WH_MSGFILTER:
68 case WH_SYSMSGFILTER:
69 case WH_GETMESSAGE:
70 case WH_JOURNALRECORD:
72 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
73 LPMSG32 lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
75 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
76 *plParam = (LPARAM)lpmsg32;
77 break;
79 case WH_JOURNALPLAYBACK:
81 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
82 LPEVENTMSG32 lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
84 lpem32->message = lpem16->message;
85 lpem32->paramL = lpem16->paramL;
86 lpem32->paramH = lpem16->paramH;
87 lpem32->time = lpem16->time;
88 lpem32->hwnd = 0; /* FIXME */
90 *plParam = (LPARAM)lpem32;
91 break;
93 case WH_CBT:
94 switch (code)
96 case HCBT_ACTIVATE:
98 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
99 LPCBTACTIVATESTRUCT32 lpcas32 = HeapAlloc( SystemHeap, 0,
100 sizeof(*lpcas32) );
101 lpcas32->fMouse = lpcas16->fMouse;
102 lpcas32->hWndActive = lpcas16->hWndActive;
103 *plParam = (LPARAM)lpcas32;
104 break;
106 case HCBT_CLICKSKIPPED:
108 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
109 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
110 sizeof(*lpms32) );
112 STRUCT32_POINT16to32( &lpms16->pt, &lpms32->pt );
114 /* wHitTestCode may be negative, so convince compiler to do
115 correct sign extension. Yay. :| */
116 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
118 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
119 lpms32->hwnd = lpms16->hwnd;
120 *plParam = (LPARAM)lpms32;
121 break;
123 case HCBT_MOVESIZE:
125 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
126 LPRECT32 lprect32 = HeapAlloc( SystemHeap, 0,
127 sizeof(*lprect32) );
129 STRUCT32_RECT16to32( lprect16, lprect32 );
130 *plParam = (LPARAM)lprect32;
131 break;
134 break;
135 case WH_MOUSE:
137 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
138 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
139 sizeof(*lpms32) );
141 STRUCT32_POINT16to32( &lpms16->pt, &lpms32->pt );
143 /* wHitTestCode may be negative, so convince compiler to do
144 correct sign extension. Yay. :| */
145 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
146 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
147 lpms32->hwnd = lpms16->hwnd;
148 *plParam = (LPARAM)lpms32;
149 break;
151 case WH_DEBUG:
153 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
154 LPDEBUGHOOKINFO32 lpdh32 = HeapAlloc( SystemHeap, 0,
155 sizeof(*lpdh32) );
157 lpdh32->idThread = 0; /* FIXME */
158 lpdh32->idThreadInstaller = 0; /* FIXME */
159 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
160 lpdh32->wParam = lpdh16->wParam;
161 lpdh32->code = lpdh16->code;
163 /* do sign extension if it was WH_MSGFILTER */
164 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
166 *plParam = (LPARAM)lpdh32;
167 break;
169 case WH_SHELL:
170 case WH_KEYBOARD:
171 break;
173 case WH_CALLWNDPROC:
174 case WH_HARDWARE:
175 break; /* NYI */
177 default:
178 fprintf(stderr, "Unknown hook id: %d\n", id);
179 return;
184 /***********************************************************************
185 * HOOK_Map16To32A
187 static void HOOK_Map16To32A(INT32 id, INT32 code, WPARAM32 *pwParam,
188 LPARAM *plParam)
190 if (id == WH_CBT && code == HCBT_CREATEWND)
192 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
193 LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
194 sizeof(*lpcbtcw32) );
195 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
196 sizeof(*lpcbtcw32->lpcs) );
198 STRUCT32_CREATESTRUCT16to32A( lpcbtcw16->lpcs, lpcbtcw32->lpcs );
200 if (HIWORD(lpcbtcw16->lpcs->lpszName))
201 lpcbtcw32->lpcs->lpszName
202 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs->lpszName);
203 else
204 lpcbtcw32->lpcs->lpszName = (LPSTR)lpcbtcw16->lpcs->lpszName;
206 if (HIWORD(lpcbtcw16->lpcs->lpszClass))
207 lpcbtcw32->lpcs->lpszClass
208 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs->lpszClass);
209 else
210 lpcbtcw32->lpcs->lpszClass = (LPSTR)lpcbtcw16->lpcs->lpszClass;
212 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
214 *plParam = (LPARAM)lpcbtcw32;
216 else
217 HOOK_Map16To32Common( id, code, pwParam, plParam );
221 /***********************************************************************
222 * HOOK_Map16To32W
224 static void HOOK_Map16To32W(INT32 id, INT32 code, WPARAM32 *pwParam,
225 LPARAM *plParam)
227 if (id == WH_CBT && code == HCBT_CREATEWND)
229 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
230 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
231 LPCBT_CREATEWND32W lpcbtcw32 = HeapAlloc( SystemHeap, 0,
232 sizeof(*lpcbtcw32) );
233 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
234 sizeof(*lpcbtcw32->lpcs) );
236 STRUCT32_CREATESTRUCT16to32A( lpcs16,
237 (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
239 if (HIWORD(lpcs16->lpszName))
240 lpcbtcw32->lpcs->lpszName =
241 STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16->lpszName) );
242 else
243 lpcbtcw32->lpcs->lpszName = (LPWSTR)lpcs16->lpszName;
245 if (HIWORD(lpcs16->lpszClass))
246 lpcbtcw32->lpcs->lpszClass =
247 STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
248 else
249 lpcbtcw32->lpcs->lpszClass = (LPWSTR)lpcs16->lpszClass;
251 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
253 *plParam = (LPARAM)lpcbtcw32;
255 else HOOK_Map16To32Common( id, code, pwParam, plParam );
259 /***********************************************************************
260 * HOOK_UnMap16To32Common
262 static void HOOK_UnMap16To32Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
263 LPARAM lParamOrig, WPARAM32 wParam,
264 LPARAM lParam)
266 switch (id)
268 case WH_MSGFILTER:
269 case WH_SYSMSGFILTER:
270 case WH_JOURNALRECORD:
271 case WH_JOURNALPLAYBACK:
273 HeapFree( SystemHeap, 0, (LPVOID)lParam );
274 break;
277 case WH_GETMESSAGE:
279 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
280 STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
281 HeapFree( SystemHeap, 0, (LPVOID)lParam );
282 break;
285 case WH_MOUSE:
286 case WH_DEBUG:
287 HeapFree( SystemHeap, 0, (LPVOID)lParam );
288 break;
290 /* I don't think any of these need to be copied */
291 case WH_CBT:
292 switch (code)
294 case HCBT_ACTIVATE:
295 case HCBT_CLICKSKIPPED:
296 case HCBT_MOVESIZE:
297 HeapFree( SystemHeap, 0, (LPVOID)lParam);
298 break;
300 break;
302 case WH_SHELL:
303 case WH_KEYBOARD:
304 break;
306 case WH_CALLWNDPROC:
307 case WH_HARDWARE:
308 fprintf(stderr, "Can't map hook id: %d\n", id);
309 break;
311 default:
312 fprintf(stderr, "Unknown hook id: %d\n", id);
313 return;
318 /***********************************************************************
319 * HOOK_UnMap16To32A
321 static void HOOK_UnMap16To32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
322 LPARAM lParamOrig, WPARAM32 wParam,
323 LPARAM lParam)
325 if (id == WH_CBT && code == HCBT_CREATEWND)
327 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
328 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
329 HeapFree( SystemHeap, 0, lpcbtcw32 );
331 else
332 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
333 lParam);
334 return;
338 /***********************************************************************
339 * HOOK_UnMap16To32W
341 static void HOOK_UnMap16To32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
342 LPARAM lParamOrig, WPARAM32 wParam,
343 LPARAM lParam)
345 if (id == WH_CBT && code == HCBT_CREATEWND)
347 LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)lParam;
348 if (HIWORD(lpcbtcw32->lpcs->lpszName))
349 free( (LPWSTR)lpcbtcw32->lpcs->lpszName );
350 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
351 free( (LPWSTR)lpcbtcw32->lpcs->lpszClass );
352 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
353 HeapFree( SystemHeap, 0, lpcbtcw32 );
355 else
356 HOOK_UnMap16To32Common(id, code, wParamOrig, lParamOrig, wParam, lParam);
360 /***********************************************************************
361 * HOOK_Map32To16Common
363 static void HOOK_Map32To16Common(INT32 id, INT32 code, WPARAM32 *pwParam,
364 LPARAM *plParam)
366 switch (id)
368 case WH_MSGFILTER:
369 case WH_SYSMSGFILTER:
370 case WH_GETMESSAGE:
371 case WH_JOURNALRECORD:
373 LPMSG32 lpmsg32 = (LPMSG32)*plParam;
374 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
376 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
378 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
379 break;
382 case WH_JOURNALPLAYBACK:
384 LPEVENTMSG32 lpem32 = (LPEVENTMSG32)*plParam;
385 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
387 lpem16->message = lpem32->message;
388 lpem16->paramL = lpem32->paramL;
389 lpem16->paramH = lpem32->paramH;
390 lpem16->time = lpem32->time;
392 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
393 break;
396 case WH_CBT:
397 switch (code)
399 case HCBT_ACTIVATE:
401 LPCBTACTIVATESTRUCT32 lpcas32 = (LPCBTACTIVATESTRUCT32)*plParam;
402 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
404 lpcas16->fMouse = lpcas32->fMouse;
405 lpcas16->hWndActive = lpcas32->hWndActive
407 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
408 break;
411 case HCBT_CLICKSKIPPED:
413 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
414 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
416 STRUCT32_POINT32to16( &lpms32->pt, &lpms16->pt );
418 lpms16->hwnd = lpms32->hwnd;
419 lpms16->wHitTestCode = lpms32->wHitTestCode;
420 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
422 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
423 break;
426 case HCBT_MOVESIZE:
428 LPRECT32 lprect32 = (LPRECT32)*plParam;
429 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
431 STRUCT32_RECT32to16( lprect32, lprect16 );
433 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
434 break;
437 break;
439 case WH_MOUSE:
441 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
442 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
444 STRUCT32_POINT32to16( &lpms32->pt, &lpms16->pt );
446 lpms16->hwnd = lpms32->hwnd;
447 lpms16->wHitTestCode = lpms32->wHitTestCode;
448 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
450 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
451 break;
454 case WH_DEBUG:
456 LPDEBUGHOOKINFO32 lpdh32 = (LPDEBUGHOOKINFO32)*plParam;
457 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
459 lpdh16->hModuleHook = 0; /* FIXME */
460 lpdh16->reserved = 0;
461 lpdh16->lParam = lpdh32->lParam;
462 lpdh16->wParam = lpdh32->wParam;
463 lpdh16->code = lpdh32->code;
465 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
466 break;
469 case WH_SHELL:
470 case WH_KEYBOARD:
471 break;
473 case WH_CALLWNDPROC:
474 case WH_HARDWARE:
475 fprintf(stderr, "Can't map hook id: %d\n", id);
476 break;
478 default:
479 fprintf(stderr, "Unknown hook id: %d\n", id);
480 return;
485 /***********************************************************************
486 * HOOK_Map32ATo16
488 static void HOOK_Map32ATo16(INT32 id, INT32 code, WPARAM32 *pwParam,
489 LPARAM *plParam)
491 if (id == WH_CBT && code == HCBT_CREATEWND)
493 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)*plParam;
494 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
495 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
497 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
498 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
500 if (HIWORD(lpcbtcw32->lpcs->lpszName))
501 lpcs16->lpszName =
502 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
503 else
504 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
506 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
507 lpcs16->lpszClass =
508 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
509 else
510 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
512 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
514 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
516 else HOOK_Map32To16Common(id, code, pwParam, plParam);
520 /***********************************************************************
521 * HOOK_Map32WTo16
523 static void HOOK_Map32WTo16(INT32 id, INT32 code, WPARAM32 *pwParam,
524 LPARAM *plParam)
526 if (id == WH_CBT && code == HCBT_CREATEWND)
528 LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
529 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
530 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
532 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
533 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
534 lpcs16 );
536 if (HIWORD(lpcbtcw32->lpcs->lpszName))
538 LPSTR str = SEGPTR_ALLOC( lstrlen32W(lpcbtcw32->lpcs->lpszName) );
539 STRING32_UniToAnsi( str, lpcbtcw32->lpcs->lpszName );
540 lpcs16->lpszName = SEGPTR_GET( str );
542 else
543 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
545 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
547 LPSTR str = SEGPTR_ALLOC( lstrlen32W(lpcbtcw32->lpcs->lpszClass) );
548 STRING32_UniToAnsi( str, lpcbtcw32->lpcs->lpszClass );
549 lpcs16->lpszClass = SEGPTR_GET( str );
551 else
552 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
554 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
556 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
558 else HOOK_Map32To16Common(id, code, pwParam, plParam);
562 /***********************************************************************
563 * HOOK_UnMap32To16Common
565 static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
566 LPARAM lParamOrig, WPARAM32 wParam,
567 LPARAM lParam)
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_GETMESSAGE:
582 LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
584 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
585 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
586 break;
589 case WH_CBT:
590 switch (code)
592 case HCBT_ACTIVATE:
593 case HCBT_CLICKSKIPPED:
594 case HCBT_MOVESIZE:
595 SEGPTR_FREE( (LPVOID)lParam );
596 break;
598 break;
600 case WH_SHELL:
601 case WH_KEYBOARD:
602 break;
604 case WH_CALLWNDPROC:
605 case WH_HARDWARE:
606 fprintf(stderr, "Can't map hook id: %d\n", id);
607 break;
609 default:
610 fprintf(stderr, "Unknown hook id: %d\n", id);
611 return;
616 /***********************************************************************
617 * HOOK_UnMap32ATo16
619 static void HOOK_UnMap32ATo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
620 LPARAM lParamOrig, WPARAM32 wParam,
621 LPARAM lParam)
623 if (id == WH_CBT && code == HCBT_CREATEWND)
625 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
626 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
628 if (HIWORD(lpcs16->lpszName))
629 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
631 if (HIWORD(lpcs16->lpszClass))
632 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
634 SEGPTR_FREE( lpcs16 );
635 SEGPTR_FREE( lpcbtcw16 );
637 else
638 return HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
639 lParam );
640 return;
644 /***********************************************************************
645 * HOOK_UnMap32WTo16
647 static void HOOK_UnMap32WTo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
648 LPARAM lParamOrig, WPARAM32 wParam,
649 LPARAM lParam)
651 HOOK_UnMap32ATo16( id, code, wParamOrig, lParamOrig, wParam, lParam );
655 /***********************************************************************
656 * HOOK_Map32ATo32W
658 static void HOOK_Map32ATo32W(INT32 id, INT32 code, WPARAM32 *pwParam,
659 LPARAM *plParam)
661 if (id == WH_CBT && code == HCBT_CREATEWND)
663 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)*plParam;
664 LPCBT_CREATEWND32W lpcbtcwW = HeapAlloc( SystemHeap, 0,
665 sizeof(*lpcbtcwW) );
666 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
668 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
669 *lpcbtcwW->lpcs = *(LPCREATESTRUCT32W)lpcbtcwA->lpcs;
671 if (HIWORD(lpcbtcwA->lpcs->lpszName))
673 lpcbtcwW->lpcs->lpszName =
674 STRING32_DupAnsiToUni( lpcbtcwA->lpcs->lpszName );
676 else
677 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
679 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
681 lpcbtcwW->lpcs->lpszClass =
682 STRING32_DupAnsiToUni( lpcbtcwA->lpcs->lpszClass);
684 else
685 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
687 return;
691 /***********************************************************************
692 * HOOK_UnMap32ATo32W
694 static void HOOK_UnMap32ATo32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
695 LPARAM lParamOrig, WPARAM32 wParam,
696 LPARAM lParam)
698 if (id == WH_CBT && code == HCBT_CREATEWND)
700 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
701 if (HIWORD(lpcbtcwW->lpcs->lpszName))
702 free( (LPWSTR)lpcbtcwW->lpcs->lpszName );
703 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
704 free( (LPWSTR)lpcbtcwW->lpcs->lpszClass );
705 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
706 HeapFree( SystemHeap, 0, lpcbtcwW );
708 return;
712 /***********************************************************************
713 * HOOK_Map32WTo32A
715 static void HOOK_Map32WTo32A(INT32 id, INT32 code, WPARAM32 *pwParam,
716 LPARAM *plParam)
718 if (id == WH_CBT && code == HCBT_CREATEWND)
720 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)*plParam;
721 LPCBT_CREATEWND32A lpcbtcwA = HeapAlloc( SystemHeap, 0,
722 sizeof(*lpcbtcwA) );
723 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
725 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
726 *lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
728 if (HIWORD(lpcbtcwW->lpcs->lpszName))
729 lpcbtcwA->lpcs->lpszName =
730 STRING32_DupUniToAnsi( lpcbtcwW->lpcs->lpszName );
731 else
732 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
734 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
735 lpcbtcwA->lpcs->lpszClass =
736 STRING32_DupUniToAnsi( lpcbtcwW->lpcs->lpszClass);
737 else
738 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
740 return;
744 /***********************************************************************
745 * HOOK_UnMap32WTo32A
747 static void HOOK_UnMap32WTo32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
748 LPARAM lParamOrig, WPARAM32 wParam,
749 LPARAM lParam)
751 if (id == WH_CBT && code == HCBT_CREATEWND)
753 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
754 if (HIWORD(lpcbtcwA->lpcs->lpszName))
755 free( (LPSTR)lpcbtcwA->lpcs->lpszName );
756 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
757 free( (LPSTR)lpcbtcwA->lpcs->lpszClass );
758 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
759 HeapFree( SystemHeap, 0, lpcbtcwA );
761 return;
765 /***********************************************************************
766 * Map Function Tables
768 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
770 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
771 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
772 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
775 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
777 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
778 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
779 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
783 /***********************************************************************
784 * Internal Functions
787 /***********************************************************************
788 * HOOK_GetNextHook
790 * Get the next hook of a given hook.
792 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
794 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
796 if (!data || !hook) return 0;
797 if (data->next) return data->next;
798 if (!data->ownerQueue) return 0; /* Already system hook */
800 /* Now start enumerating the system hooks */
801 return HOOK_systemHooks[data->id - WH_MINHOOK];
805 /***********************************************************************
806 * HOOK_GetHook
808 * Get the first hook for a given type.
810 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
812 MESSAGEQUEUE *queue;
813 HANDLE16 hook = 0;
815 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
816 hook = queue->hooks[id - WH_MINHOOK];
817 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
818 return hook;
822 /***********************************************************************
823 * HOOK_SetHook
825 * Install a given hook.
827 static HANDLE16 HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
828 HINSTANCE16 hInst, HTASK16 hTask )
830 HOOKDATA *data;
831 HANDLE16 handle;
832 HQUEUE16 hQueue = 0;
834 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
835 if (!(hInst = GetExePtr( hInst ))) return 0;
837 dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
838 id, (UINT32)proc, hInst, hTask );
840 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
842 if (hTask) /* Task-specific hook */
844 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
845 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
846 if (!(hQueue = GetTaskQueue( hTask ))) return 0;
849 /* Create the hook structure */
851 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
852 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
853 data->proc = proc;
854 data->id = id;
855 data->ownerQueue = hQueue;
856 data->ownerModule = hInst;
857 data->inHookProc = 0;
858 data->flags = type;
860 /* Insert it in the correct linked list */
862 if (hQueue)
864 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
865 data->next = queue->hooks[id - WH_MINHOOK];
866 queue->hooks[id - WH_MINHOOK] = handle;
868 else
870 data->next = HOOK_systemHooks[id - WH_MINHOOK];
871 HOOK_systemHooks[id - WH_MINHOOK] = handle;
873 dprintf_hook( stddeb, "Setting hook %d: ret=%04x [next=%04x]\n",
874 id, handle, data->next );
875 return handle;
879 /***********************************************************************
880 * HOOK_RemoveHook
882 * Remove a hook from the list.
884 static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
886 HOOKDATA *data;
887 HANDLE16 *prevHook;
889 dprintf_hook( stddeb, "Removing hook %04x\n", hook );
891 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
892 if (data->inHookProc)
894 /* Mark it for deletion later on */
895 dprintf_hook( stddeb, "Hook still running, deletion delayed\n" );
896 data->proc = (HOOKPROC32)0;
897 return TRUE;
900 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
902 /* Remove it from the linked list */
904 if (data->ownerQueue)
906 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
907 if (!queue) return FALSE;
908 prevHook = &queue->hooks[data->id - WH_MINHOOK];
910 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
912 while (*prevHook && *prevHook != hook)
913 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
915 if (!*prevHook) return FALSE;
916 *prevHook = data->next;
917 USER_HEAP_FREE( hook );
918 return TRUE;
922 /***********************************************************************
923 * HOOK_FindValidHook
925 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
927 HOOKDATA *data;
929 for (;;)
931 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
932 if (data->proc) return hook;
933 hook = data->next;
938 /***********************************************************************
939 * HOOK_CallHook
941 * Call a hook procedure.
943 static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
944 WPARAM32 wParam, LPARAM lParam )
946 MESSAGEQUEUE *queue;
947 HANDLE16 prevHook;
948 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
949 LRESULT ret;
951 WPARAM32 wParamOrig = wParam;
952 LPARAM lParamOrig = lParam;
953 HOOK_MapFunc MapFunc;
954 HOOK_UnMapFunc UnMapFunc;
956 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
957 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
959 if (MapFunc)
960 MapFunc( data->id, code, &wParam, &lParam );
962 /* Now call it */
964 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
965 prevHook = queue->hCurHook;
966 queue->hCurHook = hook;
967 data->inHookProc = TRUE;
969 dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
970 hook, code, wParam, lParam );
972 ret = data->proc(code, wParam, lParam);
974 dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
976 data->inHookProc = FALSE;
977 queue->hCurHook = prevHook;
979 if (UnMapFunc)
980 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
982 if (!data->proc) HOOK_RemoveHook( hook );
984 return ret;
987 /***********************************************************************
988 * Exported Functions & APIs
991 /***********************************************************************
992 * HOOK_GetProc16
994 * Don't call this unless you are the if1632/thunk.c.
996 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
998 HOOKDATA *data;
999 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
1000 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
1001 if (data->flags & HOOK_WIN32) return NULL;
1002 return (HOOKPROC16)data->proc;
1006 /***********************************************************************
1007 * HOOK_IsHooked
1009 * Replacement for calling HOOK_GetHook from other modules.
1011 BOOL32 HOOK_IsHooked( INT16 id )
1013 return HOOK_GetHook( id, GetTaskQueue(0) ) != 0;
1017 /***********************************************************************
1018 * HOOK_CallHooks16
1020 * Call a hook chain.
1022 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1023 LPARAM lParam )
1025 HANDLE16 hook;
1027 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1028 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1029 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1032 /***********************************************************************
1033 * HOOK_CallHooks32A
1035 * Call a hook chain.
1037 LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
1038 LPARAM lParam )
1040 HANDLE16 hook;
1042 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1043 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1044 return HOOK_CallHook( hook, HOOK_WIN32, code, wParam, lParam );
1047 /***********************************************************************
1048 * HOOK_CallHooks32W
1050 * Call a hook chain.
1052 LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
1053 LPARAM lParam )
1055 HANDLE16 hook;
1057 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1058 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1059 return HOOK_CallHook( hook, HOOK_WIN32 | HOOK_UNICODE, code, wParam,
1060 lParam );
1064 /***********************************************************************
1065 * HOOK_ResetQueueHooks
1067 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1069 MESSAGEQUEUE *queue;
1071 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
1073 HOOKDATA* data;
1074 HHOOK hook;
1075 int id;
1076 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1078 hook = queue->hooks[id - WH_MINHOOK];
1079 while( hook )
1081 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1083 data->ownerQueue = hQueue;
1084 hook = data->next;
1085 } else break;
1091 /***********************************************************************
1092 * HOOK_FreeModuleHooks
1094 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1096 /* remove all system hooks registered by this module */
1098 HOOKDATA* hptr;
1099 HHOOK hook, next;
1100 int id;
1102 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1104 hook = HOOK_systemHooks[id - WH_MINHOOK];
1105 while( hook )
1106 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1108 next = hptr->next;
1109 if( hptr->ownerModule == hModule )
1111 hptr->inHookProc = 0;
1112 HOOK_RemoveHook(hook);
1114 hook = next;
1116 else hook = 0;
1120 /***********************************************************************
1121 * HOOK_FreeQueueHooks
1123 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1125 /* remove all hooks registered by this queue */
1127 HOOKDATA* hptr = NULL;
1128 HHOOK hook, next;
1129 int id;
1131 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1133 hook = HOOK_GetHook( id, hQueue );
1134 while( hook )
1136 next = HOOK_GetNextHook(hook);
1138 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1139 if( hptr && hptr->ownerQueue == hQueue )
1141 hptr->inHookProc = 0;
1142 HOOK_RemoveHook(hook);
1144 hook = next;
1150 /***********************************************************************
1151 * SetWindowsHook16 (USER.121)
1153 FARPROC16 SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1155 HANDLE16 handle;
1156 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1158 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1159 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1161 if (id == WH_DEBUG)
1163 fprintf( stdnimp, "WH_DEBUG is broken in 16-bit Windows.\n");
1164 return 0;
1167 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
1168 return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
1172 /***********************************************************************
1173 * SetWindowsHook32A (USER32.524)
1175 * FIXME: I don't know if this is correct
1177 HHOOK SetWindowsHook32A( INT32 id, HOOKPROC32 proc )
1179 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1181 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1182 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1184 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
1185 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1189 /***********************************************************************
1190 * SetWindowsHook32W (USER32.527)
1192 * FIXME: I don't know if this is correct
1194 HHOOK SetWindowsHook32W( INT32 id, HOOKPROC32 proc )
1196 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1198 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1199 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1201 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE,
1202 hInst, hTask );
1203 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1207 /***********************************************************************
1208 * SetWindowsHookEx16 (USER.291)
1210 HHOOK SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1211 HTASK16 hTask )
1213 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
1214 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1218 /***********************************************************************
1219 * SetWindowsHookEx32A (USER32.525)
1221 HHOOK SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1222 DWORD dwThreadID )
1224 HANDLE16 handle;
1225 HTASK16 hTask;
1227 if (dwThreadID == GetCurrentThreadId())
1228 hTask = GetCurrentTask();
1229 else
1230 hTask = LOWORD(dwThreadID);
1232 handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
1233 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1237 /***********************************************************************
1238 * SetWindowsHookEx32W (USER32.526)
1240 HHOOK SetWindowsHookEx32W( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1241 DWORD dwThreadID )
1243 HANDLE16 handle;
1244 HTASK16 hTask;
1246 if (dwThreadID == GetCurrentThreadId())
1247 hTask = GetCurrentTask();
1248 else
1249 hTask = LOWORD(dwThreadID);
1251 handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE, hInst, hTask );
1252 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1256 /***********************************************************************
1257 * UnhookWindowsHook16 (USER.234)
1259 BOOL16 UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1261 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1263 dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
1265 while (hook)
1267 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1268 if (data->proc == (HOOKPROC32)proc) break;
1269 hook = HOOK_GetNextHook( hook );
1271 if (!hook) return FALSE;
1272 return HOOK_RemoveHook( hook );
1276 /***********************************************************************
1277 * UnhookWindowsHook32 (USER32.556)
1279 BOOL32 UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
1281 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1283 dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
1285 while (hook)
1287 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1288 if (data->proc == proc) break;
1289 hook = HOOK_GetNextHook( hook );
1291 if (!hook) return FALSE;
1292 return HOOK_RemoveHook( hook );
1296 /***********************************************************************
1297 * UnhookWindowHookEx16 (USER.292)
1299 BOOL16 UnhookWindowsHookEx16( HHOOK hhook )
1301 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1302 return HOOK_RemoveHook( LOWORD(hhook) );
1306 /***********************************************************************
1307 * UnhookWindowHookEx32 (USER32.557)
1309 BOOL32 UnhookWindowsHookEx32( HHOOK hhook )
1311 return UnhookWindowsHookEx16( hhook );
1315 /***********************************************************************
1316 * CallNextHookEx16 (USER.293)
1318 * I wouldn't have separated this into 16 and 32 bit versions, but I
1319 * need a way to figure out if I need to do a mapping or not.
1321 LRESULT CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1322 LPARAM lParam )
1324 HANDLE16 next;
1326 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1327 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1329 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1333 /***********************************************************************
1334 * CallNextHookEx32 (USER32.16)
1336 * There aren't ANSI and UNICODE versions of this.
1338 LRESULT CallNextHookEx32( HHOOK hhook, INT32 code, WPARAM32 wParam,
1339 LPARAM lParam )
1341 HANDLE16 next;
1342 INT32 fromtype; /* figure out Ansi/Unicode */
1343 HOOKDATA *oldhook;
1345 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1346 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1348 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1349 fromtype = oldhook->flags & HOOK_MAPTYPE;
1351 if (!(fromtype & HOOK_WIN32))
1352 fprintf(stderr, "CallNextHookEx32: called from 16bit hook!\n");
1354 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1358 /***********************************************************************
1359 * DefHookProc16 (USER.235)
1361 LRESULT DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1362 HHOOK *hhook )
1364 /* Note: the *hhook parameter is never used, since we rely on the
1365 * current hook value from the task queue to find the next hook. */
1366 MESSAGEQUEUE *queue;
1368 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
1369 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1373 /***********************************************************************
1374 * CallMsgFilter16 (USER.123)
1376 BOOL16 CallMsgFilter16( SEGPTR msg, INT16 code )
1378 if (GetSysModalWindow16()) return FALSE;
1379 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1380 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1384 /***********************************************************************
1385 * CallMsgFilter32A (USER32.14)
1388 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1389 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1391 BOOL32 CallMsgFilter32A( LPMSG32 msg, INT32 code )
1393 if (GetSysModalWindow16()) return FALSE; /* ??? */
1394 if (HOOK_CallHooks32A( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1395 return TRUE;
1396 return HOOK_CallHooks32A( WH_MSGFILTER, code, 0, (LPARAM)msg );
1400 /***********************************************************************
1401 * CallMsgFilter32W (USER32.15)
1403 BOOL32 CallMsgFilter32W( LPMSG32 msg, INT32 code )
1405 if (GetSysModalWindow16()) return FALSE; /* ??? */
1406 if (HOOK_CallHooks32W( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1407 return TRUE;
1408 return HOOK_CallHooks32W( WH_MSGFILTER, code, 0, (LPARAM)msg );