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.
29 /* Hook data (pointed to by a HHOOK) */
32 HANDLE16 next
; /* 00 Next hook in chain */
33 HOOKPROC32 proc WINE_PACKED
; /* 02 Hook procedure */
34 INT16 id
; /* 06 Hook id (WH_xxx) */
35 HQUEUE16 ownerQueue
; /* 08 Owner queue (0 for system hook) */
36 HMODULE16 ownerModule
; /* 0a Owner module */
37 WORD flags
; /* 0c flags */
42 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
44 /* This should probably reside in USER heap */
45 static HANDLE16 HOOK_systemHooks
[WH_NB_HOOKS
] = { 0, };
47 typedef VOID (*HOOK_MapFunc
)(INT32
, INT32
, WPARAM32
*, LPARAM
*);
48 typedef VOID (*HOOK_UnMapFunc
)(INT32
, INT32
, WPARAM32
, LPARAM
, WPARAM32
,
51 /***********************************************************************
52 * HOOK_Map16To32Common
54 static void HOOK_Map16To32Common(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
55 LPARAM
*plParam
, BOOL32 bA
)
63 case WH_JOURNALRECORD
:
65 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(*plParam
);
66 LPMSG32 lpmsg32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpmsg32
) );
68 STRUCT32_MSG16to32( lpmsg16
, lpmsg32
);
69 *plParam
= (LPARAM
)lpmsg32
;
73 case WH_JOURNALPLAYBACK
:
75 LPEVENTMSG16 lpem16
= PTR_SEG_TO_LIN(*plParam
);
76 LPEVENTMSG32 lpem32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpem32
) );
78 lpem32
->message
= lpem16
->message
;
79 lpem32
->paramL
= lpem16
->paramL
;
80 lpem32
->paramH
= lpem16
->paramH
;
81 lpem32
->time
= lpem16
->time
;
82 lpem32
->hwnd
= 0; /* FIXME */
84 *plParam
= (LPARAM
)lpem32
;
90 LPCWPSTRUCT16 lpcwp16
= PTR_SEG_TO_LIN(*plParam
);
91 LPCWPSTRUCT32 lpcwp32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcwp32
) );
93 lpcwp32
->hwnd
= lpcwp16
->hwnd
;
94 lpcwp32
->lParam
= lpcwp16
->lParam
;
96 if (bA
) WINPROC_MapMsg16To32A( lpcwp16
->message
, lpcwp16
->wParam
,
97 &lpcwp32
->message
, &lpcwp32
->wParam
,
99 else WINPROC_MapMsg16To32W( lpcwp16
->hwnd
,lpcwp16
->message
, lpcwp16
->wParam
,
100 &lpcwp32
->message
, &lpcwp32
->wParam
,
102 *plParam
= (LPARAM
)lpcwp32
;
111 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(*plParam
);
112 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
113 LPCBT_CREATEWND32A lpcbtcw32
= HeapAlloc( SystemHeap
, 0,
114 sizeof(*lpcbtcw32
) );
115 lpcbtcw32
->lpcs
= HeapAlloc( SystemHeap
, 0,
116 sizeof(*lpcbtcw32
->lpcs
) );
118 STRUCT32_CREATESTRUCT16to32A( lpcs16
,
119 (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
);
121 if (HIWORD(lpcs16
->lpszName
))
122 lpcbtcw32
->lpcs
->lpszName
=
123 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszName
)
124 : HEAP_strdupAtoW( SystemHeap
, 0,
125 PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
127 lpcbtcw32
->lpcs
->lpszName
= (LPCSTR
)lpcs16
->lpszName
;
129 if (HIWORD(lpcs16
->lpszClass
))
130 lpcbtcw32
->lpcs
->lpszClass
=
131 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszClass
)
132 : HEAP_strdupAtoW( SystemHeap
, 0,
133 PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
135 lpcbtcw32
->lpcs
->lpszClass
= (LPCSTR
)lpcs16
->lpszClass
;
137 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
139 *plParam
= (LPARAM
)lpcbtcw32
;
144 LPCBTACTIVATESTRUCT16 lpcas16
= PTR_SEG_TO_LIN(*plParam
);
145 LPCBTACTIVATESTRUCT32 lpcas32
= HeapAlloc( SystemHeap
, 0,
147 lpcas32
->fMouse
= lpcas16
->fMouse
;
148 lpcas32
->hWndActive
= lpcas16
->hWndActive
;
149 *plParam
= (LPARAM
)lpcas32
;
152 case HCBT_CLICKSKIPPED
:
154 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
155 LPMOUSEHOOKSTRUCT32 lpms32
= HeapAlloc( SystemHeap
, 0,
158 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
160 /* wHitTestCode may be negative, so convince compiler to do
161 correct sign extension. Yay. :| */
162 lpms32
->wHitTestCode
= (INT32
)((INT16
)lpms16
->wHitTestCode
);
164 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
165 lpms32
->hwnd
= lpms16
->hwnd
;
166 *plParam
= (LPARAM
)lpms32
;
171 LPRECT16 lprect16
= PTR_SEG_TO_LIN(*plParam
);
172 LPRECT32 lprect32
= HeapAlloc( SystemHeap
, 0,
175 CONV_RECT16TO32( lprect16
, lprect32
);
176 *plParam
= (LPARAM
)lprect32
;
184 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
185 LPMOUSEHOOKSTRUCT32 lpms32
= HeapAlloc( SystemHeap
, 0,
188 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
190 /* wHitTestCode may be negative, so convince compiler to do
191 correct sign extension. Yay. :| */
192 lpms32
->wHitTestCode
= (INT32
)((INT16
)lpms16
->wHitTestCode
);
193 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
194 lpms32
->hwnd
= lpms16
->hwnd
;
195 *plParam
= (LPARAM
)lpms32
;
201 LPDEBUGHOOKINFO16 lpdh16
= PTR_SEG_TO_LIN(*plParam
);
202 LPDEBUGHOOKINFO32 lpdh32
= HeapAlloc( SystemHeap
, 0,
205 lpdh32
->idThread
= 0; /* FIXME */
206 lpdh32
->idThreadInstaller
= 0; /* FIXME */
207 lpdh32
->lParam
= lpdh16
->lParam
; /* FIXME Check for sign ext */
208 lpdh32
->wParam
= lpdh16
->wParam
;
209 lpdh32
->code
= lpdh16
->code
;
211 /* do sign extension if it was WH_MSGFILTER */
212 if (*pwParam
== 0xffff) *pwParam
= WH_MSGFILTER
;
214 *plParam
= (LPARAM
)lpdh32
;
223 case WH_FOREGROUNDIDLE
:
224 case WH_CALLWNDPROCRET
:
225 FIXME(hook
, "\t[%i] 16to32 translation unimplemented\n", id
);
230 /***********************************************************************
233 static void HOOK_Map16To32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
236 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, TRUE
);
240 /***********************************************************************
243 static void HOOK_Map16To32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
246 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, FALSE
);
250 /***********************************************************************
251 * HOOK_UnMap16To32Common
253 static void HOOK_UnMap16To32Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
254 LPARAM lParamOrig
, WPARAM32 wParam
,
255 LPARAM lParam
, BOOL32 bA
)
260 case WH_SYSMSGFILTER
:
261 case WH_JOURNALRECORD
:
262 case WH_JOURNALPLAYBACK
:
264 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
269 LPCWPSTRUCT32 lpcwp32
= (LPCWPSTRUCT32
)lParam
;
270 if (bA
) WINPROC_UnmapMsg16To32A( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
271 lpcwp32
->lParam
, 0 );
272 else WINPROC_UnmapMsg16To32W( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
273 lpcwp32
->lParam
, 0 );
274 HeapFree( SystemHeap
, 0, lpcwp32
);
280 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(lParamOrig
);
281 STRUCT32_MSG32to16( (LPMSG32
)lParam
, lpmsg16
);
282 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
289 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
297 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)lParam
;
298 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParamOrig
);
302 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
303 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszName
);
304 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
305 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszClass
);
308 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
310 HeapFree( SystemHeap
, 0, lpcbtcw32
->lpcs
);
314 case HCBT_CLICKSKIPPED
:
317 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
327 case WH_FOREGROUNDIDLE
:
328 case WH_CALLWNDPROCRET
:
329 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
335 /***********************************************************************
338 static void HOOK_UnMap16To32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
339 LPARAM lParamOrig
, WPARAM32 wParam
,
342 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
347 /***********************************************************************
350 static void HOOK_UnMap16To32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
351 LPARAM lParamOrig
, WPARAM32 wParam
,
354 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
359 /***********************************************************************
360 * HOOK_Map32To16Common
362 static void HOOK_Map32To16Common(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
363 LPARAM
*plParam
, BOOL32 bA
)
368 case WH_SYSMSGFILTER
:
370 case WH_JOURNALRECORD
:
372 LPMSG32 lpmsg32
= (LPMSG32
)*plParam
;
373 LPMSG16 lpmsg16
= SEGPTR_NEW( MSG16
);
375 STRUCT32_MSG32to16( lpmsg32
, lpmsg16
);
377 *plParam
= (LPARAM
)SEGPTR_GET( lpmsg16
);
381 case WH_JOURNALPLAYBACK
:
383 LPEVENTMSG32 lpem32
= (LPEVENTMSG32
)*plParam
;
384 LPEVENTMSG16 lpem16
= SEGPTR_NEW( EVENTMSG16
);
386 lpem16
->message
= lpem32
->message
;
387 lpem16
->paramL
= lpem32
->paramL
;
388 lpem16
->paramH
= lpem32
->paramH
;
389 lpem16
->time
= lpem32
->time
;
391 *plParam
= (LPARAM
)SEGPTR_GET( lpem16
);
397 LPCWPSTRUCT32 lpcwp32
= (LPCWPSTRUCT32
)*plParam
;
398 LPCWPSTRUCT16 lpcwp16
= SEGPTR_NEW( CWPSTRUCT16
);
400 lpcwp16
->hwnd
= lpcwp32
->hwnd
;
401 lpcwp16
->lParam
= lpcwp32
->lParam
;
403 if (bA
) WINPROC_MapMsg32ATo16( lpcwp32
->hwnd
, lpcwp32
->message
,
404 lpcwp32
->wParam
, &lpcwp16
->message
,
405 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
406 else WINPROC_MapMsg32WTo16( lpcwp32
->hwnd
, lpcwp32
->message
,
407 lpcwp32
->wParam
, &lpcwp16
->message
,
408 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
409 *plParam
= (LPARAM
)SEGPTR_GET( lpcwp16
);
418 LPCBTACTIVATESTRUCT32 lpcas32
= (LPCBTACTIVATESTRUCT32
)*plParam
;
419 LPCBTACTIVATESTRUCT16 lpcas16
=SEGPTR_NEW( CBTACTIVATESTRUCT16
);
421 lpcas16
->fMouse
= lpcas32
->fMouse
;
422 lpcas16
->hWndActive
= lpcas32
->hWndActive
;
424 *plParam
= (LPARAM
)SEGPTR_GET( lpcas16
);
428 case HCBT_CLICKSKIPPED
:
430 LPMOUSEHOOKSTRUCT32 lpms32
= (LPMOUSEHOOKSTRUCT32
)*plParam
;
431 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
433 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
435 lpms16
->hwnd
= lpms32
->hwnd
;
436 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
437 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
439 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
445 LPRECT32 lprect32
= (LPRECT32
)*plParam
;
446 LPRECT16 lprect16
= SEGPTR_NEW( RECT16
);
448 CONV_RECT32TO16( lprect32
, lprect16
);
450 *plParam
= (LPARAM
)SEGPTR_GET( lprect16
);
458 LPMOUSEHOOKSTRUCT32 lpms32
= (LPMOUSEHOOKSTRUCT32
)*plParam
;
459 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
461 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
463 lpms16
->hwnd
= lpms32
->hwnd
;
464 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
465 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
467 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
473 LPDEBUGHOOKINFO32 lpdh32
= (LPDEBUGHOOKINFO32
)*plParam
;
474 LPDEBUGHOOKINFO16 lpdh16
= SEGPTR_NEW( DEBUGHOOKINFO16
);
476 lpdh16
->hModuleHook
= 0; /* FIXME */
477 lpdh16
->reserved
= 0;
478 lpdh16
->lParam
= lpdh32
->lParam
;
479 lpdh16
->wParam
= lpdh32
->wParam
;
480 lpdh16
->code
= lpdh32
->code
;
482 *plParam
= (LPARAM
)SEGPTR_GET( lpdh16
);
491 case WH_FOREGROUNDIDLE
:
492 case WH_CALLWNDPROCRET
:
493 FIXME(hook
,"\t[%i] 32to16 translation unimplemented\n", id
);
498 /***********************************************************************
501 static void HOOK_Map32ATo16(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
504 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
506 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)*plParam
;
507 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
508 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
510 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
511 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32
->lpcs
, lpcs16
);
513 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
515 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszName
) );
517 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
519 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
521 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszClass
) );
523 lpcs16
->lpszClass
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszClass
;
525 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
527 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
529 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, TRUE
);
533 /***********************************************************************
536 static void HOOK_Map32WTo16(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
539 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
542 LPCBT_CREATEWND32W lpcbtcw32
= (LPCBT_CREATEWND32W
)*plParam
;
543 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
544 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
546 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
547 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
,
550 name
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszName
);
551 cls
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszClass
);
552 lpcs16
->lpszName
= SEGPTR_GET( name
);
553 lpcs16
->lpszClass
= SEGPTR_GET( cls
);
554 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
556 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
558 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, FALSE
);
562 /***********************************************************************
563 * HOOK_UnMap32To16Common
565 static void HOOK_UnMap32To16Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
566 LPARAM lParamOrig
, WPARAM32 wParam
,
567 LPARAM lParam
, BOOL32 bA
)
572 case WH_SYSMSGFILTER
:
573 case WH_JOURNALRECORD
:
574 case WH_JOURNALPLAYBACK
:
577 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
582 LPCWPSTRUCT16 lpcwp16
= (LPCWPSTRUCT16
)PTR_SEG_TO_LIN(lParam
);
583 LPCWPSTRUCT32 lpcwp32
= (LPCWPSTRUCT32
)lParamOrig
;
584 MSGPARAM16 mp16
= { lpcwp16
->wParam
, lpcwp16
->lParam
, 0 };
586 if (bA
) WINPROC_UnmapMsg32ATo16( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
587 lpcwp32
->lParam
, &mp16
);
588 else WINPROC_UnmapMsg32WTo16( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
589 lpcwp32
->lParam
, &mp16
);
590 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
596 LPMSG32 lpmsg32
= (LPMSG32
)lParamOrig
;
598 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
599 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
608 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)(lParamOrig
);
609 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParam
);
610 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
612 if (HIWORD(lpcs16
->lpszName
))
613 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
615 if (HIWORD(lpcs16
->lpszClass
))
616 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
618 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
620 SEGPTR_FREE( lpcs16
);
624 case HCBT_CLICKSKIPPED
:
627 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
637 case WH_FOREGROUNDIDLE
:
638 case WH_CALLWNDPROCRET
:
639 FIXME(hook
, "\t[%i] skipping unmap\n", id
);
644 /***********************************************************************
647 static void HOOK_UnMap32ATo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
648 LPARAM lParamOrig
, WPARAM32 wParam
,
651 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
656 /***********************************************************************
659 static void HOOK_UnMap32WTo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
660 LPARAM lParamOrig
, WPARAM32 wParam
,
663 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
668 /***********************************************************************
671 static void HOOK_Map32ATo32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
674 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
676 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)*plParam
;
677 LPCBT_CREATEWND32W lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
679 lpcbtcwW
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwW
->lpcs
) );
681 lpcbtcwW
->hwndInsertAfter
= lpcbtcwA
->hwndInsertAfter
;
682 *lpcbtcwW
->lpcs
= *(LPCREATESTRUCT32W
)lpcbtcwA
->lpcs
;
684 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
686 lpcbtcwW
->lpcs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
687 lpcbtcwA
->lpcs
->lpszName
);
690 lpcbtcwW
->lpcs
->lpszName
= (LPWSTR
)lpcbtcwA
->lpcs
->lpszName
;
692 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
694 lpcbtcwW
->lpcs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
695 lpcbtcwA
->lpcs
->lpszClass
);
698 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
699 *plParam
= (LPARAM
)lpcbtcwW
;
705 /***********************************************************************
708 static void HOOK_UnMap32ATo32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
709 LPARAM lParamOrig
, WPARAM32 wParam
,
712 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
714 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)lParam
;
715 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
716 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszName
);
717 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
718 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszClass
);
719 HeapFree( SystemHeap
, 0, lpcbtcwW
->lpcs
);
720 HeapFree( SystemHeap
, 0, lpcbtcwW
);
726 /***********************************************************************
729 static void HOOK_Map32WTo32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
732 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
734 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)*plParam
;
735 LPCBT_CREATEWND32A lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
737 lpcbtcwA
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwA
->lpcs
) );
739 lpcbtcwA
->hwndInsertAfter
= lpcbtcwW
->hwndInsertAfter
;
740 *lpcbtcwA
->lpcs
= *(LPCREATESTRUCT32A
)lpcbtcwW
->lpcs
;
742 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
743 lpcbtcwA
->lpcs
->lpszName
= HEAP_strdupWtoA( SystemHeap
, 0,
744 lpcbtcwW
->lpcs
->lpszName
);
746 lpcbtcwA
->lpcs
->lpszName
= (LPSTR
)lpcbtcwW
->lpcs
->lpszName
;
748 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
749 lpcbtcwA
->lpcs
->lpszClass
= HEAP_strdupWtoA( SystemHeap
, 0,
750 lpcbtcwW
->lpcs
->lpszClass
);
752 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
753 *plParam
= (LPARAM
)lpcbtcwA
;
759 /***********************************************************************
762 static void HOOK_UnMap32WTo32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
763 LPARAM lParamOrig
, WPARAM32 wParam
,
766 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
768 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)lParam
;
769 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
770 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszName
);
771 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
772 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszClass
);
773 HeapFree( SystemHeap
, 0, lpcbtcwA
->lpcs
);
774 HeapFree( SystemHeap
, 0, lpcbtcwA
);
780 /***********************************************************************
781 * Map Function Tables
783 static const HOOK_MapFunc HOOK_MapFuncs
[3][3] =
785 { NULL
, HOOK_Map16To32A
, HOOK_Map16To32W
},
786 { HOOK_Map32ATo16
, NULL
, HOOK_Map32ATo32W
},
787 { HOOK_Map32WTo16
, HOOK_Map32WTo32A
, NULL
}
790 static const HOOK_UnMapFunc HOOK_UnMapFuncs
[3][3] =
792 { NULL
, HOOK_UnMap16To32A
, HOOK_UnMap16To32W
},
793 { HOOK_UnMap32ATo16
, NULL
, HOOK_UnMap32ATo32W
},
794 { HOOK_UnMap32WTo16
, HOOK_UnMap32WTo32A
, NULL
}
798 /***********************************************************************
802 /***********************************************************************
805 * Get the next hook of a given hook.
807 static HANDLE16
HOOK_GetNextHook( HANDLE16 hook
)
809 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( hook
);
811 if (!data
|| !hook
) return 0;
812 if (data
->next
) return data
->next
;
813 if (!data
->ownerQueue
) return 0; /* Already system hook */
815 /* Now start enumerating the system hooks */
816 return HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
820 /***********************************************************************
823 * Get the first hook for a given type.
825 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
830 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
831 hook
= queue
->hooks
[id
- WH_MINHOOK
];
832 if (!hook
) hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
834 QUEUE_Unlock( queue
);
839 /***********************************************************************
842 * Install a given hook.
844 static HHOOK
HOOK_SetHook( INT16 id
, LPVOID proc
, INT32 type
,
845 HMODULE16 hModule
, DWORD dwThreadId
)
851 if ((id
< WH_MINHOOK
) || (id
> WH_MAXHOOK
)) return 0;
853 TRACE(hook
, "Setting hook %d: %08x %04x %08lx\n",
854 id
, (UINT32
)proc
, hModule
, dwThreadId
);
856 /* Create task queue if none present */
859 if (id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(FALSE
);
861 if (dwThreadId
) /* Task-specific hook */
863 if ((id
== WH_JOURNALRECORD
) || (id
== WH_JOURNALPLAYBACK
) ||
864 (id
== WH_SYSMSGFILTER
)) return 0; /* System-only hooks */
865 if (!(hQueue
= GetThreadQueue( dwThreadId
)))
869 /* Create the hook structure */
871 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
872 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
875 data
->ownerQueue
= hQueue
;
876 data
->ownerModule
= hModule
;
879 /* Insert it in the correct linked list */
883 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
);
884 data
->next
= queue
->hooks
[id
- WH_MINHOOK
];
885 queue
->hooks
[id
- WH_MINHOOK
] = handle
;
886 QUEUE_Unlock( queue
);
890 data
->next
= HOOK_systemHooks
[id
- WH_MINHOOK
];
891 HOOK_systemHooks
[id
- WH_MINHOOK
] = handle
;
893 TRACE(hook
, "Setting hook %d: ret=%04x [next=%04x]\n",
894 id
, handle
, data
->next
);
896 return (HHOOK
)( handle
? MAKELONG( handle
, HOOK_MAGIC
) : 0 );
900 /***********************************************************************
903 * Remove a hook from the list.
905 static BOOL32
HOOK_RemoveHook( HANDLE16 hook
)
910 TRACE(hook
, "Removing hook %04x\n", hook
);
912 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return FALSE
;
913 if (data
->flags
& HOOK_INUSE
)
915 /* Mark it for deletion later on */
916 WARN(hook
, "Hook still running, deletion delayed\n" );
917 data
->proc
= (HOOKPROC32
)0;
921 if (data
->id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(TRUE
);
923 /* Remove it from the linked list */
925 if (data
->ownerQueue
)
927 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)QUEUE_Lock( data
->ownerQueue
);
928 if (!queue
) return FALSE
;
929 prevHook
= &queue
->hooks
[data
->id
- WH_MINHOOK
];
930 QUEUE_Unlock( queue
);
932 else prevHook
= &HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
934 while (*prevHook
&& *prevHook
!= hook
)
935 prevHook
= &((HOOKDATA
*)USER_HEAP_LIN_ADDR(*prevHook
))->next
;
937 if (!*prevHook
) return FALSE
;
938 *prevHook
= data
->next
;
939 USER_HEAP_FREE( hook
);
944 /***********************************************************************
947 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
953 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
954 if (data
->proc
) return hook
;
960 /***********************************************************************
963 * Call a hook procedure.
965 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT32 fromtype
, INT32 code
,
966 WPARAM32 wParam
, LPARAM lParam
)
970 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
973 WPARAM32 wParamOrig
= wParam
;
974 LPARAM lParamOrig
= lParam
;
975 HOOK_MapFunc MapFunc
;
976 HOOK_UnMapFunc UnMapFunc
;
978 MapFunc
= HOOK_MapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
979 UnMapFunc
= HOOK_UnMapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
982 MapFunc( data
->id
, code
, &wParam
, &lParam
);
986 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue() ))) return 0;
987 prevHook
= queue
->hCurHook
;
988 queue
->hCurHook
= hook
;
989 data
->flags
|= HOOK_INUSE
;
991 TRACE(hook
, "Calling hook %04x: %d %08x %08lx\n",
992 hook
, code
, wParam
, lParam
);
994 ret
= data
->proc(code
, wParam
, lParam
);
996 TRACE(hook
, "Ret hook %04x = %08lx\n", hook
, ret
);
998 data
->flags
&= ~HOOK_INUSE
;
999 queue
->hCurHook
= prevHook
;
1001 QUEUE_Unlock( queue
);
1004 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
1006 if (!data
->proc
) HOOK_RemoveHook( hook
);
1011 /***********************************************************************
1012 * Exported Functions & APIs
1015 /***********************************************************************
1018 * Don't call this unless you are the if1632/thunk.c.
1020 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
1023 if (HIWORD(hhook
) != HOOK_MAGIC
) return NULL
;
1024 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) ))) return NULL
;
1025 if ((data
->flags
& HOOK_MAPTYPE
) != HOOK_WIN16
) return NULL
;
1026 return (HOOKPROC16
)data
->proc
;
1030 /***********************************************************************
1033 * Replacement for calling HOOK_GetHook from other modules.
1035 BOOL32
HOOK_IsHooked( INT16 id
)
1037 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1038 avoid queue being created if someone wants to merely check ... */
1040 return HOOK_GetHook( id
, GetThreadQueue(0) ) != 0;
1044 /***********************************************************************
1047 * Call a hook chain.
1049 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1054 if (!(hook
= HOOK_GetHook( id
, GetFastQueue() ))) return 0;
1055 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1056 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1059 /***********************************************************************
1062 * Call a hook chain.
1064 LRESULT
HOOK_CallHooks32A( INT32 id
, INT32 code
, WPARAM32 wParam
,
1069 if (!(hook
= HOOK_GetHook( id
, GetFastQueue() ))) return 0;
1070 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1071 return HOOK_CallHook( hook
, HOOK_WIN32A
, code
, wParam
, lParam
);
1074 /***********************************************************************
1077 * Call a hook chain.
1079 LRESULT
HOOK_CallHooks32W( INT32 id
, INT32 code
, WPARAM32 wParam
,
1084 if (!(hook
= HOOK_GetHook( id
, GetFastQueue() ))) return 0;
1085 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1086 return HOOK_CallHook( hook
, HOOK_WIN32W
, code
, wParam
,
1091 /***********************************************************************
1092 * HOOK_ResetQueueHooks
1094 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1096 MESSAGEQUEUE
*queue
;
1098 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
1103 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1105 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1108 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1110 data
->ownerQueue
= hQueue
;
1116 QUEUE_Unlock( queue
);
1120 /***********************************************************************
1121 * HOOK_FreeModuleHooks
1123 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1125 /* remove all system hooks registered by this module */
1131 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1133 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1135 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1138 if( hptr
->ownerModule
== hModule
)
1140 hptr
->flags
&= HOOK_MAPTYPE
;
1141 HOOK_RemoveHook(hook
);
1149 /***********************************************************************
1150 * HOOK_FreeQueueHooks
1152 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1154 /* remove all hooks registered by this queue */
1156 HOOKDATA
* hptr
= NULL
;
1160 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1162 hook
= HOOK_GetHook( id
, hQueue
);
1165 next
= HOOK_GetNextHook(hook
);
1167 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1168 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1170 hptr
->flags
&= HOOK_MAPTYPE
;
1171 HOOK_RemoveHook(hook
);
1179 /***********************************************************************
1180 * SetWindowsHook16 (USER.121)
1182 FARPROC16 WINAPI
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1184 HINSTANCE16 hInst
= FarGetOwner( HIWORD(proc
) );
1186 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1187 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1189 return (FARPROC16
)SetWindowsHookEx16( id
, proc
, hInst
, hTask
);
1192 /***********************************************************************
1193 * SetWindowsHook32A (USER32.525)
1195 HHOOK WINAPI
SetWindowsHook32A( INT32 id
, HOOKPROC32 proc
)
1197 return SetWindowsHookEx32A( id
, proc
, 0, GetCurrentThreadId() );
1200 /***********************************************************************
1201 * SetWindowsHook32W (USER32.528)
1203 HHOOK WINAPI
SetWindowsHook32W( INT32 id
, HOOKPROC32 proc
)
1205 return SetWindowsHookEx32W( id
, proc
, 0, GetCurrentThreadId() );
1209 /***********************************************************************
1210 * SetWindowsHookEx16 (USER.291)
1212 HHOOK WINAPI
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1217 FIXME(hook
, "WH_DEBUG is broken in 16-bit Windows.\n");
1220 return HOOK_SetHook( id
, proc
, HOOK_WIN16
, GetExePtr(hInst
), (DWORD
)hTask
);
1223 /***********************************************************************
1224 * SetWindowsHookEx32A (USER32.526)
1226 HHOOK WINAPI
SetWindowsHookEx32A( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1229 return HOOK_SetHook( id
, proc
, HOOK_WIN32A
, MapHModuleLS(hInst
), dwThreadId
);
1232 /***********************************************************************
1233 * SetWindowsHookEx32W (USER32.527)
1235 HHOOK WINAPI
SetWindowsHookEx32W( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1238 return HOOK_SetHook( id
, proc
, HOOK_WIN32W
, MapHModuleLS(hInst
), dwThreadId
);
1242 /***********************************************************************
1243 * UnhookWindowsHook16 (USER.234)
1245 BOOL16 WINAPI
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1247 return UnhookWindowsHook32( id
, (HOOKPROC32
)proc
);
1250 /***********************************************************************
1251 * UnhookWindowsHook32 (USER32.557)
1253 BOOL32 WINAPI
UnhookWindowsHook32( INT32 id
, HOOKPROC32 proc
)
1255 HANDLE16 hook
= HOOK_GetHook( id
, GetFastQueue() );
1257 TRACE(hook
, "%d %08lx\n", id
, (DWORD
)proc
);
1261 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1262 if (data
->proc
== proc
) break;
1263 hook
= HOOK_GetNextHook( hook
);
1265 if (!hook
) return FALSE
;
1266 return HOOK_RemoveHook( hook
);
1270 /***********************************************************************
1271 * UnhookWindowHookEx16 (USER.292)
1273 BOOL16 WINAPI
UnhookWindowsHookEx16( HHOOK hhook
)
1275 return UnhookWindowsHookEx32( hhook
);
1278 /***********************************************************************
1279 * UnhookWindowHookEx32 (USER32.558)
1281 BOOL32 WINAPI
UnhookWindowsHookEx32( HHOOK hhook
)
1283 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1284 return HOOK_RemoveHook( LOWORD(hhook
) );
1288 /***********************************************************************
1289 * CallNextHookEx16 (USER.293)
1291 * I wouldn't have separated this into 16 and 32 bit versions, but I
1292 * need a way to figure out if I need to do a mapping or not.
1294 LRESULT WINAPI
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1299 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1300 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1302 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1306 /***********************************************************************
1307 * CallNextHookEx32 (USER32.17)
1309 * There aren't ANSI and UNICODE versions of this.
1311 LRESULT WINAPI
CallNextHookEx32( HHOOK hhook
, INT32 code
, WPARAM32 wParam
,
1315 INT32 fromtype
; /* figure out Ansi/Unicode */
1318 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1319 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1321 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1322 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1324 if (fromtype
== HOOK_WIN16
)
1325 ERR(hook
, "called from 16bit hook!\n");
1327 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1331 /***********************************************************************
1332 * DefHookProc16 (USER.235)
1334 LRESULT WINAPI
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1337 /* Note: the *hhook parameter is never used, since we rely on the
1338 * current hook value from the task queue to find the next hook. */
1339 MESSAGEQUEUE
*queue
;
1342 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue() ))) return 0;
1343 ret
= CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1344 QUEUE_Unlock( queue
);
1349 /***********************************************************************
1350 * CallMsgFilter16 (USER.123)
1352 BOOL16 WINAPI
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1354 if (GetSysModalWindow16()) return FALSE
;
1355 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1356 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1360 /***********************************************************************
1361 * WIN16_CallMsgFilter32 (USER.823)
1363 BOOL16 WINAPI
WIN16_CallMsgFilter32( SEGPTR msg16_32
, INT16 code
, BOOL16 wHaveParamHigh
)
1365 MSG16_32
*lpmsg16_32
= (MSG16_32
*)PTR_SEG_TO_LIN(msg16_32
);
1367 if (wHaveParamHigh
== FALSE
)
1369 lpmsg16_32
->wParamHigh
= 0;
1370 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1371 return CallMsgFilter16(msg16_32
, code
);
1378 msg32
.hwnd
= lpmsg16_32
->msg
.hwnd
;
1379 msg32
.message
= lpmsg16_32
->msg
.message
;
1381 MAKELONG(lpmsg16_32
->msg
.wParam
, lpmsg16_32
->wParamHigh
);
1382 msg32
.lParam
= lpmsg16_32
->msg
.lParam
;
1383 msg32
.time
= lpmsg16_32
->msg
.time
;
1384 msg32
.pt
.x
= (INT32
)lpmsg16_32
->msg
.pt
.x
;
1385 msg32
.pt
.y
= (INT32
)lpmsg16_32
->msg
.pt
.y
;
1387 ret
= (BOOL16
)CallMsgFilter32A(&msg32
, (INT32
)code
);
1389 lpmsg16_32
->msg
.hwnd
= msg32
.hwnd
;
1390 lpmsg16_32
->msg
.message
= msg32
.message
;
1391 lpmsg16_32
->msg
.wParam
= LOWORD(msg32
.wParam
);
1392 lpmsg16_32
->msg
.lParam
= msg32
.lParam
;
1393 lpmsg16_32
->msg
.time
= msg32
.time
;
1394 lpmsg16_32
->msg
.pt
.x
= (INT16
)msg32
.pt
.x
;
1395 lpmsg16_32
->msg
.pt
.y
= (INT16
)msg32
.pt
.y
;
1396 lpmsg16_32
->wParamHigh
= HIWORD(msg32
.wParam
);
1403 /***********************************************************************
1404 * CallMsgFilter32A (USER32.15)
1407 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1408 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1410 BOOL32 WINAPI
CallMsgFilter32A( LPMSG32 msg
, INT32 code
)
1412 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1413 if (HOOK_CallHooks32A( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1415 return HOOK_CallHooks32A( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1419 /***********************************************************************
1420 * CallMsgFilter32W (USER32.16)
1422 BOOL32 WINAPI
CallMsgFilter32W( LPMSG32 msg
, INT32 code
)
1424 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1425 if (HOOK_CallHooks32W( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1427 return HOOK_CallHooks32W( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);