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"
31 /* Hook data (pointed to by a HHOOK) */
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 */
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
,
53 /***********************************************************************
54 * HOOK_Map16To32Common
56 static void HOOK_Map16To32Common(INT id
, INT code
, WPARAM
*pwParam
,
57 LPARAM
*plParam
, BOOL bA
)
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
;
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
;
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
,
101 else WINPROC_MapMsg16To32W( lpcwp16
->hwnd
,lpcwp16
->message
, lpcwp16
->wParam
,
102 &lpcwp32
->message
, &lpcwp32
->wParam
,
104 *plParam
= (LPARAM
)lpcwp32
;
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
) );
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
) );
137 lpcbtcw32
->lpcs
->lpszClass
= (LPCSTR
)lpcs16
->lpszClass
;
139 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
141 *plParam
= (LPARAM
)lpcbtcw32
;
146 LPCBTACTIVATESTRUCT16 lpcas16
= PTR_SEG_TO_LIN(*plParam
);
147 LPCBTACTIVATESTRUCT lpcas32
= HeapAlloc( SystemHeap
, 0,
149 lpcas32
->fMouse
= lpcas16
->fMouse
;
150 lpcas32
->hWndActive
= lpcas16
->hWndActive
;
151 *plParam
= (LPARAM
)lpcas32
;
154 case HCBT_CLICKSKIPPED
:
156 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
157 LPMOUSEHOOKSTRUCT lpms32
= HeapAlloc( SystemHeap
, 0,
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
;
173 LPRECT16 lprect16
= PTR_SEG_TO_LIN(*plParam
);
174 LPRECT lprect32
= HeapAlloc( SystemHeap
, 0,
177 CONV_RECT16TO32( lprect16
, lprect32
);
178 *plParam
= (LPARAM
)lprect32
;
186 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
187 LPMOUSEHOOKSTRUCT lpms32
= HeapAlloc( SystemHeap
, 0,
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
;
203 LPDEBUGHOOKINFO16 lpdh16
= PTR_SEG_TO_LIN(*plParam
);
204 LPDEBUGHOOKINFO lpdh32
= HeapAlloc( SystemHeap
, 0,
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
;
225 case WH_FOREGROUNDIDLE
:
226 case WH_CALLWNDPROCRET
:
227 FIXME(hook
, "\t[%i] 16to32 translation unimplemented\n", id
);
232 /***********************************************************************
235 static void HOOK_Map16To32A(INT id
, INT code
, WPARAM
*pwParam
,
238 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, TRUE
);
242 /***********************************************************************
245 static void HOOK_Map16To32W(INT id
, INT code
, WPARAM
*pwParam
,
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
)
262 case WH_SYSMSGFILTER
:
263 case WH_JOURNALRECORD
:
264 case WH_JOURNALPLAYBACK
:
266 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
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
);
282 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(lParamOrig
);
283 STRUCT32_MSG32to16( (LPMSG
)lParam
, lpmsg16
);
284 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
291 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
299 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)lParam
;
300 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParamOrig
);
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
);
316 case HCBT_CLICKSKIPPED
:
319 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
329 case WH_FOREGROUNDIDLE
:
330 case WH_CALLWNDPROCRET
:
331 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
337 /***********************************************************************
340 static void HOOK_UnMap16To32A(INT id
, INT code
, WPARAM wParamOrig
,
341 LPARAM lParamOrig
, WPARAM wParam
,
344 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
349 /***********************************************************************
352 static void HOOK_UnMap16To32W(INT id
, INT code
, WPARAM wParamOrig
,
353 LPARAM lParamOrig
, WPARAM wParam
,
356 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
361 /***********************************************************************
362 * HOOK_Map32To16Common
364 static void HOOK_Map32To16Common(INT id
, INT code
, WPARAM
*pwParam
,
365 LPARAM
*plParam
, BOOL bA
)
370 case WH_SYSMSGFILTER
:
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
);
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
);
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
);
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
);
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
);
447 LPRECT lprect32
= (LPRECT
)*plParam
;
448 LPRECT16 lprect16
= SEGPTR_NEW( RECT16
);
450 CONV_RECT32TO16( lprect32
, lprect16
);
452 *plParam
= (LPARAM
)SEGPTR_GET( lprect16
);
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
);
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
);
493 case WH_FOREGROUNDIDLE
:
494 case WH_CALLWNDPROCRET
:
495 FIXME(hook
,"\t[%i] 32to16 translation unimplemented\n", id
);
500 /***********************************************************************
503 static void HOOK_Map32ATo16(INT id
, INT code
, WPARAM
*pwParam
,
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
))
517 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszName
) );
519 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
521 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
523 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszClass
) );
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 /***********************************************************************
538 static void HOOK_Map32WTo16(INT id
, INT code
, WPARAM
*pwParam
,
541 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
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
,
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
)
574 case WH_SYSMSGFILTER
:
575 case WH_JOURNALRECORD
:
576 case WH_JOURNALPLAYBACK
:
579 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
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
) );
598 LPMSG lpmsg32
= (LPMSG
)lParamOrig
;
600 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
601 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
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
);
626 case HCBT_CLICKSKIPPED
:
629 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
639 case WH_FOREGROUNDIDLE
:
640 case WH_CALLWNDPROCRET
:
641 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
646 /***********************************************************************
649 static void HOOK_UnMap32ATo16(INT id
, INT code
, WPARAM wParamOrig
,
650 LPARAM lParamOrig
, WPARAM wParam
,
653 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
658 /***********************************************************************
661 static void HOOK_UnMap32WTo16(INT id
, INT code
, WPARAM wParamOrig
,
662 LPARAM lParamOrig
, WPARAM wParam
,
665 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
670 /***********************************************************************
673 static void HOOK_Map32ATo32W(INT id
, INT code
, WPARAM
*pwParam
,
676 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
678 LPCBT_CREATEWNDA lpcbtcwA
= (LPCBT_CREATEWNDA
)*plParam
;
679 LPCBT_CREATEWNDW lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
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
);
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
);
700 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
701 *plParam
= (LPARAM
)lpcbtcwW
;
707 /***********************************************************************
710 static void HOOK_UnMap32ATo32W(INT id
, INT code
, WPARAM wParamOrig
,
711 LPARAM lParamOrig
, WPARAM wParam
,
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
);
728 /***********************************************************************
731 static void HOOK_Map32WTo32A(INT id
, INT code
, WPARAM
*pwParam
,
734 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
736 LPCBT_CREATEWNDW lpcbtcwW
= (LPCBT_CREATEWNDW
)*plParam
;
737 LPCBT_CREATEWNDA lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
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
);
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
);
754 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
755 *plParam
= (LPARAM
)lpcbtcwA
;
761 /***********************************************************************
764 static void HOOK_UnMap32WTo32A(INT id
, INT code
, WPARAM wParamOrig
,
765 LPARAM lParamOrig
, WPARAM wParam
,
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
);
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 /***********************************************************************
804 /***********************************************************************
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 /***********************************************************************
825 * Get the first hook for a given type.
827 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
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
);
841 /***********************************************************************
844 * Install a given hook.
846 static HHOOK
HOOK_SetHook( INT16 id
, LPVOID proc
, INT type
,
847 HMODULE16 hModule
, DWORD dwThreadId
)
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 */
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
)))
871 /* Create the hook structure */
873 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
874 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
877 data
->ownerQueue
= hQueue
;
878 data
->ownerModule
= hModule
;
881 /* Insert it in the correct linked list */
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
);
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 /***********************************************************************
905 * Remove a hook from the list.
907 static BOOL
HOOK_RemoveHook( HANDLE16 hook
)
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;
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
);
946 /***********************************************************************
949 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
955 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
956 if (data
->proc
) return hook
;
962 /***********************************************************************
965 * Call a hook procedure.
967 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT fromtype
, INT code
,
968 WPARAM wParam
, LPARAM lParam
)
972 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
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
];
984 MapFunc( data
->id
, code
, &wParam
, &lParam
);
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
);
1006 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
1008 if (!data
->proc
) HOOK_RemoveHook( hook
);
1013 /***********************************************************************
1014 * Exported Functions & APIs
1017 /***********************************************************************
1020 * Don't call this unless you are the if1632/thunk.c.
1022 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
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 /***********************************************************************
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 /***********************************************************************
1049 * Call a hook chain.
1051 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
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 /***********************************************************************
1064 * Call a hook chain.
1066 LRESULT
HOOK_CallHooksA( INT id
, INT code
, WPARAM wParam
,
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 /***********************************************************************
1079 * Call a hook chain.
1081 LRESULT
HOOK_CallHooksW( 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_WIN32W
, code
, wParam
,
1093 /***********************************************************************
1094 * HOOK_ResetQueueHooks
1096 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1098 MESSAGEQUEUE
*queue
;
1100 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
1105 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1107 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1110 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1112 data
->ownerQueue
= hQueue
;
1118 QUEUE_Unlock( queue
);
1122 /***********************************************************************
1123 * HOOK_FreeModuleHooks
1125 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1127 /* remove all system hooks registered by this module */
1133 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1135 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1137 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1140 if( hptr
->ownerModule
== hModule
)
1142 hptr
->flags
&= HOOK_MAPTYPE
;
1143 HOOK_RemoveHook(hook
);
1151 /***********************************************************************
1152 * HOOK_FreeQueueHooks
1154 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1156 /* remove all hooks registered by this queue */
1158 HOOKDATA
* hptr
= NULL
;
1162 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1164 hook
= HOOK_GetHook( id
, hQueue
);
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
);
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
,
1219 FIXME(hook
, "WH_DEBUG is broken in 16-bit Windows.\n");
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
,
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
,
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
);
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
,
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
,
1317 INT fromtype
; /* figure out Ansi/Unicode */
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
,
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
;
1344 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue16() ))) return 0;
1345 ret
= CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1346 QUEUE_Unlock( queue
);
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
);
1380 msg32
.hwnd
= lpmsg16_32
->msg
.hwnd
;
1381 msg32
.message
= lpmsg16_32
->msg
.message
;
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
);
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
))
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
))
1429 return HOOK_CallHooksW( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);