Changed 'GetDisplayMode' to return the mode previously set by
[wine/hacks.git] / windows / hook.c
blob3fa7db8be46dc6ccf9831a626cc074237d7709a6
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 "winuser.h"
18 #include "wine/winuser16.h"
19 #include "wine/winbase16.h"
20 #include "hook.h"
21 #include "queue.h"
22 #include "task.h"
23 #include "user.h"
24 #include "heap.h"
25 #include "struct32.h"
26 #include "winproc.h"
27 #include "debug.h"
29 #pragma pack(1)
31 /* Hook data (pointed to by a HHOOK) */
32 typedef struct
34 HANDLE16 next; /* 00 Next hook in chain */
35 HOOKPROC proc WINE_PACKED; /* 02 Hook procedure */
36 INT16 id; /* 06 Hook id (WH_xxx) */
37 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
38 HMODULE16 ownerModule; /* 0a Owner module */
39 WORD flags; /* 0c flags */
40 } HOOKDATA;
42 #pragma pack(4)
44 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
46 /* This should probably reside in USER heap */
47 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
49 typedef VOID (*HOOK_MapFunc)(INT, INT, WPARAM *, LPARAM *);
50 typedef VOID (*HOOK_UnMapFunc)(INT, INT, WPARAM, LPARAM, WPARAM,
51 LPARAM);
53 /***********************************************************************
54 * HOOK_Map16To32Common
56 static void HOOK_Map16To32Common(INT id, INT code, WPARAM *pwParam,
57 LPARAM *plParam, BOOL bA )
60 switch( id )
62 case WH_MSGFILTER:
63 case WH_SYSMSGFILTER:
64 case WH_GETMESSAGE:
65 case WH_JOURNALRECORD:
67 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
68 LPMSG lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
70 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
71 *plParam = (LPARAM)lpmsg32;
72 break;
75 case WH_JOURNALPLAYBACK:
77 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
78 LPEVENTMSG lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
80 lpem32->message = lpem16->message;
81 lpem32->paramL = lpem16->paramL;
82 lpem32->paramH = lpem16->paramH;
83 lpem32->time = lpem16->time;
84 lpem32->hwnd = 0; /* FIXME */
86 *plParam = (LPARAM)lpem32;
87 break;
90 case WH_CALLWNDPROC:
92 LPCWPSTRUCT16 lpcwp16 = PTR_SEG_TO_LIN(*plParam);
93 LPCWPSTRUCT lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
95 lpcwp32->hwnd = lpcwp16->hwnd;
96 lpcwp32->lParam = lpcwp16->lParam;
98 if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam,
99 &lpcwp32->message, &lpcwp32->wParam,
100 &lpcwp32->lParam );
101 else WINPROC_MapMsg16To32W( lpcwp16->hwnd,lpcwp16->message, lpcwp16->wParam,
102 &lpcwp32->message, &lpcwp32->wParam,
103 &lpcwp32->lParam );
104 *plParam = (LPARAM)lpcwp32;
105 break;
108 case WH_CBT:
109 switch (code)
111 case HCBT_CREATEWND:
113 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
114 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
115 LPCBT_CREATEWNDA lpcbtcw32 = HeapAlloc( SystemHeap, 0,
116 sizeof(*lpcbtcw32) );
117 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
118 sizeof(*lpcbtcw32->lpcs) );
120 STRUCT32_CREATESTRUCT16to32A( lpcs16,
121 (LPCREATESTRUCTA)lpcbtcw32->lpcs );
123 if (HIWORD(lpcs16->lpszName))
124 lpcbtcw32->lpcs->lpszName =
125 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
126 : HEAP_strdupAtoW( SystemHeap, 0,
127 PTR_SEG_TO_LIN(lpcs16->lpszName) );
128 else
129 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
131 if (HIWORD(lpcs16->lpszClass))
132 lpcbtcw32->lpcs->lpszClass =
133 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
134 : HEAP_strdupAtoW( SystemHeap, 0,
135 PTR_SEG_TO_LIN(lpcs16->lpszClass) );
136 else
137 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
139 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
141 *plParam = (LPARAM)lpcbtcw32;
142 break;
144 case HCBT_ACTIVATE:
146 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
147 LPCBTACTIVATESTRUCT lpcas32 = HeapAlloc( SystemHeap, 0,
148 sizeof(*lpcas32) );
149 lpcas32->fMouse = lpcas16->fMouse;
150 lpcas32->hWndActive = lpcas16->hWndActive;
151 *plParam = (LPARAM)lpcas32;
152 break;
154 case HCBT_CLICKSKIPPED:
156 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
157 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( SystemHeap, 0,
158 sizeof(*lpms32) );
160 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
162 /* wHitTestCode may be negative, so convince compiler to do
163 correct sign extension. Yay. :| */
164 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
166 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
167 lpms32->hwnd = lpms16->hwnd;
168 *plParam = (LPARAM)lpms32;
169 break;
171 case HCBT_MOVESIZE:
173 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
174 LPRECT lprect32 = HeapAlloc( SystemHeap, 0,
175 sizeof(*lprect32) );
177 CONV_RECT16TO32( lprect16, lprect32 );
178 *plParam = (LPARAM)lprect32;
179 break;
182 break;
184 case WH_MOUSE:
186 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
187 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( SystemHeap, 0,
188 sizeof(*lpms32) );
190 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
192 /* wHitTestCode may be negative, so convince compiler to do
193 correct sign extension. Yay. :| */
194 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
195 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
196 lpms32->hwnd = lpms16->hwnd;
197 *plParam = (LPARAM)lpms32;
198 break;
201 case WH_DEBUG:
203 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
204 LPDEBUGHOOKINFO lpdh32 = HeapAlloc( SystemHeap, 0,
205 sizeof(*lpdh32) );
207 lpdh32->idThread = 0; /* FIXME */
208 lpdh32->idThreadInstaller = 0; /* FIXME */
209 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
210 lpdh32->wParam = lpdh16->wParam;
211 lpdh32->code = lpdh16->code;
213 /* do sign extension if it was WH_MSGFILTER */
214 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
216 *plParam = (LPARAM)lpdh32;
217 break;
220 case WH_SHELL:
221 case WH_KEYBOARD:
222 break;
224 case WH_HARDWARE:
225 case WH_FOREGROUNDIDLE:
226 case WH_CALLWNDPROCRET:
227 FIXME(hook, "\t[%i] 16to32 translation unimplemented\n", id);
232 /***********************************************************************
233 * HOOK_Map16To32A
235 static void HOOK_Map16To32A(INT id, INT code, WPARAM *pwParam,
236 LPARAM *plParam)
238 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
242 /***********************************************************************
243 * HOOK_Map16To32W
245 static void HOOK_Map16To32W(INT id, INT code, WPARAM *pwParam,
246 LPARAM *plParam)
248 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
252 /***********************************************************************
253 * HOOK_UnMap16To32Common
255 static void HOOK_UnMap16To32Common(INT id, INT code, WPARAM wParamOrig,
256 LPARAM lParamOrig, WPARAM wParam,
257 LPARAM lParam, BOOL bA)
259 switch (id)
261 case WH_MSGFILTER:
262 case WH_SYSMSGFILTER:
263 case WH_JOURNALRECORD:
264 case WH_JOURNALPLAYBACK:
266 HeapFree( SystemHeap, 0, (LPVOID)lParam );
267 break;
269 case WH_CALLWNDPROC:
271 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParam;
272 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
273 lpcwp32->lParam, 0 );
274 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
275 lpcwp32->lParam, 0 );
276 HeapFree( SystemHeap, 0, lpcwp32 );
277 break;
280 case WH_GETMESSAGE:
282 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
283 STRUCT32_MSG32to16( (LPMSG)lParam, lpmsg16 );
284 HeapFree( SystemHeap, 0, (LPVOID)lParam );
285 break;
288 case WH_MOUSE:
289 case WH_DEBUG:
291 HeapFree( SystemHeap, 0, (LPVOID)lParam );
292 break;
294 case WH_CBT:
295 switch (code)
297 case HCBT_CREATEWND:
299 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)lParam;
300 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
302 if( !bA )
304 if (HIWORD(lpcbtcw32->lpcs->lpszName))
305 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
306 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
307 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
310 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
312 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
313 } /* fall through */
315 case HCBT_ACTIVATE:
316 case HCBT_CLICKSKIPPED:
317 case HCBT_MOVESIZE:
319 HeapFree( SystemHeap, 0, (LPVOID)lParam);
320 break;
322 break;
324 case WH_SHELL:
325 case WH_KEYBOARD:
326 break;
328 case WH_HARDWARE:
329 case WH_FOREGROUNDIDLE:
330 case WH_CALLWNDPROCRET:
331 FIXME(hook, "\t[%i] skipping unmap\n", id);
332 break;
337 /***********************************************************************
338 * HOOK_UnMap16To32A
340 static void HOOK_UnMap16To32A(INT id, INT code, WPARAM wParamOrig,
341 LPARAM lParamOrig, WPARAM wParam,
342 LPARAM lParam)
344 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
345 lParam, TRUE );
349 /***********************************************************************
350 * HOOK_UnMap16To32W
352 static void HOOK_UnMap16To32W(INT id, INT code, WPARAM wParamOrig,
353 LPARAM lParamOrig, WPARAM wParam,
354 LPARAM lParam)
356 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
357 lParam, FALSE );
361 /***********************************************************************
362 * HOOK_Map32To16Common
364 static void HOOK_Map32To16Common(INT id, INT code, WPARAM *pwParam,
365 LPARAM *plParam, BOOL bA)
367 switch (id)
369 case WH_MSGFILTER:
370 case WH_SYSMSGFILTER:
371 case WH_GETMESSAGE:
372 case WH_JOURNALRECORD:
374 LPMSG lpmsg32 = (LPMSG)*plParam;
375 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
377 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
379 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
380 break;
383 case WH_JOURNALPLAYBACK:
385 LPEVENTMSG lpem32 = (LPEVENTMSG)*plParam;
386 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
388 lpem16->message = lpem32->message;
389 lpem16->paramL = lpem32->paramL;
390 lpem16->paramH = lpem32->paramH;
391 lpem16->time = lpem32->time;
393 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
394 break;
397 case WH_CALLWNDPROC:
399 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)*plParam;
400 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
402 lpcwp16->hwnd = lpcwp32->hwnd;
403 lpcwp16->lParam = lpcwp32->lParam;
405 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
406 lpcwp32->wParam, &lpcwp16->message,
407 &lpcwp16->wParam, &lpcwp16->lParam );
408 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
409 lpcwp32->wParam, &lpcwp16->message,
410 &lpcwp16->wParam, &lpcwp16->lParam );
411 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
412 break;
415 case WH_CBT:
416 switch (code)
418 case HCBT_ACTIVATE:
420 LPCBTACTIVATESTRUCT lpcas32 = (LPCBTACTIVATESTRUCT)*plParam;
421 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
423 lpcas16->fMouse = lpcas32->fMouse;
424 lpcas16->hWndActive = lpcas32->hWndActive;
426 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
427 break;
430 case HCBT_CLICKSKIPPED:
432 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
433 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
435 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
437 lpms16->hwnd = lpms32->hwnd;
438 lpms16->wHitTestCode = lpms32->wHitTestCode;
439 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
441 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
442 break;
445 case HCBT_MOVESIZE:
447 LPRECT lprect32 = (LPRECT)*plParam;
448 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
450 CONV_RECT32TO16( lprect32, lprect16 );
452 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
453 break;
456 break;
458 case WH_MOUSE:
460 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
461 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
463 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
465 lpms16->hwnd = lpms32->hwnd;
466 lpms16->wHitTestCode = lpms32->wHitTestCode;
467 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
469 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
470 break;
473 case WH_DEBUG:
475 LPDEBUGHOOKINFO lpdh32 = (LPDEBUGHOOKINFO)*plParam;
476 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
478 lpdh16->hModuleHook = 0; /* FIXME */
479 lpdh16->reserved = 0;
480 lpdh16->lParam = lpdh32->lParam;
481 lpdh16->wParam = lpdh32->wParam;
482 lpdh16->code = lpdh32->code;
484 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
485 break;
488 case WH_SHELL:
489 case WH_KEYBOARD:
490 break;
492 case WH_HARDWARE:
493 case WH_FOREGROUNDIDLE:
494 case WH_CALLWNDPROCRET:
495 FIXME(hook,"\t[%i] 32to16 translation unimplemented\n", id);
500 /***********************************************************************
501 * HOOK_Map32ATo16
503 static void HOOK_Map32ATo16(INT id, INT code, WPARAM *pwParam,
504 LPARAM *plParam)
506 if (id == WH_CBT && code == HCBT_CREATEWND)
508 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)*plParam;
509 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
510 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
512 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
513 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
515 if (HIWORD(lpcbtcw32->lpcs->lpszName))
516 lpcs16->lpszName =
517 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
518 else
519 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
521 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
522 lpcs16->lpszClass =
523 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
524 else
525 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
527 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
529 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
531 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
535 /***********************************************************************
536 * HOOK_Map32WTo16
538 static void HOOK_Map32WTo16(INT id, INT code, WPARAM *pwParam,
539 LPARAM *plParam)
541 if (id == WH_CBT && code == HCBT_CREATEWND)
543 LPSTR name, cls;
544 LPCBT_CREATEWNDW lpcbtcw32 = (LPCBT_CREATEWNDW)*plParam;
545 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
546 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
548 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
549 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA)lpcbtcw32->lpcs,
550 lpcs16 );
552 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
553 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
554 lpcs16->lpszName = SEGPTR_GET( name );
555 lpcs16->lpszClass = SEGPTR_GET( cls );
556 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
558 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
560 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
564 /***********************************************************************
565 * HOOK_UnMap32To16Common
567 static void HOOK_UnMap32To16Common(INT id, INT code, WPARAM wParamOrig,
568 LPARAM lParamOrig, WPARAM wParam,
569 LPARAM lParam, BOOL bA)
571 switch (id)
573 case WH_MSGFILTER:
574 case WH_SYSMSGFILTER:
575 case WH_JOURNALRECORD:
576 case WH_JOURNALPLAYBACK:
577 case WH_MOUSE:
578 case WH_DEBUG:
579 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
580 break;
582 case WH_CALLWNDPROC:
584 LPCWPSTRUCT16 lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
585 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParamOrig;
586 MSGPARAM16 mp16 = { lpcwp16->wParam, lpcwp16->lParam, 0 };
588 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
589 lpcwp32->lParam, &mp16 );
590 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
591 lpcwp32->lParam, &mp16 );
592 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
593 break;
596 case WH_GETMESSAGE:
598 LPMSG lpmsg32 = (LPMSG)lParamOrig;
600 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
601 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
602 break;
605 case WH_CBT:
606 switch (code)
608 case HCBT_CREATEWND:
610 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)(lParamOrig);
611 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
612 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
614 if (HIWORD(lpcs16->lpszName))
615 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
617 if (HIWORD(lpcs16->lpszClass))
618 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
620 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
622 SEGPTR_FREE( lpcs16 );
623 } /* fall through */
625 case HCBT_ACTIVATE:
626 case HCBT_CLICKSKIPPED:
627 case HCBT_MOVESIZE:
629 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
630 break;
632 break;
634 case WH_SHELL:
635 case WH_KEYBOARD:
636 break;
638 case WH_HARDWARE:
639 case WH_FOREGROUNDIDLE:
640 case WH_CALLWNDPROCRET:
641 FIXME(hook, "\t[%i] skipping unmap\n", id);
646 /***********************************************************************
647 * HOOK_UnMap32ATo16
649 static void HOOK_UnMap32ATo16(INT id, INT code, WPARAM wParamOrig,
650 LPARAM lParamOrig, WPARAM wParam,
651 LPARAM lParam)
653 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
654 lParam, TRUE );
658 /***********************************************************************
659 * HOOK_UnMap32WTo16
661 static void HOOK_UnMap32WTo16(INT id, INT code, WPARAM wParamOrig,
662 LPARAM lParamOrig, WPARAM wParam,
663 LPARAM lParam)
665 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
666 lParam, FALSE );
670 /***********************************************************************
671 * HOOK_Map32ATo32W
673 static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
674 LPARAM *plParam)
676 if (id == WH_CBT && code == HCBT_CREATEWND)
678 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
679 LPCBT_CREATEWNDW lpcbtcwW = HeapAlloc( SystemHeap, 0,
680 sizeof(*lpcbtcwW) );
681 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
683 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
684 *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
686 if (HIWORD(lpcbtcwA->lpcs->lpszName))
688 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
689 lpcbtcwA->lpcs->lpszName );
691 else
692 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
694 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
696 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
697 lpcbtcwA->lpcs->lpszClass );
699 else
700 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
701 *plParam = (LPARAM)lpcbtcwW;
703 return;
707 /***********************************************************************
708 * HOOK_UnMap32ATo32W
710 static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
711 LPARAM lParamOrig, WPARAM wParam,
712 LPARAM lParam)
714 if (id == WH_CBT && code == HCBT_CREATEWND)
716 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
717 if (HIWORD(lpcbtcwW->lpcs->lpszName))
718 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
719 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
720 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
721 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
722 HeapFree( SystemHeap, 0, lpcbtcwW );
724 return;
728 /***********************************************************************
729 * HOOK_Map32WTo32A
731 static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
732 LPARAM *plParam)
734 if (id == WH_CBT && code == HCBT_CREATEWND)
736 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
737 LPCBT_CREATEWNDA lpcbtcwA = HeapAlloc( SystemHeap, 0,
738 sizeof(*lpcbtcwA) );
739 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
741 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
742 *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
744 if (HIWORD(lpcbtcwW->lpcs->lpszName))
745 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
746 lpcbtcwW->lpcs->lpszName );
747 else
748 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
750 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
751 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
752 lpcbtcwW->lpcs->lpszClass );
753 else
754 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
755 *plParam = (LPARAM)lpcbtcwA;
757 return;
761 /***********************************************************************
762 * HOOK_UnMap32WTo32A
764 static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
765 LPARAM lParamOrig, WPARAM wParam,
766 LPARAM lParam)
768 if (id == WH_CBT && code == HCBT_CREATEWND)
770 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
771 if (HIWORD(lpcbtcwA->lpcs->lpszName))
772 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
773 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
774 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
775 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
776 HeapFree( SystemHeap, 0, lpcbtcwA );
778 return;
782 /***********************************************************************
783 * Map Function Tables
785 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
787 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
788 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
789 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
792 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
794 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
795 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
796 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
800 /***********************************************************************
801 * Internal Functions
804 /***********************************************************************
805 * HOOK_GetNextHook
807 * Get the next hook of a given hook.
809 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
811 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
813 if (!data || !hook) return 0;
814 if (data->next) return data->next;
815 if (!data->ownerQueue) return 0; /* Already system hook */
817 /* Now start enumerating the system hooks */
818 return HOOK_systemHooks[data->id - WH_MINHOOK];
822 /***********************************************************************
823 * HOOK_GetHook
825 * Get the first hook for a given type.
827 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
829 MESSAGEQUEUE *queue;
830 HANDLE16 hook = 0;
832 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
833 hook = queue->hooks[id - WH_MINHOOK];
834 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
836 QUEUE_Unlock( queue );
837 return hook;
841 /***********************************************************************
842 * HOOK_SetHook
844 * Install a given hook.
846 static HHOOK HOOK_SetHook( INT16 id, LPVOID proc, INT type,
847 HMODULE16 hModule, DWORD dwThreadId )
849 HOOKDATA *data;
850 HANDLE16 handle;
851 HQUEUE16 hQueue = 0;
853 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
855 TRACE(hook, "Setting hook %d: %08x %04x %08lx\n",
856 id, (UINT)proc, hModule, dwThreadId );
858 /* Create task queue if none present */
859 GetFastQueue16();
861 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput16(FALSE);
863 if (dwThreadId) /* Task-specific hook */
865 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
866 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
867 if (!(hQueue = GetThreadQueue16( dwThreadId )))
868 return 0;
871 /* Create the hook structure */
873 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
874 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
875 data->proc = proc;
876 data->id = id;
877 data->ownerQueue = hQueue;
878 data->ownerModule = hModule;
879 data->flags = type;
881 /* Insert it in the correct linked list */
883 if (hQueue)
885 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
886 data->next = queue->hooks[id - WH_MINHOOK];
887 queue->hooks[id - WH_MINHOOK] = handle;
888 QUEUE_Unlock( queue );
890 else
892 data->next = HOOK_systemHooks[id - WH_MINHOOK];
893 HOOK_systemHooks[id - WH_MINHOOK] = handle;
895 TRACE(hook, "Setting hook %d: ret=%04x [next=%04x]\n",
896 id, handle, data->next );
898 return (HHOOK)( handle? MAKELONG( handle, HOOK_MAGIC ) : 0 );
902 /***********************************************************************
903 * HOOK_RemoveHook
905 * Remove a hook from the list.
907 static BOOL HOOK_RemoveHook( HANDLE16 hook )
909 HOOKDATA *data;
910 HANDLE16 *prevHook;
912 TRACE(hook, "Removing hook %04x\n", hook );
914 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
915 if (data->flags & HOOK_INUSE)
917 /* Mark it for deletion later on */
918 WARN(hook, "Hook still running, deletion delayed\n" );
919 data->proc = (HOOKPROC)0;
920 return TRUE;
923 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput16(TRUE);
925 /* Remove it from the linked list */
927 if (data->ownerQueue)
929 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( data->ownerQueue );
930 if (!queue) return FALSE;
931 prevHook = &queue->hooks[data->id - WH_MINHOOK];
932 QUEUE_Unlock( queue );
934 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
936 while (*prevHook && *prevHook != hook)
937 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
939 if (!*prevHook) return FALSE;
940 *prevHook = data->next;
941 USER_HEAP_FREE( hook );
942 return TRUE;
946 /***********************************************************************
947 * HOOK_FindValidHook
949 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
951 HOOKDATA *data;
953 for (;;)
955 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
956 if (data->proc) return hook;
957 hook = data->next;
962 /***********************************************************************
963 * HOOK_CallHook
965 * Call a hook procedure.
967 static LRESULT HOOK_CallHook( HANDLE16 hook, INT fromtype, INT code,
968 WPARAM wParam, LPARAM lParam )
970 MESSAGEQUEUE *queue;
971 HANDLE16 prevHook;
972 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
973 LRESULT ret;
975 WPARAM wParamOrig = wParam;
976 LPARAM lParamOrig = lParam;
977 HOOK_MapFunc MapFunc;
978 HOOK_UnMapFunc UnMapFunc;
980 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
981 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
983 if (MapFunc)
984 MapFunc( data->id, code, &wParam, &lParam );
986 /* Now call it */
988 if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
989 prevHook = queue->hCurHook;
990 queue->hCurHook = hook;
991 data->flags |= HOOK_INUSE;
993 TRACE(hook, "Calling hook %04x: %d %08x %08lx\n",
994 hook, code, wParam, lParam );
996 ret = data->proc(code, wParam, lParam);
998 /* Grrr. While the hook procedure is supposed to have an LRESULT return
999 value even in Win16, it seems that for those hook types where the
1000 return value is interpreted as BOOL, Windows doesn't actually check
1001 the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on
1002 that, because they neglect to clear DX ... */
1003 if ( (data->flags & HOOK_MAPTYPE) == HOOK_WIN16
1004 && data->id != WH_JOURNALPLAYBACK )
1005 ret = LOWORD( ret );
1007 TRACE(hook, "Ret hook %04x = %08lx\n", hook, ret );
1009 data->flags &= ~HOOK_INUSE;
1010 queue->hCurHook = prevHook;
1012 QUEUE_Unlock( queue );
1014 if (UnMapFunc)
1015 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
1017 if (!data->proc) HOOK_RemoveHook( hook );
1019 return ret;
1022 /***********************************************************************
1023 * Exported Functions & APIs
1026 /***********************************************************************
1027 * HOOK_GetProc16
1029 * Don't call this unless you are the if1632/thunk.c.
1031 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
1033 HOOKDATA *data;
1034 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
1035 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
1036 if ((data->flags & HOOK_MAPTYPE) != HOOK_WIN16) return NULL;
1037 return (HOOKPROC16)data->proc;
1041 /***********************************************************************
1042 * HOOK_IsHooked
1044 * Replacement for calling HOOK_GetHook from other modules.
1046 BOOL HOOK_IsHooked( INT16 id )
1048 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1049 avoid queue being created if someone wants to merely check ... */
1051 return HOOK_GetHook( id, GetThreadQueue16(0) ) != 0;
1055 /***********************************************************************
1056 * HOOK_CallHooks16
1058 * Call a hook chain.
1060 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1061 LPARAM lParam )
1063 HANDLE16 hook;
1065 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1066 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1067 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1070 /***********************************************************************
1071 * HOOK_CallHooks32A
1073 * Call a hook chain.
1075 LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
1076 LPARAM lParam )
1078 HANDLE16 hook;
1080 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1081 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1082 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1085 /***********************************************************************
1086 * HOOK_CallHooks32W
1088 * Call a hook chain.
1090 LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
1091 LPARAM lParam )
1093 HANDLE16 hook;
1095 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1096 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1097 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1098 lParam );
1102 /***********************************************************************
1103 * HOOK_ResetQueueHooks
1105 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1107 MESSAGEQUEUE *queue;
1109 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
1111 HOOKDATA* data;
1112 HHOOK hook;
1113 int id;
1114 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1116 hook = queue->hooks[id - WH_MINHOOK];
1117 while( hook )
1119 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1121 data->ownerQueue = hQueue;
1122 hook = data->next;
1123 } else break;
1127 QUEUE_Unlock( queue );
1131 /***********************************************************************
1132 * HOOK_FreeModuleHooks
1134 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1136 /* remove all system hooks registered by this module */
1138 HOOKDATA* hptr;
1139 HHOOK hook, next;
1140 int id;
1142 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1144 hook = HOOK_systemHooks[id - WH_MINHOOK];
1145 while( hook )
1146 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1148 next = hptr->next;
1149 if( hptr->ownerModule == hModule )
1151 hptr->flags &= HOOK_MAPTYPE;
1152 HOOK_RemoveHook(hook);
1154 hook = next;
1156 else hook = 0;
1160 /***********************************************************************
1161 * HOOK_FreeQueueHooks
1163 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1165 /* remove all hooks registered by this queue */
1167 HOOKDATA* hptr = NULL;
1168 HHOOK hook, next;
1169 int id;
1171 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1173 hook = HOOK_GetHook( id, hQueue );
1174 while( hook )
1176 next = HOOK_GetNextHook(hook);
1178 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1179 if( hptr && hptr->ownerQueue == hQueue )
1181 hptr->flags &= HOOK_MAPTYPE;
1182 HOOK_RemoveHook(hook);
1184 hook = next;
1190 /***********************************************************************
1191 * SetWindowsHook16 (USER.121)
1193 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1195 HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
1197 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1198 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1200 return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
1203 /***********************************************************************
1204 * SetWindowsHook32A (USER32.525)
1206 HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
1208 return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
1211 /***********************************************************************
1212 * SetWindowsHook32W (USER32.528)
1214 HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
1216 return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
1220 /***********************************************************************
1221 * SetWindowsHookEx16 (USER.291)
1223 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1224 HTASK16 hTask )
1226 if (id == WH_DEBUG)
1228 FIXME(hook, "WH_DEBUG is broken in 16-bit Windows.\n");
1229 return 0;
1231 return HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), (DWORD)hTask );
1234 /***********************************************************************
1235 * SetWindowsHookEx32A (USER32.526)
1237 HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
1238 DWORD dwThreadId )
1240 return HOOK_SetHook( id, proc, HOOK_WIN32A, MapHModuleLS(hInst), dwThreadId );
1243 /***********************************************************************
1244 * SetWindowsHookEx32W (USER32.527)
1246 HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
1247 DWORD dwThreadId )
1249 return HOOK_SetHook( id, proc, HOOK_WIN32W, MapHModuleLS(hInst), dwThreadId );
1253 /***********************************************************************
1254 * UnhookWindowsHook16 (USER.234)
1256 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1258 return UnhookWindowsHook( id, (HOOKPROC)proc );
1261 /***********************************************************************
1262 * UnhookWindowsHook32 (USER32.557)
1264 BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
1266 HANDLE16 hook = HOOK_GetHook( id, GetFastQueue16() );
1268 TRACE(hook, "%d %08lx\n", id, (DWORD)proc );
1270 while (hook)
1272 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1273 if (data->proc == proc) break;
1274 hook = HOOK_GetNextHook( hook );
1276 if (!hook) return FALSE;
1277 return HOOK_RemoveHook( hook );
1281 /***********************************************************************
1282 * UnhookWindowHookEx16 (USER.292)
1284 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1286 return UnhookWindowsHookEx( hhook );
1289 /***********************************************************************
1290 * UnhookWindowHookEx32 (USER32.558)
1292 BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
1294 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1295 return HOOK_RemoveHook( LOWORD(hhook) );
1299 /***********************************************************************
1300 * CallNextHookEx16 (USER.293)
1302 * I wouldn't have separated this into 16 and 32 bit versions, but I
1303 * need a way to figure out if I need to do a mapping or not.
1305 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1306 LPARAM lParam )
1308 HANDLE16 next;
1310 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1311 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1313 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1317 /***********************************************************************
1318 * CallNextHookEx32 (USER32.17)
1320 * There aren't ANSI and UNICODE versions of this.
1322 LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
1323 LPARAM lParam )
1325 HANDLE16 next;
1326 INT fromtype; /* figure out Ansi/Unicode */
1327 HOOKDATA *oldhook;
1329 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1330 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1332 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1333 fromtype = oldhook->flags & HOOK_MAPTYPE;
1335 if (fromtype == HOOK_WIN16)
1336 ERR(hook, "called from 16bit hook!\n");
1338 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1342 /***********************************************************************
1343 * DefHookProc16 (USER.235)
1345 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1346 HHOOK *hhook )
1348 /* Note: the *hhook parameter is never used, since we rely on the
1349 * current hook value from the task queue to find the next hook. */
1350 MESSAGEQUEUE *queue;
1351 LRESULT ret;
1353 if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
1354 ret = CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1355 QUEUE_Unlock( queue );
1356 return ret;
1360 /***********************************************************************
1361 * CallMsgFilter16 (USER.123)
1363 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1365 if (GetSysModalWindow16()) return FALSE;
1366 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1367 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1371 /***********************************************************************
1372 * WIN16_CallMsgFilter32 (USER.823)
1374 BOOL16 WINAPI CallMsgFilter32_16( SEGPTR msg16_32, INT16 code, BOOL16 wHaveParamHigh )
1376 MSG32_16 *lpmsg16_32 = (MSG32_16 *)PTR_SEG_TO_LIN(msg16_32);
1378 if (wHaveParamHigh == FALSE)
1380 lpmsg16_32->wParamHigh = 0;
1381 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1382 return CallMsgFilter16(msg16_32, code);
1384 else
1386 MSG msg32;
1387 BOOL16 ret;
1389 msg32.hwnd = lpmsg16_32->msg.hwnd;
1390 msg32.message = lpmsg16_32->msg.message;
1391 msg32.wParam =
1392 MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
1393 msg32.lParam = lpmsg16_32->msg.lParam;
1394 msg32.time = lpmsg16_32->msg.time;
1395 msg32.pt.x = (INT)lpmsg16_32->msg.pt.x;
1396 msg32.pt.y = (INT)lpmsg16_32->msg.pt.y;
1398 ret = (BOOL16)CallMsgFilterA(&msg32, (INT)code);
1400 lpmsg16_32->msg.hwnd = msg32.hwnd;
1401 lpmsg16_32->msg.message = msg32.message;
1402 lpmsg16_32->msg.wParam = LOWORD(msg32.wParam);
1403 lpmsg16_32->msg.lParam = msg32.lParam;
1404 lpmsg16_32->msg.time = msg32.time;
1405 lpmsg16_32->msg.pt.x = (INT16)msg32.pt.x;
1406 lpmsg16_32->msg.pt.y = (INT16)msg32.pt.y;
1407 lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
1409 return ret;
1414 /***********************************************************************
1415 * CallMsgFilter32A (USER32.15)
1418 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1419 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1421 BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
1423 if (GetSysModalWindow16()) return FALSE; /* ??? */
1424 if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1425 return TRUE;
1426 return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
1430 /***********************************************************************
1431 * CallMsgFilter32W (USER32.16)
1433 BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
1435 if (GetSysModalWindow16()) return FALSE; /* ??? */
1436 if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1437 return TRUE;
1438 return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );