2 * Windows hook functions
4 * Copyright 1994, 1995 Alexandre Julliard
7 * Based on investigations by Alex Korobka
12 * A HHOOK is a 32-bit handle for compatibility with Windows 3.0 where it was
13 * a pointer to the next function. Now it is in fact composed of a USER heap
14 * handle in the low 16 bits and of a HOOK_MAGIC value in the high 16 bits.
18 #include "wine/winuser16.h"
19 #include "wine/winbase16.h"
29 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(hook
)
35 /* Hook data (pointed to by a HHOOK) */
38 HANDLE16 next
; /* 00 Next hook in chain */
39 HOOKPROC proc
; /* 02 Hook procedure (original) */
40 INT16 id
; /* 06 Hook id (WH_xxx) */
41 HQUEUE16 ownerQueue
; /* 08 Owner queue (0 for system hook) */
42 HMODULE16 ownerModule
; /* 0a Owner module */
43 WORD flags
; /* 0c flags */
44 HOOKPROC thunk
; /* 0e Hook procedure (CallTo16 thunk) */
49 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
51 /* This should probably reside in USER heap */
52 static HANDLE16 HOOK_systemHooks
[WH_NB_HOOKS
] = { 0, };
54 typedef VOID (*HOOK_MapFunc
)(INT
, INT
, WPARAM
*, LPARAM
*);
55 typedef VOID (*HOOK_UnMapFunc
)(INT
, INT
, WPARAM
, LPARAM
, WPARAM
,
58 /***********************************************************************
59 * HOOK_Map16To32Common
61 static void HOOK_Map16To32Common(INT id
, INT code
, WPARAM
*pwParam
,
62 LPARAM
*plParam
, BOOL bA
)
70 case WH_JOURNALRECORD
:
72 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(*plParam
);
73 LPMSG lpmsg32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpmsg32
) );
75 STRUCT32_MSG16to32( lpmsg16
, lpmsg32
);
76 *plParam
= (LPARAM
)lpmsg32
;
80 case WH_JOURNALPLAYBACK
:
82 LPEVENTMSG16 lpem16
= PTR_SEG_TO_LIN(*plParam
);
83 LPEVENTMSG lpem32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpem32
) );
85 lpem32
->message
= lpem16
->message
;
86 lpem32
->paramL
= lpem16
->paramL
;
87 lpem32
->paramH
= lpem16
->paramH
;
88 lpem32
->time
= lpem16
->time
;
89 lpem32
->hwnd
= 0; /* FIXME */
91 *plParam
= (LPARAM
)lpem32
;
97 LPCWPSTRUCT16 lpcwp16
= PTR_SEG_TO_LIN(*plParam
);
98 LPCWPSTRUCT lpcwp32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcwp32
) );
100 lpcwp32
->hwnd
= lpcwp16
->hwnd
;
101 lpcwp32
->lParam
= lpcwp16
->lParam
;
103 if (bA
) WINPROC_MapMsg16To32A( lpcwp16
->message
, lpcwp16
->wParam
,
104 &lpcwp32
->message
, &lpcwp32
->wParam
,
106 else WINPROC_MapMsg16To32W( lpcwp16
->hwnd
,lpcwp16
->message
, lpcwp16
->wParam
,
107 &lpcwp32
->message
, &lpcwp32
->wParam
,
109 *plParam
= (LPARAM
)lpcwp32
;
118 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(*plParam
);
119 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
120 LPCBT_CREATEWNDA lpcbtcw32
= HeapAlloc( SystemHeap
, 0,
121 sizeof(*lpcbtcw32
) );
122 lpcbtcw32
->lpcs
= HeapAlloc( SystemHeap
, 0,
123 sizeof(*lpcbtcw32
->lpcs
) );
125 STRUCT32_CREATESTRUCT16to32A( lpcs16
,
126 (LPCREATESTRUCTA
)lpcbtcw32
->lpcs
);
128 if (HIWORD(lpcs16
->lpszName
))
129 lpcbtcw32
->lpcs
->lpszName
=
130 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszName
)
131 : HEAP_strdupAtoW( SystemHeap
, 0,
132 PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
134 lpcbtcw32
->lpcs
->lpszName
= (LPCSTR
)lpcs16
->lpszName
;
136 if (HIWORD(lpcs16
->lpszClass
))
137 lpcbtcw32
->lpcs
->lpszClass
=
138 (bA
) ? PTR_SEG_TO_LIN(lpcs16
->lpszClass
)
139 : HEAP_strdupAtoW( SystemHeap
, 0,
140 PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
142 lpcbtcw32
->lpcs
->lpszClass
= (LPCSTR
)lpcs16
->lpszClass
;
144 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
146 *plParam
= (LPARAM
)lpcbtcw32
;
151 LPCBTACTIVATESTRUCT16 lpcas16
= PTR_SEG_TO_LIN(*plParam
);
152 LPCBTACTIVATESTRUCT lpcas32
= HeapAlloc( SystemHeap
, 0,
154 lpcas32
->fMouse
= lpcas16
->fMouse
;
155 lpcas32
->hWndActive
= lpcas16
->hWndActive
;
156 *plParam
= (LPARAM
)lpcas32
;
159 case HCBT_CLICKSKIPPED
:
161 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
162 LPMOUSEHOOKSTRUCT lpms32
= HeapAlloc( SystemHeap
, 0,
165 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
167 /* wHitTestCode may be negative, so convince compiler to do
168 correct sign extension. Yay. :| */
169 lpms32
->wHitTestCode
= (INT
)((INT16
)lpms16
->wHitTestCode
);
171 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
172 lpms32
->hwnd
= lpms16
->hwnd
;
173 *plParam
= (LPARAM
)lpms32
;
178 LPRECT16 lprect16
= PTR_SEG_TO_LIN(*plParam
);
179 LPRECT lprect32
= HeapAlloc( SystemHeap
, 0,
182 CONV_RECT16TO32( lprect16
, lprect32
);
183 *plParam
= (LPARAM
)lprect32
;
191 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
192 LPMOUSEHOOKSTRUCT lpms32
= HeapAlloc( SystemHeap
, 0,
195 CONV_POINT16TO32( &lpms16
->pt
, &lpms32
->pt
);
197 /* wHitTestCode may be negative, so convince compiler to do
198 correct sign extension. Yay. :| */
199 lpms32
->wHitTestCode
= (INT
)((INT16
)lpms16
->wHitTestCode
);
200 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
201 lpms32
->hwnd
= lpms16
->hwnd
;
202 *plParam
= (LPARAM
)lpms32
;
208 LPDEBUGHOOKINFO16 lpdh16
= PTR_SEG_TO_LIN(*plParam
);
209 LPDEBUGHOOKINFO lpdh32
= HeapAlloc( SystemHeap
, 0,
212 lpdh32
->idThread
= 0; /* FIXME */
213 lpdh32
->idThreadInstaller
= 0; /* FIXME */
214 lpdh32
->lParam
= lpdh16
->lParam
; /* FIXME Check for sign ext */
215 lpdh32
->wParam
= lpdh16
->wParam
;
216 lpdh32
->code
= lpdh16
->code
;
218 /* do sign extension if it was WH_MSGFILTER */
219 if (*pwParam
== 0xffff) *pwParam
= WH_MSGFILTER
;
221 *plParam
= (LPARAM
)lpdh32
;
230 case WH_FOREGROUNDIDLE
:
231 case WH_CALLWNDPROCRET
:
232 FIXME("\t[%i] 16to32 translation unimplemented\n", id
);
237 /***********************************************************************
240 static void HOOK_Map16To32A(INT id
, INT code
, WPARAM
*pwParam
,
243 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, TRUE
);
247 /***********************************************************************
250 static void HOOK_Map16To32W(INT id
, INT code
, WPARAM
*pwParam
,
253 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
, FALSE
);
257 /***********************************************************************
258 * HOOK_UnMap16To32Common
260 static void HOOK_UnMap16To32Common(INT id
, INT code
, WPARAM wParamOrig
,
261 LPARAM lParamOrig
, WPARAM wParam
,
262 LPARAM lParam
, BOOL bA
)
267 case WH_SYSMSGFILTER
:
268 case WH_JOURNALRECORD
:
269 case WH_JOURNALPLAYBACK
:
271 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
276 LPCWPSTRUCT lpcwp32
= (LPCWPSTRUCT
)lParam
;
277 if (bA
) WINPROC_UnmapMsg16To32A( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
278 lpcwp32
->lParam
, 0 );
279 else WINPROC_UnmapMsg16To32W( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
280 lpcwp32
->lParam
, 0 );
281 HeapFree( SystemHeap
, 0, lpcwp32
);
287 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(lParamOrig
);
288 STRUCT32_MSG32to16( (LPMSG
)lParam
, lpmsg16
);
289 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
296 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
304 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)lParam
;
305 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParamOrig
);
309 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
310 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszName
);
311 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
312 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszClass
);
315 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
317 HeapFree( SystemHeap
, 0, lpcbtcw32
->lpcs
);
321 case HCBT_CLICKSKIPPED
:
324 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
334 case WH_FOREGROUNDIDLE
:
335 case WH_CALLWNDPROCRET
:
336 FIXME("\t[%i] skipping unmap\n", id
);
342 /***********************************************************************
345 static void HOOK_UnMap16To32A(INT id
, INT code
, WPARAM wParamOrig
,
346 LPARAM lParamOrig
, WPARAM wParam
,
349 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
354 /***********************************************************************
357 static void HOOK_UnMap16To32W(INT id
, INT code
, WPARAM wParamOrig
,
358 LPARAM lParamOrig
, WPARAM wParam
,
361 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
366 /***********************************************************************
367 * HOOK_Map32To16Common
369 static void HOOK_Map32To16Common(INT id
, INT code
, WPARAM
*pwParam
,
370 LPARAM
*plParam
, BOOL bA
)
375 case WH_SYSMSGFILTER
:
377 case WH_JOURNALRECORD
:
379 LPMSG lpmsg32
= (LPMSG
)*plParam
;
380 LPMSG16 lpmsg16
= SEGPTR_NEW( MSG16
);
382 STRUCT32_MSG32to16( lpmsg32
, lpmsg16
);
384 *plParam
= (LPARAM
)SEGPTR_GET( lpmsg16
);
388 case WH_JOURNALPLAYBACK
:
390 LPEVENTMSG lpem32
= (LPEVENTMSG
)*plParam
;
391 LPEVENTMSG16 lpem16
= SEGPTR_NEW( EVENTMSG16
);
393 lpem16
->message
= lpem32
->message
;
394 lpem16
->paramL
= lpem32
->paramL
;
395 lpem16
->paramH
= lpem32
->paramH
;
396 lpem16
->time
= lpem32
->time
;
398 *plParam
= (LPARAM
)SEGPTR_GET( lpem16
);
404 LPCWPSTRUCT lpcwp32
= (LPCWPSTRUCT
)*plParam
;
405 LPCWPSTRUCT16 lpcwp16
= SEGPTR_NEW( CWPSTRUCT16
);
407 lpcwp16
->hwnd
= lpcwp32
->hwnd
;
408 lpcwp16
->lParam
= lpcwp32
->lParam
;
410 if (bA
) WINPROC_MapMsg32ATo16( lpcwp32
->hwnd
, lpcwp32
->message
,
411 lpcwp32
->wParam
, &lpcwp16
->message
,
412 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
413 else WINPROC_MapMsg32WTo16( lpcwp32
->hwnd
, lpcwp32
->message
,
414 lpcwp32
->wParam
, &lpcwp16
->message
,
415 &lpcwp16
->wParam
, &lpcwp16
->lParam
);
416 *plParam
= (LPARAM
)SEGPTR_GET( lpcwp16
);
425 LPCBTACTIVATESTRUCT lpcas32
= (LPCBTACTIVATESTRUCT
)*plParam
;
426 LPCBTACTIVATESTRUCT16 lpcas16
=SEGPTR_NEW( CBTACTIVATESTRUCT16
);
428 lpcas16
->fMouse
= lpcas32
->fMouse
;
429 lpcas16
->hWndActive
= lpcas32
->hWndActive
;
431 *plParam
= (LPARAM
)SEGPTR_GET( lpcas16
);
435 case HCBT_CLICKSKIPPED
:
437 LPMOUSEHOOKSTRUCT lpms32
= (LPMOUSEHOOKSTRUCT
)*plParam
;
438 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
440 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
442 lpms16
->hwnd
= lpms32
->hwnd
;
443 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
444 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
446 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
452 LPRECT lprect32
= (LPRECT
)*plParam
;
453 LPRECT16 lprect16
= SEGPTR_NEW( RECT16
);
455 CONV_RECT32TO16( lprect32
, lprect16
);
457 *plParam
= (LPARAM
)SEGPTR_GET( lprect16
);
465 LPMOUSEHOOKSTRUCT lpms32
= (LPMOUSEHOOKSTRUCT
)*plParam
;
466 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
468 CONV_POINT32TO16( &lpms32
->pt
, &lpms16
->pt
);
470 lpms16
->hwnd
= lpms32
->hwnd
;
471 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
472 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
474 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
480 LPDEBUGHOOKINFO lpdh32
= (LPDEBUGHOOKINFO
)*plParam
;
481 LPDEBUGHOOKINFO16 lpdh16
= SEGPTR_NEW( DEBUGHOOKINFO16
);
483 lpdh16
->hModuleHook
= 0; /* FIXME */
484 lpdh16
->reserved
= 0;
485 lpdh16
->lParam
= lpdh32
->lParam
;
486 lpdh16
->wParam
= lpdh32
->wParam
;
487 lpdh16
->code
= lpdh32
->code
;
489 *plParam
= (LPARAM
)SEGPTR_GET( lpdh16
);
498 case WH_FOREGROUNDIDLE
:
499 case WH_CALLWNDPROCRET
:
500 FIXME("\t[%i] 32to16 translation unimplemented\n", id
);
505 /***********************************************************************
508 static void HOOK_Map32ATo16(INT id
, INT code
, WPARAM
*pwParam
,
511 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
513 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)*plParam
;
514 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
515 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
517 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
518 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32
->lpcs
, lpcs16
);
520 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
522 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszName
) );
524 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
526 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
528 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszClass
) );
530 lpcs16
->lpszClass
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszClass
;
532 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
534 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
536 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, TRUE
);
540 /***********************************************************************
543 static void HOOK_Map32WTo16(INT id
, INT code
, WPARAM
*pwParam
,
546 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
549 LPCBT_CREATEWNDW lpcbtcw32
= (LPCBT_CREATEWNDW
)*plParam
;
550 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
551 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
553 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
554 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA
)lpcbtcw32
->lpcs
,
557 name
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszName
);
558 cls
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszClass
);
559 lpcs16
->lpszName
= SEGPTR_GET( name
);
560 lpcs16
->lpszClass
= SEGPTR_GET( cls
);
561 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
563 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
565 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
, FALSE
);
569 /***********************************************************************
570 * HOOK_UnMap32To16Common
572 static void HOOK_UnMap32To16Common(INT id
, INT code
, WPARAM wParamOrig
,
573 LPARAM lParamOrig
, WPARAM wParam
,
574 LPARAM lParam
, BOOL bA
)
579 case WH_SYSMSGFILTER
:
580 case WH_JOURNALRECORD
:
581 case WH_JOURNALPLAYBACK
:
584 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
589 LPCWPSTRUCT16 lpcwp16
= (LPCWPSTRUCT16
)PTR_SEG_TO_LIN(lParam
);
590 LPCWPSTRUCT lpcwp32
= (LPCWPSTRUCT
)lParamOrig
;
593 mp16
.wParam
= lpcwp16
->wParam
;
594 mp16
.lParam
= lpcwp16
->lParam
;
597 if (bA
) WINPROC_UnmapMsg32ATo16( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
598 lpcwp32
->lParam
, &mp16
);
599 else WINPROC_UnmapMsg32WTo16( lpcwp32
->hwnd
,lpcwp32
->message
, lpcwp32
->wParam
,
600 lpcwp32
->lParam
, &mp16
);
601 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
607 LPMSG lpmsg32
= (LPMSG
)lParamOrig
;
609 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
610 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
619 LPCBT_CREATEWNDA lpcbtcw32
= (LPCBT_CREATEWNDA
)(lParamOrig
);
620 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParam
);
621 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
623 if (HIWORD(lpcs16
->lpszName
))
624 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
626 if (HIWORD(lpcs16
->lpszClass
))
627 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
629 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
631 SEGPTR_FREE( lpcs16
);
635 case HCBT_CLICKSKIPPED
:
638 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
648 case WH_FOREGROUNDIDLE
:
649 case WH_CALLWNDPROCRET
:
650 FIXME("\t[%i] skipping unmap\n", id
);
655 /***********************************************************************
658 static void HOOK_UnMap32ATo16(INT id
, INT code
, WPARAM wParamOrig
,
659 LPARAM lParamOrig
, WPARAM wParam
,
662 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
667 /***********************************************************************
670 static void HOOK_UnMap32WTo16(INT id
, INT code
, WPARAM wParamOrig
,
671 LPARAM lParamOrig
, WPARAM wParam
,
674 HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
679 /***********************************************************************
682 static void HOOK_Map32ATo32W(INT id
, INT code
, WPARAM
*pwParam
,
685 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
687 LPCBT_CREATEWNDA lpcbtcwA
= (LPCBT_CREATEWNDA
)*plParam
;
688 LPCBT_CREATEWNDW lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
690 lpcbtcwW
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwW
->lpcs
) );
692 lpcbtcwW
->hwndInsertAfter
= lpcbtcwA
->hwndInsertAfter
;
693 *lpcbtcwW
->lpcs
= *(LPCREATESTRUCTW
)lpcbtcwA
->lpcs
;
695 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
697 lpcbtcwW
->lpcs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
698 lpcbtcwA
->lpcs
->lpszName
);
701 lpcbtcwW
->lpcs
->lpszName
= (LPWSTR
)lpcbtcwA
->lpcs
->lpszName
;
703 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
705 lpcbtcwW
->lpcs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
706 lpcbtcwA
->lpcs
->lpszClass
);
709 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
710 *plParam
= (LPARAM
)lpcbtcwW
;
716 /***********************************************************************
719 static void HOOK_UnMap32ATo32W(INT id
, INT code
, WPARAM wParamOrig
,
720 LPARAM lParamOrig
, WPARAM wParam
,
723 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
725 LPCBT_CREATEWNDW lpcbtcwW
= (LPCBT_CREATEWNDW
)lParam
;
726 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
727 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszName
);
728 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
729 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszClass
);
730 HeapFree( SystemHeap
, 0, lpcbtcwW
->lpcs
);
731 HeapFree( SystemHeap
, 0, lpcbtcwW
);
737 /***********************************************************************
740 static void HOOK_Map32WTo32A(INT id
, INT code
, WPARAM
*pwParam
,
743 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
745 LPCBT_CREATEWNDW lpcbtcwW
= (LPCBT_CREATEWNDW
)*plParam
;
746 LPCBT_CREATEWNDA lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
748 lpcbtcwA
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwA
->lpcs
) );
750 lpcbtcwA
->hwndInsertAfter
= lpcbtcwW
->hwndInsertAfter
;
751 *lpcbtcwA
->lpcs
= *(LPCREATESTRUCTA
)lpcbtcwW
->lpcs
;
753 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
754 lpcbtcwA
->lpcs
->lpszName
= HEAP_strdupWtoA( SystemHeap
, 0,
755 lpcbtcwW
->lpcs
->lpszName
);
757 lpcbtcwA
->lpcs
->lpszName
= (LPSTR
)lpcbtcwW
->lpcs
->lpszName
;
759 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
760 lpcbtcwA
->lpcs
->lpszClass
= HEAP_strdupWtoA( SystemHeap
, 0,
761 lpcbtcwW
->lpcs
->lpszClass
);
763 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
764 *plParam
= (LPARAM
)lpcbtcwA
;
770 /***********************************************************************
773 static void HOOK_UnMap32WTo32A(INT id
, INT code
, WPARAM wParamOrig
,
774 LPARAM lParamOrig
, WPARAM wParam
,
777 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
779 LPCBT_CREATEWNDA lpcbtcwA
= (LPCBT_CREATEWNDA
)lParam
;
780 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
781 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszName
);
782 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
783 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszClass
);
784 HeapFree( SystemHeap
, 0, lpcbtcwA
->lpcs
);
785 HeapFree( SystemHeap
, 0, lpcbtcwA
);
791 /***********************************************************************
792 * Map Function Tables
794 static const HOOK_MapFunc HOOK_MapFuncs
[3][3] =
796 { NULL
, HOOK_Map16To32A
, HOOK_Map16To32W
},
797 { HOOK_Map32ATo16
, NULL
, HOOK_Map32ATo32W
},
798 { HOOK_Map32WTo16
, HOOK_Map32WTo32A
, NULL
}
801 static const HOOK_UnMapFunc HOOK_UnMapFuncs
[3][3] =
803 { NULL
, HOOK_UnMap16To32A
, HOOK_UnMap16To32W
},
804 { HOOK_UnMap32ATo16
, NULL
, HOOK_UnMap32ATo32W
},
805 { HOOK_UnMap32WTo16
, HOOK_UnMap32WTo32A
, NULL
}
809 /***********************************************************************
813 /***********************************************************************
816 * Get the next hook of a given hook.
818 static HANDLE16
HOOK_GetNextHook( HANDLE16 hook
)
820 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( hook
);
822 if (!data
|| !hook
) return 0;
823 if (data
->next
) return data
->next
;
824 if (!data
->ownerQueue
) return 0; /* Already system hook */
826 /* Now start enumerating the system hooks */
827 return HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
831 /***********************************************************************
834 * Get the first hook for a given type.
836 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
841 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
842 hook
= queue
->hooks
[id
- WH_MINHOOK
];
843 if (!hook
) hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
845 QUEUE_Unlock( queue
);
850 /***********************************************************************
853 * Install a given hook.
855 /* ### start build ### */
856 extern LONG CALLBACK
HOOK_CallTo16_long_wwl(FARPROC16
,WORD
,WORD
,LONG
);
857 /* ### stop build ### */
858 static HHOOK
HOOK_SetHook( INT16 id
, LPVOID proc
, INT type
,
859 HMODULE16 hModule
, DWORD dwThreadId
)
865 if ((id
< WH_MINHOOK
) || (id
> WH_MAXHOOK
)) return 0;
867 TRACE("Setting hook %d: %08x %04x %08lx\n",
868 id
, (UINT
)proc
, hModule
, dwThreadId
);
870 /* Create task queue if none present */
873 if (id
== WH_JOURNALPLAYBACK
) EnableHardwareInput16(FALSE
);
875 if (dwThreadId
) /* Task-specific hook */
877 if ((id
== WH_JOURNALRECORD
) || (id
== WH_JOURNALPLAYBACK
) ||
878 (id
== WH_SYSMSGFILTER
)) return 0; /* System-only hooks */
879 if (!(hQueue
= GetThreadQueue16( dwThreadId
)))
883 /* Create the hook structure */
885 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
886 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
889 data
->ownerQueue
= hQueue
;
890 data
->ownerModule
= hModule
;
893 /* Create CallTo16 thunk for 16-bit hooks */
895 if ( (data
->flags
& HOOK_MAPTYPE
) == HOOK_WIN16
)
896 data
->thunk
= (HOOKPROC
)THUNK_Alloc( (FARPROC16
)data
->proc
,
897 (RELAY
)HOOK_CallTo16_long_wwl
);
899 data
->thunk
= data
->proc
;
901 if ( !data
->thunk
&& data
->proc
)
903 USER_HEAP_FREE( handle
);
907 /* Insert it in the correct linked list */
911 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
);
912 data
->next
= queue
->hooks
[id
- WH_MINHOOK
];
913 queue
->hooks
[id
- WH_MINHOOK
] = handle
;
914 QUEUE_Unlock( queue
);
918 data
->next
= HOOK_systemHooks
[id
- WH_MINHOOK
];
919 HOOK_systemHooks
[id
- WH_MINHOOK
] = handle
;
921 TRACE("Setting hook %d: ret=%04x [next=%04x]\n",
922 id
, handle
, data
->next
);
924 return (HHOOK
)( handle
? MAKELONG( handle
, HOOK_MAGIC
) : 0 );
928 /***********************************************************************
931 * Remove a hook from the list.
933 static BOOL
HOOK_RemoveHook( HANDLE16 hook
)
938 TRACE("Removing hook %04x\n", hook
);
940 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return FALSE
;
941 if (data
->flags
& HOOK_INUSE
)
943 /* Mark it for deletion later on */
944 WARN("Hook still running, deletion delayed\n" );
945 data
->proc
= (HOOKPROC
)0;
949 if (data
->id
== WH_JOURNALPLAYBACK
) EnableHardwareInput16(TRUE
);
951 /* Remove it from the linked list */
953 if (data
->ownerQueue
)
955 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)QUEUE_Lock( data
->ownerQueue
);
956 if (!queue
) return FALSE
;
957 prevHook
= &queue
->hooks
[data
->id
- WH_MINHOOK
];
958 QUEUE_Unlock( queue
);
960 else prevHook
= &HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
962 while (*prevHook
&& *prevHook
!= hook
)
963 prevHook
= &((HOOKDATA
*)USER_HEAP_LIN_ADDR(*prevHook
))->next
;
965 if (!*prevHook
) return FALSE
;
966 *prevHook
= data
->next
;
968 if ( (data
->flags
& HOOK_MAPTYPE
) == HOOK_WIN16
)
969 THUNK_Free( (FARPROC
)data
->thunk
);
971 USER_HEAP_FREE( hook
);
976 /***********************************************************************
979 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
985 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
986 if (data
->proc
) return hook
;
992 /***********************************************************************
995 * Call a hook procedure.
997 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT fromtype
, INT code
,
998 WPARAM wParam
, LPARAM lParam
)
1000 MESSAGEQUEUE
*queue
;
1002 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1006 WPARAM wParamOrig
= wParam
;
1007 LPARAM lParamOrig
= lParam
;
1008 HOOK_MapFunc MapFunc
;
1009 HOOK_UnMapFunc UnMapFunc
;
1011 MapFunc
= HOOK_MapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
1012 UnMapFunc
= HOOK_UnMapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
1015 MapFunc( data
->id
, code
, &wParam
, &lParam
);
1019 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue16() ))) return 0;
1020 prevHook
= queue
->hCurHook
;
1021 queue
->hCurHook
= hook
;
1022 data
->flags
|= HOOK_INUSE
;
1024 TRACE("Calling hook %04x: %d %08x %08lx\n",
1025 hook
, code
, wParam
, lParam
);
1027 /* Suspend window structure locks before calling user code */
1028 iWndsLocks
= WIN_SuspendWndsLock();
1030 ret
= data
->thunk(code
, wParam
, lParam
);
1032 /* Grrr. While the hook procedure is supposed to have an LRESULT return
1033 value even in Win16, it seems that for those hook types where the
1034 return value is interpreted as BOOL, Windows doesn't actually check
1035 the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on
1036 that, because they neglect to clear DX ... */
1037 if ( (data
->flags
& HOOK_MAPTYPE
) == HOOK_WIN16
1038 && data
->id
!= WH_JOURNALPLAYBACK
)
1039 ret
= LOWORD( ret
);
1041 WIN_RestoreWndsLock(iWndsLocks
);
1043 TRACE("Ret hook %04x = %08lx\n", hook
, ret
);
1045 data
->flags
&= ~HOOK_INUSE
;
1046 queue
->hCurHook
= prevHook
;
1048 QUEUE_Unlock( queue
);
1051 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
1053 if (!data
->proc
) HOOK_RemoveHook( hook
);
1058 /***********************************************************************
1059 * Exported Functions & APIs
1062 /***********************************************************************
1065 * Replacement for calling HOOK_GetHook from other modules.
1067 BOOL
HOOK_IsHooked( INT16 id
)
1069 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1070 avoid queue being created if someone wants to merely check ... */
1072 return HOOK_GetHook( id
, GetThreadQueue16(0) ) != 0;
1076 /***********************************************************************
1079 * Call a hook chain.
1081 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1086 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1087 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1088 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1091 /***********************************************************************
1094 * Call a hook chain.
1096 LRESULT
HOOK_CallHooksA( INT id
, INT code
, WPARAM wParam
,
1101 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1102 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1103 return HOOK_CallHook( hook
, HOOK_WIN32A
, code
, wParam
, lParam
);
1106 /***********************************************************************
1109 * Call a hook chain.
1111 LRESULT
HOOK_CallHooksW( INT id
, INT code
, WPARAM wParam
,
1116 if (!(hook
= HOOK_GetHook( id
, GetFastQueue16() ))) return 0;
1117 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1118 return HOOK_CallHook( hook
, HOOK_WIN32W
, code
, wParam
,
1123 /***********************************************************************
1124 * HOOK_ResetQueueHooks
1126 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1128 MESSAGEQUEUE
*queue
;
1130 if ((queue
= (MESSAGEQUEUE
*)QUEUE_Lock( hQueue
)) != NULL
)
1135 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1137 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1140 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1142 data
->ownerQueue
= hQueue
;
1148 QUEUE_Unlock( queue
);
1152 /***********************************************************************
1153 * HOOK_FreeModuleHooks
1155 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1157 /* remove all system hooks registered by this module */
1163 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1165 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1167 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1170 if( hptr
->ownerModule
== hModule
)
1172 hptr
->flags
&= HOOK_MAPTYPE
;
1173 HOOK_RemoveHook(hook
);
1181 /***********************************************************************
1182 * HOOK_FreeQueueHooks
1184 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1186 /* remove all hooks registered by this queue */
1188 HOOKDATA
* hptr
= NULL
;
1192 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1194 hook
= HOOK_GetHook( id
, hQueue
);
1197 next
= HOOK_GetNextHook(hook
);
1199 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1200 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1202 hptr
->flags
&= HOOK_MAPTYPE
;
1203 HOOK_RemoveHook(hook
);
1211 /***********************************************************************
1212 * SetWindowsHook16 (USER.121)
1214 FARPROC16 WINAPI
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1216 HINSTANCE16 hInst
= FarGetOwner16( HIWORD(proc
) );
1218 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1219 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1221 return (FARPROC16
)SetWindowsHookEx16( id
, proc
, hInst
, hTask
);
1224 /***********************************************************************
1225 * SetWindowsHook32A (USER32.525)
1227 HHOOK WINAPI
SetWindowsHookA( INT id
, HOOKPROC proc
)
1229 return SetWindowsHookExA( id
, proc
, 0, GetCurrentThreadId() );
1232 /***********************************************************************
1233 * SetWindowsHook32W (USER32.528)
1235 HHOOK WINAPI
SetWindowsHookW( INT id
, HOOKPROC proc
)
1237 return SetWindowsHookExW( id
, proc
, 0, GetCurrentThreadId() );
1241 /***********************************************************************
1242 * SetWindowsHookEx16 (USER.291)
1244 HHOOK WINAPI
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1249 FIXME("WH_DEBUG is broken in 16-bit Windows.\n");
1252 return HOOK_SetHook( id
, proc
, HOOK_WIN16
, GetExePtr(hInst
), (DWORD
)hTask
);
1255 /***********************************************************************
1256 * SetWindowsHookEx32A (USER32.526)
1258 HHOOK WINAPI
SetWindowsHookExA( INT id
, HOOKPROC proc
, HINSTANCE hInst
,
1261 return HOOK_SetHook( id
, proc
, HOOK_WIN32A
, MapHModuleLS(hInst
), dwThreadId
);
1264 /***********************************************************************
1265 * SetWindowsHookEx32W (USER32.527)
1267 HHOOK WINAPI
SetWindowsHookExW( INT id
, HOOKPROC proc
, HINSTANCE hInst
,
1270 return HOOK_SetHook( id
, proc
, HOOK_WIN32W
, MapHModuleLS(hInst
), dwThreadId
);
1274 /***********************************************************************
1275 * UnhookWindowsHook16 (USER.234)
1277 BOOL16 WINAPI
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1279 return UnhookWindowsHook( id
, (HOOKPROC
)proc
);
1282 /***********************************************************************
1283 * UnhookWindowsHook32 (USER32.557)
1285 BOOL WINAPI
UnhookWindowsHook( INT id
, HOOKPROC proc
)
1287 HANDLE16 hook
= HOOK_GetHook( id
, GetFastQueue16() );
1289 TRACE("%d %08lx\n", id
, (DWORD
)proc
);
1293 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1294 if (data
->proc
== proc
) break;
1295 hook
= HOOK_GetNextHook( hook
);
1297 if (!hook
) return FALSE
;
1298 return HOOK_RemoveHook( hook
);
1302 /***********************************************************************
1303 * UnhookWindowHookEx16 (USER.292)
1305 BOOL16 WINAPI
UnhookWindowsHookEx16( HHOOK hhook
)
1307 return UnhookWindowsHookEx( hhook
);
1310 /***********************************************************************
1311 * UnhookWindowHookEx32 (USER32.558)
1313 BOOL WINAPI
UnhookWindowsHookEx( HHOOK hhook
)
1315 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1316 return HOOK_RemoveHook( LOWORD(hhook
) );
1320 /***********************************************************************
1321 * CallNextHookEx16 (USER.293)
1323 * I wouldn't have separated this into 16 and 32 bit versions, but I
1324 * need a way to figure out if I need to do a mapping or not.
1326 LRESULT WINAPI
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1331 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1332 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1334 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1338 /***********************************************************************
1339 * CallNextHookEx32 (USER32.17)
1341 * There aren't ANSI and UNICODE versions of this.
1343 LRESULT WINAPI
CallNextHookEx( HHOOK hhook
, INT code
, WPARAM wParam
,
1347 INT fromtype
; /* figure out Ansi/Unicode */
1350 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1351 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1353 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1354 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1356 if (fromtype
== HOOK_WIN16
)
1357 ERR("called from 16bit hook!\n");
1359 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1363 /***********************************************************************
1364 * DefHookProc16 (USER.235)
1366 LRESULT WINAPI
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1369 /* Note: the *hhook parameter is never used, since we rely on the
1370 * current hook value from the task queue to find the next hook. */
1371 MESSAGEQUEUE
*queue
;
1374 if (!(queue
= (MESSAGEQUEUE
*)QUEUE_Lock( GetFastQueue16() ))) return 0;
1375 ret
= CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1376 QUEUE_Unlock( queue
);
1381 /***********************************************************************
1382 * CallMsgFilter16 (USER.123)
1384 BOOL16 WINAPI
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1386 if (GetSysModalWindow16()) return FALSE
;
1387 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1388 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1392 /***********************************************************************
1393 * WIN16_CallMsgFilter32 (USER.823)
1395 BOOL16 WINAPI
CallMsgFilter32_16( SEGPTR msg16_32
, INT16 code
, BOOL16 wHaveParamHigh
)
1397 MSG32_16
*lpmsg16_32
= (MSG32_16
*)PTR_SEG_TO_LIN(msg16_32
);
1399 if (wHaveParamHigh
== FALSE
)
1401 lpmsg16_32
->wParamHigh
= 0;
1402 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1403 return CallMsgFilter16(msg16_32
, code
);
1410 msg32
.hwnd
= lpmsg16_32
->msg
.hwnd
;
1411 msg32
.message
= lpmsg16_32
->msg
.message
;
1413 MAKELONG(lpmsg16_32
->msg
.wParam
, lpmsg16_32
->wParamHigh
);
1414 msg32
.lParam
= lpmsg16_32
->msg
.lParam
;
1415 msg32
.time
= lpmsg16_32
->msg
.time
;
1416 msg32
.pt
.x
= (INT
)lpmsg16_32
->msg
.pt
.x
;
1417 msg32
.pt
.y
= (INT
)lpmsg16_32
->msg
.pt
.y
;
1419 ret
= (BOOL16
)CallMsgFilterA(&msg32
, (INT
)code
);
1421 lpmsg16_32
->msg
.hwnd
= msg32
.hwnd
;
1422 lpmsg16_32
->msg
.message
= msg32
.message
;
1423 lpmsg16_32
->msg
.wParam
= LOWORD(msg32
.wParam
);
1424 lpmsg16_32
->msg
.lParam
= msg32
.lParam
;
1425 lpmsg16_32
->msg
.time
= msg32
.time
;
1426 lpmsg16_32
->msg
.pt
.x
= (INT16
)msg32
.pt
.x
;
1427 lpmsg16_32
->msg
.pt
.y
= (INT16
)msg32
.pt
.y
;
1428 lpmsg16_32
->wParamHigh
= HIWORD(msg32
.wParam
);
1435 /***********************************************************************
1436 * CallMsgFilter32A (USER32.15)
1439 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1440 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1442 BOOL WINAPI
CallMsgFilterA( LPMSG msg
, INT code
)
1444 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1445 if (HOOK_CallHooksA( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1447 return HOOK_CallHooksA( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1451 /***********************************************************************
1452 * CallMsgFilter32W (USER32.16)
1454 BOOL WINAPI
CallMsgFilterW( LPMSG msg
, INT code
)
1456 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1457 if (HOOK_CallHooksW( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1459 return HOOK_CallHooksW( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);