Synchronize access to the s_COMLockCount, firstRegisteredClass,
[wine/multimedia.git] / windows / hook.c
blobd0cb5797b52cbdeab9e547500363866e72e1cd42
1 /*
2 * Windows hook functions
4 * Copyright 1994, 1995 Alexandre Julliard
5 * 1996 Andrew Lewycky
7 * Based on investigations by Alex Korobka
8 */
11 * Warning!
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.
17 #include "windef.h"
18 #include "winbase.h"
19 #include "wingdi.h"
20 #include "winuser.h"
21 #include "wine/winuser16.h"
22 #include "wine/winbase16.h"
23 #include "callback.h"
24 #include "hook.h"
25 #include "win.h"
26 #include "queue.h"
27 #include "user.h"
28 #include "heap.h"
29 #include "struct32.h"
30 #include "winproc.h"
31 #include "debugtools.h"
33 DEFAULT_DEBUG_CHANNEL(hook);
35 #include "pshpack1.h"
37 /* Hook data (pointed to by a HHOOK) */
38 typedef struct
40 HANDLE16 next; /* 00 Next hook in chain */
41 HOOKPROC proc; /* 02 Hook procedure (original) */
42 INT16 id; /* 06 Hook id (WH_xxx) */
43 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
44 HMODULE16 ownerModule; /* 0a Owner module */
45 WORD flags; /* 0c flags */
46 HOOKPROC thunk; /* 0e Hook procedure (CallTo16 thunk) */
47 } HOOKDATA;
49 #include "poppack.h"
51 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
53 /* This should probably reside in USER heap */
54 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
56 typedef VOID (*HOOK_MapFunc)(INT, INT, WPARAM *, LPARAM *);
57 typedef VOID (*HOOK_UnMapFunc)(INT, INT, WPARAM, LPARAM, WPARAM,
58 LPARAM);
60 /***********************************************************************
61 * HOOK_Map16To32Common
63 static void HOOK_Map16To32Common(INT id, INT code, WPARAM *pwParam,
64 LPARAM *plParam, BOOL bA )
67 switch( id )
69 case WH_MSGFILTER:
70 case WH_SYSMSGFILTER:
71 case WH_GETMESSAGE:
72 case WH_JOURNALRECORD:
74 LPMSG16 lpmsg16 = MapSL(*plParam);
75 LPMSG lpmsg32 = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpmsg32) );
77 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
78 *plParam = (LPARAM)lpmsg32;
79 break;
82 case WH_JOURNALPLAYBACK:
84 LPEVENTMSG16 lpem16 = MapSL(*plParam);
85 LPEVENTMSG lpem32 = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpem32) );
87 lpem32->message = lpem16->message;
88 lpem32->paramL = lpem16->paramL;
89 lpem32->paramH = lpem16->paramH;
90 lpem32->time = lpem16->time;
91 lpem32->hwnd = 0; /* FIXME */
93 *plParam = (LPARAM)lpem32;
94 break;
97 case WH_CALLWNDPROC:
99 LPCWPSTRUCT16 lpcwp16 = MapSL(*plParam);
100 LPCWPSTRUCT lpcwp32 = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcwp32) );
102 lpcwp32->hwnd = lpcwp16->hwnd;
103 lpcwp32->lParam = lpcwp16->lParam;
105 if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam,
106 &lpcwp32->message, &lpcwp32->wParam,
107 &lpcwp32->lParam );
108 else WINPROC_MapMsg16To32W( lpcwp16->hwnd,lpcwp16->message, lpcwp16->wParam,
109 &lpcwp32->message, &lpcwp32->wParam,
110 &lpcwp32->lParam );
111 *plParam = (LPARAM)lpcwp32;
112 break;
115 case WH_CBT:
116 switch (code)
118 case HCBT_CREATEWND:
120 LPCBT_CREATEWND16 lpcbtcw16 = MapSL(*plParam);
121 LPCREATESTRUCT16 lpcs16 = MapSL((SEGPTR)lpcbtcw16->lpcs);
122 LPCBT_CREATEWNDA lpcbtcw32 = HeapAlloc( GetProcessHeap(), 0,
123 sizeof(*lpcbtcw32) );
124 lpcbtcw32->lpcs = HeapAlloc( GetProcessHeap(), 0,
125 sizeof(*lpcbtcw32->lpcs) );
127 STRUCT32_CREATESTRUCT16to32A( lpcs16,
128 (LPCREATESTRUCTA)lpcbtcw32->lpcs );
130 if (HIWORD(lpcs16->lpszName))
131 lpcbtcw32->lpcs->lpszName =
132 (bA) ? MapSL(lpcs16->lpszName)
133 : HEAP_strdupAtoW( GetProcessHeap(), 0,
134 MapSL(lpcs16->lpszName) );
135 else
136 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
138 if (HIWORD(lpcs16->lpszClass))
139 lpcbtcw32->lpcs->lpszClass =
140 (bA) ? MapSL(lpcs16->lpszClass)
141 : HEAP_strdupAtoW( GetProcessHeap(), 0,
142 MapSL(lpcs16->lpszClass) );
143 else
144 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
146 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
148 *plParam = (LPARAM)lpcbtcw32;
149 break;
151 case HCBT_ACTIVATE:
153 LPCBTACTIVATESTRUCT16 lpcas16 = MapSL(*plParam);
154 LPCBTACTIVATESTRUCT lpcas32 = HeapAlloc( GetProcessHeap(), 0,
155 sizeof(*lpcas32) );
156 lpcas32->fMouse = lpcas16->fMouse;
157 lpcas32->hWndActive = lpcas16->hWndActive;
158 *plParam = (LPARAM)lpcas32;
159 break;
161 case HCBT_CLICKSKIPPED:
163 LPMOUSEHOOKSTRUCT16 lpms16 = MapSL(*plParam);
164 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( GetProcessHeap(), 0,
165 sizeof(*lpms32) );
167 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
169 /* wHitTestCode may be negative, so convince compiler to do
170 correct sign extension. Yay. :| */
171 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
173 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
174 lpms32->hwnd = lpms16->hwnd;
175 *plParam = (LPARAM)lpms32;
176 break;
178 case HCBT_MOVESIZE:
180 LPRECT16 lprect16 = MapSL(*plParam);
181 LPRECT lprect32 = HeapAlloc( GetProcessHeap(), 0,
182 sizeof(*lprect32) );
184 CONV_RECT16TO32( lprect16, lprect32 );
185 *plParam = (LPARAM)lprect32;
186 break;
189 break;
191 case WH_MOUSE:
193 LPMOUSEHOOKSTRUCT16 lpms16 = MapSL(*plParam);
194 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( GetProcessHeap(), 0,
195 sizeof(*lpms32) );
197 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
199 /* wHitTestCode may be negative, so convince compiler to do
200 correct sign extension. Yay. :| */
201 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
202 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
203 lpms32->hwnd = lpms16->hwnd;
204 *plParam = (LPARAM)lpms32;
205 break;
208 case WH_DEBUG:
210 LPDEBUGHOOKINFO16 lpdh16 = MapSL(*plParam);
211 LPDEBUGHOOKINFO lpdh32 = HeapAlloc( GetProcessHeap(), 0,
212 sizeof(*lpdh32) );
214 lpdh32->idThread = 0; /* FIXME */
215 lpdh32->idThreadInstaller = 0; /* FIXME */
216 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
217 lpdh32->wParam = lpdh16->wParam;
218 lpdh32->code = lpdh16->code;
220 /* do sign extension if it was WH_MSGFILTER */
221 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
223 *plParam = (LPARAM)lpdh32;
224 break;
227 case WH_SHELL:
228 case WH_KEYBOARD:
229 break;
231 case WH_HARDWARE:
232 case WH_FOREGROUNDIDLE:
233 case WH_CALLWNDPROCRET:
234 FIXME("\t[%i] 16to32 translation unimplemented\n", id);
239 /***********************************************************************
240 * HOOK_Map16To32A
242 static void HOOK_Map16To32A(INT id, INT code, WPARAM *pwParam,
243 LPARAM *plParam)
245 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
249 /***********************************************************************
250 * HOOK_Map16To32W
252 static void HOOK_Map16To32W(INT id, INT code, WPARAM *pwParam,
253 LPARAM *plParam)
255 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
259 /***********************************************************************
260 * HOOK_UnMap16To32Common
262 static void HOOK_UnMap16To32Common(INT id, INT code, WPARAM wParamOrig,
263 LPARAM lParamOrig, WPARAM wParam,
264 LPARAM lParam, BOOL bA)
266 switch (id)
268 case WH_MSGFILTER:
269 case WH_SYSMSGFILTER:
270 case WH_JOURNALRECORD:
271 case WH_JOURNALPLAYBACK:
273 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
274 break;
276 case WH_CALLWNDPROC:
278 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParam;
279 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
280 lpcwp32->lParam, 0 );
281 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
282 lpcwp32->lParam, 0 );
283 HeapFree( GetProcessHeap(), 0, lpcwp32 );
284 break;
287 case WH_GETMESSAGE:
289 LPMSG16 lpmsg16 = MapSL(lParamOrig);
290 STRUCT32_MSG32to16( (LPMSG)lParam, lpmsg16 );
291 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
292 break;
295 case WH_MOUSE:
296 case WH_DEBUG:
298 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
299 break;
301 case WH_CBT:
302 switch (code)
304 case HCBT_CREATEWND:
306 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)lParam;
307 LPCBT_CREATEWND16 lpcbtcw16 = MapSL(lParamOrig);
309 if( !bA )
311 if (HIWORD(lpcbtcw32->lpcs->lpszName))
312 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
313 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
314 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
317 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
319 HeapFree( GetProcessHeap(), 0, lpcbtcw32->lpcs );
320 } /* fall through */
322 case HCBT_ACTIVATE:
323 case HCBT_CLICKSKIPPED:
324 case HCBT_MOVESIZE:
326 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam);
327 break;
329 break;
331 case WH_SHELL:
332 case WH_KEYBOARD:
333 break;
335 case WH_HARDWARE:
336 case WH_FOREGROUNDIDLE:
337 case WH_CALLWNDPROCRET:
338 FIXME("\t[%i] skipping unmap\n", id);
339 break;
344 /***********************************************************************
345 * HOOK_UnMap16To32A
347 static void HOOK_UnMap16To32A(INT id, INT code, WPARAM wParamOrig,
348 LPARAM lParamOrig, WPARAM wParam,
349 LPARAM lParam)
351 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
352 lParam, TRUE );
356 /***********************************************************************
357 * HOOK_UnMap16To32W
359 static void HOOK_UnMap16To32W(INT id, INT code, WPARAM wParamOrig,
360 LPARAM lParamOrig, WPARAM wParam,
361 LPARAM lParam)
363 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
364 lParam, FALSE );
368 /***********************************************************************
369 * HOOK_Map32To16Common
371 static void HOOK_Map32To16Common(INT id, INT code, WPARAM *pwParam,
372 LPARAM *plParam, BOOL bA)
374 switch (id)
376 case WH_MSGFILTER:
377 case WH_SYSMSGFILTER:
378 case WH_GETMESSAGE:
379 case WH_JOURNALRECORD:
381 LPMSG lpmsg32 = (LPMSG)*plParam;
382 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
384 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
386 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
387 break;
390 case WH_JOURNALPLAYBACK:
392 LPEVENTMSG lpem32 = (LPEVENTMSG)*plParam;
393 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
395 lpem16->message = lpem32->message;
396 lpem16->paramL = lpem32->paramL;
397 lpem16->paramH = lpem32->paramH;
398 lpem16->time = lpem32->time;
400 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
401 break;
404 case WH_CALLWNDPROC:
406 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)*plParam;
407 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
409 lpcwp16->hwnd = lpcwp32->hwnd;
410 lpcwp16->lParam = lpcwp32->lParam;
412 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
413 lpcwp32->wParam, &lpcwp16->message,
414 &lpcwp16->wParam, &lpcwp16->lParam );
415 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
416 lpcwp32->wParam, &lpcwp16->message,
417 &lpcwp16->wParam, &lpcwp16->lParam );
418 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
419 break;
422 case WH_CBT:
423 switch (code)
425 case HCBT_ACTIVATE:
427 LPCBTACTIVATESTRUCT lpcas32 = (LPCBTACTIVATESTRUCT)*plParam;
428 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
430 lpcas16->fMouse = lpcas32->fMouse;
431 lpcas16->hWndActive = lpcas32->hWndActive;
433 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
434 break;
437 case HCBT_CLICKSKIPPED:
439 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
440 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
442 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
444 lpms16->hwnd = lpms32->hwnd;
445 lpms16->wHitTestCode = lpms32->wHitTestCode;
446 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
448 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
449 break;
452 case HCBT_MOVESIZE:
454 LPRECT lprect32 = (LPRECT)*plParam;
455 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
457 CONV_RECT32TO16( lprect32, lprect16 );
459 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
460 break;
463 break;
465 case WH_MOUSE:
467 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
468 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
470 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
472 lpms16->hwnd = lpms32->hwnd;
473 lpms16->wHitTestCode = lpms32->wHitTestCode;
474 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
476 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
477 break;
480 case WH_DEBUG:
482 LPDEBUGHOOKINFO lpdh32 = (LPDEBUGHOOKINFO)*plParam;
483 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
485 lpdh16->hModuleHook = 0; /* FIXME */
486 lpdh16->reserved = 0;
487 lpdh16->lParam = lpdh32->lParam;
488 lpdh16->wParam = lpdh32->wParam;
489 lpdh16->code = lpdh32->code;
491 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
492 break;
495 case WH_SHELL:
496 case WH_KEYBOARD:
497 break;
499 case WH_HARDWARE:
500 case WH_FOREGROUNDIDLE:
501 case WH_CALLWNDPROCRET:
502 FIXME("\t[%i] 32to16 translation unimplemented\n", id);
507 /***********************************************************************
508 * HOOK_Map32ATo16
510 static void HOOK_Map32ATo16(INT id, INT code, WPARAM *pwParam,
511 LPARAM *plParam)
513 if (id == WH_CBT && code == HCBT_CREATEWND)
515 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)*plParam;
516 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
517 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
519 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
520 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
522 if (HIWORD(lpcbtcw32->lpcs->lpszName))
523 lpcs16->lpszName =
524 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
525 else
526 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
528 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
529 lpcs16->lpszClass =
530 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
531 else
532 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
534 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
536 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
538 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
542 /***********************************************************************
543 * HOOK_Map32WTo16
545 static void HOOK_Map32WTo16(INT id, INT code, WPARAM *pwParam,
546 LPARAM *plParam)
548 if (id == WH_CBT && code == HCBT_CREATEWND)
550 LPSTR name, cls;
551 LPCBT_CREATEWNDW lpcbtcw32 = (LPCBT_CREATEWNDW)*plParam;
552 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
553 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
555 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
556 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA)lpcbtcw32->lpcs,
557 lpcs16 );
559 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
560 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
561 lpcs16->lpszName = SEGPTR_GET( name );
562 lpcs16->lpszClass = SEGPTR_GET( cls );
563 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
565 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
567 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
571 /***********************************************************************
572 * HOOK_UnMap32To16Common
574 static void HOOK_UnMap32To16Common(INT id, INT code, WPARAM wParamOrig,
575 LPARAM lParamOrig, WPARAM wParam,
576 LPARAM lParam, BOOL bA)
578 switch (id)
580 case WH_MSGFILTER:
581 case WH_SYSMSGFILTER:
582 case WH_JOURNALRECORD:
583 case WH_JOURNALPLAYBACK:
584 case WH_MOUSE:
585 case WH_DEBUG:
586 SEGPTR_FREE( MapSL(lParam) );
587 break;
589 case WH_CALLWNDPROC:
591 LPCWPSTRUCT16 lpcwp16 = MapSL(lParam);
592 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParamOrig;
593 MSGPARAM16 mp16;
595 mp16.wParam = lpcwp16->wParam;
596 mp16.lParam = lpcwp16->lParam;
597 mp16.lResult = 0;
599 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
600 lpcwp32->lParam, &mp16 );
601 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
602 lpcwp32->lParam, &mp16 );
603 SEGPTR_FREE( MapSL(lParam) );
604 break;
607 case WH_GETMESSAGE:
609 LPMSG lpmsg32 = (LPMSG)lParamOrig;
611 STRUCT32_MSG16to32( MapSL(lParam), lpmsg32 );
612 SEGPTR_FREE( MapSL(lParam) );
613 break;
616 case WH_CBT:
617 switch (code)
619 case HCBT_CREATEWND:
621 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)(lParamOrig);
622 LPCBT_CREATEWND16 lpcbtcw16 = MapSL(lParam);
623 LPCREATESTRUCT16 lpcs16 = MapSL((SEGPTR)lpcbtcw16->lpcs);
625 if (HIWORD(lpcs16->lpszName))
626 SEGPTR_FREE( MapSL(lpcs16->lpszName) );
628 if (HIWORD(lpcs16->lpszClass))
629 SEGPTR_FREE( MapSL(lpcs16->lpszClass) );
631 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
633 SEGPTR_FREE( lpcs16 );
634 } /* fall through */
636 case HCBT_ACTIVATE:
637 case HCBT_CLICKSKIPPED:
638 case HCBT_MOVESIZE:
640 SEGPTR_FREE( MapSL(lParam) );
641 break;
643 break;
645 case WH_SHELL:
646 case WH_KEYBOARD:
647 break;
649 case WH_HARDWARE:
650 case WH_FOREGROUNDIDLE:
651 case WH_CALLWNDPROCRET:
652 FIXME("\t[%i] skipping unmap\n", id);
657 /***********************************************************************
658 * HOOK_UnMap32ATo16
660 static void HOOK_UnMap32ATo16(INT id, INT code, WPARAM wParamOrig,
661 LPARAM lParamOrig, WPARAM wParam,
662 LPARAM lParam)
664 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
665 lParam, TRUE );
669 /***********************************************************************
670 * HOOK_UnMap32WTo16
672 static void HOOK_UnMap32WTo16(INT id, INT code, WPARAM wParamOrig,
673 LPARAM lParamOrig, WPARAM wParam,
674 LPARAM lParam)
676 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
677 lParam, FALSE );
681 /***********************************************************************
682 * HOOK_Map32ATo32W
684 static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
685 LPARAM *plParam)
687 if (id == WH_CBT && code == HCBT_CREATEWND)
689 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
690 LPCBT_CREATEWNDW lpcbtcwW = HeapAlloc( GetProcessHeap(), 0,
691 sizeof(*lpcbtcwW) );
692 lpcbtcwW->lpcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwW->lpcs) );
694 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
695 *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
697 if (HIWORD(lpcbtcwA->lpcs->lpszName))
699 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
700 lpcbtcwA->lpcs->lpszName );
702 else
703 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
705 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
707 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
708 lpcbtcwA->lpcs->lpszClass );
710 else
711 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
712 *plParam = (LPARAM)lpcbtcwW;
714 return;
718 /***********************************************************************
719 * HOOK_UnMap32ATo32W
721 static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
722 LPARAM lParamOrig, WPARAM wParam,
723 LPARAM lParam)
725 if (id == WH_CBT && code == HCBT_CREATEWND)
727 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
728 if (HIWORD(lpcbtcwW->lpcs->lpszName))
729 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
730 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
731 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
732 HeapFree( GetProcessHeap(), 0, lpcbtcwW->lpcs );
733 HeapFree( GetProcessHeap(), 0, lpcbtcwW );
735 return;
739 /***********************************************************************
740 * HOOK_Map32WTo32A
742 static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
743 LPARAM *plParam)
745 if (id == WH_CBT && code == HCBT_CREATEWND)
747 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
748 LPCBT_CREATEWNDA lpcbtcwA = HeapAlloc( GetProcessHeap(), 0,
749 sizeof(*lpcbtcwA) );
750 lpcbtcwA->lpcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwA->lpcs) );
752 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
753 *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
755 if (HIWORD(lpcbtcwW->lpcs->lpszName))
756 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
757 lpcbtcwW->lpcs->lpszName );
758 else
759 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
761 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
762 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
763 lpcbtcwW->lpcs->lpszClass );
764 else
765 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
766 *plParam = (LPARAM)lpcbtcwA;
768 return;
772 /***********************************************************************
773 * HOOK_UnMap32WTo32A
775 static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
776 LPARAM lParamOrig, WPARAM wParam,
777 LPARAM lParam)
779 if (id == WH_CBT && code == HCBT_CREATEWND)
781 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
782 if (HIWORD(lpcbtcwA->lpcs->lpszName))
783 HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
784 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
785 HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
786 HeapFree( GetProcessHeap(), 0, lpcbtcwA->lpcs );
787 HeapFree( GetProcessHeap(), 0, lpcbtcwA );
789 return;
793 /***********************************************************************
794 * Map Function Tables
796 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
798 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
799 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
800 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
803 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
805 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
806 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
807 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
811 /***********************************************************************
812 * Internal Functions
815 /***********************************************************************
816 * HOOK_GetNextHook
818 * Get the next hook of a given hook.
820 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
822 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
824 if (!data || !hook) return 0;
825 if (data->next) return data->next;
826 if (!data->ownerQueue) return 0; /* Already system hook */
828 /* Now start enumerating the system hooks */
829 return HOOK_systemHooks[data->id - WH_MINHOOK];
833 /***********************************************************************
834 * HOOK_GetHook
836 * Get the first hook for a given type.
838 static HANDLE16 HOOK_GetHook( INT16 id )
840 MESSAGEQUEUE *queue;
841 HANDLE16 hook = 0;
843 if ((queue = QUEUE_Current()) != NULL)
844 hook = queue->hooks[id - WH_MINHOOK];
845 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
846 return hook;
850 /***********************************************************************
851 * HOOK_SetHook
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 )
861 HOOKDATA *data;
862 HANDLE16 handle;
863 HQUEUE16 hQueue = 0;
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 */
871 InitThreadInput16( 0, 0 );
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 )))
880 return 0;
883 /* Create the hook structure */
885 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
886 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
887 data->proc = proc;
888 data->id = id;
889 data->ownerQueue = hQueue;
890 data->ownerModule = hModule;
891 data->flags = type;
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 );
898 else
899 data->thunk = data->proc;
901 if ( !data->thunk && data->proc )
903 USER_HEAP_FREE( handle );
904 return 0;
907 /* Insert it in the correct linked list */
909 if (hQueue)
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 );
916 else
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 /***********************************************************************
929 * HOOK_RemoveHook
931 * Remove a hook from the list.
933 static BOOL HOOK_RemoveHook( HANDLE16 hook )
935 HOOKDATA *data;
936 HANDLE16 *prevHook;
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;
946 return TRUE;
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 );
972 return TRUE;
976 /***********************************************************************
977 * HOOK_FindValidHook
979 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
981 HOOKDATA *data;
983 for (;;)
985 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
986 if (data->proc) return hook;
987 hook = data->next;
992 /***********************************************************************
993 * HOOK_CallHook
995 * Call a hook procedure.
997 static LRESULT HOOK_CallHook( HANDLE16 hook, INT fromtype, INT code,
998 WPARAM wParam, LPARAM lParam )
1000 MESSAGEQUEUE *queue;
1001 HANDLE16 prevHook;
1002 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1003 LRESULT ret;
1004 int iWndsLocks;
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];
1014 if (MapFunc)
1015 MapFunc( data->id, code, &wParam, &lParam );
1017 /* Now call it */
1019 if (!(queue = QUEUE_Current())) 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 if (UnMapFunc)
1049 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
1051 if (!data->proc) HOOK_RemoveHook( hook );
1053 return ret;
1056 /***********************************************************************
1057 * Exported Functions & APIs
1060 /***********************************************************************
1061 * HOOK_IsHooked
1063 * Replacement for calling HOOK_GetHook from other modules.
1065 BOOL HOOK_IsHooked( INT16 id )
1067 return HOOK_GetHook( id ) != 0;
1071 /***********************************************************************
1072 * HOOK_CallHooks16
1074 * Call a hook chain.
1076 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1077 LPARAM lParam )
1079 HANDLE16 hook;
1081 if (!(hook = HOOK_GetHook( id ))) return 0;
1082 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1083 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1086 /***********************************************************************
1087 * HOOK_CallHooksA
1089 * Call a hook chain.
1091 LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
1092 LPARAM lParam )
1094 HANDLE16 hook;
1096 if (!(hook = HOOK_GetHook( id ))) return 0;
1097 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1098 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1101 /***********************************************************************
1102 * HOOK_CallHooksW
1104 * Call a hook chain.
1106 LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
1107 LPARAM lParam )
1109 HANDLE16 hook;
1111 if (!(hook = HOOK_GetHook( id ))) return 0;
1112 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1113 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1114 lParam );
1118 /***********************************************************************
1119 * HOOK_FreeModuleHooks
1121 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1123 /* remove all system hooks registered by this module */
1125 HOOKDATA* hptr;
1126 HHOOK hook, next;
1127 int id;
1129 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1131 hook = HOOK_systemHooks[id - WH_MINHOOK];
1132 while( hook )
1133 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1135 next = hptr->next;
1136 if( hptr->ownerModule == hModule )
1138 hptr->flags &= HOOK_MAPTYPE;
1139 HOOK_RemoveHook(hook);
1141 hook = next;
1143 else hook = 0;
1147 /***********************************************************************
1148 * HOOK_FreeQueueHooks
1150 void HOOK_FreeQueueHooks(void)
1152 /* remove all hooks registered by the current queue */
1154 HOOKDATA* hptr = NULL;
1155 HHOOK hook, next;
1156 int id;
1158 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1160 hook = HOOK_GetHook( id );
1161 while( hook )
1163 next = HOOK_GetNextHook(hook);
1165 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1166 if( hptr && hptr->ownerQueue )
1168 hptr->flags &= HOOK_MAPTYPE;
1169 HOOK_RemoveHook(hook);
1171 hook = next;
1177 /***********************************************************************
1178 * SetWindowsHook (USER.121)
1180 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1182 HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
1184 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1185 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1187 return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
1190 /***********************************************************************
1191 * SetWindowsHookA (USER32.@)
1193 HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
1195 return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
1198 /***********************************************************************
1199 * SetWindowsHookW (USER32.@)
1201 HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
1203 return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
1207 /***********************************************************************
1208 * SetWindowsHookEx (USER.291)
1209 * SetWindowsHookEx16 (USER32.@)
1211 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1212 HTASK16 hTask )
1214 if (id == WH_DEBUG)
1216 FIXME("WH_DEBUG is broken in 16-bit Windows.\n");
1217 return 0;
1219 return HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), (DWORD)hTask );
1222 /***********************************************************************
1223 * SetWindowsHookExA (USER32.@)
1225 HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
1226 DWORD dwThreadId )
1228 return HOOK_SetHook( id, proc, HOOK_WIN32A, MapHModuleLS(hInst), dwThreadId );
1231 /***********************************************************************
1232 * SetWindowsHookExW (USER32.@)
1234 HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
1235 DWORD dwThreadId )
1237 return HOOK_SetHook( id, proc, HOOK_WIN32W, MapHModuleLS(hInst), dwThreadId );
1241 /***********************************************************************
1242 * UnhookWindowsHook (USER.234)
1244 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1246 return UnhookWindowsHook( id, (HOOKPROC)proc );
1249 /***********************************************************************
1250 * UnhookWindowsHook (USER32.@)
1252 BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
1254 HANDLE16 hook = HOOK_GetHook( id );
1256 TRACE("%d %08lx\n", id, (DWORD)proc );
1258 while (hook)
1260 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1261 if (data->proc == proc) break;
1262 hook = HOOK_GetNextHook( hook );
1264 if (!hook) return FALSE;
1265 return HOOK_RemoveHook( hook );
1269 /***********************************************************************
1270 * UnhookWindowsHookEx (USER.292)
1272 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1274 return UnhookWindowsHookEx( hhook );
1277 /***********************************************************************
1278 * UnhookWindowsHookEx (USER32.@)
1280 BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
1282 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1283 return HOOK_RemoveHook( LOWORD(hhook) );
1287 /***********************************************************************
1288 * CallNextHookEx (USER.293)
1289 * CallNextHookEx16 (USER32.@)
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,
1295 LPARAM lParam )
1297 HANDLE16 next;
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 * CallNextHookEx (USER32.@)
1309 * There aren't ANSI and UNICODE versions of this.
1311 LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
1312 LPARAM lParam )
1314 HANDLE16 next;
1315 INT fromtype; /* figure out Ansi/Unicode */
1316 HOOKDATA *oldhook;
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("called from 16bit hook!\n");
1327 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1331 /***********************************************************************
1332 * DefHookProc (USER.235)
1334 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1335 HHOOK *hhook )
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;
1341 if (!(queue = QUEUE_Current())) return 0;
1342 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1346 /***********************************************************************
1347 * CallMsgFilter (USER.123)
1349 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1351 if (GetSysModalWindow16()) return FALSE;
1352 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1353 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1357 /***********************************************************************
1358 * CallMsgFilter32 (USER.823)
1360 BOOL16 WINAPI CallMsgFilter32_16( SEGPTR msg16_32, INT16 code, BOOL16 wHaveParamHigh )
1362 MSG32_16 *lpmsg16_32 = MapSL(msg16_32);
1364 if (wHaveParamHigh == FALSE)
1366 lpmsg16_32->wParamHigh = 0;
1367 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1368 return CallMsgFilter16(msg16_32, code);
1370 else
1372 MSG msg32;
1373 BOOL16 ret;
1375 msg32.hwnd = lpmsg16_32->msg.hwnd;
1376 msg32.message = lpmsg16_32->msg.message;
1377 msg32.wParam =
1378 MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
1379 msg32.lParam = lpmsg16_32->msg.lParam;
1380 msg32.time = lpmsg16_32->msg.time;
1381 msg32.pt.x = (INT)lpmsg16_32->msg.pt.x;
1382 msg32.pt.y = (INT)lpmsg16_32->msg.pt.y;
1384 ret = (BOOL16)CallMsgFilterA(&msg32, (INT)code);
1386 lpmsg16_32->msg.hwnd = msg32.hwnd;
1387 lpmsg16_32->msg.message = msg32.message;
1388 lpmsg16_32->msg.wParam = LOWORD(msg32.wParam);
1389 lpmsg16_32->msg.lParam = msg32.lParam;
1390 lpmsg16_32->msg.time = msg32.time;
1391 lpmsg16_32->msg.pt.x = (INT16)msg32.pt.x;
1392 lpmsg16_32->msg.pt.y = (INT16)msg32.pt.y;
1393 lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
1395 return ret;
1400 /***********************************************************************
1401 * CallMsgFilterA (USER32.@)
1403 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1404 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1406 BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
1408 if (GetSysModalWindow16()) return FALSE; /* ??? */
1409 if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1410 return TRUE;
1411 return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
1415 /***********************************************************************
1416 * CallMsgFilterW (USER32.@)
1418 BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
1420 if (GetSysModalWindow16()) return FALSE; /* ??? */
1421 if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1422 return TRUE;
1423 return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );