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.
28 /* Hook data (pointed to by a HHOOK) */
31 HANDLE16 next
; /* 00 Next hook in chain */
32 HOOKPROC32 proc WINE_PACKED
; /* 02 Hook procedure */
33 INT16 id
; /* 06 Hook id (WH_xxx) */
34 HQUEUE16 ownerQueue
; /* 08 Owner queue (0 for system hook) */
35 HMODULE16 ownerModule
; /* 0a Owner module */
36 WORD flags
; /* 0c flags */
41 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
43 /* This should probably reside in USER heap */
44 static HANDLE16 HOOK_systemHooks
[WH_NB_HOOKS
] = { 0, };
46 typedef VOID (*HOOK_MapFunc
)(INT32
, INT32
, WPARAM32
*, LPARAM
*);
47 typedef VOID (*HOOK_UnMapFunc
)(INT32
, INT32
, WPARAM32
, LPARAM
, WPARAM32
,
50 /***********************************************************************
51 * HOOK_Map16To32Common
53 static void HOOK_Map16To32Common(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
54 LPARAM
*plParam
, BOOL32 bA
)
62 case WH_JOURNALRECORD
:
64 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(*plParam
);
65 LPMSG32 lpmsg32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpmsg32
) );
67 STRUCT32_MSG16to32( lpmsg16
, lpmsg32
);
68 *plParam
= (LPARAM
)lpmsg32
;
72 case WH_JOURNALPLAYBACK
:
74 LPEVENTMSG16 lpem16
= PTR_SEG_TO_LIN(*plParam
);
75 LPEVENTMSG32 lpem32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpem32
) );
77 lpem32
->message
= lpem16
->message
;
78 lpem32
->paramL
= lpem16
->paramL
;
79 lpem32
->paramH
= lpem16
->paramH
;
80 lpem32
->time
= lpem16
->time
;
81 lpem32
->hwnd
= 0; /* FIXME */
83 *plParam
= (LPARAM
)lpem32
;
89 LPCWPSTRUCT16 lpcwp16
= PTR_SEG_TO_LIN(*plParam
);
90 LPCWPSTRUCT32 lpcwp32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcwp32
) );
92 lpcwp32
->hwnd
= lpcwp16
->hwnd
;
93 lpcwp32
->lParam
= lpcwp16
->lParam
;
95 if (bA
) WINPROC_MapMsg16To32A( lpcwp16
->message
, lpcwp16
->wParam
,
96 &lpcwp32
->message
, &lpcwp32
->wParam
,
98 else WINPROC_MapMsg16To32W( lpcwp16
->message
, lpcwp16
->wParam
,
99 &lpcwp32
->message
, &lpcwp32
->wParam
,
101 *plParam
= (LPARAM
)lpcwp32
;
110 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(*plParam
);
111 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
112 LPCBT_CREATEWND32A lpcbtcw32
= HeapAlloc( SystemHeap
, 0,
113 sizeof(*lpcbtcw32
) );
114 lpcbtcw32
->lpcs
= HeapAlloc( SystemHeap
, 0,
115 sizeof(*lpcbtcw32
->lpcs
) );
117 STRUCT32_CREATESTRUCT16to32A( lpcs16
,
118 (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
);
120 if (HIWORD(lpcs16
->lpszName
))
121 lpcbtcw32
->lpcs
->lpszName
=
122 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszName
)
123 : HEAP_strdupAtoW( SystemHeap
, 0,
124 PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
126 lpcbtcw32
->lpcs
->lpszName
= (LPCSTR
)lpcs16
->lpszName
;
128 if (HIWORD(lpcs16
->lpszClass
))
129 lpcbtcw32
->lpcs
->lpszClass
=
130 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszClass
)
131 : HEAP_strdupAtoW( SystemHeap
, 0,
132 PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
134 lpcbtcw32
->lpcs
->lpszClass
= (LPCSTR
)lpcs16
->lpszClass
;
136 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
138 *plParam
= (LPARAM
)lpcbtcw32
;
143 LPCBTACTIVATESTRUCT16 lpcas16
= PTR_SEG_TO_LIN(*plParam
);
144 LPCBTACTIVATESTRUCT32 lpcas32
= HeapAlloc( SystemHeap
, 0,
146 lpcas32
->fMouse
= lpcas16
->fMouse
;
147 lpcas32
->hWndActive
= lpcas16
->hWndActive
;
148 *plParam
= (LPARAM
)lpcas32
;
151 case HCBT_CLICKSKIPPED
:
153 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
154 LPMOUSEHOOKSTRUCT32 lpms32
= HeapAlloc( SystemHeap
, 0,
157 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
159 /* wHitTestCode may be negative, so convince compiler to do
160 correct sign extension. Yay. :| */
161 lpms32
->wHitTestCode
= (INT32
)((INT16
)lpms16
->wHitTestCode
);
163 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
164 lpms32
->hwnd
= lpms16
->hwnd
;
165 *plParam
= (LPARAM
)lpms32
;
170 LPRECT16 lprect16
= PTR_SEG_TO_LIN(*plParam
);
171 LPRECT32 lprect32
= HeapAlloc( SystemHeap
, 0,
174 CONV_RECT16TO32( lprect16
, lprect32
);
175 *plParam
= (LPARAM
)lprect32
;
183 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
184 LPMOUSEHOOKSTRUCT32 lpms32
= HeapAlloc( SystemHeap
, 0,
187 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
189 /* wHitTestCode may be negative, so convince compiler to do
190 correct sign extension. Yay. :| */
191 lpms32
->wHitTestCode
= (INT32
)((INT16
)lpms16
->wHitTestCode
);
192 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
193 lpms32
->hwnd
= lpms16
->hwnd
;
194 *plParam
= (LPARAM
)lpms32
;
200 LPDEBUGHOOKINFO16 lpdh16
= PTR_SEG_TO_LIN(*plParam
);
201 LPDEBUGHOOKINFO32 lpdh32
= HeapAlloc( SystemHeap
, 0,
204 lpdh32
->idThread
= 0; /* FIXME */
205 lpdh32
->idThreadInstaller
= 0; /* FIXME */
206 lpdh32
->lParam
= lpdh16
->lParam
; /* FIXME Check for sign ext */
207 lpdh32
->wParam
= lpdh16
->wParam
;
208 lpdh32
->code
= lpdh16
->code
;
210 /* do sign extension if it was WH_MSGFILTER */
211 if (*pwParam
== 0xffff) *pwParam
= WH_MSGFILTER
;
213 *plParam
= (LPARAM
)lpdh32
;
222 case WH_FOREGROUNDIDLE
:
223 case WH_CALLWNDPROCRET
:
224 FIXME(hook
, "\t[%i] 16to32 translation unimplemented\n", id
);
229 /***********************************************************************
232 static void HOOK_Map16To32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
235 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, TRUE
);
239 /***********************************************************************
242 static void HOOK_Map16To32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
245 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, FALSE
);
249 /***********************************************************************
250 * HOOK_UnMap16To32Common
252 static void HOOK_UnMap16To32Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
253 LPARAM lParamOrig
, WPARAM32 wParam
,
254 LPARAM lParam
, BOOL32 bA
)
259 case WH_SYSMSGFILTER
:
260 case WH_JOURNALRECORD
:
261 case WH_JOURNALPLAYBACK
:
263 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
268 LPCWPSTRUCT32 lpcwp32
= (LPCWPSTRUCT32
)lParam
;
269 if (bA
) WINPROC_UnmapMsg16To32A( lpcwp32
->message
, lpcwp32
->wParam
,
270 lpcwp32
->lParam
, 0 );
271 else WINPROC_UnmapMsg16To32W( lpcwp32
->message
, lpcwp32
->wParam
,
272 lpcwp32
->lParam
, 0 );
273 HeapFree( SystemHeap
, 0, lpcwp32
);
279 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(lParamOrig
);
280 STRUCT32_MSG32to16( (LPMSG32
)lParam
, lpmsg16
);
281 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
288 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
296 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)lParam
;
297 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParamOrig
);
301 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
302 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszName
);
303 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
304 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszClass
);
307 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
309 HeapFree( SystemHeap
, 0, lpcbtcw32
->lpcs
);
313 case HCBT_CLICKSKIPPED
:
316 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
326 case WH_FOREGROUNDIDLE
:
327 case WH_CALLWNDPROCRET
:
328 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
334 /***********************************************************************
337 static void HOOK_UnMap16To32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
338 LPARAM lParamOrig
, WPARAM32 wParam
,
341 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
346 /***********************************************************************
349 static void HOOK_UnMap16To32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
350 LPARAM lParamOrig
, WPARAM32 wParam
,
353 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
358 /***********************************************************************
359 * HOOK_Map32To16Common
361 static void HOOK_Map32To16Common(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
362 LPARAM
*plParam
, BOOL32 bA
)
367 case WH_SYSMSGFILTER
:
369 case WH_JOURNALRECORD
:
371 LPMSG32 lpmsg32
= (LPMSG32
)*plParam
;
372 LPMSG16 lpmsg16
= SEGPTR_NEW( MSG16
);
374 STRUCT32_MSG32to16( lpmsg32
, lpmsg16
);
376 *plParam
= (LPARAM
)SEGPTR_GET( lpmsg16
);
380 case WH_JOURNALPLAYBACK
:
382 LPEVENTMSG32 lpem32
= (LPEVENTMSG32
)*plParam
;
383 LPEVENTMSG16 lpem16
= SEGPTR_NEW( EVENTMSG16
);
385 lpem16
->message
= lpem32
->message
;
386 lpem16
->paramL
= lpem32
->paramL
;
387 lpem16
->paramH
= lpem32
->paramH
;
388 lpem16
->time
= lpem32
->time
;
390 *plParam
= (LPARAM
)SEGPTR_GET( lpem16
);
396 LPCWPSTRUCT32 lpcwp32
= (LPCWPSTRUCT32
)*plParam
;
397 LPCWPSTRUCT16 lpcwp16
= SEGPTR_NEW( CWPSTRUCT16
);
399 lpcwp16
->hwnd
= lpcwp32
->hwnd
;
400 lpcwp16
->lParam
= lpcwp32
->lParam
;
402 if (bA
) WINPROC_MapMsg32ATo16( lpcwp32
->hwnd
, lpcwp32
->message
,
403 lpcwp32
->wParam
, &lpcwp16
->message
,
404 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
405 else WINPROC_MapMsg32WTo16( lpcwp32
->hwnd
, lpcwp32
->message
,
406 lpcwp32
->wParam
, &lpcwp16
->message
,
407 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
408 *plParam
= (LPARAM
)SEGPTR_GET( lpcwp16
);
417 LPCBTACTIVATESTRUCT32 lpcas32
= (LPCBTACTIVATESTRUCT32
)*plParam
;
418 LPCBTACTIVATESTRUCT16 lpcas16
=SEGPTR_NEW( CBTACTIVATESTRUCT16
);
420 lpcas16
->fMouse
= lpcas32
->fMouse
;
421 lpcas16
->hWndActive
= lpcas32
->hWndActive
;
423 *plParam
= (LPARAM
)SEGPTR_GET( lpcas16
);
427 case HCBT_CLICKSKIPPED
:
429 LPMOUSEHOOKSTRUCT32 lpms32
= (LPMOUSEHOOKSTRUCT32
)*plParam
;
430 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
432 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
434 lpms16
->hwnd
= lpms32
->hwnd
;
435 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
436 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
438 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
444 LPRECT32 lprect32
= (LPRECT32
)*plParam
;
445 LPRECT16 lprect16
= SEGPTR_NEW( RECT16
);
447 CONV_RECT32TO16( lprect32
, lprect16
);
449 *plParam
= (LPARAM
)SEGPTR_GET( lprect16
);
457 LPMOUSEHOOKSTRUCT32 lpms32
= (LPMOUSEHOOKSTRUCT32
)*plParam
;
458 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
460 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
462 lpms16
->hwnd
= lpms32
->hwnd
;
463 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
464 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
466 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
472 LPDEBUGHOOKINFO32 lpdh32
= (LPDEBUGHOOKINFO32
)*plParam
;
473 LPDEBUGHOOKINFO16 lpdh16
= SEGPTR_NEW( DEBUGHOOKINFO16
);
475 lpdh16
->hModuleHook
= 0; /* FIXME */
476 lpdh16
->reserved
= 0;
477 lpdh16
->lParam
= lpdh32
->lParam
;
478 lpdh16
->wParam
= lpdh32
->wParam
;
479 lpdh16
->code
= lpdh32
->code
;
481 *plParam
= (LPARAM
)SEGPTR_GET( lpdh16
);
490 case WH_FOREGROUNDIDLE
:
491 case WH_CALLWNDPROCRET
:
492 FIXME(hook
,"\t[%i] 32to16 translation unimplemented\n", id
);
497 /***********************************************************************
500 static void HOOK_Map32ATo16(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
503 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
505 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)*plParam
;
506 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
507 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
509 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
510 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32
->lpcs
, lpcs16
);
512 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
514 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszName
) );
516 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
518 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
520 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszClass
) );
522 lpcs16
->lpszClass
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszClass
;
524 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
526 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
528 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, TRUE
);
532 /***********************************************************************
535 static void HOOK_Map32WTo16(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
538 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
541 LPCBT_CREATEWND32W lpcbtcw32
= (LPCBT_CREATEWND32W
)*plParam
;
542 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
543 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
545 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
546 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
,
549 name
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszName
);
550 cls
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszClass
);
551 lpcs16
->lpszName
= SEGPTR_GET( name
);
552 lpcs16
->lpszClass
= SEGPTR_GET( cls
);
553 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
555 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
557 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, FALSE
);
561 /***********************************************************************
562 * HOOK_UnMap32To16Common
564 static void HOOK_UnMap32To16Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
565 LPARAM lParamOrig
, WPARAM32 wParam
,
566 LPARAM lParam
, BOOL32 bA
)
571 case WH_SYSMSGFILTER
:
572 case WH_JOURNALRECORD
:
573 case WH_JOURNALPLAYBACK
:
576 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
581 LPCWPSTRUCT16 lpcwp16
= (LPCWPSTRUCT16
)PTR_SEG_TO_LIN(lParam
);
582 LPCWPSTRUCT32 lpcwp32
= (LPCWPSTRUCT32
)lParamOrig
;
583 MSGPARAM16 mp16
= { lpcwp16
->wParam
, lpcwp16
->lParam
, 0 };
585 if (bA
) WINPROC_UnmapMsg32ATo16( lpcwp32
->message
, lpcwp32
->wParam
,
586 lpcwp32
->lParam
, &mp16
);
587 else WINPROC_UnmapMsg32WTo16( lpcwp32
->message
, lpcwp32
->wParam
,
588 lpcwp32
->lParam
, &mp16
);
589 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
595 LPMSG32 lpmsg32
= (LPMSG32
)lParamOrig
;
597 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
598 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
607 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)(lParamOrig
);
608 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParam
);
609 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
611 if (HIWORD(lpcs16
->lpszName
))
612 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
614 if (HIWORD(lpcs16
->lpszClass
))
615 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
617 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
619 SEGPTR_FREE( lpcs16
);
623 case HCBT_CLICKSKIPPED
:
626 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
636 case WH_FOREGROUNDIDLE
:
637 case WH_CALLWNDPROCRET
:
638 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
643 /***********************************************************************
646 static void HOOK_UnMap32ATo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
647 LPARAM lParamOrig
, WPARAM32 wParam
,
650 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
655 /***********************************************************************
658 static void HOOK_UnMap32WTo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
659 LPARAM lParamOrig
, WPARAM32 wParam
,
662 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
667 /***********************************************************************
670 static void HOOK_Map32ATo32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
673 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
675 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)*plParam
;
676 LPCBT_CREATEWND32W lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
678 lpcbtcwW
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwW
->lpcs
) );
680 lpcbtcwW
->hwndInsertAfter
= lpcbtcwA
->hwndInsertAfter
;
681 *lpcbtcwW
->lpcs
= *(LPCREATESTRUCT32W
)lpcbtcwA
->lpcs
;
683 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
685 lpcbtcwW
->lpcs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
686 lpcbtcwA
->lpcs
->lpszName
);
689 lpcbtcwW
->lpcs
->lpszName
= (LPWSTR
)lpcbtcwA
->lpcs
->lpszName
;
691 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
693 lpcbtcwW
->lpcs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
694 lpcbtcwA
->lpcs
->lpszClass
);
697 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
698 *plParam
= (LPARAM
)lpcbtcwW
;
704 /***********************************************************************
707 static void HOOK_UnMap32ATo32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
708 LPARAM lParamOrig
, WPARAM32 wParam
,
711 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
713 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)lParam
;
714 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
715 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszName
);
716 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
717 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszClass
);
718 HeapFree( SystemHeap
, 0, lpcbtcwW
->lpcs
);
719 HeapFree( SystemHeap
, 0, lpcbtcwW
);
725 /***********************************************************************
728 static void HOOK_Map32WTo32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
731 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
733 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)*plParam
;
734 LPCBT_CREATEWND32A lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
736 lpcbtcwA
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwA
->lpcs
) );
738 lpcbtcwA
->hwndInsertAfter
= lpcbtcwW
->hwndInsertAfter
;
739 *lpcbtcwA
->lpcs
= *(LPCREATESTRUCT32A
)lpcbtcwW
->lpcs
;
741 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
742 lpcbtcwA
->lpcs
->lpszName
= HEAP_strdupWtoA( SystemHeap
, 0,
743 lpcbtcwW
->lpcs
->lpszName
);
745 lpcbtcwA
->lpcs
->lpszName
= (LPSTR
)lpcbtcwW
->lpcs
->lpszName
;
747 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
748 lpcbtcwA
->lpcs
->lpszClass
= HEAP_strdupWtoA( SystemHeap
, 0,
749 lpcbtcwW
->lpcs
->lpszClass
);
751 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
752 *plParam
= (LPARAM
)lpcbtcwA
;
758 /***********************************************************************
761 static void HOOK_UnMap32WTo32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
762 LPARAM lParamOrig
, WPARAM32 wParam
,
765 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
767 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)lParam
;
768 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
769 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszName
);
770 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
771 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszClass
);
772 HeapFree( SystemHeap
, 0, lpcbtcwA
->lpcs
);
773 HeapFree( SystemHeap
, 0, lpcbtcwA
);
779 /***********************************************************************
780 * Map Function Tables
782 static const HOOK_MapFunc HOOK_MapFuncs
[3][3] =
784 { NULL
, HOOK_Map16To32A
, HOOK_Map16To32W
},
785 { HOOK_Map32ATo16
, NULL
, HOOK_Map32ATo32W
},
786 { HOOK_Map32WTo16
, HOOK_Map32WTo32A
, NULL
}
789 static const HOOK_UnMapFunc HOOK_UnMapFuncs
[3][3] =
791 { NULL
, HOOK_UnMap16To32A
, HOOK_UnMap16To32W
},
792 { HOOK_UnMap32ATo16
, NULL
, HOOK_UnMap32ATo32W
},
793 { HOOK_UnMap32WTo16
, HOOK_UnMap32WTo32A
, NULL
}
797 /***********************************************************************
801 /***********************************************************************
804 * Get the next hook of a given hook.
806 static HANDLE16
HOOK_GetNextHook( HANDLE16 hook
)
808 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( hook
);
810 if (!data
|| !hook
) return 0;
811 if (data
->next
) return data
->next
;
812 if (!data
->ownerQueue
) return 0; /* Already system hook */
814 /* Now start enumerating the system hooks */
815 return HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
819 /***********************************************************************
822 * Get the first hook for a given type.
824 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
829 if ((queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
)) != NULL
)
830 hook
= queue
->hooks
[id
- WH_MINHOOK
];
831 if (!hook
) hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
836 /***********************************************************************
839 * Install a given hook.
841 static HANDLE16
HOOK_SetHook( INT16 id
, LPVOID proc
, INT32 type
,
842 HINSTANCE16 hInst
, HTASK16 hTask
)
848 if ((id
< WH_MINHOOK
) || (id
> WH_MAXHOOK
)) return 0;
850 TRACE(hook
, "Setting hook %d: %08x %04x %04x\n",
851 id
, (UINT32
)proc
, hInst
, hTask
);
853 if (!hInst
&& (type
!=HOOK_WIN16
))
854 hInst
= GetModuleHandle32A(NULL
);/*FIXME: correct? probably not */
856 if (id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(FALSE
);
858 if (hTask
) /* Task-specific hook */
860 if ((id
== WH_JOURNALRECORD
) || (id
== WH_JOURNALPLAYBACK
) ||
861 (id
== WH_SYSMSGFILTER
)) return 0; /* System-only hooks */
862 if (!(hQueue
= GetTaskQueue( hTask
))) return 0;
865 /* Create the hook structure */
867 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
868 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
871 data
->ownerQueue
= hQueue
;
872 data
->ownerModule
= hInst
;
875 /* Insert it in the correct linked list */
879 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
);
880 data
->next
= queue
->hooks
[id
- WH_MINHOOK
];
881 queue
->hooks
[id
- WH_MINHOOK
] = handle
;
885 data
->next
= HOOK_systemHooks
[id
- WH_MINHOOK
];
886 HOOK_systemHooks
[id
- WH_MINHOOK
] = handle
;
888 TRACE(hook
, "Setting hook %d: ret=%04x [next=%04x]\n",
889 id
, handle
, data
->next
);
894 /***********************************************************************
897 * Remove a hook from the list.
899 static BOOL32
HOOK_RemoveHook( HANDLE16 hook
)
904 TRACE(hook
, "Removing hook %04x\n", hook
);
906 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return FALSE
;
907 if (data
->flags
& HOOK_INUSE
)
909 /* Mark it for deletion later on */
910 WARN(hook
, "Hook still running, deletion delayed\n" );
911 data
->proc
= (HOOKPROC32
)0;
915 if (data
->id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(TRUE
);
917 /* Remove it from the linked list */
919 if (data
->ownerQueue
)
921 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)GlobalLock16( data
->ownerQueue
);
922 if (!queue
) return FALSE
;
923 prevHook
= &queue
->hooks
[data
->id
- WH_MINHOOK
];
925 else prevHook
= &HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
927 while (*prevHook
&& *prevHook
!= hook
)
928 prevHook
= &((HOOKDATA
*)USER_HEAP_LIN_ADDR(*prevHook
))->next
;
930 if (!*prevHook
) return FALSE
;
931 *prevHook
= data
->next
;
932 USER_HEAP_FREE( hook
);
937 /***********************************************************************
940 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
946 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
947 if (data
->proc
) return hook
;
953 /***********************************************************************
956 * Call a hook procedure.
958 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT32 fromtype
, INT32 code
,
959 WPARAM32 wParam
, LPARAM lParam
)
963 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
966 WPARAM32 wParamOrig
= wParam
;
967 LPARAM lParamOrig
= lParam
;
968 HOOK_MapFunc MapFunc
;
969 HOOK_UnMapFunc UnMapFunc
;
971 MapFunc
= HOOK_MapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
972 UnMapFunc
= HOOK_UnMapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
975 MapFunc( data
->id
, code
, &wParam
, &lParam
);
979 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
980 prevHook
= queue
->hCurHook
;
981 queue
->hCurHook
= hook
;
982 data
->flags
|= HOOK_INUSE
;
984 TRACE(hook
, "Calling hook %04x: %d %08x %08lx\n",
985 hook
, code
, wParam
, lParam
);
987 ret
= data
->proc(code
, wParam
, lParam
);
989 TRACE(hook
, "Ret hook %04x = %08lx\n", hook
, ret
);
991 data
->flags
&= ~HOOK_INUSE
;
992 queue
->hCurHook
= prevHook
;
995 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
997 if (!data
->proc
) HOOK_RemoveHook( hook
);
1002 /***********************************************************************
1003 * Exported Functions & APIs
1006 /***********************************************************************
1009 * Don't call this unless you are the if1632/thunk.c.
1011 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
1014 if (HIWORD(hhook
) != HOOK_MAGIC
) return NULL
;
1015 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) ))) return NULL
;
1016 if ((data
->flags
& HOOK_MAPTYPE
) != HOOK_WIN16
) return NULL
;
1017 return (HOOKPROC16
)data
->proc
;
1021 /***********************************************************************
1024 * Replacement for calling HOOK_GetHook from other modules.
1026 BOOL32
HOOK_IsHooked( INT16 id
)
1028 return HOOK_GetHook( id
, GetTaskQueue(0) ) != 0;
1032 /***********************************************************************
1035 * Call a hook chain.
1037 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1042 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1043 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1044 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1047 /***********************************************************************
1050 * Call a hook chain.
1052 LRESULT
HOOK_CallHooks32A( INT32 id
, INT32 code
, WPARAM32 wParam
,
1057 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1058 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1059 return HOOK_CallHook( hook
, HOOK_WIN32A
, code
, wParam
, lParam
);
1062 /***********************************************************************
1065 * Call a hook chain.
1067 LRESULT
HOOK_CallHooks32W( INT32 id
, INT32 code
, WPARAM32 wParam
,
1072 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1073 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1074 return HOOK_CallHook( hook
, HOOK_WIN32W
, code
, wParam
,
1079 /***********************************************************************
1080 * HOOK_ResetQueueHooks
1082 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1084 MESSAGEQUEUE
*queue
;
1086 if ((queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
)) != NULL
)
1091 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1093 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1096 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1098 data
->ownerQueue
= hQueue
;
1106 /***********************************************************************
1107 * HOOK_FreeModuleHooks
1109 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1111 /* remove all system hooks registered by this module */
1117 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1119 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1121 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1124 if( hptr
->ownerModule
== hModule
)
1126 hptr
->flags
&= HOOK_MAPTYPE
;
1127 HOOK_RemoveHook(hook
);
1135 /***********************************************************************
1136 * HOOK_FreeQueueHooks
1138 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1140 /* remove all hooks registered by this queue */
1142 HOOKDATA
* hptr
= NULL
;
1146 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1148 hook
= HOOK_GetHook( id
, hQueue
);
1151 next
= HOOK_GetNextHook(hook
);
1153 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1154 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1156 hptr
->flags
&= HOOK_MAPTYPE
;
1157 HOOK_RemoveHook(hook
);
1165 /***********************************************************************
1166 * SetWindowsHook16 (USER.121)
1168 FARPROC16 WINAPI
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1171 HINSTANCE16 hInst
= FarGetOwner( HIWORD(proc
) );
1173 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1174 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1178 FIXME(hook
, "WH_DEBUG is broken in 16-bit Windows.\n");
1182 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN16
, GetExePtr(hInst
), hTask
);
1183 return (handle
) ? (FARPROC16
)MAKELONG( handle
, HOOK_MAGIC
) : NULL
;
1187 /***********************************************************************
1188 * SetWindowsHook32A (USER32.525)
1190 * FIXME: I don't know if this is correct
1192 HHOOK WINAPI
SetWindowsHook32A( INT32 id
, HOOKPROC32 proc
)
1194 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1195 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1197 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32A
, 0, hTask
);
1198 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : 0;
1202 /***********************************************************************
1203 * SetWindowsHook32W (USER32.528)
1205 * FIXME: I don't know if this is correct
1207 HHOOK WINAPI
SetWindowsHook32W( INT32 id
, HOOKPROC32 proc
)
1209 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1210 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1212 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32W
, 0, hTask
);
1213 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : 0;
1217 /***********************************************************************
1218 * SetWindowsHookEx16 (USER.291)
1220 HHOOK WINAPI
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1223 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN16
, GetExePtr(hInst
), hTask
);
1224 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1228 /***********************************************************************
1229 * SetWindowsHookEx32A (USER32.526)
1231 HHOOK WINAPI
SetWindowsHookEx32A( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1237 if (dwThreadID
== GetCurrentThreadId())
1238 hTask
= GetCurrentTask();
1240 hTask
= LOWORD(dwThreadID
); /* FIXME! */
1242 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32A
, hInst
, hTask
);
1243 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1247 /***********************************************************************
1248 * SetWindowsHookEx32W (USER32.527)
1250 HHOOK WINAPI
SetWindowsHookEx32W( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1256 if (dwThreadID
== GetCurrentThreadId())
1257 hTask
= GetCurrentTask();
1259 hTask
= LOWORD(dwThreadID
); /* FIXME! */
1261 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32W
, hInst
, hTask
);
1262 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1266 /***********************************************************************
1267 * UnhookWindowsHook16 (USER.234)
1269 BOOL16 WINAPI
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1271 HANDLE16 hook
= HOOK_GetHook( id
, GetTaskQueue(0) );
1273 TRACE(hook
, "%d %08lx\n", id
, (DWORD
)proc
);
1277 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1278 if (data
->proc
== (HOOKPROC32
)proc
) break;
1279 hook
= HOOK_GetNextHook( hook
);
1281 if (!hook
) return FALSE
;
1282 return HOOK_RemoveHook( hook
);
1286 /***********************************************************************
1287 * UnhookWindowsHook32 (USER32.557)
1289 BOOL32 WINAPI
UnhookWindowsHook32( INT32 id
, HOOKPROC32 proc
)
1291 HANDLE16 hook
= HOOK_GetHook( id
, GetTaskQueue(0) );
1293 TRACE(hook
, "%d %08lx\n", id
, (DWORD
)proc
);
1297 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1298 if (data
->proc
== proc
) break;
1299 hook
= HOOK_GetNextHook( hook
);
1301 if (!hook
) return FALSE
;
1302 return HOOK_RemoveHook( hook
);
1306 /***********************************************************************
1307 * UnhookWindowHookEx16 (USER.292)
1309 BOOL16 WINAPI
UnhookWindowsHookEx16( HHOOK hhook
)
1311 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1312 return HOOK_RemoveHook( LOWORD(hhook
) );
1316 /***********************************************************************
1317 * UnhookWindowHookEx32 (USER32.558)
1319 BOOL32 WINAPI
UnhookWindowsHookEx32( HHOOK hhook
)
1321 return UnhookWindowsHookEx16( hhook
);
1325 /***********************************************************************
1326 * CallNextHookEx16 (USER.293)
1328 * I wouldn't have separated this into 16 and 32 bit versions, but I
1329 * need a way to figure out if I need to do a mapping or not.
1331 LRESULT WINAPI
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1336 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1337 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1339 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1343 /***********************************************************************
1344 * CallNextHookEx32 (USER32.17)
1346 * There aren't ANSI and UNICODE versions of this.
1348 LRESULT WINAPI
CallNextHookEx32( HHOOK hhook
, INT32 code
, WPARAM32 wParam
,
1352 INT32 fromtype
; /* figure out Ansi/Unicode */
1355 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1356 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1358 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1359 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1361 if (fromtype
== HOOK_WIN16
)
1362 ERR(hook
, "called from 16bit hook!\n");
1364 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1368 /***********************************************************************
1369 * DefHookProc16 (USER.235)
1371 LRESULT WINAPI
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1374 /* Note: the *hhook parameter is never used, since we rely on the
1375 * current hook value from the task queue to find the next hook. */
1376 MESSAGEQUEUE
*queue
;
1378 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
1379 return CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1383 /***********************************************************************
1384 * CallMsgFilter16 (USER.123)
1386 BOOL16 WINAPI
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1388 if (GetSysModalWindow16()) return FALSE
;
1389 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1390 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1394 /***********************************************************************
1395 * CallMsgFilter32A (USER32.15)
1398 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1399 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1401 BOOL32 WINAPI
CallMsgFilter32A( LPMSG32 msg
, INT32 code
)
1403 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1404 if (HOOK_CallHooks32A( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1406 return HOOK_CallHooks32A( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1410 /***********************************************************************
1411 * CallMsgFilter32W (USER32.16)
1413 BOOL32 WINAPI
CallMsgFilter32W( LPMSG32 msg
, INT32 code
)
1415 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1416 if (HOOK_CallHooks32W( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1418 return HOOK_CallHooks32W( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);