Implemented StartServiceCtrlDispatcherA according to DispatcherW.
[wine.git] / windows / hook.c
blob4ede6fa545f18ee4b8665bf7a550ec4617a5483e
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 "callback.h"
21 #include "hook.h"
22 #include "win.h"
23 #include "queue.h"
24 #include "task.h"
25 #include "user.h"
26 #include "heap.h"
27 #include "struct32.h"
28 #include "winproc.h"
29 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(hook)
33 #include "pshpack1.h"
35 /* Hook data (pointed to by a HHOOK) */
36 typedef struct
38 HANDLE16 next; /* 00 Next hook in chain */
39 HOOKPROC proc; /* 02 Hook procedure (original) */
40 INT16 id; /* 06 Hook id (WH_xxx) */
41 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
42 HMODULE16 ownerModule; /* 0a Owner module */
43 WORD flags; /* 0c flags */
44 HOOKPROC thunk; /* 0e Hook procedure (CallTo16 thunk) */
45 } HOOKDATA;
47 #include "poppack.h"
49 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
51 /* This should probably reside in USER heap */
52 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
54 typedef VOID (*HOOK_MapFunc)(INT, INT, WPARAM *, LPARAM *);
55 typedef VOID (*HOOK_UnMapFunc)(INT, INT, WPARAM, LPARAM, WPARAM,
56 LPARAM);
58 /***********************************************************************
59 * HOOK_Map16To32Common
61 static void HOOK_Map16To32Common(INT id, INT code, WPARAM *pwParam,
62 LPARAM *plParam, BOOL bA )
65 switch( id )
67 case WH_MSGFILTER:
68 case WH_SYSMSGFILTER:
69 case WH_GETMESSAGE:
70 case WH_JOURNALRECORD:
72 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
73 LPMSG lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
75 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
76 *plParam = (LPARAM)lpmsg32;
77 break;
80 case WH_JOURNALPLAYBACK:
82 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
83 LPEVENTMSG lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
85 lpem32->message = lpem16->message;
86 lpem32->paramL = lpem16->paramL;
87 lpem32->paramH = lpem16->paramH;
88 lpem32->time = lpem16->time;
89 lpem32->hwnd = 0; /* FIXME */
91 *plParam = (LPARAM)lpem32;
92 break;
95 case WH_CALLWNDPROC:
97 LPCWPSTRUCT16 lpcwp16 = PTR_SEG_TO_LIN(*plParam);
98 LPCWPSTRUCT lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
100 lpcwp32->hwnd = lpcwp16->hwnd;
101 lpcwp32->lParam = lpcwp16->lParam;
103 if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam,
104 &lpcwp32->message, &lpcwp32->wParam,
105 &lpcwp32->lParam );
106 else WINPROC_MapMsg16To32W( lpcwp16->hwnd,lpcwp16->message, lpcwp16->wParam,
107 &lpcwp32->message, &lpcwp32->wParam,
108 &lpcwp32->lParam );
109 *plParam = (LPARAM)lpcwp32;
110 break;
113 case WH_CBT:
114 switch (code)
116 case HCBT_CREATEWND:
118 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
119 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
120 LPCBT_CREATEWNDA lpcbtcw32 = HeapAlloc( SystemHeap, 0,
121 sizeof(*lpcbtcw32) );
122 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
123 sizeof(*lpcbtcw32->lpcs) );
125 STRUCT32_CREATESTRUCT16to32A( lpcs16,
126 (LPCREATESTRUCTA)lpcbtcw32->lpcs );
128 if (HIWORD(lpcs16->lpszName))
129 lpcbtcw32->lpcs->lpszName =
130 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
131 : HEAP_strdupAtoW( SystemHeap, 0,
132 PTR_SEG_TO_LIN(lpcs16->lpszName) );
133 else
134 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
136 if (HIWORD(lpcs16->lpszClass))
137 lpcbtcw32->lpcs->lpszClass =
138 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
139 : HEAP_strdupAtoW( SystemHeap, 0,
140 PTR_SEG_TO_LIN(lpcs16->lpszClass) );
141 else
142 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
144 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
146 *plParam = (LPARAM)lpcbtcw32;
147 break;
149 case HCBT_ACTIVATE:
151 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
152 LPCBTACTIVATESTRUCT lpcas32 = HeapAlloc( SystemHeap, 0,
153 sizeof(*lpcas32) );
154 lpcas32->fMouse = lpcas16->fMouse;
155 lpcas32->hWndActive = lpcas16->hWndActive;
156 *plParam = (LPARAM)lpcas32;
157 break;
159 case HCBT_CLICKSKIPPED:
161 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
162 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( SystemHeap, 0,
163 sizeof(*lpms32) );
165 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
167 /* wHitTestCode may be negative, so convince compiler to do
168 correct sign extension. Yay. :| */
169 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
171 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
172 lpms32->hwnd = lpms16->hwnd;
173 *plParam = (LPARAM)lpms32;
174 break;
176 case HCBT_MOVESIZE:
178 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
179 LPRECT lprect32 = HeapAlloc( SystemHeap, 0,
180 sizeof(*lprect32) );
182 CONV_RECT16TO32( lprect16, lprect32 );
183 *plParam = (LPARAM)lprect32;
184 break;
187 break;
189 case WH_MOUSE:
191 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
192 LPMOUSEHOOKSTRUCT lpms32 = HeapAlloc( SystemHeap, 0,
193 sizeof(*lpms32) );
195 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
197 /* wHitTestCode may be negative, so convince compiler to do
198 correct sign extension. Yay. :| */
199 lpms32->wHitTestCode = (INT)((INT16)lpms16->wHitTestCode);
200 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
201 lpms32->hwnd = lpms16->hwnd;
202 *plParam = (LPARAM)lpms32;
203 break;
206 case WH_DEBUG:
208 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
209 LPDEBUGHOOKINFO lpdh32 = HeapAlloc( SystemHeap, 0,
210 sizeof(*lpdh32) );
212 lpdh32->idThread = 0; /* FIXME */
213 lpdh32->idThreadInstaller = 0; /* FIXME */
214 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
215 lpdh32->wParam = lpdh16->wParam;
216 lpdh32->code = lpdh16->code;
218 /* do sign extension if it was WH_MSGFILTER */
219 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
221 *plParam = (LPARAM)lpdh32;
222 break;
225 case WH_SHELL:
226 case WH_KEYBOARD:
227 break;
229 case WH_HARDWARE:
230 case WH_FOREGROUNDIDLE:
231 case WH_CALLWNDPROCRET:
232 FIXME("\t[%i] 16to32 translation unimplemented\n", id);
237 /***********************************************************************
238 * HOOK_Map16To32A
240 static void HOOK_Map16To32A(INT id, INT code, WPARAM *pwParam,
241 LPARAM *plParam)
243 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
247 /***********************************************************************
248 * HOOK_Map16To32W
250 static void HOOK_Map16To32W(INT id, INT code, WPARAM *pwParam,
251 LPARAM *plParam)
253 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
257 /***********************************************************************
258 * HOOK_UnMap16To32Common
260 static void HOOK_UnMap16To32Common(INT id, INT code, WPARAM wParamOrig,
261 LPARAM lParamOrig, WPARAM wParam,
262 LPARAM lParam, BOOL bA)
264 switch (id)
266 case WH_MSGFILTER:
267 case WH_SYSMSGFILTER:
268 case WH_JOURNALRECORD:
269 case WH_JOURNALPLAYBACK:
271 HeapFree( SystemHeap, 0, (LPVOID)lParam );
272 break;
274 case WH_CALLWNDPROC:
276 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParam;
277 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
278 lpcwp32->lParam, 0 );
279 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
280 lpcwp32->lParam, 0 );
281 HeapFree( SystemHeap, 0, lpcwp32 );
282 break;
285 case WH_GETMESSAGE:
287 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
288 STRUCT32_MSG32to16( (LPMSG)lParam, lpmsg16 );
289 HeapFree( SystemHeap, 0, (LPVOID)lParam );
290 break;
293 case WH_MOUSE:
294 case WH_DEBUG:
296 HeapFree( SystemHeap, 0, (LPVOID)lParam );
297 break;
299 case WH_CBT:
300 switch (code)
302 case HCBT_CREATEWND:
304 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)lParam;
305 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
307 if( !bA )
309 if (HIWORD(lpcbtcw32->lpcs->lpszName))
310 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
311 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
312 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
315 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
317 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
318 } /* fall through */
320 case HCBT_ACTIVATE:
321 case HCBT_CLICKSKIPPED:
322 case HCBT_MOVESIZE:
324 HeapFree( SystemHeap, 0, (LPVOID)lParam);
325 break;
327 break;
329 case WH_SHELL:
330 case WH_KEYBOARD:
331 break;
333 case WH_HARDWARE:
334 case WH_FOREGROUNDIDLE:
335 case WH_CALLWNDPROCRET:
336 FIXME("\t[%i] skipping unmap\n", id);
337 break;
342 /***********************************************************************
343 * HOOK_UnMap16To32A
345 static void HOOK_UnMap16To32A(INT id, INT code, WPARAM wParamOrig,
346 LPARAM lParamOrig, WPARAM wParam,
347 LPARAM lParam)
349 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
350 lParam, TRUE );
354 /***********************************************************************
355 * HOOK_UnMap16To32W
357 static void HOOK_UnMap16To32W(INT id, INT code, WPARAM wParamOrig,
358 LPARAM lParamOrig, WPARAM wParam,
359 LPARAM lParam)
361 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
362 lParam, FALSE );
366 /***********************************************************************
367 * HOOK_Map32To16Common
369 static void HOOK_Map32To16Common(INT id, INT code, WPARAM *pwParam,
370 LPARAM *plParam, BOOL bA)
372 switch (id)
374 case WH_MSGFILTER:
375 case WH_SYSMSGFILTER:
376 case WH_GETMESSAGE:
377 case WH_JOURNALRECORD:
379 LPMSG lpmsg32 = (LPMSG)*plParam;
380 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
382 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
384 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
385 break;
388 case WH_JOURNALPLAYBACK:
390 LPEVENTMSG lpem32 = (LPEVENTMSG)*plParam;
391 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
393 lpem16->message = lpem32->message;
394 lpem16->paramL = lpem32->paramL;
395 lpem16->paramH = lpem32->paramH;
396 lpem16->time = lpem32->time;
398 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
399 break;
402 case WH_CALLWNDPROC:
404 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)*plParam;
405 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
407 lpcwp16->hwnd = lpcwp32->hwnd;
408 lpcwp16->lParam = lpcwp32->lParam;
410 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
411 lpcwp32->wParam, &lpcwp16->message,
412 &lpcwp16->wParam, &lpcwp16->lParam );
413 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
414 lpcwp32->wParam, &lpcwp16->message,
415 &lpcwp16->wParam, &lpcwp16->lParam );
416 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
417 break;
420 case WH_CBT:
421 switch (code)
423 case HCBT_ACTIVATE:
425 LPCBTACTIVATESTRUCT lpcas32 = (LPCBTACTIVATESTRUCT)*plParam;
426 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
428 lpcas16->fMouse = lpcas32->fMouse;
429 lpcas16->hWndActive = lpcas32->hWndActive;
431 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
432 break;
435 case HCBT_CLICKSKIPPED:
437 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
438 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
440 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
442 lpms16->hwnd = lpms32->hwnd;
443 lpms16->wHitTestCode = lpms32->wHitTestCode;
444 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
446 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
447 break;
450 case HCBT_MOVESIZE:
452 LPRECT lprect32 = (LPRECT)*plParam;
453 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
455 CONV_RECT32TO16( lprect32, lprect16 );
457 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
458 break;
461 break;
463 case WH_MOUSE:
465 LPMOUSEHOOKSTRUCT lpms32 = (LPMOUSEHOOKSTRUCT)*plParam;
466 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
468 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
470 lpms16->hwnd = lpms32->hwnd;
471 lpms16->wHitTestCode = lpms32->wHitTestCode;
472 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
474 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
475 break;
478 case WH_DEBUG:
480 LPDEBUGHOOKINFO lpdh32 = (LPDEBUGHOOKINFO)*plParam;
481 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
483 lpdh16->hModuleHook = 0; /* FIXME */
484 lpdh16->reserved = 0;
485 lpdh16->lParam = lpdh32->lParam;
486 lpdh16->wParam = lpdh32->wParam;
487 lpdh16->code = lpdh32->code;
489 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
490 break;
493 case WH_SHELL:
494 case WH_KEYBOARD:
495 break;
497 case WH_HARDWARE:
498 case WH_FOREGROUNDIDLE:
499 case WH_CALLWNDPROCRET:
500 FIXME("\t[%i] 32to16 translation unimplemented\n", id);
505 /***********************************************************************
506 * HOOK_Map32ATo16
508 static void HOOK_Map32ATo16(INT id, INT code, WPARAM *pwParam,
509 LPARAM *plParam)
511 if (id == WH_CBT && code == HCBT_CREATEWND)
513 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)*plParam;
514 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
515 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
517 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
518 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
520 if (HIWORD(lpcbtcw32->lpcs->lpszName))
521 lpcs16->lpszName =
522 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
523 else
524 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
526 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
527 lpcs16->lpszClass =
528 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
529 else
530 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
532 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
534 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
536 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
540 /***********************************************************************
541 * HOOK_Map32WTo16
543 static void HOOK_Map32WTo16(INT id, INT code, WPARAM *pwParam,
544 LPARAM *plParam)
546 if (id == WH_CBT && code == HCBT_CREATEWND)
548 LPSTR name, cls;
549 LPCBT_CREATEWNDW lpcbtcw32 = (LPCBT_CREATEWNDW)*plParam;
550 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
551 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
553 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
554 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCTA)lpcbtcw32->lpcs,
555 lpcs16 );
557 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
558 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
559 lpcs16->lpszName = SEGPTR_GET( name );
560 lpcs16->lpszClass = SEGPTR_GET( cls );
561 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
563 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
565 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
569 /***********************************************************************
570 * HOOK_UnMap32To16Common
572 static void HOOK_UnMap32To16Common(INT id, INT code, WPARAM wParamOrig,
573 LPARAM lParamOrig, WPARAM wParam,
574 LPARAM lParam, BOOL bA)
576 switch (id)
578 case WH_MSGFILTER:
579 case WH_SYSMSGFILTER:
580 case WH_JOURNALRECORD:
581 case WH_JOURNALPLAYBACK:
582 case WH_MOUSE:
583 case WH_DEBUG:
584 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
585 break;
587 case WH_CALLWNDPROC:
589 LPCWPSTRUCT16 lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
590 LPCWPSTRUCT lpcwp32 = (LPCWPSTRUCT)lParamOrig;
591 MSGPARAM16 mp16;
593 mp16.wParam = lpcwp16->wParam;
594 mp16.lParam = lpcwp16->lParam;
595 mp16.lResult = 0;
597 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
598 lpcwp32->lParam, &mp16 );
599 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
600 lpcwp32->lParam, &mp16 );
601 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
602 break;
605 case WH_GETMESSAGE:
607 LPMSG lpmsg32 = (LPMSG)lParamOrig;
609 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
610 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
611 break;
614 case WH_CBT:
615 switch (code)
617 case HCBT_CREATEWND:
619 LPCBT_CREATEWNDA lpcbtcw32 = (LPCBT_CREATEWNDA)(lParamOrig);
620 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
621 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
623 if (HIWORD(lpcs16->lpszName))
624 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
626 if (HIWORD(lpcs16->lpszClass))
627 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
629 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
631 SEGPTR_FREE( lpcs16 );
632 } /* fall through */
634 case HCBT_ACTIVATE:
635 case HCBT_CLICKSKIPPED:
636 case HCBT_MOVESIZE:
638 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
639 break;
641 break;
643 case WH_SHELL:
644 case WH_KEYBOARD:
645 break;
647 case WH_HARDWARE:
648 case WH_FOREGROUNDIDLE:
649 case WH_CALLWNDPROCRET:
650 FIXME("\t[%i] skipping unmap\n", id);
655 /***********************************************************************
656 * HOOK_UnMap32ATo16
658 static void HOOK_UnMap32ATo16(INT id, INT code, WPARAM wParamOrig,
659 LPARAM lParamOrig, WPARAM wParam,
660 LPARAM lParam)
662 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
663 lParam, TRUE );
667 /***********************************************************************
668 * HOOK_UnMap32WTo16
670 static void HOOK_UnMap32WTo16(INT id, INT code, WPARAM wParamOrig,
671 LPARAM lParamOrig, WPARAM wParam,
672 LPARAM lParam)
674 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
675 lParam, FALSE );
679 /***********************************************************************
680 * HOOK_Map32ATo32W
682 static void HOOK_Map32ATo32W(INT id, INT code, WPARAM *pwParam,
683 LPARAM *plParam)
685 if (id == WH_CBT && code == HCBT_CREATEWND)
687 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)*plParam;
688 LPCBT_CREATEWNDW lpcbtcwW = HeapAlloc( SystemHeap, 0,
689 sizeof(*lpcbtcwW) );
690 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
692 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
693 *lpcbtcwW->lpcs = *(LPCREATESTRUCTW)lpcbtcwA->lpcs;
695 if (HIWORD(lpcbtcwA->lpcs->lpszName))
697 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
698 lpcbtcwA->lpcs->lpszName );
700 else
701 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
703 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
705 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
706 lpcbtcwA->lpcs->lpszClass );
708 else
709 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
710 *plParam = (LPARAM)lpcbtcwW;
712 return;
716 /***********************************************************************
717 * HOOK_UnMap32ATo32W
719 static void HOOK_UnMap32ATo32W(INT id, INT code, WPARAM wParamOrig,
720 LPARAM lParamOrig, WPARAM wParam,
721 LPARAM lParam)
723 if (id == WH_CBT && code == HCBT_CREATEWND)
725 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)lParam;
726 if (HIWORD(lpcbtcwW->lpcs->lpszName))
727 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
728 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
729 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
730 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
731 HeapFree( SystemHeap, 0, lpcbtcwW );
733 return;
737 /***********************************************************************
738 * HOOK_Map32WTo32A
740 static void HOOK_Map32WTo32A(INT id, INT code, WPARAM *pwParam,
741 LPARAM *plParam)
743 if (id == WH_CBT && code == HCBT_CREATEWND)
745 LPCBT_CREATEWNDW lpcbtcwW = (LPCBT_CREATEWNDW)*plParam;
746 LPCBT_CREATEWNDA lpcbtcwA = HeapAlloc( SystemHeap, 0,
747 sizeof(*lpcbtcwA) );
748 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
750 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
751 *lpcbtcwA->lpcs = *(LPCREATESTRUCTA)lpcbtcwW->lpcs;
753 if (HIWORD(lpcbtcwW->lpcs->lpszName))
754 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
755 lpcbtcwW->lpcs->lpszName );
756 else
757 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
759 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
760 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
761 lpcbtcwW->lpcs->lpszClass );
762 else
763 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
764 *plParam = (LPARAM)lpcbtcwA;
766 return;
770 /***********************************************************************
771 * HOOK_UnMap32WTo32A
773 static void HOOK_UnMap32WTo32A(INT id, INT code, WPARAM wParamOrig,
774 LPARAM lParamOrig, WPARAM wParam,
775 LPARAM lParam)
777 if (id == WH_CBT && code == HCBT_CREATEWND)
779 LPCBT_CREATEWNDA lpcbtcwA = (LPCBT_CREATEWNDA)lParam;
780 if (HIWORD(lpcbtcwA->lpcs->lpszName))
781 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
782 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
783 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
784 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
785 HeapFree( SystemHeap, 0, lpcbtcwA );
787 return;
791 /***********************************************************************
792 * Map Function Tables
794 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
796 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
797 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
798 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
801 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
803 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
804 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
805 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
809 /***********************************************************************
810 * Internal Functions
813 /***********************************************************************
814 * HOOK_GetNextHook
816 * Get the next hook of a given hook.
818 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
820 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
822 if (!data || !hook) return 0;
823 if (data->next) return data->next;
824 if (!data->ownerQueue) return 0; /* Already system hook */
826 /* Now start enumerating the system hooks */
827 return HOOK_systemHooks[data->id - WH_MINHOOK];
831 /***********************************************************************
832 * HOOK_GetHook
834 * Get the first hook for a given type.
836 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
838 MESSAGEQUEUE *queue;
839 HANDLE16 hook = 0;
841 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
842 hook = queue->hooks[id - WH_MINHOOK];
843 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
845 QUEUE_Unlock( queue );
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 GetFastQueue16();
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 = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
1020 prevHook = queue->hCurHook;
1021 queue->hCurHook = hook;
1022 data->flags |= HOOK_INUSE;
1024 TRACE("Calling hook %04x: %d %08x %08lx\n",
1025 hook, code, wParam, lParam );
1027 /* Suspend window structure locks before calling user code */
1028 iWndsLocks = WIN_SuspendWndsLock();
1030 ret = data->thunk(code, wParam, lParam);
1032 /* Grrr. While the hook procedure is supposed to have an LRESULT return
1033 value even in Win16, it seems that for those hook types where the
1034 return value is interpreted as BOOL, Windows doesn't actually check
1035 the HIWORD ... Some buggy Win16 programs, notably WINFILE, rely on
1036 that, because they neglect to clear DX ... */
1037 if ( (data->flags & HOOK_MAPTYPE) == HOOK_WIN16
1038 && data->id != WH_JOURNALPLAYBACK )
1039 ret = LOWORD( ret );
1041 WIN_RestoreWndsLock(iWndsLocks);
1043 TRACE("Ret hook %04x = %08lx\n", hook, ret );
1045 data->flags &= ~HOOK_INUSE;
1046 queue->hCurHook = prevHook;
1048 QUEUE_Unlock( queue );
1050 if (UnMapFunc)
1051 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
1053 if (!data->proc) HOOK_RemoveHook( hook );
1055 return ret;
1058 /***********************************************************************
1059 * Exported Functions & APIs
1062 /***********************************************************************
1063 * HOOK_IsHooked
1065 * Replacement for calling HOOK_GetHook from other modules.
1067 BOOL HOOK_IsHooked( INT16 id )
1069 /* Hmmm. Use GetThreadQueue(0) instead of GetFastQueue() here to
1070 avoid queue being created if someone wants to merely check ... */
1072 return HOOK_GetHook( id, GetThreadQueue16(0) ) != 0;
1076 /***********************************************************************
1077 * HOOK_CallHooks16
1079 * Call a hook chain.
1081 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1082 LPARAM lParam )
1084 HANDLE16 hook;
1086 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1087 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1088 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1091 /***********************************************************************
1092 * HOOK_CallHooks32A
1094 * Call a hook chain.
1096 LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
1097 LPARAM lParam )
1099 HANDLE16 hook;
1101 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1102 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1103 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1106 /***********************************************************************
1107 * HOOK_CallHooks32W
1109 * Call a hook chain.
1111 LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
1112 LPARAM lParam )
1114 HANDLE16 hook;
1116 if (!(hook = HOOK_GetHook( id, GetFastQueue16() ))) return 0;
1117 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1118 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1119 lParam );
1123 /***********************************************************************
1124 * HOOK_ResetQueueHooks
1126 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1128 MESSAGEQUEUE *queue;
1130 if ((queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue )) != NULL)
1132 HOOKDATA* data;
1133 HHOOK hook;
1134 int id;
1135 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1137 hook = queue->hooks[id - WH_MINHOOK];
1138 while( hook )
1140 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1142 data->ownerQueue = hQueue;
1143 hook = data->next;
1144 } else break;
1148 QUEUE_Unlock( queue );
1152 /***********************************************************************
1153 * HOOK_FreeModuleHooks
1155 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1157 /* remove all system hooks registered by this module */
1159 HOOKDATA* hptr;
1160 HHOOK hook, next;
1161 int id;
1163 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1165 hook = HOOK_systemHooks[id - WH_MINHOOK];
1166 while( hook )
1167 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1169 next = hptr->next;
1170 if( hptr->ownerModule == hModule )
1172 hptr->flags &= HOOK_MAPTYPE;
1173 HOOK_RemoveHook(hook);
1175 hook = next;
1177 else hook = 0;
1181 /***********************************************************************
1182 * HOOK_FreeQueueHooks
1184 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1186 /* remove all hooks registered by this queue */
1188 HOOKDATA* hptr = NULL;
1189 HHOOK hook, next;
1190 int id;
1192 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1194 hook = HOOK_GetHook( id, hQueue );
1195 while( hook )
1197 next = HOOK_GetNextHook(hook);
1199 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1200 if( hptr && hptr->ownerQueue == hQueue )
1202 hptr->flags &= HOOK_MAPTYPE;
1203 HOOK_RemoveHook(hook);
1205 hook = next;
1211 /***********************************************************************
1212 * SetWindowsHook16 (USER.121)
1214 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1216 HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
1218 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1219 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1221 return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
1224 /***********************************************************************
1225 * SetWindowsHook32A (USER32.525)
1227 HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
1229 return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
1232 /***********************************************************************
1233 * SetWindowsHook32W (USER32.528)
1235 HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
1237 return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
1241 /***********************************************************************
1242 * SetWindowsHookEx16 (USER.291)
1244 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1245 HTASK16 hTask )
1247 if (id == WH_DEBUG)
1249 FIXME("WH_DEBUG is broken in 16-bit Windows.\n");
1250 return 0;
1252 return HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), (DWORD)hTask );
1255 /***********************************************************************
1256 * SetWindowsHookEx32A (USER32.526)
1258 HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
1259 DWORD dwThreadId )
1261 return HOOK_SetHook( id, proc, HOOK_WIN32A, MapHModuleLS(hInst), dwThreadId );
1264 /***********************************************************************
1265 * SetWindowsHookEx32W (USER32.527)
1267 HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
1268 DWORD dwThreadId )
1270 return HOOK_SetHook( id, proc, HOOK_WIN32W, MapHModuleLS(hInst), dwThreadId );
1274 /***********************************************************************
1275 * UnhookWindowsHook16 (USER.234)
1277 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1279 return UnhookWindowsHook( id, (HOOKPROC)proc );
1282 /***********************************************************************
1283 * UnhookWindowsHook32 (USER32.557)
1285 BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
1287 HANDLE16 hook = HOOK_GetHook( id, GetFastQueue16() );
1289 TRACE("%d %08lx\n", id, (DWORD)proc );
1291 while (hook)
1293 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1294 if (data->proc == proc) break;
1295 hook = HOOK_GetNextHook( hook );
1297 if (!hook) return FALSE;
1298 return HOOK_RemoveHook( hook );
1302 /***********************************************************************
1303 * UnhookWindowHookEx16 (USER.292)
1305 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1307 return UnhookWindowsHookEx( hhook );
1310 /***********************************************************************
1311 * UnhookWindowHookEx32 (USER32.558)
1313 BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
1315 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1316 return HOOK_RemoveHook( LOWORD(hhook) );
1320 /***********************************************************************
1321 * CallNextHookEx16 (USER.293)
1323 * I wouldn't have separated this into 16 and 32 bit versions, but I
1324 * need a way to figure out if I need to do a mapping or not.
1326 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1327 LPARAM lParam )
1329 HANDLE16 next;
1331 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1332 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1334 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1338 /***********************************************************************
1339 * CallNextHookEx32 (USER32.17)
1341 * There aren't ANSI and UNICODE versions of this.
1343 LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
1344 LPARAM lParam )
1346 HANDLE16 next;
1347 INT fromtype; /* figure out Ansi/Unicode */
1348 HOOKDATA *oldhook;
1350 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1351 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1353 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1354 fromtype = oldhook->flags & HOOK_MAPTYPE;
1356 if (fromtype == HOOK_WIN16)
1357 ERR("called from 16bit hook!\n");
1359 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1363 /***********************************************************************
1364 * DefHookProc16 (USER.235)
1366 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1367 HHOOK *hhook )
1369 /* Note: the *hhook parameter is never used, since we rely on the
1370 * current hook value from the task queue to find the next hook. */
1371 MESSAGEQUEUE *queue;
1372 LRESULT ret;
1374 if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() ))) return 0;
1375 ret = CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1376 QUEUE_Unlock( queue );
1377 return ret;
1381 /***********************************************************************
1382 * CallMsgFilter16 (USER.123)
1384 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1386 if (GetSysModalWindow16()) return FALSE;
1387 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1388 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1392 /***********************************************************************
1393 * WIN16_CallMsgFilter32 (USER.823)
1395 BOOL16 WINAPI CallMsgFilter32_16( SEGPTR msg16_32, INT16 code, BOOL16 wHaveParamHigh )
1397 MSG32_16 *lpmsg16_32 = (MSG32_16 *)PTR_SEG_TO_LIN(msg16_32);
1399 if (wHaveParamHigh == FALSE)
1401 lpmsg16_32->wParamHigh = 0;
1402 /* WARNING: msg16_32->msg has to be the first variable in the struct */
1403 return CallMsgFilter16(msg16_32, code);
1405 else
1407 MSG msg32;
1408 BOOL16 ret;
1410 msg32.hwnd = lpmsg16_32->msg.hwnd;
1411 msg32.message = lpmsg16_32->msg.message;
1412 msg32.wParam =
1413 MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
1414 msg32.lParam = lpmsg16_32->msg.lParam;
1415 msg32.time = lpmsg16_32->msg.time;
1416 msg32.pt.x = (INT)lpmsg16_32->msg.pt.x;
1417 msg32.pt.y = (INT)lpmsg16_32->msg.pt.y;
1419 ret = (BOOL16)CallMsgFilterA(&msg32, (INT)code);
1421 lpmsg16_32->msg.hwnd = msg32.hwnd;
1422 lpmsg16_32->msg.message = msg32.message;
1423 lpmsg16_32->msg.wParam = LOWORD(msg32.wParam);
1424 lpmsg16_32->msg.lParam = msg32.lParam;
1425 lpmsg16_32->msg.time = msg32.time;
1426 lpmsg16_32->msg.pt.x = (INT16)msg32.pt.x;
1427 lpmsg16_32->msg.pt.y = (INT16)msg32.pt.y;
1428 lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
1430 return ret;
1435 /***********************************************************************
1436 * CallMsgFilter32A (USER32.15)
1439 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1440 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1442 BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
1444 if (GetSysModalWindow16()) return FALSE; /* ??? */
1445 if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1446 return TRUE;
1447 return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
1451 /***********************************************************************
1452 * CallMsgFilter32W (USER32.16)
1454 BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
1456 if (GetSysModalWindow16()) return FALSE; /* ??? */
1457 if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1458 return TRUE;
1459 return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );