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 /* Grrr. While the hook procedure is supposed to have an LRESULT return
999 value even in Win16, it seems that for those hook types where the
1000 return value is interpreted as BOOL, Windows doesn't actually check
1001 the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on
1002 that, because they neglect to clear DX ... */
1003 if ( (data
->flags
& HOOK_MAPTYPE
) == HOOK_WIN16
1004 && data
->id
!= WH_JOURNALPLAYBACK
)
1005 ret
= LOWORD( ret
);
1007 TRACE(hook
, "Ret hook %04x = %08lx\n", hook
, ret
);
1009 data
->flags
&= ~HOOK_INUSE
;
1010 queue
->hCurHook
= prevHook
;
1012 QUEUE_Unlock( queue
);
1015 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
1017 if (!data
->proc
) HOOK_RemoveHook( hook
);
1022 /***********************************************************************
1023 * Exported Functions & APIs
1026 /***********************************************************************
1029 * Don't call this unless you are the if1632/thunk.c.
1031 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
1034 if (HIWORD(hhook
) != HOOK_MAGIC
) return NULL
;
1035 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) ))) return NULL
;
1036 if ((data
->flags
& HOOK_MAPTYPE
) != HOOK_WIN16
) return NULL
;
1037 return (HOOKPROC16
)data
->proc
;
1041 /***********************************************************************
1044 * Replacement for calling HOOK_GetHook from other modules.
1046 BOOL
HOOK_IsHooked( INT16 id
)
1048 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1049 avoid queue being created if someone wants to merely check ... */
1051 return HOOK_GetHook( id
, GetThreadQueue16(0) ) != 0;
1055 /***********************************************************************
1058 * Call a hook chain.
1060 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1065 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1066 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1067 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1070 /***********************************************************************
1073 * Call a hook chain.
1075 LRESULT
HOOK_CallHooksA( INT id
, INT code
, WPARAM wParam
,
1080 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1081 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1082 return HOOK_CallHook( hook
, HOOK_WIN32A
, code
, wParam
, lParam
);
1085 /***********************************************************************
1088 * Call a hook chain.
1090 LRESULT
HOOK_CallHooksW( INT id
, INT code
, WPARAM wParam
,
1095 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1096 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1097 return HOOK_CallHook( hook
, HOOK_WIN32W
, code
, wParam
,
1102 /***********************************************************************
1103 * HOOK_ResetQueueHooks
1105 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1107 MESSAGEQUEUE
*queue
;
1109 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
1114 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1116 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1119 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1121 data
->ownerQueue
= hQueue
;
1127 QUEUE_Unlock( queue
);
1131 /***********************************************************************
1132 * HOOK_FreeModuleHooks
1134 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1136 /* remove all system hooks registered by this module */
1142 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1144 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1146 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1149 if( hptr
->ownerModule
== hModule
)
1151 hptr
->flags
&= HOOK_MAPTYPE
;
1152 HOOK_RemoveHook(hook
);
1160 /***********************************************************************
1161 * HOOK_FreeQueueHooks
1163 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1165 /* remove all hooks registered by this queue */
1167 HOOKDATA
* hptr
= NULL
;
1171 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1173 hook
= HOOK_GetHook( id
, hQueue
);
1176 next
= HOOK_GetNextHook(hook
);
1178 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1179 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1181 hptr
->flags
&= HOOK_MAPTYPE
;
1182 HOOK_RemoveHook(hook
);
1190 /***********************************************************************
1191 * SetWindowsHook16 (USER.121)
1193 FARPROC16 WINAPI
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1195 HINSTANCE16 hInst
= FarGetOwner16( HIWORD(proc
) );
1197 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1198 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1200 return (FARPROC16
)SetWindowsHookEx16( id
, proc
, hInst
, hTask
);
1203 /***********************************************************************
1204 * SetWindowsHook32A (USER32.525)
1206 HHOOK WINAPI
SetWindowsHookA( INT id
, HOOKPROC proc
)
1208 return SetWindowsHookExA( id
, proc
, 0, GetCurrentThreadId() );
1211 /***********************************************************************
1212 * SetWindowsHook32W (USER32.528)
1214 HHOOK WINAPI
SetWindowsHookW( INT id
, HOOKPROC proc
)
1216 return SetWindowsHookExW( id
, proc
, 0, GetCurrentThreadId() );
1220 /***********************************************************************
1221 * SetWindowsHookEx16 (USER.291)
1223 HHOOK WINAPI
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1228 FIXME(hook
, "WH_DEBUG is broken in 16-bit Windows.\n");
1231 return HOOK_SetHook( id
, proc
, HOOK_WIN16
, GetExePtr(hInst
), (DWORD
)hTask
);
1234 /***********************************************************************
1235 * SetWindowsHookEx32A (USER32.526)
1237 HHOOK WINAPI
SetWindowsHookExA( INT id
, HOOKPROC proc
, HINSTANCE hInst
,
1240 return HOOK_SetHook( id
, proc
, HOOK_WIN32A
, MapHModuleLS(hInst
), dwThreadId
);
1243 /***********************************************************************
1244 * SetWindowsHookEx32W (USER32.527)
1246 HHOOK WINAPI
SetWindowsHookExW( INT id
, HOOKPROC proc
, HINSTANCE hInst
,
1249 return HOOK_SetHook( id
, proc
, HOOK_WIN32W
, MapHModuleLS(hInst
), dwThreadId
);
1253 /***********************************************************************
1254 * UnhookWindowsHook16 (USER.234)
1256 BOOL16 WINAPI
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1258 return UnhookWindowsHook( id
, (HOOKPROC
)proc
);
1261 /***********************************************************************
1262 * UnhookWindowsHook32 (USER32.557)
1264 BOOL WINAPI
UnhookWindowsHook( INT id
, HOOKPROC proc
)
1266 HANDLE16 hook
= HOOK_GetHook( id
, GetFastQueue16() );
1268 TRACE(hook
, "%d %08lx\n", id
, (DWORD
)proc
);
1272 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1273 if (data
->proc
== proc
) break;
1274 hook
= HOOK_GetNextHook( hook
);
1276 if (!hook
) return FALSE
;
1277 return HOOK_RemoveHook( hook
);
1281 /***********************************************************************
1282 * UnhookWindowHookEx16 (USER.292)
1284 BOOL16 WINAPI
UnhookWindowsHookEx16( HHOOK hhook
)
1286 return UnhookWindowsHookEx( hhook
);
1289 /***********************************************************************
1290 * UnhookWindowHookEx32 (USER32.558)
1292 BOOL WINAPI
UnhookWindowsHookEx( HHOOK hhook
)
1294 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1295 return HOOK_RemoveHook( LOWORD(hhook
) );
1299 /***********************************************************************
1300 * CallNextHookEx16 (USER.293)
1302 * I wouldn't have separated this into 16 and 32 bit versions, but I
1303 * need a way to figure out if I need to do a mapping or not.
1305 LRESULT WINAPI
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1310 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1311 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1313 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1317 /***********************************************************************
1318 * CallNextHookEx32 (USER32.17)
1320 * There aren't ANSI and UNICODE versions of this.
1322 LRESULT WINAPI
CallNextHookEx( HHOOK hhook
, INT code
, WPARAM wParam
,
1326 INT fromtype
; /* figure out Ansi/Unicode */
1329 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1330 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1332 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1333 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1335 if (fromtype
== HOOK_WIN16
)
1336 ERR(hook
, "called from 16bit hook!\n");
1338 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1342 /***********************************************************************
1343 * DefHookProc16 (USER.235)
1345 LRESULT WINAPI
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1348 /* Note: the *hhook parameter is never used, since we rely on the
1349 * current hook value from the task queue to find the next hook. */
1350 MESSAGEQUEUE
*queue
;
1353 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue16() ))) return 0;
1354 ret
= CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1355 QUEUE_Unlock( queue
);
1360 /***********************************************************************
1361 * CallMsgFilter16 (USER.123)
1363 BOOL16 WINAPI
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1365 if (GetSysModalWindow16()) return FALSE
;
1366 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1367 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1371 /***********************************************************************
1372 * WIN16_CallMsgFilter32 (USER.823)
1374 BOOL16 WINAPI
CallMsgFilter32_16( SEGPTR msg16_32
, INT16 code
, BOOL16 wHaveParamHigh
)
1376 MSG32_16
*lpmsg16_32
= (MSG32_16
*)PTR_SEG_TO_LIN(msg16_32
);
1378 if (wHaveParamHigh
== FALSE
)
1380 lpmsg16_32
->wParamHigh
= 0;
1381 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1382 return CallMsgFilter16(msg16_32
, code
);
1389 msg32
.hwnd
= lpmsg16_32
->msg
.hwnd
;
1390 msg32
.message
= lpmsg16_32
->msg
.message
;
1392 MAKELONG(lpmsg16_32
->msg
.wParam
, lpmsg16_32
->wParamHigh
);
1393 msg32
.lParam
= lpmsg16_32
->msg
.lParam
;
1394 msg32
.time
= lpmsg16_32
->msg
.time
;
1395 msg32
.pt
.x
= (INT
)lpmsg16_32
->msg
.pt
.x
;
1396 msg32
.pt
.y
= (INT
)lpmsg16_32
->msg
.pt
.y
;
1398 ret
= (BOOL16
)CallMsgFilterA(&msg32
, (INT
)code
);
1400 lpmsg16_32
->msg
.hwnd
= msg32
.hwnd
;
1401 lpmsg16_32
->msg
.message
= msg32
.message
;
1402 lpmsg16_32
->msg
.wParam
= LOWORD(msg32
.wParam
);
1403 lpmsg16_32
->msg
.lParam
= msg32
.lParam
;
1404 lpmsg16_32
->msg
.time
= msg32
.time
;
1405 lpmsg16_32
->msg
.pt
.x
= (INT16
)msg32
.pt
.x
;
1406 lpmsg16_32
->msg
.pt
.y
= (INT16
)msg32
.pt
.y
;
1407 lpmsg16_32
->wParamHigh
= HIWORD(msg32
.wParam
);
1414 /***********************************************************************
1415 * CallMsgFilter32A (USER32.15)
1418 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1419 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1421 BOOL WINAPI
CallMsgFilterA( LPMSG msg
, INT code
)
1423 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1424 if (HOOK_CallHooksA( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1426 return HOOK_CallHooksA( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1430 /***********************************************************************
1431 * CallMsgFilter32W (USER32.16)
1433 BOOL WINAPI
CallMsgFilterW( LPMSG msg
, INT code
)
1435 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1436 if (HOOK_CallHooksW( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1438 return HOOK_CallHooksW( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);