2 * Windows hook functions
4 * Copyright 1994, 1995 Alexandre Julliard
7 * Based on investigations by Alex Korobka
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.
18 #include "wine/winuser16.h"
19 #include "wine/winbase16.h"
29 DEFAULT_DEBUG_CHANNEL(hook
)
33 /* Hook data (pointed to by a HHOOK) */
36 HANDLE16 next
; /* 00 Next hook in chain */
37 HOOKPROC proc WINE_PACKED
; /* 02 Hook procedure */
38 INT16 id
; /* 06 Hook id (WH_xxx) */
39 HQUEUE16 ownerQueue
; /* 08 Owner queue (0 for system hook) */
40 HMODULE16 ownerModule
; /* 0a Owner module */
41 WORD flags
; /* 0c flags */
46 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
48 /* This should probably reside in USER heap */
49 static HANDLE16 HOOK_systemHooks
[WH_NB_HOOKS
] = { 0, };
51 typedef VOID (*HOOK_MapFunc
)(INT
, INT
, WPARAM
*, LPARAM
*);
52 typedef VOID (*HOOK_UnMapFunc
)(INT
, INT
, WPARAM
, LPARAM
, WPARAM
,
55 /***********************************************************************
56 * HOOK_Map16To32Common
58 static void HOOK_Map16To32Common(INT id
, INT code
, WPARAM
*pwParam
,
59 LPARAM
*plParam
, BOOL bA
)
67 case WH_JOURNALRECORD
:
69 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(*plParam
);
70 LPMSG lpmsg32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpmsg32
) );
72 STRUCT32_MSG16to32( lpmsg16
, lpmsg32
);
73 *plParam
= (LPARAM
)lpmsg32
;
77 case WH_JOURNALPLAYBACK
:
79 LPEVENTMSG16 lpem16
= PTR_SEG_TO_LIN(*plParam
);
80 LPEVENTMSG lpem32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpem32
) );
82 lpem32
->message
= lpem16
->message
;
83 lpem32
->paramL
= lpem16
->paramL
;
84 lpem32
->paramH
= lpem16
->paramH
;
85 lpem32
->time
= lpem16
->time
;
86 lpem32
->hwnd
= 0; /* FIXME */
88 *plParam
= (LPARAM
)lpem32
;
94 LPCWPSTRUCT16 lpcwp16
= PTR_SEG_TO_LIN(*plParam
);
95 LPCWPSTRUCT lpcwp32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcwp32
) );
97 lpcwp32
->hwnd
= lpcwp16
->hwnd
;
98 lpcwp32
->lParam
= lpcwp16
->lParam
;
100 if (bA
) WINPROC_MapMsg16To32A( lpcwp16
->message
, lpcwp16
->wParam
,
101 &lpcwp32
->message
, &lpcwp32
->wParam
,
103 else WINPROC_MapMsg16To32W( lpcwp16
->hwnd
,lpcwp16
->message
, lpcwp16
->wParam
,
104 &lpcwp32
->message
, &lpcwp32
->wParam
,
106 *plParam
= (LPARAM
)lpcwp32
;
115 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(*plParam
);
116 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
117 LPCBT_CREATEWNDA lpcbtcw32
= HeapAlloc( SystemHeap
, 0,
118 sizeof(*lpcbtcw32
) );
119 lpcbtcw32
->lpcs
= HeapAlloc( SystemHeap
, 0,
120 sizeof(*lpcbtcw32
->lpcs
) );
122 STRUCT32_CREATESTRUCT16to32A( lpcs16
,
123 (LPCREATESTRUCTA
)lpcbtcw32
->lpcs
);
125 if (HIWORD(lpcs16
->lpszName
))
126 lpcbtcw32
->lpcs
->lpszName
=
127 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszName
)
128 : HEAP_strdupAtoW( SystemHeap
, 0,
129 PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
131 lpcbtcw32
->lpcs
->lpszName
= (LPCSTR
)lpcs16
->lpszName
;
133 if (HIWORD(lpcs16
->lpszClass
))
134 lpcbtcw32
->lpcs
->lpszClass
=
135 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszClass
)
136 : HEAP_strdupAtoW( SystemHeap
, 0,
137 PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
139 lpcbtcw32
->lpcs
->lpszClass
= (LPCSTR
)lpcs16
->lpszClass
;
141 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
143 *plParam
= (LPARAM
)lpcbtcw32
;
148 LPCBTACTIVATESTRUCT16 lpcas16
= PTR_SEG_TO_LIN(*plParam
);
149 LPCBTACTIVATESTRUCT lpcas32
= HeapAlloc( SystemHeap
, 0,
151 lpcas32
->fMouse
= lpcas16
->fMouse
;
152 lpcas32
->hWndActive
= lpcas16
->hWndActive
;
153 *plParam
= (LPARAM
)lpcas32
;
156 case HCBT_CLICKSKIPPED
:
158 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
159 LPMOUSEHOOKSTRUCT lpms32
= HeapAlloc( SystemHeap
, 0,
162 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
164 /* wHitTestCode may be negative, so convince compiler to do
165 correct sign extension. Yay. :| */
166 lpms32
->wHitTestCode
= (INT
)((INT16
)lpms16
->wHitTestCode
);
168 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
169 lpms32
->hwnd
= lpms16
->hwnd
;
170 *plParam
= (LPARAM
)lpms32
;
175 LPRECT16 lprect16
= PTR_SEG_TO_LIN(*plParam
);
176 LPRECT lprect32
= HeapAlloc( SystemHeap
, 0,
179 CONV_RECT16TO32( lprect16
, lprect32
);
180 *plParam
= (LPARAM
)lprect32
;
188 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
189 LPMOUSEHOOKSTRUCT lpms32
= HeapAlloc( SystemHeap
, 0,
192 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
194 /* wHitTestCode may be negative, so convince compiler to do
195 correct sign extension. Yay. :| */
196 lpms32
->wHitTestCode
= (INT
)((INT16
)lpms16
->wHitTestCode
);
197 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
198 lpms32
->hwnd
= lpms16
->hwnd
;
199 *plParam
= (LPARAM
)lpms32
;
205 LPDEBUGHOOKINFO16 lpdh16
= PTR_SEG_TO_LIN(*plParam
);
206 LPDEBUGHOOKINFO lpdh32
= HeapAlloc( SystemHeap
, 0,
209 lpdh32
->idThread
= 0; /* FIXME */
210 lpdh32
->idThreadInstaller
= 0; /* FIXME */
211 lpdh32
->lParam
= lpdh16
->lParam
; /* FIXME Check for sign ext */
212 lpdh32
->wParam
= lpdh16
->wParam
;
213 lpdh32
->code
= lpdh16
->code
;
215 /* do sign extension if it was WH_MSGFILTER */
216 if (*pwParam
== 0xffff) *pwParam
= WH_MSGFILTER
;
218 *plParam
= (LPARAM
)lpdh32
;
227 case WH_FOREGROUNDIDLE
:
228 case WH_CALLWNDPROCRET
:
229 FIXME(hook
, "\t[%i] 16to32 translation unimplemented\n", id
);
234 /***********************************************************************
237 static void HOOK_Map16To32A(INT id
, INT code
, WPARAM
*pwParam
,
240 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, TRUE
);
244 /***********************************************************************
247 static void HOOK_Map16To32W(INT id
, INT code
, WPARAM
*pwParam
,
250 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, FALSE
);
254 /***********************************************************************
255 * HOOK_UnMap16To32Common
257 static void HOOK_UnMap16To32Common(INT id
, INT code
, WPARAM wParamOrig
,
258 LPARAM lParamOrig
, WPARAM wParam
,
259 LPARAM lParam
, BOOL bA
)
264 case WH_SYSMSGFILTER
:
265 case WH_JOURNALRECORD
:
266 case WH_JOURNALPLAYBACK
:
268 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
273 LPCWPSTRUCT lpcwp32
= (LPCWPSTRUCT
)lParam
;
274 if (bA
) WINPROC_UnmapMsg16To32A( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
275 lpcwp32
->lParam
, 0 );
276 else WINPROC_UnmapMsg16To32W( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
277 lpcwp32
->lParam
, 0 );
278 HeapFree( SystemHeap
, 0, lpcwp32
);
284 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(lParamOrig
);
285 STRUCT32_MSG32to16( (LPMSG
)lParam
, lpmsg16
);
286 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
293 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
301 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)lParam
;
302 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParamOrig
);
306 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
307 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszName
);
308 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
309 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszClass
);
312 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
314 HeapFree( SystemHeap
, 0, lpcbtcw32
->lpcs
);
318 case HCBT_CLICKSKIPPED
:
321 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
331 case WH_FOREGROUNDIDLE
:
332 case WH_CALLWNDPROCRET
:
333 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
339 /***********************************************************************
342 static void HOOK_UnMap16To32A(INT id
, INT code
, WPARAM wParamOrig
,
343 LPARAM lParamOrig
, WPARAM wParam
,
346 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
351 /***********************************************************************
354 static void HOOK_UnMap16To32W(INT id
, INT code
, WPARAM wParamOrig
,
355 LPARAM lParamOrig
, WPARAM wParam
,
358 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
363 /***********************************************************************
364 * HOOK_Map32To16Common
366 static void HOOK_Map32To16Common(INT id
, INT code
, WPARAM
*pwParam
,
367 LPARAM
*plParam
, BOOL bA
)
372 case WH_SYSMSGFILTER
:
374 case WH_JOURNALRECORD
:
376 LPMSG lpmsg32
= (LPMSG
)*plParam
;
377 LPMSG16 lpmsg16
= SEGPTR_NEW( MSG16
);
379 STRUCT32_MSG32to16( lpmsg32
, lpmsg16
);
381 *plParam
= (LPARAM
)SEGPTR_GET( lpmsg16
);
385 case WH_JOURNALPLAYBACK
:
387 LPEVENTMSG lpem32
= (LPEVENTMSG
)*plParam
;
388 LPEVENTMSG16 lpem16
= SEGPTR_NEW( EVENTMSG16
);
390 lpem16
->message
= lpem32
->message
;
391 lpem16
->paramL
= lpem32
->paramL
;
392 lpem16
->paramH
= lpem32
->paramH
;
393 lpem16
->time
= lpem32
->time
;
395 *plParam
= (LPARAM
)SEGPTR_GET( lpem16
);
401 LPCWPSTRUCT lpcwp32
= (LPCWPSTRUCT
)*plParam
;
402 LPCWPSTRUCT16 lpcwp16
= SEGPTR_NEW( CWPSTRUCT16
);
404 lpcwp16
->hwnd
= lpcwp32
->hwnd
;
405 lpcwp16
->lParam
= lpcwp32
->lParam
;
407 if (bA
) WINPROC_MapMsg32ATo16( lpcwp32
->hwnd
, lpcwp32
->message
,
408 lpcwp32
->wParam
, &lpcwp16
->message
,
409 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
410 else WINPROC_MapMsg32WTo16( lpcwp32
->hwnd
, lpcwp32
->message
,
411 lpcwp32
->wParam
, &lpcwp16
->message
,
412 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
413 *plParam
= (LPARAM
)SEGPTR_GET( lpcwp16
);
422 LPCBTACTIVATESTRUCT lpcas32
= (LPCBTACTIVATESTRUCT
)*plParam
;
423 LPCBTACTIVATESTRUCT16 lpcas16
=SEGPTR_NEW( CBTACTIVATESTRUCT16
);
425 lpcas16
->fMouse
= lpcas32
->fMouse
;
426 lpcas16
->hWndActive
= lpcas32
->hWndActive
;
428 *plParam
= (LPARAM
)SEGPTR_GET( lpcas16
);
432 case HCBT_CLICKSKIPPED
:
434 LPMOUSEHOOKSTRUCT lpms32
= (LPMOUSEHOOKSTRUCT
)*plParam
;
435 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
437 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
439 lpms16
->hwnd
= lpms32
->hwnd
;
440 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
441 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
443 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
449 LPRECT lprect32
= (LPRECT
)*plParam
;
450 LPRECT16 lprect16
= SEGPTR_NEW( RECT16
);
452 CONV_RECT32TO16( lprect32
, lprect16
);
454 *plParam
= (LPARAM
)SEGPTR_GET( lprect16
);
462 LPMOUSEHOOKSTRUCT lpms32
= (LPMOUSEHOOKSTRUCT
)*plParam
;
463 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
465 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
467 lpms16
->hwnd
= lpms32
->hwnd
;
468 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
469 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
471 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
477 LPDEBUGHOOKINFO lpdh32
= (LPDEBUGHOOKINFO
)*plParam
;
478 LPDEBUGHOOKINFO16 lpdh16
= SEGPTR_NEW( DEBUGHOOKINFO16
);
480 lpdh16
->hModuleHook
= 0; /* FIXME */
481 lpdh16
->reserved
= 0;
482 lpdh16
->lParam
= lpdh32
->lParam
;
483 lpdh16
->wParam
= lpdh32
->wParam
;
484 lpdh16
->code
= lpdh32
->code
;
486 *plParam
= (LPARAM
)SEGPTR_GET( lpdh16
);
495 case WH_FOREGROUNDIDLE
:
496 case WH_CALLWNDPROCRET
:
497 FIXME(hook
,"\t[%i] 32to16 translation unimplemented\n", id
);
502 /***********************************************************************
505 static void HOOK_Map32ATo16(INT id
, INT code
, WPARAM
*pwParam
,
508 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
510 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)*plParam
;
511 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
512 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
514 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
515 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32
->lpcs
, lpcs16
);
517 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
519 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszName
) );
521 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
523 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
525 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszClass
) );
527 lpcs16
->lpszClass
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszClass
;
529 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
531 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
533 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, TRUE
);
537 /***********************************************************************
540 static void HOOK_Map32WTo16(INT id
, INT code
, WPARAM
*pwParam
,
543 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
546 LPCBT_CREATEWNDW lpcbtcw32
= (LPCBT_CREATEWNDW
)*plParam
;
547 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
548 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
550 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
551 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA
)lpcbtcw32
->lpcs
,
554 name
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszName
);
555 cls
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszClass
);
556 lpcs16
->lpszName
= SEGPTR_GET( name
);
557 lpcs16
->lpszClass
= SEGPTR_GET( cls
);
558 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
560 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
562 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, FALSE
);
566 /***********************************************************************
567 * HOOK_UnMap32To16Common
569 static void HOOK_UnMap32To16Common(INT id
, INT code
, WPARAM wParamOrig
,
570 LPARAM lParamOrig
, WPARAM wParam
,
571 LPARAM lParam
, BOOL bA
)
576 case WH_SYSMSGFILTER
:
577 case WH_JOURNALRECORD
:
578 case WH_JOURNALPLAYBACK
:
581 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
586 LPCWPSTRUCT16 lpcwp16
= (LPCWPSTRUCT16
)PTR_SEG_TO_LIN(lParam
);
587 LPCWPSTRUCT lpcwp32
= (LPCWPSTRUCT
)lParamOrig
;
590 mp16
.wParam
= lpcwp16
->wParam
;
591 mp16
.lParam
= lpcwp16
->lParam
;
594 if (bA
) WINPROC_UnmapMsg32ATo16( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
595 lpcwp32
->lParam
, &mp16
);
596 else WINPROC_UnmapMsg32WTo16( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
597 lpcwp32
->lParam
, &mp16
);
598 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
604 LPMSG lpmsg32
= (LPMSG
)lParamOrig
;
606 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
607 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
616 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)(lParamOrig
);
617 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParam
);
618 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
620 if (HIWORD(lpcs16
->lpszName
))
621 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
623 if (HIWORD(lpcs16
->lpszClass
))
624 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
626 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
628 SEGPTR_FREE( lpcs16
);
632 case HCBT_CLICKSKIPPED
:
635 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
645 case WH_FOREGROUNDIDLE
:
646 case WH_CALLWNDPROCRET
:
647 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
652 /***********************************************************************
655 static void HOOK_UnMap32ATo16(INT id
, INT code
, WPARAM wParamOrig
,
656 LPARAM lParamOrig
, WPARAM wParam
,
659 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
664 /***********************************************************************
667 static void HOOK_UnMap32WTo16(INT id
, INT code
, WPARAM wParamOrig
,
668 LPARAM lParamOrig
, WPARAM wParam
,
671 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
676 /***********************************************************************
679 static void HOOK_Map32ATo32W(INT id
, INT code
, WPARAM
*pwParam
,
682 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
684 LPCBT_CREATEWNDA lpcbtcwA
= (LPCBT_CREATEWNDA
)*plParam
;
685 LPCBT_CREATEWNDW lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
687 lpcbtcwW
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwW
->lpcs
) );
689 lpcbtcwW
->hwndInsertAfter
= lpcbtcwA
->hwndInsertAfter
;
690 *lpcbtcwW
->lpcs
= *(LPCREATESTRUCTW
)lpcbtcwA
->lpcs
;
692 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
694 lpcbtcwW
->lpcs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
695 lpcbtcwA
->lpcs
->lpszName
);
698 lpcbtcwW
->lpcs
->lpszName
= (LPWSTR
)lpcbtcwA
->lpcs
->lpszName
;
700 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
702 lpcbtcwW
->lpcs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
703 lpcbtcwA
->lpcs
->lpszClass
);
706 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
707 *plParam
= (LPARAM
)lpcbtcwW
;
713 /***********************************************************************
716 static void HOOK_UnMap32ATo32W(INT id
, INT code
, WPARAM wParamOrig
,
717 LPARAM lParamOrig
, WPARAM wParam
,
720 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
722 LPCBT_CREATEWNDW lpcbtcwW
= (LPCBT_CREATEWNDW
)lParam
;
723 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
724 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszName
);
725 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
726 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszClass
);
727 HeapFree( SystemHeap
, 0, lpcbtcwW
->lpcs
);
728 HeapFree( SystemHeap
, 0, lpcbtcwW
);
734 /***********************************************************************
737 static void HOOK_Map32WTo32A(INT id
, INT code
, WPARAM
*pwParam
,
740 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
742 LPCBT_CREATEWNDW lpcbtcwW
= (LPCBT_CREATEWNDW
)*plParam
;
743 LPCBT_CREATEWNDA lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
745 lpcbtcwA
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwA
->lpcs
) );
747 lpcbtcwA
->hwndInsertAfter
= lpcbtcwW
->hwndInsertAfter
;
748 *lpcbtcwA
->lpcs
= *(LPCREATESTRUCTA
)lpcbtcwW
->lpcs
;
750 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
751 lpcbtcwA
->lpcs
->lpszName
= HEAP_strdupWtoA( SystemHeap
, 0,
752 lpcbtcwW
->lpcs
->lpszName
);
754 lpcbtcwA
->lpcs
->lpszName
= (LPSTR
)lpcbtcwW
->lpcs
->lpszName
;
756 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
757 lpcbtcwA
->lpcs
->lpszClass
= HEAP_strdupWtoA( SystemHeap
, 0,
758 lpcbtcwW
->lpcs
->lpszClass
);
760 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
761 *plParam
= (LPARAM
)lpcbtcwA
;
767 /***********************************************************************
770 static void HOOK_UnMap32WTo32A(INT id
, INT code
, WPARAM wParamOrig
,
771 LPARAM lParamOrig
, WPARAM wParam
,
774 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
776 LPCBT_CREATEWNDA lpcbtcwA
= (LPCBT_CREATEWNDA
)lParam
;
777 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
778 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszName
);
779 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
780 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszClass
);
781 HeapFree( SystemHeap
, 0, lpcbtcwA
->lpcs
);
782 HeapFree( SystemHeap
, 0, lpcbtcwA
);
788 /***********************************************************************
789 * Map Function Tables
791 static const HOOK_MapFunc HOOK_MapFuncs
[3][3] =
793 { NULL
, HOOK_Map16To32A
, HOOK_Map16To32W
},
794 { HOOK_Map32ATo16
, NULL
, HOOK_Map32ATo32W
},
795 { HOOK_Map32WTo16
, HOOK_Map32WTo32A
, NULL
}
798 static const HOOK_UnMapFunc HOOK_UnMapFuncs
[3][3] =
800 { NULL
, HOOK_UnMap16To32A
, HOOK_UnMap16To32W
},
801 { HOOK_UnMap32ATo16
, NULL
, HOOK_UnMap32ATo32W
},
802 { HOOK_UnMap32WTo16
, HOOK_UnMap32WTo32A
, NULL
}
806 /***********************************************************************
810 /***********************************************************************
813 * Get the next hook of a given hook.
815 static HANDLE16
HOOK_GetNextHook( HANDLE16 hook
)
817 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( hook
);
819 if (!data
|| !hook
) return 0;
820 if (data
->next
) return data
->next
;
821 if (!data
->ownerQueue
) return 0; /* Already system hook */
823 /* Now start enumerating the system hooks */
824 return HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
828 /***********************************************************************
831 * Get the first hook for a given type.
833 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
838 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
839 hook
= queue
->hooks
[id
- WH_MINHOOK
];
840 if (!hook
) hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
842 QUEUE_Unlock( queue
);
847 /***********************************************************************
850 * Install a given hook.
852 static HHOOK
HOOK_SetHook( INT16 id
, LPVOID proc
, INT type
,
853 HMODULE16 hModule
, DWORD dwThreadId
)
859 if ((id
< WH_MINHOOK
) || (id
> WH_MAXHOOK
)) return 0;
861 TRACE(hook
, "Setting hook %d: %08x %04x %08lx\n",
862 id
, (UINT
)proc
, hModule
, dwThreadId
);
864 /* Create task queue if none present */
867 if (id
== WH_JOURNALPLAYBACK
) EnableHardwareInput16(FALSE
);
869 if (dwThreadId
) /* Task-specific hook */
871 if ((id
== WH_JOURNALRECORD
) || (id
== WH_JOURNALPLAYBACK
) ||
872 (id
== WH_SYSMSGFILTER
)) return 0; /* System-only hooks */
873 if (!(hQueue
= GetThreadQueue16( dwThreadId
)))
877 /* Create the hook structure */
879 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
880 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
883 data
->ownerQueue
= hQueue
;
884 data
->ownerModule
= hModule
;
887 /* Insert it in the correct linked list */
891 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
);
892 data
->next
= queue
->hooks
[id
- WH_MINHOOK
];
893 queue
->hooks
[id
- WH_MINHOOK
] = handle
;
894 QUEUE_Unlock( queue
);
898 data
->next
= HOOK_systemHooks
[id
- WH_MINHOOK
];
899 HOOK_systemHooks
[id
- WH_MINHOOK
] = handle
;
901 TRACE(hook
, "Setting hook %d: ret=%04x [next=%04x]\n",
902 id
, handle
, data
->next
);
904 return (HHOOK
)( handle
? MAKELONG( handle
, HOOK_MAGIC
) : 0 );
908 /***********************************************************************
911 * Remove a hook from the list.
913 static BOOL
HOOK_RemoveHook( HANDLE16 hook
)
918 TRACE(hook
, "Removing hook %04x\n", hook
);
920 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return FALSE
;
921 if (data
->flags
& HOOK_INUSE
)
923 /* Mark it for deletion later on */
924 WARN(hook
, "Hook still running, deletion delayed\n" );
925 data
->proc
= (HOOKPROC
)0;
929 if (data
->id
== WH_JOURNALPLAYBACK
) EnableHardwareInput16(TRUE
);
931 /* Remove it from the linked list */
933 if (data
->ownerQueue
)
935 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)QUEUE_Lock( data
->ownerQueue
);
936 if (!queue
) return FALSE
;
937 prevHook
= &queue
->hooks
[data
->id
- WH_MINHOOK
];
938 QUEUE_Unlock( queue
);
940 else prevHook
= &HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
942 while (*prevHook
&& *prevHook
!= hook
)
943 prevHook
= &((HOOKDATA
*)USER_HEAP_LIN_ADDR(*prevHook
))->next
;
945 if (!*prevHook
) return FALSE
;
946 *prevHook
= data
->next
;
947 USER_HEAP_FREE( hook
);
952 /***********************************************************************
955 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
961 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
962 if (data
->proc
) return hook
;
968 /***********************************************************************
971 * Call a hook procedure.
973 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT fromtype
, INT code
,
974 WPARAM wParam
, LPARAM lParam
)
978 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
981 WPARAM wParamOrig
= wParam
;
982 LPARAM lParamOrig
= lParam
;
983 HOOK_MapFunc MapFunc
;
984 HOOK_UnMapFunc UnMapFunc
;
986 MapFunc
= HOOK_MapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
987 UnMapFunc
= HOOK_UnMapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
990 MapFunc( data
->id
, code
, &wParam
, &lParam
);
994 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue16() ))) return 0;
995 prevHook
= queue
->hCurHook
;
996 queue
->hCurHook
= hook
;
997 data
->flags
|= HOOK_INUSE
;
999 TRACE(hook
, "Calling hook %04x: %d %08x %08lx\n",
1000 hook
, code
, wParam
, lParam
);
1002 ret
= data
->proc(code
, wParam
, lParam
);
1004 /* Grrr. While the hook procedure is supposed to have an LRESULT return
1005 value even in Win16, it seems that for those hook types where the
1006 return value is interpreted as BOOL, Windows doesn't actually check
1007 the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on
1008 that, because they neglect to clear DX ... */
1009 if ( (data
->flags
& HOOK_MAPTYPE
) == HOOK_WIN16
1010 && data
->id
!= WH_JOURNALPLAYBACK
)
1011 ret
= LOWORD( ret
);
1013 TRACE(hook
, "Ret hook %04x = %08lx\n", hook
, ret
);
1015 data
->flags
&= ~HOOK_INUSE
;
1016 queue
->hCurHook
= prevHook
;
1018 QUEUE_Unlock( queue
);
1021 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
1023 if (!data
->proc
) HOOK_RemoveHook( hook
);
1028 /***********************************************************************
1029 * Exported Functions & APIs
1032 /***********************************************************************
1035 * Don't call this unless you are the if1632/thunk.c.
1037 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
1040 if (HIWORD(hhook
) != HOOK_MAGIC
) return NULL
;
1041 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) ))) return NULL
;
1042 if ((data
->flags
& HOOK_MAPTYPE
) != HOOK_WIN16
) return NULL
;
1043 return (HOOKPROC16
)data
->proc
;
1047 /***********************************************************************
1050 * Replacement for calling HOOK_GetHook from other modules.
1052 BOOL
HOOK_IsHooked( INT16 id
)
1054 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1055 avoid queue being created if someone wants to merely check ... */
1057 return HOOK_GetHook( id
, GetThreadQueue16(0) ) != 0;
1061 /***********************************************************************
1064 * Call a hook chain.
1066 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1071 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1072 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1073 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1076 /***********************************************************************
1079 * Call a hook chain.
1081 LRESULT
HOOK_CallHooksA( INT id
, INT code
, WPARAM wParam
,
1086 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1087 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1088 return HOOK_CallHook( hook
, HOOK_WIN32A
, code
, wParam
, lParam
);
1091 /***********************************************************************
1094 * Call a hook chain.
1096 LRESULT
HOOK_CallHooksW( INT id
, INT code
, WPARAM wParam
,
1101 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1102 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1103 return HOOK_CallHook( hook
, HOOK_WIN32W
, code
, wParam
,
1108 /***********************************************************************
1109 * HOOK_ResetQueueHooks
1111 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1113 MESSAGEQUEUE
*queue
;
1115 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
1120 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1122 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1125 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1127 data
->ownerQueue
= hQueue
;
1133 QUEUE_Unlock( queue
);
1137 /***********************************************************************
1138 * HOOK_FreeModuleHooks
1140 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1142 /* remove all system hooks registered by this module */
1148 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1150 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1152 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1155 if( hptr
->ownerModule
== hModule
)
1157 hptr
->flags
&= HOOK_MAPTYPE
;
1158 HOOK_RemoveHook(hook
);
1166 /***********************************************************************
1167 * HOOK_FreeQueueHooks
1169 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1171 /* remove all hooks registered by this queue */
1173 HOOKDATA
* hptr
= NULL
;
1177 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1179 hook
= HOOK_GetHook( id
, hQueue
);
1182 next
= HOOK_GetNextHook(hook
);
1184 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1185 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1187 hptr
->flags
&= HOOK_MAPTYPE
;
1188 HOOK_RemoveHook(hook
);
1196 /***********************************************************************
1197 * SetWindowsHook16 (USER.121)
1199 FARPROC16 WINAPI
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1201 HINSTANCE16 hInst
= FarGetOwner16( HIWORD(proc
) );
1203 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1204 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1206 return (FARPROC16
)SetWindowsHookEx16( id
, proc
, hInst
, hTask
);
1209 /***********************************************************************
1210 * SetWindowsHook32A (USER32.525)
1212 HHOOK WINAPI
SetWindowsHookA( INT id
, HOOKPROC proc
)
1214 return SetWindowsHookExA( id
, proc
, 0, GetCurrentThreadId() );
1217 /***********************************************************************
1218 * SetWindowsHook32W (USER32.528)
1220 HHOOK WINAPI
SetWindowsHookW( INT id
, HOOKPROC proc
)
1222 return SetWindowsHookExW( id
, proc
, 0, GetCurrentThreadId() );
1226 /***********************************************************************
1227 * SetWindowsHookEx16 (USER.291)
1229 HHOOK WINAPI
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1234 FIXME(hook
, "WH_DEBUG is broken in 16-bit Windows.\n");
1237 return HOOK_SetHook( id
, proc
, HOOK_WIN16
, GetExePtr(hInst
), (DWORD
)hTask
);
1240 /***********************************************************************
1241 * SetWindowsHookEx32A (USER32.526)
1243 HHOOK WINAPI
SetWindowsHookExA( INT id
, HOOKPROC proc
, HINSTANCE hInst
,
1246 return HOOK_SetHook( id
, proc
, HOOK_WIN32A
, MapHModuleLS(hInst
), dwThreadId
);
1249 /***********************************************************************
1250 * SetWindowsHookEx32W (USER32.527)
1252 HHOOK WINAPI
SetWindowsHookExW( INT id
, HOOKPROC proc
, HINSTANCE hInst
,
1255 return HOOK_SetHook( id
, proc
, HOOK_WIN32W
, MapHModuleLS(hInst
), dwThreadId
);
1259 /***********************************************************************
1260 * UnhookWindowsHook16 (USER.234)
1262 BOOL16 WINAPI
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1264 return UnhookWindowsHook( id
, (HOOKPROC
)proc
);
1267 /***********************************************************************
1268 * UnhookWindowsHook32 (USER32.557)
1270 BOOL WINAPI
UnhookWindowsHook( INT id
, HOOKPROC proc
)
1272 HANDLE16 hook
= HOOK_GetHook( id
, GetFastQueue16() );
1274 TRACE(hook
, "%d %08lx\n", id
, (DWORD
)proc
);
1278 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1279 if (data
->proc
== proc
) break;
1280 hook
= HOOK_GetNextHook( hook
);
1282 if (!hook
) return FALSE
;
1283 return HOOK_RemoveHook( hook
);
1287 /***********************************************************************
1288 * UnhookWindowHookEx16 (USER.292)
1290 BOOL16 WINAPI
UnhookWindowsHookEx16( HHOOK hhook
)
1292 return UnhookWindowsHookEx( hhook
);
1295 /***********************************************************************
1296 * UnhookWindowHookEx32 (USER32.558)
1298 BOOL WINAPI
UnhookWindowsHookEx( HHOOK hhook
)
1300 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1301 return HOOK_RemoveHook( LOWORD(hhook
) );
1305 /***********************************************************************
1306 * CallNextHookEx16 (USER.293)
1308 * I wouldn't have separated this into 16 and 32 bit versions, but I
1309 * need a way to figure out if I need to do a mapping or not.
1311 LRESULT WINAPI
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1316 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1317 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1319 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1323 /***********************************************************************
1324 * CallNextHookEx32 (USER32.17)
1326 * There aren't ANSI and UNICODE versions of this.
1328 LRESULT WINAPI
CallNextHookEx( HHOOK hhook
, INT code
, WPARAM wParam
,
1332 INT fromtype
; /* figure out Ansi/Unicode */
1335 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1336 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1338 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1339 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1341 if (fromtype
== HOOK_WIN16
)
1342 ERR(hook
, "called from 16bit hook!\n");
1344 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1348 /***********************************************************************
1349 * DefHookProc16 (USER.235)
1351 LRESULT WINAPI
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1354 /* Note: the *hhook parameter is never used, since we rely on the
1355 * current hook value from the task queue to find the next hook. */
1356 MESSAGEQUEUE
*queue
;
1359 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue16() ))) return 0;
1360 ret
= CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1361 QUEUE_Unlock( queue
);
1366 /***********************************************************************
1367 * CallMsgFilter16 (USER.123)
1369 BOOL16 WINAPI
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1371 if (GetSysModalWindow16()) return FALSE
;
1372 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1373 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1377 /***********************************************************************
1378 * WIN16_CallMsgFilter32 (USER.823)
1380 BOOL16 WINAPI
CallMsgFilter32_16( SEGPTR msg16_32
, INT16 code
, BOOL16 wHaveParamHigh
)
1382 MSG32_16
*lpmsg16_32
= (MSG32_16
*)PTR_SEG_TO_LIN(msg16_32
);
1384 if (wHaveParamHigh
== FALSE
)
1386 lpmsg16_32
->wParamHigh
= 0;
1387 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1388 return CallMsgFilter16(msg16_32
, code
);
1395 msg32
.hwnd
= lpmsg16_32
->msg
.hwnd
;
1396 msg32
.message
= lpmsg16_32
->msg
.message
;
1398 MAKELONG(lpmsg16_32
->msg
.wParam
, lpmsg16_32
->wParamHigh
);
1399 msg32
.lParam
= lpmsg16_32
->msg
.lParam
;
1400 msg32
.time
= lpmsg16_32
->msg
.time
;
1401 msg32
.pt
.x
= (INT
)lpmsg16_32
->msg
.pt
.x
;
1402 msg32
.pt
.y
= (INT
)lpmsg16_32
->msg
.pt
.y
;
1404 ret
= (BOOL16
)CallMsgFilterA(&msg32
, (INT
)code
);
1406 lpmsg16_32
->msg
.hwnd
= msg32
.hwnd
;
1407 lpmsg16_32
->msg
.message
= msg32
.message
;
1408 lpmsg16_32
->msg
.wParam
= LOWORD(msg32
.wParam
);
1409 lpmsg16_32
->msg
.lParam
= msg32
.lParam
;
1410 lpmsg16_32
->msg
.time
= msg32
.time
;
1411 lpmsg16_32
->msg
.pt
.x
= (INT16
)msg32
.pt
.x
;
1412 lpmsg16_32
->msg
.pt
.y
= (INT16
)msg32
.pt
.y
;
1413 lpmsg16_32
->wParamHigh
= HIWORD(msg32
.wParam
);
1420 /***********************************************************************
1421 * CallMsgFilter32A (USER32.15)
1424 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1425 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1427 BOOL WINAPI
CallMsgFilterA( LPMSG msg
, INT code
)
1429 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1430 if (HOOK_CallHooksA( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1432 return HOOK_CallHooksA( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1436 /***********************************************************************
1437 * CallMsgFilter32W (USER32.16)
1439 BOOL WINAPI
CallMsgFilterW( LPMSG msg
, INT code
)
1441 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1442 if (HOOK_CallHooksW( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1444 return HOOK_CallHooksW( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);