Release 961222
[wine/multimedia.git] / windows / hook.c
blobf5dd48a8d3dc5ab8efd493de84ac6631eef1a928
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 "stackframe.h"
22 #include "user.h"
23 #include "heap.h"
24 #include "struct32.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 = HEAP_strdupAtoW( SystemHeap, 0,
241 PTR_SEG_TO_LIN(lpcs16->lpszName) );
242 else
243 lpcbtcw32->lpcs->lpszName = (LPWSTR)lpcs16->lpszName;
245 if (HIWORD(lpcs16->lpszClass))
246 lpcbtcw32->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
247 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 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
350 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
351 HeapFree( SystemHeap, 0, (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 LPSTR name, cls;
529 LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
530 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
531 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
533 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
534 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
535 lpcs16 );
537 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
538 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
539 lpcs16->lpszName = SEGPTR_GET( name );
540 lpcs16->lpszClass = SEGPTR_GET( cls );
541 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
543 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
545 else HOOK_Map32To16Common(id, code, pwParam, plParam);
549 /***********************************************************************
550 * HOOK_UnMap32To16Common
552 static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
553 LPARAM lParamOrig, WPARAM32 wParam,
554 LPARAM lParam)
556 switch (id)
558 case WH_MSGFILTER:
559 case WH_SYSMSGFILTER:
560 case WH_JOURNALRECORD:
561 case WH_JOURNALPLAYBACK:
562 case WH_MOUSE:
563 case WH_DEBUG:
564 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
565 break;
567 case WH_GETMESSAGE:
569 LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
571 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
572 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
573 break;
576 case WH_CBT:
577 switch (code)
579 case HCBT_ACTIVATE:
580 case HCBT_CLICKSKIPPED:
581 case HCBT_MOVESIZE:
582 SEGPTR_FREE( (LPVOID)lParam );
583 break;
585 break;
587 case WH_SHELL:
588 case WH_KEYBOARD:
589 break;
591 case WH_CALLWNDPROC:
592 case WH_HARDWARE:
593 fprintf(stderr, "Can't map hook id: %d\n", id);
594 break;
596 default:
597 fprintf(stderr, "Unknown hook id: %d\n", id);
598 return;
603 /***********************************************************************
604 * HOOK_UnMap32ATo16
606 static void HOOK_UnMap32ATo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
607 LPARAM lParamOrig, WPARAM32 wParam,
608 LPARAM lParam)
610 if (id == WH_CBT && code == HCBT_CREATEWND)
612 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
613 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
615 if (HIWORD(lpcs16->lpszName))
616 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
618 if (HIWORD(lpcs16->lpszClass))
619 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
621 SEGPTR_FREE( lpcs16 );
622 SEGPTR_FREE( lpcbtcw16 );
624 else
625 return HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
626 lParam );
627 return;
631 /***********************************************************************
632 * HOOK_UnMap32WTo16
634 static void HOOK_UnMap32WTo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
635 LPARAM lParamOrig, WPARAM32 wParam,
636 LPARAM lParam)
638 HOOK_UnMap32ATo16( id, code, wParamOrig, lParamOrig, wParam, lParam );
642 /***********************************************************************
643 * HOOK_Map32ATo32W
645 static void HOOK_Map32ATo32W(INT32 id, INT32 code, WPARAM32 *pwParam,
646 LPARAM *plParam)
648 if (id == WH_CBT && code == HCBT_CREATEWND)
650 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)*plParam;
651 LPCBT_CREATEWND32W lpcbtcwW = HeapAlloc( SystemHeap, 0,
652 sizeof(*lpcbtcwW) );
653 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
655 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
656 *lpcbtcwW->lpcs = *(LPCREATESTRUCT32W)lpcbtcwA->lpcs;
658 if (HIWORD(lpcbtcwA->lpcs->lpszName))
660 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
661 lpcbtcwA->lpcs->lpszName );
663 else
664 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
666 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
668 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
669 lpcbtcwA->lpcs->lpszClass );
671 else
672 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
674 return;
678 /***********************************************************************
679 * HOOK_UnMap32ATo32W
681 static void HOOK_UnMap32ATo32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
682 LPARAM lParamOrig, WPARAM32 wParam,
683 LPARAM lParam)
685 if (id == WH_CBT && code == HCBT_CREATEWND)
687 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
688 if (HIWORD(lpcbtcwW->lpcs->lpszName))
689 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
690 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
691 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
692 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
693 HeapFree( SystemHeap, 0, lpcbtcwW );
695 return;
699 /***********************************************************************
700 * HOOK_Map32WTo32A
702 static void HOOK_Map32WTo32A(INT32 id, INT32 code, WPARAM32 *pwParam,
703 LPARAM *plParam)
705 if (id == WH_CBT && code == HCBT_CREATEWND)
707 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)*plParam;
708 LPCBT_CREATEWND32A lpcbtcwA = HeapAlloc( SystemHeap, 0,
709 sizeof(*lpcbtcwA) );
710 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
712 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
713 *lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
715 if (HIWORD(lpcbtcwW->lpcs->lpszName))
716 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
717 lpcbtcwW->lpcs->lpszName );
718 else
719 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
721 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
722 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
723 lpcbtcwW->lpcs->lpszClass );
724 else
725 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
727 return;
731 /***********************************************************************
732 * HOOK_UnMap32WTo32A
734 static void HOOK_UnMap32WTo32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
735 LPARAM lParamOrig, WPARAM32 wParam,
736 LPARAM lParam)
738 if (id == WH_CBT && code == HCBT_CREATEWND)
740 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
741 if (HIWORD(lpcbtcwA->lpcs->lpszName))
742 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
743 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
744 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
745 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
746 HeapFree( SystemHeap, 0, lpcbtcwA );
748 return;
752 /***********************************************************************
753 * Map Function Tables
755 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
757 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
758 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
759 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
762 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
764 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
765 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
766 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
770 /***********************************************************************
771 * Internal Functions
774 /***********************************************************************
775 * HOOK_GetNextHook
777 * Get the next hook of a given hook.
779 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
781 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
783 if (!data || !hook) return 0;
784 if (data->next) return data->next;
785 if (!data->ownerQueue) return 0; /* Already system hook */
787 /* Now start enumerating the system hooks */
788 return HOOK_systemHooks[data->id - WH_MINHOOK];
792 /***********************************************************************
793 * HOOK_GetHook
795 * Get the first hook for a given type.
797 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
799 MESSAGEQUEUE *queue;
800 HANDLE16 hook = 0;
802 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
803 hook = queue->hooks[id - WH_MINHOOK];
804 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
805 return hook;
809 /***********************************************************************
810 * HOOK_SetHook
812 * Install a given hook.
814 static HANDLE16 HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
815 HINSTANCE16 hInst, HTASK16 hTask )
817 HOOKDATA *data;
818 HANDLE16 handle;
819 HQUEUE16 hQueue = 0;
821 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
822 if (!(hInst = GetExePtr( hInst ))) return 0;
824 dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
825 id, (UINT32)proc, hInst, hTask );
827 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
829 if (hTask) /* Task-specific hook */
831 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
832 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
833 if (!(hQueue = GetTaskQueue( hTask ))) return 0;
836 /* Create the hook structure */
838 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
839 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
840 data->proc = proc;
841 data->id = id;
842 data->ownerQueue = hQueue;
843 data->ownerModule = hInst;
844 data->inHookProc = 0;
845 data->flags = type;
847 /* Insert it in the correct linked list */
849 if (hQueue)
851 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
852 data->next = queue->hooks[id - WH_MINHOOK];
853 queue->hooks[id - WH_MINHOOK] = handle;
855 else
857 data->next = HOOK_systemHooks[id - WH_MINHOOK];
858 HOOK_systemHooks[id - WH_MINHOOK] = handle;
860 dprintf_hook( stddeb, "Setting hook %d: ret=%04x [next=%04x]\n",
861 id, handle, data->next );
862 return handle;
866 /***********************************************************************
867 * HOOK_RemoveHook
869 * Remove a hook from the list.
871 static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
873 HOOKDATA *data;
874 HANDLE16 *prevHook;
876 dprintf_hook( stddeb, "Removing hook %04x\n", hook );
878 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
879 if (data->inHookProc)
881 /* Mark it for deletion later on */
882 dprintf_hook( stddeb, "Hook still running, deletion delayed\n" );
883 data->proc = (HOOKPROC32)0;
884 return TRUE;
887 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
889 /* Remove it from the linked list */
891 if (data->ownerQueue)
893 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
894 if (!queue) return FALSE;
895 prevHook = &queue->hooks[data->id - WH_MINHOOK];
897 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
899 while (*prevHook && *prevHook != hook)
900 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
902 if (!*prevHook) return FALSE;
903 *prevHook = data->next;
904 USER_HEAP_FREE( hook );
905 return TRUE;
909 /***********************************************************************
910 * HOOK_FindValidHook
912 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
914 HOOKDATA *data;
916 for (;;)
918 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
919 if (data->proc) return hook;
920 hook = data->next;
925 /***********************************************************************
926 * HOOK_CallHook
928 * Call a hook procedure.
930 static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
931 WPARAM32 wParam, LPARAM lParam )
933 MESSAGEQUEUE *queue;
934 HANDLE16 prevHook;
935 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
936 LRESULT ret;
937 WORD old_ds;
939 WPARAM32 wParamOrig = wParam;
940 LPARAM lParamOrig = lParam;
941 HOOK_MapFunc MapFunc;
942 HOOK_UnMapFunc UnMapFunc;
944 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
945 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
947 if (MapFunc)
948 MapFunc( data->id, code, &wParam, &lParam );
950 /* Now call it */
952 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
953 prevHook = queue->hCurHook;
954 queue->hCurHook = hook;
955 data->inHookProc = TRUE;
957 dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
958 hook, code, wParam, lParam );
960 /* Set DS = SS to call hook procedure */
961 old_ds = CURRENT_DS;
962 CURRENT_DS = IF1632_Saved16_ss;
963 ret = data->proc(code, wParam, lParam);
964 CURRENT_DS = old_ds;
966 dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
968 data->inHookProc = FALSE;
969 queue->hCurHook = prevHook;
971 if (UnMapFunc)
972 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
974 if (!data->proc) HOOK_RemoveHook( hook );
976 return ret;
979 /***********************************************************************
980 * Exported Functions & APIs
983 /***********************************************************************
984 * HOOK_GetProc16
986 * Don't call this unless you are the if1632/thunk.c.
988 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
990 HOOKDATA *data;
991 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
992 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
993 if (data->flags & HOOK_WIN32) return NULL;
994 return (HOOKPROC16)data->proc;
998 /***********************************************************************
999 * HOOK_IsHooked
1001 * Replacement for calling HOOK_GetHook from other modules.
1003 BOOL32 HOOK_IsHooked( INT16 id )
1005 return HOOK_GetHook( id, GetTaskQueue(0) ) != 0;
1009 /***********************************************************************
1010 * HOOK_CallHooks16
1012 * Call a hook chain.
1014 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1015 LPARAM lParam )
1017 HANDLE16 hook;
1019 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1020 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1021 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1024 /***********************************************************************
1025 * HOOK_CallHooks32A
1027 * Call a hook chain.
1029 LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
1030 LPARAM lParam )
1032 HANDLE16 hook;
1034 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1035 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1036 return HOOK_CallHook( hook, HOOK_WIN32, code, wParam, lParam );
1039 /***********************************************************************
1040 * HOOK_CallHooks32W
1042 * Call a hook chain.
1044 LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
1045 LPARAM lParam )
1047 HANDLE16 hook;
1049 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1050 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1051 return HOOK_CallHook( hook, HOOK_WIN32 | HOOK_UNICODE, code, wParam,
1052 lParam );
1056 /***********************************************************************
1057 * HOOK_ResetQueueHooks
1059 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1061 MESSAGEQUEUE *queue;
1063 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
1065 HOOKDATA* data;
1066 HHOOK hook;
1067 int id;
1068 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1070 hook = queue->hooks[id - WH_MINHOOK];
1071 while( hook )
1073 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1075 data->ownerQueue = hQueue;
1076 hook = data->next;
1077 } else break;
1083 /***********************************************************************
1084 * HOOK_FreeModuleHooks
1086 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1088 /* remove all system hooks registered by this module */
1090 HOOKDATA* hptr;
1091 HHOOK hook, next;
1092 int id;
1094 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1096 hook = HOOK_systemHooks[id - WH_MINHOOK];
1097 while( hook )
1098 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1100 next = hptr->next;
1101 if( hptr->ownerModule == hModule )
1103 hptr->inHookProc = 0;
1104 HOOK_RemoveHook(hook);
1106 hook = next;
1108 else hook = 0;
1112 /***********************************************************************
1113 * HOOK_FreeQueueHooks
1115 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1117 /* remove all hooks registered by this queue */
1119 HOOKDATA* hptr = NULL;
1120 HHOOK hook, next;
1121 int id;
1123 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1125 hook = HOOK_GetHook( id, hQueue );
1126 while( hook )
1128 next = HOOK_GetNextHook(hook);
1130 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1131 if( hptr && hptr->ownerQueue == hQueue )
1133 hptr->inHookProc = 0;
1134 HOOK_RemoveHook(hook);
1136 hook = next;
1142 /***********************************************************************
1143 * SetWindowsHook16 (USER.121)
1145 FARPROC16 SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1147 HANDLE16 handle;
1148 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1150 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1151 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1153 if (id == WH_DEBUG)
1155 fprintf( stdnimp, "WH_DEBUG is broken in 16-bit Windows.\n");
1156 return 0;
1159 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
1160 return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
1164 /***********************************************************************
1165 * SetWindowsHook32A (USER32.524)
1167 * FIXME: I don't know if this is correct
1169 HHOOK SetWindowsHook32A( INT32 id, HOOKPROC32 proc )
1171 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1173 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1174 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1176 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
1177 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1181 /***********************************************************************
1182 * SetWindowsHook32W (USER32.527)
1184 * FIXME: I don't know if this is correct
1186 HHOOK SetWindowsHook32W( INT32 id, HOOKPROC32 proc )
1188 HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
1190 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1191 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1193 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE,
1194 hInst, hTask );
1195 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1199 /***********************************************************************
1200 * SetWindowsHookEx16 (USER.291)
1202 HHOOK SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1203 HTASK16 hTask )
1205 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
1206 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1210 /***********************************************************************
1211 * SetWindowsHookEx32A (USER32.525)
1213 HHOOK SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1214 DWORD dwThreadID )
1216 HANDLE16 handle;
1217 HTASK16 hTask;
1219 if (dwThreadID == GetCurrentThreadId())
1220 hTask = GetCurrentTask();
1221 else
1222 hTask = LOWORD(dwThreadID);
1224 handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
1225 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1229 /***********************************************************************
1230 * SetWindowsHookEx32W (USER32.526)
1232 HHOOK SetWindowsHookEx32W( 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_WIN32 | HOOK_UNICODE, hInst, hTask );
1244 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1248 /***********************************************************************
1249 * UnhookWindowsHook16 (USER.234)
1251 BOOL16 UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1253 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1255 dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
1257 while (hook)
1259 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1260 if (data->proc == (HOOKPROC32)proc) break;
1261 hook = HOOK_GetNextHook( hook );
1263 if (!hook) return FALSE;
1264 return HOOK_RemoveHook( hook );
1268 /***********************************************************************
1269 * UnhookWindowsHook32 (USER32.556)
1271 BOOL32 UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
1273 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1275 dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
1277 while (hook)
1279 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1280 if (data->proc == proc) break;
1281 hook = HOOK_GetNextHook( hook );
1283 if (!hook) return FALSE;
1284 return HOOK_RemoveHook( hook );
1288 /***********************************************************************
1289 * UnhookWindowHookEx16 (USER.292)
1291 BOOL16 UnhookWindowsHookEx16( HHOOK hhook )
1293 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1294 return HOOK_RemoveHook( LOWORD(hhook) );
1298 /***********************************************************************
1299 * UnhookWindowHookEx32 (USER32.557)
1301 BOOL32 UnhookWindowsHookEx32( HHOOK hhook )
1303 return UnhookWindowsHookEx16( hhook );
1307 /***********************************************************************
1308 * CallNextHookEx16 (USER.293)
1310 * I wouldn't have separated this into 16 and 32 bit versions, but I
1311 * need a way to figure out if I need to do a mapping or not.
1313 LRESULT CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1314 LPARAM lParam )
1316 HANDLE16 next;
1318 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1319 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1321 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1325 /***********************************************************************
1326 * CallNextHookEx32 (USER32.16)
1328 * There aren't ANSI and UNICODE versions of this.
1330 LRESULT CallNextHookEx32( HHOOK hhook, INT32 code, WPARAM32 wParam,
1331 LPARAM lParam )
1333 HANDLE16 next;
1334 INT32 fromtype; /* figure out Ansi/Unicode */
1335 HOOKDATA *oldhook;
1337 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1338 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1340 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1341 fromtype = oldhook->flags & HOOK_MAPTYPE;
1343 if (!(fromtype & HOOK_WIN32))
1344 fprintf(stderr, "CallNextHookEx32: called from 16bit hook!\n");
1346 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1350 /***********************************************************************
1351 * DefHookProc16 (USER.235)
1353 LRESULT DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1354 HHOOK *hhook )
1356 /* Note: the *hhook parameter is never used, since we rely on the
1357 * current hook value from the task queue to find the next hook. */
1358 MESSAGEQUEUE *queue;
1360 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
1361 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1365 /***********************************************************************
1366 * CallMsgFilter16 (USER.123)
1368 BOOL16 CallMsgFilter16( SEGPTR msg, INT16 code )
1370 if (GetSysModalWindow16()) return FALSE;
1371 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1372 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1376 /***********************************************************************
1377 * CallMsgFilter32A (USER32.14)
1380 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1381 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1383 BOOL32 CallMsgFilter32A( LPMSG32 msg, INT32 code )
1385 if (GetSysModalWindow16()) return FALSE; /* ??? */
1386 if (HOOK_CallHooks32A( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1387 return TRUE;
1388 return HOOK_CallHooks32A( WH_MSGFILTER, code, 0, (LPARAM)msg );
1392 /***********************************************************************
1393 * CallMsgFilter32W (USER32.15)
1395 BOOL32 CallMsgFilter32W( LPMSG32 msg, INT32 code )
1397 if (GetSysModalWindow16()) return FALSE; /* ??? */
1398 if (HOOK_CallHooks32W( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1399 return TRUE;
1400 return HOOK_CallHooks32W( WH_MSGFILTER, code, 0, (LPARAM)msg );