2 * Windows hook functions
4 * Copyright 1994, 1995 Alexandre Julliard
7 * Based on investigations by Alex Korobka
12 * A HHOOK is a 32-bit handle for compatibility with Windows 3.0 where it was
13 * a pointer to the next function. Now it is in fact composed of a USER heap
14 * handle in the low 16 bits and of a HOOK_MAGIC value in the high 16 bits.
17 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
21 #include "stackframe.h"
30 /* Hook data (pointed to by a HHOOK) */
33 HANDLE16 next
; /* 00 Next hook in chain */
34 HOOKPROC32 proc WINE_PACKED
; /* 02 Hook procedure */
35 INT16 id
; /* 06 Hook id (WH_xxx) */
36 HQUEUE16 ownerQueue
; /* 08 Owner queue (0 for system hook) */
37 HMODULE16 ownerModule
; /* 0a Owner module */
38 WORD inHookProc
; /* 0c TRUE if in this->proc */
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
)(INT32
, INT32
, WPARAM32
*, LPARAM
*);
50 typedef VOID (*HOOK_UnMapFunc
)(INT32
, INT32
, WPARAM32
, LPARAM
, WPARAM32
,
54 /***********************************************************************
55 * Hook Mapping Functions
59 /***********************************************************************
60 * HOOK_Map16To32Common
62 static void HOOK_Map16To32Common(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
70 case WH_JOURNALRECORD
:
72 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(*plParam
);
73 LPMSG32 lpmsg32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpmsg32
) );
75 STRUCT32_MSG16to32( lpmsg16
, lpmsg32
);
76 *plParam
= (LPARAM
)lpmsg32
;
79 case WH_JOURNALPLAYBACK
:
81 LPEVENTMSG16 lpem16
= PTR_SEG_TO_LIN(*plParam
);
82 LPEVENTMSG32 lpem32
= HeapAlloc( SystemHeap
, 0, sizeof(*lpem32
) );
84 lpem32
->message
= lpem16
->message
;
85 lpem32
->paramL
= lpem16
->paramL
;
86 lpem32
->paramH
= lpem16
->paramH
;
87 lpem32
->time
= lpem16
->time
;
88 lpem32
->hwnd
= 0; /* FIXME */
90 *plParam
= (LPARAM
)lpem32
;
98 LPCBTACTIVATESTRUCT16 lpcas16
= PTR_SEG_TO_LIN(*plParam
);
99 LPCBTACTIVATESTRUCT32 lpcas32
= HeapAlloc( SystemHeap
, 0,
101 lpcas32
->fMouse
= lpcas16
->fMouse
;
102 lpcas32
->hWndActive
= lpcas16
->hWndActive
;
103 *plParam
= (LPARAM
)lpcas32
;
106 case HCBT_CLICKSKIPPED
:
108 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
109 LPMOUSEHOOKSTRUCT32 lpms32
= HeapAlloc( SystemHeap
, 0,
112 STRUCT32_POINT16to32( &lpms16
->pt
, &lpms32
->pt
);
114 /* wHitTestCode may be negative, so convince compiler to do
115 correct sign extension. Yay. :| */
116 lpms32
->wHitTestCode
= (INT32
)((INT16
)lpms16
->wHitTestCode
);
118 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
119 lpms32
->hwnd
= lpms16
->hwnd
;
120 *plParam
= (LPARAM
)lpms32
;
125 LPRECT16 lprect16
= PTR_SEG_TO_LIN(*plParam
);
126 LPRECT32 lprect32
= HeapAlloc( SystemHeap
, 0,
129 STRUCT32_RECT16to32( lprect16
, lprect32
);
130 *plParam
= (LPARAM
)lprect32
;
137 LPMOUSEHOOKSTRUCT16 lpms16
= PTR_SEG_TO_LIN(*plParam
);
138 LPMOUSEHOOKSTRUCT32 lpms32
= HeapAlloc( SystemHeap
, 0,
141 STRUCT32_POINT16to32( &lpms16
->pt
, &lpms32
->pt
);
143 /* wHitTestCode may be negative, so convince compiler to do
144 correct sign extension. Yay. :| */
145 lpms32
->wHitTestCode
= (INT32
)((INT16
)lpms16
->wHitTestCode
);
146 lpms32
->dwExtraInfo
= lpms16
->dwExtraInfo
;
147 lpms32
->hwnd
= lpms16
->hwnd
;
148 *plParam
= (LPARAM
)lpms32
;
153 LPDEBUGHOOKINFO16 lpdh16
= PTR_SEG_TO_LIN(*plParam
);
154 LPDEBUGHOOKINFO32 lpdh32
= HeapAlloc( SystemHeap
, 0,
157 lpdh32
->idThread
= 0; /* FIXME */
158 lpdh32
->idThreadInstaller
= 0; /* FIXME */
159 lpdh32
->lParam
= lpdh16
->lParam
; /* FIXME Check for sign ext */
160 lpdh32
->wParam
= lpdh16
->wParam
;
161 lpdh32
->code
= lpdh16
->code
;
163 /* do sign extension if it was WH_MSGFILTER */
164 if (*pwParam
== 0xffff) *pwParam
= WH_MSGFILTER
;
166 *plParam
= (LPARAM
)lpdh32
;
178 fprintf(stderr
, "Unknown hook id: %d\n", id
);
184 /***********************************************************************
187 static void HOOK_Map16To32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
190 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
192 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(*plParam
);
193 LPCBT_CREATEWND32A lpcbtcw32
= HeapAlloc( SystemHeap
, 0,
194 sizeof(*lpcbtcw32
) );
195 lpcbtcw32
->lpcs
= HeapAlloc( SystemHeap
, 0,
196 sizeof(*lpcbtcw32
->lpcs
) );
198 STRUCT32_CREATESTRUCT16to32A( lpcbtcw16
->lpcs
, lpcbtcw32
->lpcs
);
200 if (HIWORD(lpcbtcw16
->lpcs
->lpszName
))
201 lpcbtcw32
->lpcs
->lpszName
202 = PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
->lpszName
);
204 lpcbtcw32
->lpcs
->lpszName
= (LPSTR
)lpcbtcw16
->lpcs
->lpszName
;
206 if (HIWORD(lpcbtcw16
->lpcs
->lpszClass
))
207 lpcbtcw32
->lpcs
->lpszClass
208 = PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
->lpszClass
);
210 lpcbtcw32
->lpcs
->lpszClass
= (LPSTR
)lpcbtcw16
->lpcs
->lpszClass
;
212 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
214 *plParam
= (LPARAM
)lpcbtcw32
;
217 HOOK_Map16To32Common( id
, code
, pwParam
, plParam
);
221 /***********************************************************************
224 static void HOOK_Map16To32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
227 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
229 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(*plParam
);
230 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
231 LPCBT_CREATEWND32W lpcbtcw32
= HeapAlloc( SystemHeap
, 0,
232 sizeof(*lpcbtcw32
) );
233 lpcbtcw32
->lpcs
= HeapAlloc( SystemHeap
, 0,
234 sizeof(*lpcbtcw32
->lpcs
) );
236 STRUCT32_CREATESTRUCT16to32A( lpcs16
,
237 (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
);
239 if (HIWORD(lpcs16
->lpszName
))
240 lpcbtcw32
->lpcs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
241 PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
243 lpcbtcw32
->lpcs
->lpszName
= (LPWSTR
)lpcs16
->lpszName
;
245 if (HIWORD(lpcs16
->lpszClass
))
246 lpcbtcw32
->lpcs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
247 PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
249 lpcbtcw32
->lpcs
->lpszClass
= (LPWSTR
)lpcs16
->lpszClass
;
251 lpcbtcw32
->hwndInsertAfter
= lpcbtcw16
->hwndInsertAfter
;
253 *plParam
= (LPARAM
)lpcbtcw32
;
255 else HOOK_Map16To32Common( id
, code
, pwParam
, plParam
);
259 /***********************************************************************
260 * HOOK_UnMap16To32Common
262 static void HOOK_UnMap16To32Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
263 LPARAM lParamOrig
, WPARAM32 wParam
,
269 case WH_SYSMSGFILTER
:
270 case WH_JOURNALRECORD
:
271 case WH_JOURNALPLAYBACK
:
273 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
279 LPMSG16 lpmsg16
= PTR_SEG_TO_LIN(lParamOrig
);
280 STRUCT32_MSG32to16( (LPMSG32
)lParam
, lpmsg16
);
281 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
287 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
290 /* I don't think any of these need to be copied */
295 case HCBT_CLICKSKIPPED
:
297 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
308 fprintf(stderr
, "Can't map hook id: %d\n", id
);
312 fprintf(stderr
, "Unknown hook id: %d\n", id
);
318 /***********************************************************************
321 static void HOOK_UnMap16To32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
322 LPARAM lParamOrig
, WPARAM32 wParam
,
325 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
327 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)lParam
;
328 HeapFree( SystemHeap
, 0, lpcbtcw32
->lpcs
);
329 HeapFree( SystemHeap
, 0, lpcbtcw32
);
332 HOOK_UnMap16To32Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
338 /***********************************************************************
341 static void HOOK_UnMap16To32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
342 LPARAM lParamOrig
, WPARAM32 wParam
,
345 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
347 LPCBT_CREATEWND32W lpcbtcw32
= (LPCBT_CREATEWND32W
)lParam
;
348 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
349 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszName
);
350 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
351 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcw32
->lpcs
->lpszClass
);
352 HeapFree( SystemHeap
, 0, lpcbtcw32
->lpcs
);
353 HeapFree( SystemHeap
, 0, lpcbtcw32
);
356 HOOK_UnMap16To32Common(id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
360 /***********************************************************************
361 * HOOK_Map32To16Common
363 static void HOOK_Map32To16Common(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
369 case WH_SYSMSGFILTER
:
371 case WH_JOURNALRECORD
:
373 LPMSG32 lpmsg32
= (LPMSG32
)*plParam
;
374 LPMSG16 lpmsg16
= SEGPTR_NEW( MSG16
);
376 STRUCT32_MSG32to16( lpmsg32
, lpmsg16
);
378 *plParam
= (LPARAM
)SEGPTR_GET( lpmsg16
);
382 case WH_JOURNALPLAYBACK
:
384 LPEVENTMSG32 lpem32
= (LPEVENTMSG32
)*plParam
;
385 LPEVENTMSG16 lpem16
= SEGPTR_NEW( EVENTMSG16
);
387 lpem16
->message
= lpem32
->message
;
388 lpem16
->paramL
= lpem32
->paramL
;
389 lpem16
->paramH
= lpem32
->paramH
;
390 lpem16
->time
= lpem32
->time
;
392 *plParam
= (LPARAM
)SEGPTR_GET( lpem16
);
401 LPCBTACTIVATESTRUCT32 lpcas32
= (LPCBTACTIVATESTRUCT32
)*plParam
;
402 LPCBTACTIVATESTRUCT16 lpcas16
=SEGPTR_NEW( CBTACTIVATESTRUCT16
);
404 lpcas16
->fMouse
= lpcas32
->fMouse
;
405 lpcas16
->hWndActive
= lpcas32
->hWndActive
407 *plParam
= (LPARAM
)SEGPTR_GET( lpcas16
);
411 case HCBT_CLICKSKIPPED
:
413 LPMOUSEHOOKSTRUCT32 lpms32
= (LPMOUSEHOOKSTRUCT32
)*plParam
;
414 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
416 STRUCT32_POINT32to16( &lpms32
->pt
, &lpms16
->pt
);
418 lpms16
->hwnd
= lpms32
->hwnd
;
419 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
420 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
422 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
428 LPRECT32 lprect32
= (LPRECT32
)*plParam
;
429 LPRECT16 lprect16
= SEGPTR_NEW( RECT16
);
431 STRUCT32_RECT32to16( lprect32
, lprect16
);
433 *plParam
= (LPARAM
)SEGPTR_GET( lprect16
);
441 LPMOUSEHOOKSTRUCT32 lpms32
= (LPMOUSEHOOKSTRUCT32
)*plParam
;
442 LPMOUSEHOOKSTRUCT16 lpms16
= SEGPTR_NEW( MOUSEHOOKSTRUCT16
);
444 STRUCT32_POINT32to16( &lpms32
->pt
, &lpms16
->pt
);
446 lpms16
->hwnd
= lpms32
->hwnd
;
447 lpms16
->wHitTestCode
= lpms32
->wHitTestCode
;
448 lpms16
->dwExtraInfo
= lpms32
->dwExtraInfo
;
450 *plParam
= (LPARAM
)SEGPTR_GET( lpms16
);
456 LPDEBUGHOOKINFO32 lpdh32
= (LPDEBUGHOOKINFO32
)*plParam
;
457 LPDEBUGHOOKINFO16 lpdh16
= SEGPTR_NEW( DEBUGHOOKINFO16
);
459 lpdh16
->hModuleHook
= 0; /* FIXME */
460 lpdh16
->reserved
= 0;
461 lpdh16
->lParam
= lpdh32
->lParam
;
462 lpdh16
->wParam
= lpdh32
->wParam
;
463 lpdh16
->code
= lpdh32
->code
;
465 *plParam
= (LPARAM
)SEGPTR_GET( lpdh16
);
475 fprintf(stderr
, "Can't map hook id: %d\n", id
);
479 fprintf(stderr
, "Unknown hook id: %d\n", id
);
485 /***********************************************************************
488 static void HOOK_Map32ATo16(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
491 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
493 LPCBT_CREATEWND32A lpcbtcw32
= (LPCBT_CREATEWND32A
)*plParam
;
494 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
495 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
497 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
498 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32
->lpcs
, lpcs16
);
500 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
502 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszName
) );
504 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
506 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
508 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32
->lpcs
->lpszClass
) );
510 lpcs16
->lpszClass
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszClass
;
512 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
514 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
516 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
);
520 /***********************************************************************
523 static void HOOK_Map32WTo16(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
526 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
529 LPCBT_CREATEWND32W lpcbtcw32
= (LPCBT_CREATEWND32W
)*plParam
;
530 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
531 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
533 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
534 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
,
537 name
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszName
);
538 cls
= SEGPTR_STRDUP_WtoA( lpcbtcw32
->lpcs
->lpszClass
);
539 lpcs16
->lpszName
= SEGPTR_GET( name
);
540 lpcs16
->lpszClass
= SEGPTR_GET( cls
);
541 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
543 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
545 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
);
549 /***********************************************************************
550 * HOOK_UnMap32To16Common
552 static void HOOK_UnMap32To16Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
553 LPARAM lParamOrig
, WPARAM32 wParam
,
559 case WH_SYSMSGFILTER
:
560 case WH_JOURNALRECORD
:
561 case WH_JOURNALPLAYBACK
:
564 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
569 LPMSG32 lpmsg32
= (LPMSG32
)lParamOrig
;
571 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
572 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
580 case HCBT_CLICKSKIPPED
:
582 SEGPTR_FREE( (LPVOID
)lParam
);
593 fprintf(stderr
, "Can't map hook id: %d\n", id
);
597 fprintf(stderr
, "Unknown hook id: %d\n", id
);
603 /***********************************************************************
606 static void HOOK_UnMap32ATo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
607 LPARAM lParamOrig
, WPARAM32 wParam
,
610 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
612 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParam
);
613 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
615 if (HIWORD(lpcs16
->lpszName
))
616 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
618 if (HIWORD(lpcs16
->lpszClass
))
619 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
621 SEGPTR_FREE( lpcs16
);
622 SEGPTR_FREE( lpcbtcw16
);
625 return HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
631 /***********************************************************************
634 static void HOOK_UnMap32WTo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
635 LPARAM lParamOrig
, WPARAM32 wParam
,
638 HOOK_UnMap32ATo16( id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
642 /***********************************************************************
645 static void HOOK_Map32ATo32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
648 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
650 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)*plParam
;
651 LPCBT_CREATEWND32W lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
653 lpcbtcwW
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwW
->lpcs
) );
655 lpcbtcwW
->hwndInsertAfter
= lpcbtcwA
->hwndInsertAfter
;
656 *lpcbtcwW
->lpcs
= *(LPCREATESTRUCT32W
)lpcbtcwA
->lpcs
;
658 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
660 lpcbtcwW
->lpcs
->lpszName
= HEAP_strdupAtoW( SystemHeap
, 0,
661 lpcbtcwA
->lpcs
->lpszName
);
664 lpcbtcwW
->lpcs
->lpszName
= (LPWSTR
)lpcbtcwA
->lpcs
->lpszName
;
666 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
668 lpcbtcwW
->lpcs
->lpszClass
= HEAP_strdupAtoW( SystemHeap
, 0,
669 lpcbtcwA
->lpcs
->lpszClass
);
672 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
678 /***********************************************************************
681 static void HOOK_UnMap32ATo32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
682 LPARAM lParamOrig
, WPARAM32 wParam
,
685 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
687 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)lParam
;
688 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
689 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszName
);
690 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
691 HeapFree( SystemHeap
, 0, (LPWSTR
)lpcbtcwW
->lpcs
->lpszClass
);
692 HeapFree( SystemHeap
, 0, lpcbtcwW
->lpcs
);
693 HeapFree( SystemHeap
, 0, lpcbtcwW
);
699 /***********************************************************************
702 static void HOOK_Map32WTo32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
705 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
707 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)*plParam
;
708 LPCBT_CREATEWND32A lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
710 lpcbtcwA
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwA
->lpcs
) );
712 lpcbtcwA
->hwndInsertAfter
= lpcbtcwW
->hwndInsertAfter
;
713 *lpcbtcwA
->lpcs
= *(LPCREATESTRUCT32A
)lpcbtcwW
->lpcs
;
715 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
716 lpcbtcwA
->lpcs
->lpszName
= HEAP_strdupWtoA( SystemHeap
, 0,
717 lpcbtcwW
->lpcs
->lpszName
);
719 lpcbtcwA
->lpcs
->lpszName
= (LPSTR
)lpcbtcwW
->lpcs
->lpszName
;
721 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
722 lpcbtcwA
->lpcs
->lpszClass
= HEAP_strdupWtoA( SystemHeap
, 0,
723 lpcbtcwW
->lpcs
->lpszClass
);
725 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
731 /***********************************************************************
734 static void HOOK_UnMap32WTo32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
735 LPARAM lParamOrig
, WPARAM32 wParam
,
738 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
740 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)lParam
;
741 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
742 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszName
);
743 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
744 HeapFree( SystemHeap
, 0, (LPSTR
)lpcbtcwA
->lpcs
->lpszClass
);
745 HeapFree( SystemHeap
, 0, lpcbtcwA
->lpcs
);
746 HeapFree( SystemHeap
, 0, lpcbtcwA
);
752 /***********************************************************************
753 * Map Function Tables
755 static const HOOK_MapFunc HOOK_MapFuncs
[3][3] =
757 { NULL
, HOOK_Map16To32A
, HOOK_Map16To32W
},
758 { HOOK_Map32ATo16
, NULL
, HOOK_Map32ATo32W
},
759 { HOOK_Map32WTo16
, HOOK_Map32WTo32A
, NULL
}
762 static const HOOK_UnMapFunc HOOK_UnMapFuncs
[3][3] =
764 { NULL
, HOOK_UnMap16To32A
, HOOK_UnMap16To32W
},
765 { HOOK_UnMap32ATo16
, NULL
, HOOK_UnMap32ATo32W
},
766 { HOOK_UnMap32WTo16
, HOOK_UnMap32WTo32A
, NULL
}
770 /***********************************************************************
774 /***********************************************************************
777 * Get the next hook of a given hook.
779 static HANDLE16
HOOK_GetNextHook( HANDLE16 hook
)
781 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( hook
);
783 if (!data
|| !hook
) return 0;
784 if (data
->next
) return data
->next
;
785 if (!data
->ownerQueue
) return 0; /* Already system hook */
787 /* Now start enumerating the system hooks */
788 return HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
792 /***********************************************************************
795 * Get the first hook for a given type.
797 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
802 if ((queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
)) != NULL
)
803 hook
= queue
->hooks
[id
- WH_MINHOOK
];
804 if (!hook
) hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
809 /***********************************************************************
812 * Install a given hook.
814 static HANDLE16
HOOK_SetHook( INT16 id
, LPVOID proc
, INT32 type
,
815 HINSTANCE16 hInst
, HTASK16 hTask
)
821 if ((id
< WH_MINHOOK
) || (id
> WH_MAXHOOK
)) return 0;
822 if (!(hInst
= GetExePtr( hInst
))) return 0;
824 dprintf_hook( stddeb
, "Setting hook %d: %08x %04x %04x\n",
825 id
, (UINT32
)proc
, hInst
, hTask
);
827 if (id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(FALSE
);
829 if (hTask
) /* Task-specific hook */
831 if ((id
== WH_JOURNALRECORD
) || (id
== WH_JOURNALPLAYBACK
) ||
832 (id
== WH_SYSMSGFILTER
)) return 0; /* System-only hooks */
833 if (!(hQueue
= GetTaskQueue( hTask
))) return 0;
836 /* Create the hook structure */
838 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
839 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
842 data
->ownerQueue
= hQueue
;
843 data
->ownerModule
= hInst
;
844 data
->inHookProc
= 0;
847 /* Insert it in the correct linked list */
851 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
);
852 data
->next
= queue
->hooks
[id
- WH_MINHOOK
];
853 queue
->hooks
[id
- WH_MINHOOK
] = handle
;
857 data
->next
= HOOK_systemHooks
[id
- WH_MINHOOK
];
858 HOOK_systemHooks
[id
- WH_MINHOOK
] = handle
;
860 dprintf_hook( stddeb
, "Setting hook %d: ret=%04x [next=%04x]\n",
861 id
, handle
, data
->next
);
866 /***********************************************************************
869 * Remove a hook from the list.
871 static BOOL32
HOOK_RemoveHook( HANDLE16 hook
)
876 dprintf_hook( stddeb
, "Removing hook %04x\n", hook
);
878 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return FALSE
;
879 if (data
->inHookProc
)
881 /* Mark it for deletion later on */
882 dprintf_hook( stddeb
, "Hook still running, deletion delayed\n" );
883 data
->proc
= (HOOKPROC32
)0;
887 if (data
->id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(TRUE
);
889 /* Remove it from the linked list */
891 if (data
->ownerQueue
)
893 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)GlobalLock16( data
->ownerQueue
);
894 if (!queue
) return FALSE
;
895 prevHook
= &queue
->hooks
[data
->id
- WH_MINHOOK
];
897 else prevHook
= &HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
899 while (*prevHook
&& *prevHook
!= hook
)
900 prevHook
= &((HOOKDATA
*)USER_HEAP_LIN_ADDR(*prevHook
))->next
;
902 if (!*prevHook
) return FALSE
;
903 *prevHook
= data
->next
;
904 USER_HEAP_FREE( hook
);
909 /***********************************************************************
912 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
918 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
919 if (data
->proc
) return hook
;
925 /***********************************************************************
928 * Call a hook procedure.
930 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT32 fromtype
, INT32 code
,
931 WPARAM32 wParam
, LPARAM lParam
)
935 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
939 WPARAM32 wParamOrig
= wParam
;
940 LPARAM lParamOrig
= lParam
;
941 HOOK_MapFunc MapFunc
;
942 HOOK_UnMapFunc UnMapFunc
;
944 MapFunc
= HOOK_MapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
945 UnMapFunc
= HOOK_UnMapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
948 MapFunc( data
->id
, code
, &wParam
, &lParam
);
952 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
953 prevHook
= queue
->hCurHook
;
954 queue
->hCurHook
= hook
;
955 data
->inHookProc
= TRUE
;
957 dprintf_hook( stddeb
, "Calling hook %04x: %d %08x %08lx\n",
958 hook
, code
, wParam
, lParam
);
960 /* Set DS = SS to call hook procedure */
962 CURRENT_DS
= IF1632_Saved16_ss
;
963 ret
= data
->proc(code
, wParam
, lParam
);
966 dprintf_hook( stddeb
, "Ret hook %04x = %08lx\n", hook
, ret
);
968 data
->inHookProc
= FALSE
;
969 queue
->hCurHook
= prevHook
;
972 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
974 if (!data
->proc
) HOOK_RemoveHook( hook
);
979 /***********************************************************************
980 * Exported Functions & APIs
983 /***********************************************************************
986 * Don't call this unless you are the if1632/thunk.c.
988 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
991 if (HIWORD(hhook
) != HOOK_MAGIC
) return NULL
;
992 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) ))) return NULL
;
993 if (data
->flags
& HOOK_WIN32
) return NULL
;
994 return (HOOKPROC16
)data
->proc
;
998 /***********************************************************************
1001 * Replacement for calling HOOK_GetHook from other modules.
1003 BOOL32
HOOK_IsHooked( INT16 id
)
1005 return HOOK_GetHook( id
, GetTaskQueue(0) ) != 0;
1009 /***********************************************************************
1012 * Call a hook chain.
1014 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1019 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1020 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1021 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1024 /***********************************************************************
1027 * Call a hook chain.
1029 LRESULT
HOOK_CallHooks32A( INT32 id
, INT32 code
, WPARAM32 wParam
,
1034 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1035 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1036 return HOOK_CallHook( hook
, HOOK_WIN32
, code
, wParam
, lParam
);
1039 /***********************************************************************
1042 * Call a hook chain.
1044 LRESULT
HOOK_CallHooks32W( INT32 id
, INT32 code
, WPARAM32 wParam
,
1049 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1050 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1051 return HOOK_CallHook( hook
, HOOK_WIN32
| HOOK_UNICODE
, code
, wParam
,
1056 /***********************************************************************
1057 * HOOK_ResetQueueHooks
1059 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1061 MESSAGEQUEUE
*queue
;
1063 if ((queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
)) != NULL
)
1068 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1070 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1073 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1075 data
->ownerQueue
= hQueue
;
1083 /***********************************************************************
1084 * HOOK_FreeModuleHooks
1086 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1088 /* remove all system hooks registered by this module */
1094 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1096 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1098 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1101 if( hptr
->ownerModule
== hModule
)
1103 hptr
->inHookProc
= 0;
1104 HOOK_RemoveHook(hook
);
1112 /***********************************************************************
1113 * HOOK_FreeQueueHooks
1115 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1117 /* remove all hooks registered by this queue */
1119 HOOKDATA
* hptr
= NULL
;
1123 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1125 hook
= HOOK_GetHook( id
, hQueue
);
1128 next
= HOOK_GetNextHook(hook
);
1130 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1131 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1133 hptr
->inHookProc
= 0;
1134 HOOK_RemoveHook(hook
);
1142 /***********************************************************************
1143 * SetWindowsHook16 (USER.121)
1145 FARPROC16
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1148 HINSTANCE16 hInst
= __winelib
? 0 : FarGetOwner( HIWORD(proc
) );
1150 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1151 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1155 fprintf( stdnimp
, "WH_DEBUG is broken in 16-bit Windows.\n");
1159 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN16
, hInst
, hTask
);
1160 return (handle
) ? (FARPROC16
)MAKELONG( handle
, HOOK_MAGIC
) : NULL
;
1164 /***********************************************************************
1165 * SetWindowsHook32A (USER32.524)
1167 * FIXME: I don't know if this is correct
1169 HHOOK
SetWindowsHook32A( INT32 id
, HOOKPROC32 proc
)
1171 HINSTANCE16 hInst
= __winelib
? 0 : FarGetOwner( HIWORD(proc
) );
1173 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1174 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1176 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
, hInst
, hTask
);
1177 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : 0;
1181 /***********************************************************************
1182 * SetWindowsHook32W (USER32.527)
1184 * FIXME: I don't know if this is correct
1186 HHOOK
SetWindowsHook32W( INT32 id
, HOOKPROC32 proc
)
1188 HINSTANCE16 hInst
= __winelib
? 0 : FarGetOwner( HIWORD(proc
) );
1190 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1191 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1193 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
| HOOK_UNICODE
,
1195 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : 0;
1199 /***********************************************************************
1200 * SetWindowsHookEx16 (USER.291)
1202 HHOOK
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1205 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN16
, hInst
, hTask
);
1206 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1210 /***********************************************************************
1211 * SetWindowsHookEx32A (USER32.525)
1213 HHOOK
SetWindowsHookEx32A( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1219 if (dwThreadID
== GetCurrentThreadId())
1220 hTask
= GetCurrentTask();
1222 hTask
= LOWORD(dwThreadID
);
1224 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
, hInst
, hTask
);
1225 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1229 /***********************************************************************
1230 * SetWindowsHookEx32W (USER32.526)
1232 HHOOK
SetWindowsHookEx32W( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1238 if (dwThreadID
== GetCurrentThreadId())
1239 hTask
= GetCurrentTask();
1241 hTask
= LOWORD(dwThreadID
);
1243 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
| HOOK_UNICODE
, hInst
, hTask
);
1244 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1248 /***********************************************************************
1249 * UnhookWindowsHook16 (USER.234)
1251 BOOL16
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1253 HANDLE16 hook
= HOOK_GetHook( id
, GetTaskQueue(0) );
1255 dprintf_hook( stddeb
, "UnhookWindowsHook: %d %08lx\n", id
, (DWORD
)proc
);
1259 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1260 if (data
->proc
== (HOOKPROC32
)proc
) break;
1261 hook
= HOOK_GetNextHook( hook
);
1263 if (!hook
) return FALSE
;
1264 return HOOK_RemoveHook( hook
);
1268 /***********************************************************************
1269 * UnhookWindowsHook32 (USER32.556)
1271 BOOL32
UnhookWindowsHook32( INT32 id
, HOOKPROC32 proc
)
1273 HANDLE16 hook
= HOOK_GetHook( id
, GetTaskQueue(0) );
1275 dprintf_hook( stddeb
, "UnhookWindowsHook: %d %08lx\n", id
, (DWORD
)proc
);
1279 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1280 if (data
->proc
== proc
) break;
1281 hook
= HOOK_GetNextHook( hook
);
1283 if (!hook
) return FALSE
;
1284 return HOOK_RemoveHook( hook
);
1288 /***********************************************************************
1289 * UnhookWindowHookEx16 (USER.292)
1291 BOOL16
UnhookWindowsHookEx16( HHOOK hhook
)
1293 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1294 return HOOK_RemoveHook( LOWORD(hhook
) );
1298 /***********************************************************************
1299 * UnhookWindowHookEx32 (USER32.557)
1301 BOOL32
UnhookWindowsHookEx32( HHOOK hhook
)
1303 return UnhookWindowsHookEx16( hhook
);
1307 /***********************************************************************
1308 * CallNextHookEx16 (USER.293)
1310 * I wouldn't have separated this into 16 and 32 bit versions, but I
1311 * need a way to figure out if I need to do a mapping or not.
1313 LRESULT
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1318 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1319 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1321 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1325 /***********************************************************************
1326 * CallNextHookEx32 (USER32.16)
1328 * There aren't ANSI and UNICODE versions of this.
1330 LRESULT
CallNextHookEx32( HHOOK hhook
, INT32 code
, WPARAM32 wParam
,
1334 INT32 fromtype
; /* figure out Ansi/Unicode */
1337 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1338 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1340 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1341 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1343 if (!(fromtype
& HOOK_WIN32
))
1344 fprintf(stderr
, "CallNextHookEx32: called from 16bit hook!\n");
1346 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1350 /***********************************************************************
1351 * DefHookProc16 (USER.235)
1353 LRESULT
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1356 /* Note: the *hhook parameter is never used, since we rely on the
1357 * current hook value from the task queue to find the next hook. */
1358 MESSAGEQUEUE
*queue
;
1360 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
1361 return CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1365 /***********************************************************************
1366 * CallMsgFilter16 (USER.123)
1368 BOOL16
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1370 if (GetSysModalWindow16()) return FALSE
;
1371 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1372 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1376 /***********************************************************************
1377 * CallMsgFilter32A (USER32.14)
1380 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1381 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1383 BOOL32
CallMsgFilter32A( LPMSG32 msg
, INT32 code
)
1385 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1386 if (HOOK_CallHooks32A( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1388 return HOOK_CallHooks32A( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1392 /***********************************************************************
1393 * CallMsgFilter32W (USER32.15)
1395 BOOL32
CallMsgFilter32W( LPMSG32 msg
, INT32 code
)
1397 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1398 if (HOOK_CallHooks32W( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1400 return HOOK_CallHooks32W( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);