For drawing a caret, internally replaced the brush by a bitmap (this
[wine/wine-kai.git] / windows / hook.c
blobed6b084462a9ff3d556dcc58de0e5a1db272117d
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 = WIN_Handle32(lpcwp16->hwnd);
103 lpcwp32->lParam = lpcwp16->lParam;
105 if (bA) WINPROC_MapMsg16To32A( lpcwp32->hwnd, lpcwp16->message, lpcwp16->wParam,
106 &lpcwp32->message, &lpcwp32->wParam,
107 &lpcwp32->lParam );
108 else WINPROC_MapMsg16To32W( lpcwp32->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 = WIN_Handle32( 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 = WIN_Handle32(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 = WIN_Handle32( 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 = WIN_Handle32(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 default:
235 FIXME("\t[%i] 16to32 translation unimplemented\n", id);
240 /***********************************************************************
241 * HOOK_Map16To32A
243 static void HOOK_Map16To32A(INT id, INT code, WPARAM *pwParam,
244 LPARAM *plParam)
246 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
250 /***********************************************************************
251 * HOOK_Map16To32W
253 static void HOOK_Map16To32W(INT id, INT code, WPARAM *pwParam,
254 LPARAM *plParam)
256 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
260 /***********************************************************************
261 * HOOK_UnMap16To32Common
263 static void HOOK_UnMap16To32Common(INT id, INT code, WPARAM wParamOrig,
264 LPARAM lParamOrig, WPARAM wParam,
265 LPARAM lParam, BOOL bA)
267 switch (id)
269 case WH_MSGFILTER:
270 case WH_SYSMSGFILTER:
271 case WH_JOURNALRECORD:
272 case WH_JOURNALPLAYBACK:
274 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
275 break;
277 case WH_CALLWNDPROC:
279 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParam;
280 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
281 lpcwp32->lParam, 0 );
282 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
283 lpcwp32->lParam, 0 );
284 HeapFree( GetProcessHeap(), 0, lpcwp32 );
285 break;
288 case WH_GETMESSAGE:
290 LPMSG16 lpmsg16 = MapSL(lParamOrig);
291 STRUCT32_MSG32to16( (LPMSG)lParam, lpmsg16 );
292 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
293 break;
296 case WH_MOUSE:
297 case WH_DEBUG:
299 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
300 break;
302 case WH_CBT:
303 switch (code)
305 case HCBT_CREATEWND:
307 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)lParam;
308 LPCBT_CREATEWND16 lpcbtcw16 = MapSL(lParamOrig);
310 if( !bA )
312 if (HIWORD(lpcbtcw32->lpcs->lpszName))
313 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
314 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
315 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
318 lpcbtcw16->hwndInsertAfter = WIN_Handle16( lpcbtcw32->hwndInsertAfter );
320 HeapFree( GetProcessHeap(), 0, lpcbtcw32->lpcs );
321 } /* fall through */
323 case HCBT_ACTIVATE:
324 case HCBT_CLICKSKIPPED:
325 case HCBT_MOVESIZE:
327 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam);
328 break;
330 break;
332 case WH_SHELL:
333 case WH_KEYBOARD:
334 break;
336 case WH_HARDWARE:
337 case WH_FOREGROUNDIDLE:
338 case WH_CALLWNDPROCRET:
339 default:
340 FIXME("\t[%i] skipping unmap\n", id);
341 break;
346 /***********************************************************************
347 * HOOK_UnMap16To32A
349 static void HOOK_UnMap16To32A(INT id, INT code, WPARAM wParamOrig,
350 LPARAM lParamOrig, WPARAM wParam,
351 LPARAM lParam)
353 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
354 lParam, TRUE );
358 /***********************************************************************
359 * HOOK_UnMap16To32W
361 static void HOOK_UnMap16To32W(INT id, INT code, WPARAM wParamOrig,
362 LPARAM lParamOrig, WPARAM wParam,
363 LPARAM lParam)
365 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
366 lParam, FALSE );
370 /***********************************************************************
371 * HOOK_Map32To16Common
373 static void HOOK_Map32To16Common(INT id, INT code, WPARAM *pwParam,
374 LPARAM *plParam, BOOL bA)
376 switch (id)
378 case WH_MSGFILTER:
379 case WH_SYSMSGFILTER:
380 case WH_GETMESSAGE:
381 case WH_JOURNALRECORD:
383 LPMSG lpmsg32 = (LPMSG)*plParam;
384 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
386 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
388 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
389 break;
392 case WH_JOURNALPLAYBACK:
394 LPEVENTMSG lpem32 = (LPEVENTMSG)*plParam;
395 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
397 lpem16->message = lpem32->message;
398 lpem16->paramL = lpem32->paramL;
399 lpem16->paramH = lpem32->paramH;
400 lpem16->time = lpem32->time;
402 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
403 break;
406 case WH_CALLWNDPROC:
408 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)*plParam;
409 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
411 lpcwp16->hwnd = WIN_Handle16(lpcwp32->hwnd);
412 lpcwp16->lParam = lpcwp32->lParam;
414 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
415 lpcwp32->wParam, &lpcwp16->message,
416 &lpcwp16->wParam, &lpcwp16->lParam );
417 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
418 lpcwp32->wParam, &lpcwp16->message,
419 &lpcwp16->wParam, &lpcwp16->lParam );
420 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
421 break;
424 case WH_CBT:
425 switch (code)
427 case HCBT_ACTIVATE:
429 LPCBTACTIVATESTRUCT lpcas32 = (LPCBTACTIVATESTRUCT)*plParam;
430 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
432 lpcas16->fMouse = lpcas32->fMouse;
433 lpcas16->hWndActive = WIN_Handle16( lpcas32->hWndActive );
435 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
436 break;
439 case HCBT_CLICKSKIPPED:
441 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
442 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
444 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
446 lpms16->hwnd = WIN_Handle16( lpms32->hwnd );
447 lpms16->wHitTestCode = lpms32->wHitTestCode;
448 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
450 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
451 break;
454 case HCBT_MOVESIZE:
456 LPRECT lprect32 = (LPRECT)*plParam;
457 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
459 CONV_RECT32TO16( lprect32, lprect16 );
461 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
462 break;
465 break;
467 case WH_MOUSE:
469 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
470 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
472 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
474 lpms16->hwnd = WIN_Handle16( lpms32->hwnd );
475 lpms16->wHitTestCode = lpms32->wHitTestCode;
476 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
478 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
479 break;
482 case WH_DEBUG:
484 LPDEBUGHOOKINFO lpdh32 = (LPDEBUGHOOKINFO)*plParam;
485 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
487 lpdh16->hModuleHook = 0; /* FIXME */
488 lpdh16->reserved = 0;
489 lpdh16->lParam = lpdh32->lParam;
490 lpdh16->wParam = lpdh32->wParam;
491 lpdh16->code = lpdh32->code;
493 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
494 break;
497 case WH_SHELL:
498 case WH_KEYBOARD:
499 break;
501 case WH_HARDWARE:
502 case WH_FOREGROUNDIDLE:
503 case WH_CALLWNDPROCRET:
504 default:
505 FIXME("\t[%i] 32to16 translation unimplemented\n", id);
510 /***********************************************************************
511 * HOOK_Map32ATo16
513 static void HOOK_Map32ATo16(INT id, INT code, WPARAM *pwParam,
514 LPARAM *plParam)
516 if (id == WH_CBT && code == HCBT_CREATEWND)
518 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)*plParam;
519 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
520 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
522 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
523 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
525 if (HIWORD(lpcbtcw32->lpcs->lpszName))
526 lpcs16->lpszName =
527 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
528 else
529 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
531 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
532 lpcs16->lpszClass =
533 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
534 else
535 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
537 lpcbtcw16->hwndInsertAfter = WIN_Handle16( lpcbtcw32->hwndInsertAfter );
539 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
541 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
545 /***********************************************************************
546 * HOOK_Map32WTo16
548 static void HOOK_Map32WTo16(INT id, INT code, WPARAM *pwParam,
549 LPARAM *plParam)
551 if (id == WH_CBT && code == HCBT_CREATEWND)
553 LPSTR name, cls;
554 LPCBT_CREATEWNDW lpcbtcw32 = (LPCBT_CREATEWNDW)*plParam;
555 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
556 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
558 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
559 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA)lpcbtcw32->lpcs,
560 lpcs16 );
562 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
563 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
564 lpcs16->lpszName = SEGPTR_GET( name );
565 lpcs16->lpszClass = SEGPTR_GET( cls );
566 lpcbtcw16->hwndInsertAfter = WIN_Handle16( lpcbtcw32->hwndInsertAfter );
568 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
570 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
574 /***********************************************************************
575 * HOOK_UnMap32To16Common
577 static void HOOK_UnMap32To16Common(INT id, INT code, WPARAM wParamOrig,
578 LPARAM lParamOrig, WPARAM wParam,
579 LPARAM lParam, BOOL bA)
581 switch (id)
583 case WH_MSGFILTER:
584 case WH_SYSMSGFILTER:
585 case WH_JOURNALRECORD:
586 case WH_JOURNALPLAYBACK:
587 case WH_MOUSE:
588 case WH_DEBUG:
589 SEGPTR_FREE( MapSL(lParam) );
590 break;
592 case WH_CALLWNDPROC:
594 LPCWPSTRUCT16 lpcwp16 = MapSL(lParam);
595 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParamOrig;
596 MSGPARAM16 mp16;
598 mp16.wParam = lpcwp16->wParam;
599 mp16.lParam = lpcwp16->lParam;
600 mp16.lResult = 0;
602 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
603 lpcwp32->lParam, &mp16 );
604 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
605 lpcwp32->lParam, &mp16 );
606 SEGPTR_FREE( MapSL(lParam) );
607 break;
610 case WH_GETMESSAGE:
612 LPMSG lpmsg32 = (LPMSG)lParamOrig;
614 STRUCT32_MSG16to32( MapSL(lParam), lpmsg32 );
615 SEGPTR_FREE( MapSL(lParam) );
616 break;
619 case WH_CBT:
620 switch (code)
622 case HCBT_CREATEWND:
624 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)(lParamOrig);
625 LPCBT_CREATEWND16 lpcbtcw16 = MapSL(lParam);
626 LPCREATESTRUCT16 lpcs16 = MapSL((SEGPTR)lpcbtcw16->lpcs);
628 if (HIWORD(lpcs16->lpszName))
629 SEGPTR_FREE( MapSL(lpcs16->lpszName) );
631 if (HIWORD(lpcs16->lpszClass))
632 SEGPTR_FREE( MapSL(lpcs16->lpszClass) );
634 lpcbtcw32->hwndInsertAfter = WIN_Handle32( lpcbtcw16->hwndInsertAfter );
636 SEGPTR_FREE( lpcs16 );
637 } /* fall through */
639 case HCBT_ACTIVATE:
640 case HCBT_CLICKSKIPPED:
641 case HCBT_MOVESIZE:
643 SEGPTR_FREE( MapSL(lParam) );
644 break;
646 break;
648 case WH_SHELL:
649 case WH_KEYBOARD:
650 break;
652 case WH_HARDWARE:
653 case WH_FOREGROUNDIDLE:
654 case WH_CALLWNDPROCRET:
655 default:
656 FIXME("\t[%i] skipping unmap\n", id);
661 /***********************************************************************
662 * HOOK_UnMap32ATo16
664 static void HOOK_UnMap32ATo16(INT id, INT code, WPARAM wParamOrig,
665 LPARAM lParamOrig, WPARAM wParam,
666 LPARAM lParam)
668 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
669 lParam, TRUE );
673 /***********************************************************************
674 * HOOK_UnMap32WTo16
676 static void HOOK_UnMap32WTo16(INT id, INT code, WPARAM wParamOrig,
677 LPARAM lParamOrig, WPARAM wParam,
678 LPARAM lParam)
680 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
681 lParam, FALSE );
685 /***********************************************************************
686 * HOOK_Map32ATo32W
688 static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
689 LPARAM *plParam)
691 if (id == WH_CBT && code == HCBT_CREATEWND)
693 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
694 LPCBT_CREATEWNDW lpcbtcwW = HeapAlloc( GetProcessHeap(), 0,
695 sizeof(*lpcbtcwW) );
696 lpcbtcwW->lpcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwW->lpcs) );
698 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
699 *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
701 if (HIWORD(lpcbtcwA->lpcs->lpszName))
703 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
704 lpcbtcwA->lpcs->lpszName );
706 else
707 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
709 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
711 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
712 lpcbtcwA->lpcs->lpszClass );
714 else
715 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
716 *plParam = (LPARAM)lpcbtcwW;
718 return;
722 /***********************************************************************
723 * HOOK_UnMap32ATo32W
725 static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
726 LPARAM lParamOrig, WPARAM wParam,
727 LPARAM lParam)
729 if (id == WH_CBT && code == HCBT_CREATEWND)
731 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
732 if (HIWORD(lpcbtcwW->lpcs->lpszName))
733 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
734 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
735 HeapFree( GetProcessHeap(), 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
736 HeapFree( GetProcessHeap(), 0, lpcbtcwW->lpcs );
737 HeapFree( GetProcessHeap(), 0, lpcbtcwW );
739 return;
743 /***********************************************************************
744 * HOOK_Map32WTo32A
746 static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
747 LPARAM *plParam)
749 if (id == WH_CBT && code == HCBT_CREATEWND)
751 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
752 LPCBT_CREATEWNDA lpcbtcwA = HeapAlloc( GetProcessHeap(), 0,
753 sizeof(*lpcbtcwA) );
754 lpcbtcwA->lpcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*lpcbtcwA->lpcs) );
756 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
757 *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
759 if (HIWORD(lpcbtcwW->lpcs->lpszName))
760 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
761 lpcbtcwW->lpcs->lpszName );
762 else
763 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
765 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
766 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
767 lpcbtcwW->lpcs->lpszClass );
768 else
769 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
770 *plParam = (LPARAM)lpcbtcwA;
772 return;
776 /***********************************************************************
777 * HOOK_UnMap32WTo32A
779 static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
780 LPARAM lParamOrig, WPARAM wParam,
781 LPARAM lParam)
783 if (id == WH_CBT && code == HCBT_CREATEWND)
785 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
786 if (HIWORD(lpcbtcwA->lpcs->lpszName))
787 HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
788 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
789 HeapFree( GetProcessHeap(), 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
790 HeapFree( GetProcessHeap(), 0, lpcbtcwA->lpcs );
791 HeapFree( GetProcessHeap(), 0, lpcbtcwA );
793 return;
797 /***********************************************************************
798 * Map Function Tables
800 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
802 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
803 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
804 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
807 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
809 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
810 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
811 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
815 /***********************************************************************
816 * Internal Functions
819 /***********************************************************************
820 * HOOK_GetNextHook
822 * Get the next hook of a given hook.
824 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
826 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
828 if (!data || !hook) return 0;
829 if (data->next) return data->next;
830 if (!data->ownerQueue) return 0; /* Already system hook */
832 /* Now start enumerating the system hooks */
833 return HOOK_systemHooks[data->id - WH_MINHOOK];
837 /***********************************************************************
838 * HOOK_GetHook
840 * Get the first hook for a given type.
842 static HANDLE16 HOOK_GetHook( INT16 id )
844 MESSAGEQUEUE *queue;
845 HANDLE16 hook = 0;
847 if ((queue = QUEUE_Current()) != NULL)
848 hook = queue->hooks[id - WH_MINHOOK];
849 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
850 return hook;
854 /***********************************************************************
855 * HOOK_SetHook
857 * Install a given hook.
859 /* ### start build ### */
860 extern LONG CALLBACK HOOK_CallTo16_long_wwl(FARPROC16,WORD,WORD,LONG);
861 /* ### stop build ### */
862 static HHOOK HOOK_SetHook( INT16 id, LPVOID proc, INT type,
863 HMODULE16 hModule, DWORD dwThreadId )
865 HOOKDATA *data;
866 HANDLE16 handle;
867 HQUEUE16 hQueue = 0;
869 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
871 TRACE("Setting hook %d: %08x %04x %08lx\n",
872 id, (UINT)proc, hModule, dwThreadId );
874 /* Create task queue if none present */
875 InitThreadInput16( 0, 0 );
877 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput16(FALSE);
879 if (dwThreadId) /* Task-specific hook */
881 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
882 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
883 if (!(hQueue = GetThreadQueue16( dwThreadId )))
884 return 0;
887 /* Create the hook structure */
889 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
890 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
891 data->proc = proc;
892 data->id = id;
893 data->ownerQueue = hQueue;
894 data->ownerModule = hModule;
895 data->flags = type;
897 /* Create CallTo16 thunk for 16-bit hooks */
899 if ( (data->flags & HOOK_MAPTYPE) == HOOK_WIN16 )
900 data->thunk = (HOOKPROC)THUNK_Alloc( (FARPROC16)data->proc,
901 (RELAY)HOOK_CallTo16_long_wwl );
902 else
903 data->thunk = data->proc;
905 if ( !data->thunk && data->proc )
907 USER_HEAP_FREE( handle );
908 return 0;
911 /* Insert it in the correct linked list */
913 if (hQueue)
915 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
916 data->next = queue->hooks[id - WH_MINHOOK];
917 queue->hooks[id - WH_MINHOOK] = handle;
918 QUEUE_Unlock( queue );
920 else
922 data->next = HOOK_systemHooks[id - WH_MINHOOK];
923 HOOK_systemHooks[id - WH_MINHOOK] = handle;
925 TRACE("Setting hook %d: ret=%04x [next=%04x]\n",
926 id, handle, data->next );
928 return (HHOOK)( handle? MAKELONG( handle, HOOK_MAGIC ) : 0 );
932 /***********************************************************************
933 * HOOK_RemoveHook
935 * Remove a hook from the list.
937 static BOOL HOOK_RemoveHook( HANDLE16 hook )
939 HOOKDATA *data;
940 HANDLE16 *prevHook;
942 TRACE("Removing hook %04x\n", hook );
944 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
945 if (data->flags & HOOK_INUSE)
947 /* Mark it for deletion later on */
948 WARN("Hook still running, deletion delayed\n" );
949 data->proc = (HOOKPROC)0;
950 return TRUE;
953 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput16(TRUE);
955 /* Remove it from the linked list */
957 if (data->ownerQueue)
959 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( data->ownerQueue );
960 if (!queue) return FALSE;
961 prevHook = &queue->hooks[data->id - WH_MINHOOK];
962 QUEUE_Unlock( queue );
964 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
966 while (*prevHook && *prevHook != hook)
967 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
969 if (!*prevHook) return FALSE;
970 *prevHook = data->next;
972 if ( (data->flags & HOOK_MAPTYPE) == HOOK_WIN16 )
973 THUNK_Free( (FARPROC)data->thunk );
975 USER_HEAP_FREE( hook );
976 return TRUE;
980 /***********************************************************************
981 * HOOK_FindValidHook
983 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
985 HOOKDATA *data;
987 for (;;)
989 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
990 if (data->proc) return hook;
991 hook = data->next;
996 /***********************************************************************
997 * HOOK_CallHook
999 * Call a hook procedure.
1001 static LRESULT HOOK_CallHook( HANDLE16 hook, INT fromtype, INT code,
1002 WPARAM wParam, LPARAM lParam )
1004 MESSAGEQUEUE *queue;
1005 HANDLE16 prevHook;
1006 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1007 LRESULT ret;
1008 int iWndsLocks;
1010 WPARAM wParamOrig = wParam;
1011 LPARAM lParamOrig = lParam;
1012 HOOK_MapFunc MapFunc;
1013 HOOK_UnMapFunc UnMapFunc;
1015 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
1016 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
1018 if (MapFunc)
1019 MapFunc( data->id, code, &wParam, &lParam );
1021 /* Now call it */
1023 if (!(queue = QUEUE_Current())) return 0;
1024 prevHook = queue->hCurHook;
1025 queue->hCurHook = hook;
1026 data->flags |= HOOK_INUSE;
1028 TRACE("Calling hook %04x: %d %08x %08lx\n",
1029 hook, code, wParam, lParam );
1031 /* Suspend window structure locks before calling user code */
1032 iWndsLocks = WIN_SuspendWndsLock();
1034 ret = data->thunk(code, wParam, lParam);
1036 /* Grrr. While the hook procedure is supposed to have an LRESULT return
1037 value even in Win16, it seems that for those hook types where the
1038 return value is interpreted as BOOL, Windows doesn't actually check
1039 the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on
1040 that, because they neglect to clear DX ... */
1041 if ( (data->flags & HOOK_MAPTYPE) == HOOK_WIN16
1042 && data->id != WH_JOURNALPLAYBACK )
1043 ret = LOWORD( ret );
1045 WIN_RestoreWndsLock(iWndsLocks);
1047 TRACE("Ret hook %04x = %08lx\n", hook, ret );
1049 data->flags &= ~HOOK_INUSE;
1050 queue->hCurHook = prevHook;
1052 if (UnMapFunc)
1053 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
1055 if (!data->proc) HOOK_RemoveHook( hook );
1057 return ret;
1060 /***********************************************************************
1061 * Exported Functions & APIs
1064 /***********************************************************************
1065 * HOOK_IsHooked
1067 * Replacement for calling HOOK_GetHook from other modules.
1069 BOOL HOOK_IsHooked( INT16 id )
1071 return HOOK_GetHook( id ) != 0;
1075 /***********************************************************************
1076 * HOOK_CallHooks16
1078 * Call a hook chain.
1080 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1081 LPARAM lParam )
1083 HANDLE16 hook;
1085 if (!(hook = HOOK_GetHook( id ))) return 0;
1086 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1087 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1090 /***********************************************************************
1091 * HOOK_CallHooksA
1093 * Call a hook chain.
1095 LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
1096 LPARAM lParam )
1098 HANDLE16 hook;
1100 if (!(hook = HOOK_GetHook( id ))) return 0;
1101 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1102 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1105 /***********************************************************************
1106 * HOOK_CallHooksW
1108 * Call a hook chain.
1110 LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
1111 LPARAM lParam )
1113 HANDLE16 hook;
1115 if (!(hook = HOOK_GetHook( id ))) return 0;
1116 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1117 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1118 lParam );
1122 /***********************************************************************
1123 * HOOK_FreeModuleHooks
1125 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1127 /* remove all system hooks registered by this module */
1129 HOOKDATA* hptr;
1130 HHOOK hook, next;
1131 int id;
1133 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1135 hook = HOOK_systemHooks[id - WH_MINHOOK];
1136 while( hook )
1137 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1139 next = hptr->next;
1140 if( hptr->ownerModule == hModule )
1142 hptr->flags &= HOOK_MAPTYPE;
1143 HOOK_RemoveHook(hook);
1145 hook = next;
1147 else hook = 0;
1151 /***********************************************************************
1152 * HOOK_FreeQueueHooks
1154 void HOOK_FreeQueueHooks(void)
1156 /* remove all hooks registered by the current queue */
1158 HOOKDATA* hptr = NULL;
1159 HHOOK hook, next;
1160 int id;
1162 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1164 hook = HOOK_GetHook( id );
1165 while( hook )
1167 next = HOOK_GetNextHook(hook);
1169 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1170 if( hptr && hptr->ownerQueue )
1172 hptr->flags &= HOOK_MAPTYPE;
1173 HOOK_RemoveHook(hook);
1175 hook = next;
1181 /***********************************************************************
1182 * SetWindowsHook (USER.121)
1184 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1186 HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
1188 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1189 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1191 return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
1194 /***********************************************************************
1195 * SetWindowsHookA (USER32.@)
1197 HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
1199 return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
1202 /***********************************************************************
1203 * SetWindowsHookW (USER32.@)
1205 HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
1207 return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
1211 /***********************************************************************
1212 * SetWindowsHookEx (USER.291)
1213 * SetWindowsHookEx16 (USER32.@)
1215 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1216 HTASK16 hTask )
1218 if (id == WH_DEBUG)
1220 FIXME("WH_DEBUG is broken in 16-bit Windows.\n");
1221 return 0;
1223 return HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), (DWORD)hTask );
1226 /***********************************************************************
1227 * SetWindowsHookExA (USER32.@)
1229 HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
1230 DWORD dwThreadId )
1232 return HOOK_SetHook( id, proc, HOOK_WIN32A, MapHModuleLS(hInst), dwThreadId );
1235 /***********************************************************************
1236 * SetWindowsHookExW (USER32.@)
1238 HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
1239 DWORD dwThreadId )
1241 return HOOK_SetHook( id, proc, HOOK_WIN32W, MapHModuleLS(hInst), dwThreadId );
1245 /***********************************************************************
1246 * UnhookWindowsHook (USER.234)
1248 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1250 return UnhookWindowsHook( id, (HOOKPROC)proc );
1253 /***********************************************************************
1254 * UnhookWindowsHook (USER32.@)
1256 BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
1258 HANDLE16 hook = HOOK_GetHook( id );
1260 TRACE("%d %08lx\n", id, (DWORD)proc );
1262 while (hook)
1264 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1265 if (data->proc == proc) break;
1266 hook = HOOK_GetNextHook( hook );
1268 if (!hook) return FALSE;
1269 return HOOK_RemoveHook( hook );
1273 /***********************************************************************
1274 * UnhookWindowsHookEx (USER.292)
1276 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1278 return UnhookWindowsHookEx( hhook );
1281 /***********************************************************************
1282 * UnhookWindowsHookEx (USER32.@)
1284 BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
1286 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1287 return HOOK_RemoveHook( LOWORD(hhook) );
1291 /***********************************************************************
1292 * CallNextHookEx (USER.293)
1293 * CallNextHookEx16 (USER32.@)
1295 * I wouldn't have separated this into 16 and 32 bit versions, but I
1296 * need a way to figure out if I need to do a mapping or not.
1298 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1299 LPARAM lParam )
1301 HANDLE16 next;
1303 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1304 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1306 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1310 /***********************************************************************
1311 * CallNextHookEx (USER32.@)
1313 * There aren't ANSI and UNICODE versions of this.
1315 LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
1316 LPARAM lParam )
1318 HANDLE16 next;
1319 INT fromtype; /* figure out Ansi/Unicode */
1320 HOOKDATA *oldhook;
1322 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1323 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1325 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1326 fromtype = oldhook->flags & HOOK_MAPTYPE;
1328 if (fromtype == HOOK_WIN16)
1329 ERR("called from 16bit hook!\n");
1331 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1335 /***********************************************************************
1336 * DefHookProc (USER.235)
1338 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1339 HHOOK *hhook )
1341 /* Note: the *hhook parameter is never used, since we rely on the
1342 * current hook value from the task queue to find the next hook. */
1343 MESSAGEQUEUE *queue;
1345 if (!(queue = QUEUE_Current())) return 0;
1346 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1350 /***********************************************************************
1351 * CallMsgFilter (USER.123)
1353 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1355 if (GetSysModalWindow16()) return FALSE;
1356 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1357 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1361 /***********************************************************************
1362 * CallMsgFilter32 (USER.823)
1364 BOOL16 WINAPI CallMsgFilter32_16( SEGPTR msg16_32, INT16 code, BOOL16 wHaveParamHigh )
1366 MSG32_16 *lpmsg16_32 = MapSL(msg16_32);
1368 if (wHaveParamHigh == FALSE)
1370 lpmsg16_32->wParamHigh = 0;
1371 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1372 return CallMsgFilter16(msg16_32, code);
1374 else
1376 MSG msg32;
1377 BOOL16 ret;
1379 msg32.hwnd = WIN_Handle32( lpmsg16_32->msg.hwnd );
1380 msg32.message = lpmsg16_32->msg.message;
1381 msg32.wParam = 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 = lpmsg16_32->msg.pt.x;
1385 msg32.pt.y = lpmsg16_32->msg.pt.y;
1387 ret = (BOOL16)CallMsgFilterA(&msg32, (INT)code);
1389 lpmsg16_32->msg.hwnd = WIN_Handle16( 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 = msg32.pt.x;
1395 lpmsg16_32->msg.pt.y = msg32.pt.y;
1396 lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
1398 return ret;
1403 /***********************************************************************
1404 * CallMsgFilterA (USER32.@)
1406 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1407 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1409 BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
1411 if (GetSysModalWindow16()) return FALSE; /* ??? */
1412 if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1413 return TRUE;
1414 return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
1418 /***********************************************************************
1419 * CallMsgFilterW (USER32.@)
1421 BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
1423 if (GetSysModalWindow16()) return FALSE; /* ??? */
1424 if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1425 return TRUE;
1426 return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );