Large-scale renaming of all Win32 functions and types to use the
[wine/multimedia.git] / windows / hook.c
blob81feb35b664ac39d137afc1803ef260e65ad7c58
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 "winuser.h"
18 #include "wine/winuser16.h"
19 #include "wine/winbase16.h"
20 #include "hook.h"
21 #include "queue.h"
22 #include "task.h"
23 #include "user.h"
24 #include "heap.h"
25 #include "struct32.h"
26 #include "winproc.h"
27 #include "debug.h"
29 #pragma pack(1)
31 /* Hook data (pointed to by a HHOOK) */
32 typedef struct
34 HANDLE16 next; /* 00 Next hook in chain */
35 HOOKPROC proc WINE_PACKED; /* 02 Hook procedure */
36 INT16 id; /* 06 Hook id (WH_xxx) */
37 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
38 HMODULE16 ownerModule; /* 0a Owner module */
39 WORD flags; /* 0c 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)(INT, INT, WPARAM *, LPARAM *);
50 typedef VOID (*HOOK_UnMapFunc)(INT, INT, WPARAM, LPARAM, WPARAM,
51 LPARAM);
53 /***********************************************************************
54 * HOOK_Map16To32Common
56 static void HOOK_Map16To32Common(INT id, INT code, WPARAM *pwParam,
57 LPARAM *plParam, BOOL bA )
60 switch( id )
62 case WH_MSGFILTER:
63 case WH_SYSMSGFILTER:
64 case WH_GETMESSAGE:
65 case WH_JOURNALRECORD:
67 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
68 LPMSG lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
70 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
71 *plParam = (LPARAM)lpmsg32;
72 break;
75 case WH_JOURNALPLAYBACK:
77 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
78 LPEVENTMSG lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
80 lpem32->message = lpem16->message;
81 lpem32->paramL = lpem16->paramL;
82 lpem32->paramH = lpem16->paramH;
83 lpem32->time = lpem16->time;
84 lpem32->hwnd = 0; /* FIXME */
86 *plParam = (LPARAM)lpem32;
87 break;
90 case WH_CALLWNDPROC:
92 LPCWPSTRUCT16 lpcwp16 = PTR_SEG_TO_LIN(*plParam);
93 LPCWPSTRUCT lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
95 lpcwp32->hwnd = lpcwp16->hwnd;
96 lpcwp32->lParam = lpcwp16->lParam;
98 if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam,
99 &lpcwp32->message, &lpcwp32->wParam,
100 &lpcwp32->lParam );
101 else WINPROC_MapMsg16To32W( lpcwp16->hwnd,lpcwp16->message, lpcwp16->wParam,
102 &lpcwp32->message, &lpcwp32->wParam,
103 &lpcwp32->lParam );
104 *plParam = (LPARAM)lpcwp32;
105 break;
108 case WH_CBT:
109 switch (code)
111 case HCBT_CREATEWND:
113 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
114 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
115 LPCBT_CREATEWNDA lpcbtcw32 = HeapAlloc( SystemHeap, 0,
116 sizeof(*lpcbtcw32) );
117 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
118 sizeof(*lpcbtcw32->lpcs) );
120 STRUCT32_CREATESTRUCT16to32A( lpcs16,
121 (LPCREATESTRUCTA)lpcbtcw32->lpcs );
123 if (HIWORD(lpcs16->lpszName))
124 lpcbtcw32->lpcs->lpszName =
125 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
126 : HEAP_strdupAtoW( SystemHeap, 0,
127 PTR_SEG_TO_LIN(lpcs16->lpszName) );
128 else
129 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
131 if (HIWORD(lpcs16->lpszClass))
132 lpcbtcw32->lpcs->lpszClass =
133 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
134 : HEAP_strdupAtoW( SystemHeap, 0,
135 PTR_SEG_TO_LIN(lpcs16->lpszClass) );
136 else
137 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
139 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
141 *plParam = (LPARAM)lpcbtcw32;
142 break;
144 case HCBT_ACTIVATE:
146 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
147 LPCBTACTIVATESTRUCT lpcas32 = HeapAlloc( SystemHeap, 0,
148 sizeof(*lpcas32) );
149 lpcas32->fMouse = lpcas16->fMouse;
150 lpcas32->hWndActive = lpcas16->hWndActive;
151 *plParam = (LPARAM)lpcas32;
152 break;
154 case HCBT_CLICKSKIPPED:
156 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
157 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( SystemHeap, 0,
158 sizeof(*lpms32) );
160 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
162 /* wHitTestCode may be negative, so convince compiler to do
163 correct sign extension. Yay. :| */
164 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
166 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
167 lpms32->hwnd = lpms16->hwnd;
168 *plParam = (LPARAM)lpms32;
169 break;
171 case HCBT_MOVESIZE:
173 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
174 LPRECT lprect32 = HeapAlloc( SystemHeap, 0,
175 sizeof(*lprect32) );
177 CONV_RECT16TO32( lprect16, lprect32 );
178 *plParam = (LPARAM)lprect32;
179 break;
182 break;
184 case WH_MOUSE:
186 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
187 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( SystemHeap, 0,
188 sizeof(*lpms32) );
190 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
192 /* wHitTestCode may be negative, so convince compiler to do
193 correct sign extension. Yay. :| */
194 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
195 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
196 lpms32->hwnd = lpms16->hwnd;
197 *plParam = (LPARAM)lpms32;
198 break;
201 case WH_DEBUG:
203 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
204 LPDEBUGHOOKINFO lpdh32 = HeapAlloc( SystemHeap, 0,
205 sizeof(*lpdh32) );
207 lpdh32->idThread = 0; /* FIXME */
208 lpdh32->idThreadInstaller = 0; /* FIXME */
209 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
210 lpdh32->wParam = lpdh16->wParam;
211 lpdh32->code = lpdh16->code;
213 /* do sign extension if it was WH_MSGFILTER */
214 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
216 *plParam = (LPARAM)lpdh32;
217 break;
220 case WH_SHELL:
221 case WH_KEYBOARD:
222 break;
224 case WH_HARDWARE:
225 case WH_FOREGROUNDIDLE:
226 case WH_CALLWNDPROCRET:
227 FIXME(hook, "\t[%i] 16to32 translation unimplemented\n", id);
232 /***********************************************************************
233 * HOOK_Map16To32A
235 static void HOOK_Map16To32A(INT id, INT code, WPARAM *pwParam,
236 LPARAM *plParam)
238 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
242 /***********************************************************************
243 * HOOK_Map16To32W
245 static void HOOK_Map16To32W(INT id, INT code, WPARAM *pwParam,
246 LPARAM *plParam)
248 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
252 /***********************************************************************
253 * HOOK_UnMap16To32Common
255 static void HOOK_UnMap16To32Common(INT id, INT code, WPARAM wParamOrig,
256 LPARAM lParamOrig, WPARAM wParam,
257 LPARAM lParam, BOOL bA)
259 switch (id)
261 case WH_MSGFILTER:
262 case WH_SYSMSGFILTER:
263 case WH_JOURNALRECORD:
264 case WH_JOURNALPLAYBACK:
266 HeapFree( SystemHeap, 0, (LPVOID)lParam );
267 break;
269 case WH_CALLWNDPROC:
271 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParam;
272 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
273 lpcwp32->lParam, 0 );
274 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
275 lpcwp32->lParam, 0 );
276 HeapFree( SystemHeap, 0, lpcwp32 );
277 break;
280 case WH_GETMESSAGE:
282 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
283 STRUCT32_MSG32to16( (LPMSG)lParam, lpmsg16 );
284 HeapFree( SystemHeap, 0, (LPVOID)lParam );
285 break;
288 case WH_MOUSE:
289 case WH_DEBUG:
291 HeapFree( SystemHeap, 0, (LPVOID)lParam );
292 break;
294 case WH_CBT:
295 switch (code)
297 case HCBT_CREATEWND:
299 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)lParam;
300 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
302 if( !bA )
304 if (HIWORD(lpcbtcw32->lpcs->lpszName))
305 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
306 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
307 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
310 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
312 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
313 } /* fall through */
315 case HCBT_ACTIVATE:
316 case HCBT_CLICKSKIPPED:
317 case HCBT_MOVESIZE:
319 HeapFree( SystemHeap, 0, (LPVOID)lParam);
320 break;
322 break;
324 case WH_SHELL:
325 case WH_KEYBOARD:
326 break;
328 case WH_HARDWARE:
329 case WH_FOREGROUNDIDLE:
330 case WH_CALLWNDPROCRET:
331 FIXME(hook, "\t[%i] skipping unmap\n", id);
332 break;
337 /***********************************************************************
338 * HOOK_UnMap16To32A
340 static void HOOK_UnMap16To32A(INT id, INT code, WPARAM wParamOrig,
341 LPARAM lParamOrig, WPARAM wParam,
342 LPARAM lParam)
344 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
345 lParam, TRUE );
349 /***********************************************************************
350 * HOOK_UnMap16To32W
352 static void HOOK_UnMap16To32W(INT id, INT code, WPARAM wParamOrig,
353 LPARAM lParamOrig, WPARAM wParam,
354 LPARAM lParam)
356 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
357 lParam, FALSE );
361 /***********************************************************************
362 * HOOK_Map32To16Common
364 static void HOOK_Map32To16Common(INT id, INT code, WPARAM *pwParam,
365 LPARAM *plParam, BOOL bA)
367 switch (id)
369 case WH_MSGFILTER:
370 case WH_SYSMSGFILTER:
371 case WH_GETMESSAGE:
372 case WH_JOURNALRECORD:
374 LPMSG lpmsg32 = (LPMSG)*plParam;
375 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
377 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
379 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
380 break;
383 case WH_JOURNALPLAYBACK:
385 LPEVENTMSG lpem32 = (LPEVENTMSG)*plParam;
386 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
388 lpem16->message = lpem32->message;
389 lpem16->paramL = lpem32->paramL;
390 lpem16->paramH = lpem32->paramH;
391 lpem16->time = lpem32->time;
393 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
394 break;
397 case WH_CALLWNDPROC:
399 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)*plParam;
400 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
402 lpcwp16->hwnd = lpcwp32->hwnd;
403 lpcwp16->lParam = lpcwp32->lParam;
405 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
406 lpcwp32->wParam, &lpcwp16->message,
407 &lpcwp16->wParam, &lpcwp16->lParam );
408 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
409 lpcwp32->wParam, &lpcwp16->message,
410 &lpcwp16->wParam, &lpcwp16->lParam );
411 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
412 break;
415 case WH_CBT:
416 switch (code)
418 case HCBT_ACTIVATE:
420 LPCBTACTIVATESTRUCT lpcas32 = (LPCBTACTIVATESTRUCT)*plParam;
421 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
423 lpcas16->fMouse = lpcas32->fMouse;
424 lpcas16->hWndActive = lpcas32->hWndActive;
426 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
427 break;
430 case HCBT_CLICKSKIPPED:
432 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
433 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
435 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
437 lpms16->hwnd = lpms32->hwnd;
438 lpms16->wHitTestCode = lpms32->wHitTestCode;
439 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
441 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
442 break;
445 case HCBT_MOVESIZE:
447 LPRECT lprect32 = (LPRECT)*plParam;
448 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
450 CONV_RECT32TO16( lprect32, lprect16 );
452 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
453 break;
456 break;
458 case WH_MOUSE:
460 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
461 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
463 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
465 lpms16->hwnd = lpms32->hwnd;
466 lpms16->wHitTestCode = lpms32->wHitTestCode;
467 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
469 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
470 break;
473 case WH_DEBUG:
475 LPDEBUGHOOKINFO lpdh32 = (LPDEBUGHOOKINFO)*plParam;
476 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
478 lpdh16->hModuleHook = 0; /* FIXME */
479 lpdh16->reserved = 0;
480 lpdh16->lParam = lpdh32->lParam;
481 lpdh16->wParam = lpdh32->wParam;
482 lpdh16->code = lpdh32->code;
484 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
485 break;
488 case WH_SHELL:
489 case WH_KEYBOARD:
490 break;
492 case WH_HARDWARE:
493 case WH_FOREGROUNDIDLE:
494 case WH_CALLWNDPROCRET:
495 FIXME(hook,"\t[%i] 32to16 translation unimplemented\n", id);
500 /***********************************************************************
501 * HOOK_Map32ATo16
503 static void HOOK_Map32ATo16(INT id, INT code, WPARAM *pwParam,
504 LPARAM *plParam)
506 if (id == WH_CBT && code == HCBT_CREATEWND)
508 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)*plParam;
509 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
510 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
512 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
513 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
515 if (HIWORD(lpcbtcw32->lpcs->lpszName))
516 lpcs16->lpszName =
517 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
518 else
519 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
521 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
522 lpcs16->lpszClass =
523 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
524 else
525 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
527 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
529 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
531 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
535 /***********************************************************************
536 * HOOK_Map32WTo16
538 static void HOOK_Map32WTo16(INT id, INT code, WPARAM *pwParam,
539 LPARAM *plParam)
541 if (id == WH_CBT && code == HCBT_CREATEWND)
543 LPSTR name, cls;
544 LPCBT_CREATEWNDW lpcbtcw32 = (LPCBT_CREATEWNDW)*plParam;
545 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
546 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
548 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
549 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA)lpcbtcw32->lpcs,
550 lpcs16 );
552 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
553 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
554 lpcs16->lpszName = SEGPTR_GET( name );
555 lpcs16->lpszClass = SEGPTR_GET( cls );
556 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
558 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
560 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
564 /***********************************************************************
565 * HOOK_UnMap32To16Common
567 static void HOOK_UnMap32To16Common(INT id, INT code, WPARAM wParamOrig,
568 LPARAM lParamOrig, WPARAM wParam,
569 LPARAM lParam, BOOL bA)
571 switch (id)
573 case WH_MSGFILTER:
574 case WH_SYSMSGFILTER:
575 case WH_JOURNALRECORD:
576 case WH_JOURNALPLAYBACK:
577 case WH_MOUSE:
578 case WH_DEBUG:
579 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
580 break;
582 case WH_CALLWNDPROC:
584 LPCWPSTRUCT16 lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
585 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParamOrig;
586 MSGPARAM16 mp16 = { lpcwp16->wParam, lpcwp16->lParam, 0 };
588 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
589 lpcwp32->lParam, &mp16 );
590 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
591 lpcwp32->lParam, &mp16 );
592 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
593 break;
596 case WH_GETMESSAGE:
598 LPMSG lpmsg32 = (LPMSG)lParamOrig;
600 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
601 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
602 break;
605 case WH_CBT:
606 switch (code)
608 case HCBT_CREATEWND:
610 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)(lParamOrig);
611 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
612 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
614 if (HIWORD(lpcs16->lpszName))
615 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
617 if (HIWORD(lpcs16->lpszClass))
618 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
620 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
622 SEGPTR_FREE( lpcs16 );
623 } /* fall through */
625 case HCBT_ACTIVATE:
626 case HCBT_CLICKSKIPPED:
627 case HCBT_MOVESIZE:
629 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
630 break;
632 break;
634 case WH_SHELL:
635 case WH_KEYBOARD:
636 break;
638 case WH_HARDWARE:
639 case WH_FOREGROUNDIDLE:
640 case WH_CALLWNDPROCRET:
641 FIXME(hook, "\t[%i] skipping unmap\n", id);
646 /***********************************************************************
647 * HOOK_UnMap32ATo16
649 static void HOOK_UnMap32ATo16(INT id, INT code, WPARAM wParamOrig,
650 LPARAM lParamOrig, WPARAM wParam,
651 LPARAM lParam)
653 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
654 lParam, TRUE );
658 /***********************************************************************
659 * HOOK_UnMap32WTo16
661 static void HOOK_UnMap32WTo16(INT id, INT code, WPARAM wParamOrig,
662 LPARAM lParamOrig, WPARAM wParam,
663 LPARAM lParam)
665 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
666 lParam, FALSE );
670 /***********************************************************************
671 * HOOK_Map32ATo32W
673 static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
674 LPARAM *plParam)
676 if (id == WH_CBT && code == HCBT_CREATEWND)
678 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
679 LPCBT_CREATEWNDW lpcbtcwW = HeapAlloc( SystemHeap, 0,
680 sizeof(*lpcbtcwW) );
681 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
683 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
684 *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
686 if (HIWORD(lpcbtcwA->lpcs->lpszName))
688 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
689 lpcbtcwA->lpcs->lpszName );
691 else
692 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
694 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
696 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
697 lpcbtcwA->lpcs->lpszClass );
699 else
700 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
701 *plParam = (LPARAM)lpcbtcwW;
703 return;
707 /***********************************************************************
708 * HOOK_UnMap32ATo32W
710 static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
711 LPARAM lParamOrig, WPARAM wParam,
712 LPARAM lParam)
714 if (id == WH_CBT && code == HCBT_CREATEWND)
716 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
717 if (HIWORD(lpcbtcwW->lpcs->lpszName))
718 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
719 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
720 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
721 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
722 HeapFree( SystemHeap, 0, lpcbtcwW );
724 return;
728 /***********************************************************************
729 * HOOK_Map32WTo32A
731 static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
732 LPARAM *plParam)
734 if (id == WH_CBT && code == HCBT_CREATEWND)
736 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
737 LPCBT_CREATEWNDA lpcbtcwA = HeapAlloc( SystemHeap, 0,
738 sizeof(*lpcbtcwA) );
739 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
741 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
742 *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
744 if (HIWORD(lpcbtcwW->lpcs->lpszName))
745 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
746 lpcbtcwW->lpcs->lpszName );
747 else
748 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
750 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
751 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
752 lpcbtcwW->lpcs->lpszClass );
753 else
754 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
755 *plParam = (LPARAM)lpcbtcwA;
757 return;
761 /***********************************************************************
762 * HOOK_UnMap32WTo32A
764 static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
765 LPARAM lParamOrig, WPARAM wParam,
766 LPARAM lParam)
768 if (id == WH_CBT && code == HCBT_CREATEWND)
770 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
771 if (HIWORD(lpcbtcwA->lpcs->lpszName))
772 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
773 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
774 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
775 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
776 HeapFree( SystemHeap, 0, lpcbtcwA );
778 return;
782 /***********************************************************************
783 * Map Function Tables
785 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
787 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
788 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
789 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
792 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
794 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
795 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
796 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
800 /***********************************************************************
801 * Internal Functions
804 /***********************************************************************
805 * HOOK_GetNextHook
807 * Get the next hook of a given hook.
809 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
811 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
813 if (!data || !hook) return 0;
814 if (data->next) return data->next;
815 if (!data->ownerQueue) return 0; /* Already system hook */
817 /* Now start enumerating the system hooks */
818 return HOOK_systemHooks[data->id - WH_MINHOOK];
822 /***********************************************************************
823 * HOOK_GetHook
825 * Get the first hook for a given type.
827 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
829 MESSAGEQUEUE *queue;
830 HANDLE16 hook = 0;
832 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
833 hook = queue->hooks[id - WH_MINHOOK];
834 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
836 QUEUE_Unlock( queue );
837 return hook;
841 /***********************************************************************
842 * HOOK_SetHook
844 * Install a given hook.
846 static HHOOK HOOK_SetHook( INT16 id, LPVOID proc, INT type,
847 HMODULE16 hModule, DWORD dwThreadId )
849 HOOKDATA *data;
850 HANDLE16 handle;
851 HQUEUE16 hQueue = 0;
853 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
855 TRACE(hook, "Setting hook %d: %08x %04x %08lx\n",
856 id, (UINT)proc, hModule, dwThreadId );
858 /* Create task queue if none present */
859 GetFastQueue16();
861 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput16(FALSE);
863 if (dwThreadId) /* Task-specific hook */
865 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
866 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
867 if (!(hQueue = GetThreadQueue16( dwThreadId )))
868 return 0;
871 /* Create the hook structure */
873 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
874 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
875 data->proc = proc;
876 data->id = id;
877 data->ownerQueue = hQueue;
878 data->ownerModule = hModule;
879 data->flags = type;
881 /* Insert it in the correct linked list */
883 if (hQueue)
885 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
886 data->next = queue->hooks[id - WH_MINHOOK];
887 queue->hooks[id - WH_MINHOOK] = handle;
888 QUEUE_Unlock( queue );
890 else
892 data->next = HOOK_systemHooks[id - WH_MINHOOK];
893 HOOK_systemHooks[id - WH_MINHOOK] = handle;
895 TRACE(hook, "Setting hook %d: ret=%04x [next=%04x]\n",
896 id, handle, data->next );
898 return (HHOOK)( handle? MAKELONG( handle, HOOK_MAGIC ) : 0 );
902 /***********************************************************************
903 * HOOK_RemoveHook
905 * Remove a hook from the list.
907 static BOOL HOOK_RemoveHook( HANDLE16 hook )
909 HOOKDATA *data;
910 HANDLE16 *prevHook;
912 TRACE(hook, "Removing hook %04x\n", hook );
914 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
915 if (data->flags & HOOK_INUSE)
917 /* Mark it for deletion later on */
918 WARN(hook, "Hook still running, deletion delayed\n" );
919 data->proc = (HOOKPROC)0;
920 return TRUE;
923 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput16(TRUE);
925 /* Remove it from the linked list */
927 if (data->ownerQueue)
929 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( data->ownerQueue );
930 if (!queue) return FALSE;
931 prevHook = &queue->hooks[data->id - WH_MINHOOK];
932 QUEUE_Unlock( queue );
934 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
936 while (*prevHook && *prevHook != hook)
937 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
939 if (!*prevHook) return FALSE;
940 *prevHook = data->next;
941 USER_HEAP_FREE( hook );
942 return TRUE;
946 /***********************************************************************
947 * HOOK_FindValidHook
949 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
951 HOOKDATA *data;
953 for (;;)
955 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
956 if (data->proc) return hook;
957 hook = data->next;
962 /***********************************************************************
963 * HOOK_CallHook
965 * Call a hook procedure.
967 static LRESULT HOOK_CallHook( HANDLE16 hook, INT fromtype, INT code,
968 WPARAM wParam, LPARAM lParam )
970 MESSAGEQUEUE *queue;
971 HANDLE16 prevHook;
972 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
973 LRESULT ret;
975 WPARAM wParamOrig = wParam;
976 LPARAM lParamOrig = lParam;
977 HOOK_MapFunc MapFunc;
978 HOOK_UnMapFunc UnMapFunc;
980 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
981 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
983 if (MapFunc)
984 MapFunc( data->id, code, &wParam, &lParam );
986 /* Now call it */
988 if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
989 prevHook = queue->hCurHook;
990 queue->hCurHook = hook;
991 data->flags |= HOOK_INUSE;
993 TRACE(hook, "Calling hook %04x: %d %08x %08lx\n",
994 hook, code, wParam, lParam );
996 ret = data->proc(code, wParam, lParam);
998 TRACE(hook, "Ret hook %04x = %08lx\n", hook, ret );
1000 data->flags &= ~HOOK_INUSE;
1001 queue->hCurHook = prevHook;
1003 QUEUE_Unlock( queue );
1005 if (UnMapFunc)
1006 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
1008 if (!data->proc) HOOK_RemoveHook( hook );
1010 return ret;
1013 /***********************************************************************
1014 * Exported Functions & APIs
1017 /***********************************************************************
1018 * HOOK_GetProc16
1020 * Don't call this unless you are the if1632/thunk.c.
1022 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
1024 HOOKDATA *data;
1025 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
1026 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
1027 if ((data->flags & HOOK_MAPTYPE) != HOOK_WIN16) return NULL;
1028 return (HOOKPROC16)data->proc;
1032 /***********************************************************************
1033 * HOOK_IsHooked
1035 * Replacement for calling HOOK_GetHook from other modules.
1037 BOOL HOOK_IsHooked( INT16 id )
1039 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1040 avoid queue being created if someone wants to merely check ... */
1042 return HOOK_GetHook( id, GetThreadQueue16(0) ) != 0;
1046 /***********************************************************************
1047 * HOOK_CallHooks16
1049 * Call a hook chain.
1051 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1052 LPARAM lParam )
1054 HANDLE16 hook;
1056 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1057 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1058 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1061 /***********************************************************************
1062 * HOOK_CallHooks32A
1064 * Call a hook chain.
1066 LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
1067 LPARAM lParam )
1069 HANDLE16 hook;
1071 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1072 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1073 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1076 /***********************************************************************
1077 * HOOK_CallHooks32W
1079 * Call a hook chain.
1081 LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
1082 LPARAM lParam )
1084 HANDLE16 hook;
1086 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1087 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1088 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1089 lParam );
1093 /***********************************************************************
1094 * HOOK_ResetQueueHooks
1096 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1098 MESSAGEQUEUE *queue;
1100 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
1102 HOOKDATA* data;
1103 HHOOK hook;
1104 int id;
1105 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1107 hook = queue->hooks[id - WH_MINHOOK];
1108 while( hook )
1110 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1112 data->ownerQueue = hQueue;
1113 hook = data->next;
1114 } else break;
1118 QUEUE_Unlock( queue );
1122 /***********************************************************************
1123 * HOOK_FreeModuleHooks
1125 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1127 /* remove all system hooks registered by this module */
1129 HOOKDATA* hptr;
1130 HHOOK hook, next;
1131 int id;
1133 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1135 hook = HOOK_systemHooks[id - WH_MINHOOK];
1136 while( hook )
1137 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1139 next = hptr->next;
1140 if( hptr->ownerModule == hModule )
1142 hptr->flags &= HOOK_MAPTYPE;
1143 HOOK_RemoveHook(hook);
1145 hook = next;
1147 else hook = 0;
1151 /***********************************************************************
1152 * HOOK_FreeQueueHooks
1154 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1156 /* remove all hooks registered by this queue */
1158 HOOKDATA* hptr = NULL;
1159 HHOOK hook, next;
1160 int id;
1162 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1164 hook = HOOK_GetHook( id, hQueue );
1165 while( hook )
1167 next = HOOK_GetNextHook(hook);
1169 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1170 if( hptr && hptr->ownerQueue == hQueue )
1172 hptr->flags &= HOOK_MAPTYPE;
1173 HOOK_RemoveHook(hook);
1175 hook = next;
1181 /***********************************************************************
1182 * SetWindowsHook16 (USER.121)
1184 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1186 HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
1188 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1189 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1191 return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
1194 /***********************************************************************
1195 * SetWindowsHook32A (USER32.525)
1197 HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
1199 return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
1202 /***********************************************************************
1203 * SetWindowsHook32W (USER32.528)
1205 HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
1207 return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
1211 /***********************************************************************
1212 * SetWindowsHookEx16 (USER.291)
1214 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1215 HTASK16 hTask )
1217 if (id == WH_DEBUG)
1219 FIXME(hook, "WH_DEBUG is broken in 16-bit Windows.\n");
1220 return 0;
1222 return HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), (DWORD)hTask );
1225 /***********************************************************************
1226 * SetWindowsHookEx32A (USER32.526)
1228 HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
1229 DWORD dwThreadId )
1231 return HOOK_SetHook( id, proc, HOOK_WIN32A, MapHModuleLS(hInst), dwThreadId );
1234 /***********************************************************************
1235 * SetWindowsHookEx32W (USER32.527)
1237 HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
1238 DWORD dwThreadId )
1240 return HOOK_SetHook( id, proc, HOOK_WIN32W, MapHModuleLS(hInst), dwThreadId );
1244 /***********************************************************************
1245 * UnhookWindowsHook16 (USER.234)
1247 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1249 return UnhookWindowsHook( id, (HOOKPROC)proc );
1252 /***********************************************************************
1253 * UnhookWindowsHook32 (USER32.557)
1255 BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
1257 HANDLE16 hook = HOOK_GetHook( id, GetFastQueue16() );
1259 TRACE(hook, "%d %08lx\n", id, (DWORD)proc );
1261 while (hook)
1263 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1264 if (data->proc == proc) break;
1265 hook = HOOK_GetNextHook( hook );
1267 if (!hook) return FALSE;
1268 return HOOK_RemoveHook( hook );
1272 /***********************************************************************
1273 * UnhookWindowHookEx16 (USER.292)
1275 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1277 return UnhookWindowsHookEx( hhook );
1280 /***********************************************************************
1281 * UnhookWindowHookEx32 (USER32.558)
1283 BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
1285 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1286 return HOOK_RemoveHook( LOWORD(hhook) );
1290 /***********************************************************************
1291 * CallNextHookEx16 (USER.293)
1293 * I wouldn't have separated this into 16 and 32 bit versions, but I
1294 * need a way to figure out if I need to do a mapping or not.
1296 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1297 LPARAM lParam )
1299 HANDLE16 next;
1301 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1302 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1304 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1308 /***********************************************************************
1309 * CallNextHookEx32 (USER32.17)
1311 * There aren't ANSI and UNICODE versions of this.
1313 LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
1314 LPARAM lParam )
1316 HANDLE16 next;
1317 INT fromtype; /* figure out Ansi/Unicode */
1318 HOOKDATA *oldhook;
1320 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1321 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1323 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1324 fromtype = oldhook->flags & HOOK_MAPTYPE;
1326 if (fromtype == HOOK_WIN16)
1327 ERR(hook, "called from 16bit hook!\n");
1329 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1333 /***********************************************************************
1334 * DefHookProc16 (USER.235)
1336 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1337 HHOOK *hhook )
1339 /* Note: the *hhook parameter is never used, since we rely on the
1340 * current hook value from the task queue to find the next hook. */
1341 MESSAGEQUEUE *queue;
1342 LRESULT ret;
1344 if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
1345 ret = CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1346 QUEUE_Unlock( queue );
1347 return ret;
1351 /***********************************************************************
1352 * CallMsgFilter16 (USER.123)
1354 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1356 if (GetSysModalWindow16()) return FALSE;
1357 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1358 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1362 /***********************************************************************
1363 * WIN16_CallMsgFilter32 (USER.823)
1365 BOOL16 WINAPI CallMsgFilter32_16( SEGPTR msg16_32, INT16 code, BOOL16 wHaveParamHigh )
1367 MSG32_16 *lpmsg16_32 = (MSG32_16 *)PTR_SEG_TO_LIN(msg16_32);
1369 if (wHaveParamHigh == FALSE)
1371 lpmsg16_32->wParamHigh = 0;
1372 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1373 return CallMsgFilter16(msg16_32, code);
1375 else
1377 MSG msg32;
1378 BOOL16 ret;
1380 msg32.hwnd = lpmsg16_32->msg.hwnd;
1381 msg32.message = lpmsg16_32->msg.message;
1382 msg32.wParam =
1383 MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
1384 msg32.lParam = lpmsg16_32->msg.lParam;
1385 msg32.time = lpmsg16_32->msg.time;
1386 msg32.pt.x = (INT)lpmsg16_32->msg.pt.x;
1387 msg32.pt.y = (INT)lpmsg16_32->msg.pt.y;
1389 ret = (BOOL16)CallMsgFilterA(&msg32, (INT)code);
1391 lpmsg16_32->msg.hwnd = msg32.hwnd;
1392 lpmsg16_32->msg.message = msg32.message;
1393 lpmsg16_32->msg.wParam = LOWORD(msg32.wParam);
1394 lpmsg16_32->msg.lParam = msg32.lParam;
1395 lpmsg16_32->msg.time = msg32.time;
1396 lpmsg16_32->msg.pt.x = (INT16)msg32.pt.x;
1397 lpmsg16_32->msg.pt.y = (INT16)msg32.pt.y;
1398 lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
1400 return ret;
1405 /***********************************************************************
1406 * CallMsgFilter32A (USER32.15)
1409 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1410 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1412 BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
1414 if (GetSysModalWindow16()) return FALSE; /* ??? */
1415 if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1416 return TRUE;
1417 return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
1421 /***********************************************************************
1422 * CallMsgFilter32W (USER32.16)
1424 BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
1426 if (GetSysModalWindow16()) return FALSE; /* ??? */
1427 if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1428 return TRUE;
1429 return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );