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 */
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
=
241 STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
243 lpcbtcw32
->lpcs
->lpszName
= (LPWSTR
)lpcs16
->lpszName
;
245 if (HIWORD(lpcs16
->lpszClass
))
246 lpcbtcw32
->lpcs
->lpszClass
=
247 STRING32_DupAnsiToUni( 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 free( (LPWSTR
)lpcbtcw32
->lpcs
->lpszName
);
350 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
351 free( (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
)
528 LPCBT_CREATEWND32W lpcbtcw32
= (LPCBT_CREATEWND32W
)*plParam
;
529 LPCBT_CREATEWND16 lpcbtcw16
= SEGPTR_NEW( CBT_CREATEWND16
);
530 LPCREATESTRUCT16 lpcs16
= SEGPTR_NEW( CREATESTRUCT16
);
532 lpcbtcw16
->lpcs
= (LPCREATESTRUCT16
)SEGPTR_GET( lpcs16
);
533 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A
)lpcbtcw32
->lpcs
,
536 if (HIWORD(lpcbtcw32
->lpcs
->lpszName
))
538 LPSTR str
= SEGPTR_ALLOC( lstrlen32W(lpcbtcw32
->lpcs
->lpszName
) );
539 STRING32_UniToAnsi( str
, lpcbtcw32
->lpcs
->lpszName
);
540 lpcs16
->lpszName
= SEGPTR_GET( str
);
543 lpcs16
->lpszName
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszName
;
545 if (HIWORD(lpcbtcw32
->lpcs
->lpszClass
))
547 LPSTR str
= SEGPTR_ALLOC( lstrlen32W(lpcbtcw32
->lpcs
->lpszClass
) );
548 STRING32_UniToAnsi( str
, lpcbtcw32
->lpcs
->lpszClass
);
549 lpcs16
->lpszClass
= SEGPTR_GET( str
);
552 lpcs16
->lpszClass
= (SEGPTR
)lpcbtcw32
->lpcs
->lpszClass
;
554 lpcbtcw16
->hwndInsertAfter
= lpcbtcw32
->hwndInsertAfter
;
556 *plParam
= (LPARAM
)SEGPTR_GET( lpcbtcw16
);
558 else HOOK_Map32To16Common(id
, code
, pwParam
, plParam
);
562 /***********************************************************************
563 * HOOK_UnMap32To16Common
565 static void HOOK_UnMap32To16Common(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
566 LPARAM lParamOrig
, WPARAM32 wParam
,
572 case WH_SYSMSGFILTER
:
573 case WH_JOURNALRECORD
:
574 case WH_JOURNALPLAYBACK
:
577 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
582 LPMSG32 lpmsg32
= (LPMSG32
)lParamOrig
;
584 STRUCT32_MSG16to32( (LPMSG16
)PTR_SEG_TO_LIN(lParam
), lpmsg32
);
585 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
593 case HCBT_CLICKSKIPPED
:
595 SEGPTR_FREE( (LPVOID
)lParam
);
606 fprintf(stderr
, "Can't map hook id: %d\n", id
);
610 fprintf(stderr
, "Unknown hook id: %d\n", id
);
616 /***********************************************************************
619 static void HOOK_UnMap32ATo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
620 LPARAM lParamOrig
, WPARAM32 wParam
,
623 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
625 LPCBT_CREATEWND16 lpcbtcw16
= PTR_SEG_TO_LIN(lParam
);
626 LPCREATESTRUCT16 lpcs16
= PTR_SEG_TO_LIN(lpcbtcw16
->lpcs
);
628 if (HIWORD(lpcs16
->lpszName
))
629 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszName
) );
631 if (HIWORD(lpcs16
->lpszClass
))
632 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16
->lpszClass
) );
634 SEGPTR_FREE( lpcs16
);
635 SEGPTR_FREE( lpcbtcw16
);
638 return HOOK_UnMap32To16Common( id
, code
, wParamOrig
, lParamOrig
, wParam
,
644 /***********************************************************************
647 static void HOOK_UnMap32WTo16(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
648 LPARAM lParamOrig
, WPARAM32 wParam
,
651 HOOK_UnMap32ATo16( id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
655 /***********************************************************************
658 static void HOOK_Map32ATo32W(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
661 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
663 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)*plParam
;
664 LPCBT_CREATEWND32W lpcbtcwW
= HeapAlloc( SystemHeap
, 0,
666 lpcbtcwW
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwW
->lpcs
) );
668 lpcbtcwW
->hwndInsertAfter
= lpcbtcwA
->hwndInsertAfter
;
669 *lpcbtcwW
->lpcs
= *(LPCREATESTRUCT32W
)lpcbtcwA
->lpcs
;
671 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
673 lpcbtcwW
->lpcs
->lpszName
=
674 STRING32_DupAnsiToUni( lpcbtcwA
->lpcs
->lpszName
);
677 lpcbtcwW
->lpcs
->lpszName
= (LPWSTR
)lpcbtcwA
->lpcs
->lpszName
;
679 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
681 lpcbtcwW
->lpcs
->lpszClass
=
682 STRING32_DupAnsiToUni( lpcbtcwA
->lpcs
->lpszClass
);
685 lpcbtcwW
->lpcs
->lpszClass
= (LPCWSTR
)lpcbtcwA
->lpcs
->lpszClass
;
691 /***********************************************************************
694 static void HOOK_UnMap32ATo32W(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
695 LPARAM lParamOrig
, WPARAM32 wParam
,
698 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
700 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)lParam
;
701 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
702 free( (LPWSTR
)lpcbtcwW
->lpcs
->lpszName
);
703 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
704 free( (LPWSTR
)lpcbtcwW
->lpcs
->lpszClass
);
705 HeapFree( SystemHeap
, 0, lpcbtcwW
->lpcs
);
706 HeapFree( SystemHeap
, 0, lpcbtcwW
);
712 /***********************************************************************
715 static void HOOK_Map32WTo32A(INT32 id
, INT32 code
, WPARAM32
*pwParam
,
718 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
720 LPCBT_CREATEWND32W lpcbtcwW
= (LPCBT_CREATEWND32W
)*plParam
;
721 LPCBT_CREATEWND32A lpcbtcwA
= HeapAlloc( SystemHeap
, 0,
723 lpcbtcwA
->lpcs
= HeapAlloc( SystemHeap
, 0, sizeof(*lpcbtcwA
->lpcs
) );
725 lpcbtcwA
->hwndInsertAfter
= lpcbtcwW
->hwndInsertAfter
;
726 *lpcbtcwA
->lpcs
= *(LPCREATESTRUCT32A
)lpcbtcwW
->lpcs
;
728 if (HIWORD(lpcbtcwW
->lpcs
->lpszName
))
729 lpcbtcwA
->lpcs
->lpszName
=
730 STRING32_DupUniToAnsi( lpcbtcwW
->lpcs
->lpszName
);
732 lpcbtcwA
->lpcs
->lpszName
= (LPSTR
)lpcbtcwW
->lpcs
->lpszName
;
734 if (HIWORD(lpcbtcwW
->lpcs
->lpszClass
))
735 lpcbtcwA
->lpcs
->lpszClass
=
736 STRING32_DupUniToAnsi( lpcbtcwW
->lpcs
->lpszClass
);
738 lpcbtcwA
->lpcs
->lpszClass
= (LPSTR
)lpcbtcwW
->lpcs
->lpszClass
;
744 /***********************************************************************
747 static void HOOK_UnMap32WTo32A(INT32 id
, INT32 code
, WPARAM32 wParamOrig
,
748 LPARAM lParamOrig
, WPARAM32 wParam
,
751 if (id
== WH_CBT
&& code
== HCBT_CREATEWND
)
753 LPCBT_CREATEWND32A lpcbtcwA
= (LPCBT_CREATEWND32A
)lParam
;
754 if (HIWORD(lpcbtcwA
->lpcs
->lpszName
))
755 free( (LPSTR
)lpcbtcwA
->lpcs
->lpszName
);
756 if (HIWORD(lpcbtcwA
->lpcs
->lpszClass
))
757 free( (LPSTR
)lpcbtcwA
->lpcs
->lpszClass
);
758 HeapFree( SystemHeap
, 0, lpcbtcwA
->lpcs
);
759 HeapFree( SystemHeap
, 0, lpcbtcwA
);
765 /***********************************************************************
766 * Map Function Tables
768 static const HOOK_MapFunc HOOK_MapFuncs
[3][3] =
770 { NULL
, HOOK_Map16To32A
, HOOK_Map16To32W
},
771 { HOOK_Map32ATo16
, NULL
, HOOK_Map32ATo32W
},
772 { HOOK_Map32WTo16
, HOOK_Map32WTo32A
, NULL
}
775 static const HOOK_UnMapFunc HOOK_UnMapFuncs
[3][3] =
777 { NULL
, HOOK_UnMap16To32A
, HOOK_UnMap16To32W
},
778 { HOOK_UnMap32ATo16
, NULL
, HOOK_UnMap32ATo32W
},
779 { HOOK_UnMap32WTo16
, HOOK_UnMap32WTo32A
, NULL
}
783 /***********************************************************************
787 /***********************************************************************
790 * Get the next hook of a given hook.
792 static HANDLE16
HOOK_GetNextHook( HANDLE16 hook
)
794 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( hook
);
796 if (!data
|| !hook
) return 0;
797 if (data
->next
) return data
->next
;
798 if (!data
->ownerQueue
) return 0; /* Already system hook */
800 /* Now start enumerating the system hooks */
801 return HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
805 /***********************************************************************
808 * Get the first hook for a given type.
810 static HANDLE16
HOOK_GetHook( INT16 id
, HQUEUE16 hQueue
)
815 if ((queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
)) != NULL
)
816 hook
= queue
->hooks
[id
- WH_MINHOOK
];
817 if (!hook
) hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
822 /***********************************************************************
825 * Install a given hook.
827 static HANDLE16
HOOK_SetHook( INT16 id
, LPVOID proc
, INT32 type
,
828 HINSTANCE16 hInst
, HTASK16 hTask
)
834 if ((id
< WH_MINHOOK
) || (id
> WH_MAXHOOK
)) return 0;
835 if (!(hInst
= GetExePtr( hInst
))) return 0;
837 dprintf_hook( stddeb
, "Setting hook %d: %08x %04x %04x\n",
838 id
, (UINT32
)proc
, hInst
, hTask
);
840 if (id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(FALSE
);
842 if (hTask
) /* Task-specific hook */
844 if ((id
== WH_JOURNALRECORD
) || (id
== WH_JOURNALPLAYBACK
) ||
845 (id
== WH_SYSMSGFILTER
)) return 0; /* System-only hooks */
846 if (!(hQueue
= GetTaskQueue( hTask
))) return 0;
849 /* Create the hook structure */
851 if (!(handle
= USER_HEAP_ALLOC( sizeof(HOOKDATA
) ))) return 0;
852 data
= (HOOKDATA
*) USER_HEAP_LIN_ADDR( handle
);
855 data
->ownerQueue
= hQueue
;
856 data
->ownerModule
= hInst
;
857 data
->inHookProc
= 0;
860 /* Insert it in the correct linked list */
864 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
);
865 data
->next
= queue
->hooks
[id
- WH_MINHOOK
];
866 queue
->hooks
[id
- WH_MINHOOK
] = handle
;
870 data
->next
= HOOK_systemHooks
[id
- WH_MINHOOK
];
871 HOOK_systemHooks
[id
- WH_MINHOOK
] = handle
;
873 dprintf_hook( stddeb
, "Setting hook %d: ret=%04x [next=%04x]\n",
874 id
, handle
, data
->next
);
879 /***********************************************************************
882 * Remove a hook from the list.
884 static BOOL32
HOOK_RemoveHook( HANDLE16 hook
)
889 dprintf_hook( stddeb
, "Removing hook %04x\n", hook
);
891 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return FALSE
;
892 if (data
->inHookProc
)
894 /* Mark it for deletion later on */
895 dprintf_hook( stddeb
, "Hook still running, deletion delayed\n" );
896 data
->proc
= (HOOKPROC32
)0;
900 if (data
->id
== WH_JOURNALPLAYBACK
) EnableHardwareInput(TRUE
);
902 /* Remove it from the linked list */
904 if (data
->ownerQueue
)
906 MESSAGEQUEUE
*queue
= (MESSAGEQUEUE
*)GlobalLock16( data
->ownerQueue
);
907 if (!queue
) return FALSE
;
908 prevHook
= &queue
->hooks
[data
->id
- WH_MINHOOK
];
910 else prevHook
= &HOOK_systemHooks
[data
->id
- WH_MINHOOK
];
912 while (*prevHook
&& *prevHook
!= hook
)
913 prevHook
= &((HOOKDATA
*)USER_HEAP_LIN_ADDR(*prevHook
))->next
;
915 if (!*prevHook
) return FALSE
;
916 *prevHook
= data
->next
;
917 USER_HEAP_FREE( hook
);
922 /***********************************************************************
925 static HANDLE16
HOOK_FindValidHook( HANDLE16 hook
)
931 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
))) return 0;
932 if (data
->proc
) return hook
;
938 /***********************************************************************
941 * Call a hook procedure.
943 static LRESULT
HOOK_CallHook( HANDLE16 hook
, INT32 fromtype
, INT32 code
,
944 WPARAM32 wParam
, LPARAM lParam
)
948 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
951 WPARAM32 wParamOrig
= wParam
;
952 LPARAM lParamOrig
= lParam
;
953 HOOK_MapFunc MapFunc
;
954 HOOK_UnMapFunc UnMapFunc
;
956 MapFunc
= HOOK_MapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
957 UnMapFunc
= HOOK_UnMapFuncs
[fromtype
][data
->flags
& HOOK_MAPTYPE
];
960 MapFunc( data
->id
, code
, &wParam
, &lParam
);
964 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
965 prevHook
= queue
->hCurHook
;
966 queue
->hCurHook
= hook
;
967 data
->inHookProc
= TRUE
;
969 dprintf_hook( stddeb
, "Calling hook %04x: %d %08x %08lx\n",
970 hook
, code
, wParam
, lParam
);
972 ret
= data
->proc(code
, wParam
, lParam
);
974 dprintf_hook( stddeb
, "Ret hook %04x = %08lx\n", hook
, ret
);
976 data
->inHookProc
= FALSE
;
977 queue
->hCurHook
= prevHook
;
980 UnMapFunc( data
->id
, code
, wParamOrig
, lParamOrig
, wParam
, lParam
);
982 if (!data
->proc
) HOOK_RemoveHook( hook
);
987 /***********************************************************************
988 * Exported Functions & APIs
991 /***********************************************************************
994 * Don't call this unless you are the if1632/thunk.c.
996 HOOKPROC16
HOOK_GetProc16( HHOOK hhook
)
999 if (HIWORD(hhook
) != HOOK_MAGIC
) return NULL
;
1000 if (!(data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) ))) return NULL
;
1001 if (data
->flags
& HOOK_WIN32
) return NULL
;
1002 return (HOOKPROC16
)data
->proc
;
1006 /***********************************************************************
1009 * Replacement for calling HOOK_GetHook from other modules.
1011 BOOL32
HOOK_IsHooked( INT16 id
)
1013 return HOOK_GetHook( id
, GetTaskQueue(0) ) != 0;
1017 /***********************************************************************
1020 * Call a hook chain.
1022 LRESULT
HOOK_CallHooks16( INT16 id
, INT16 code
, WPARAM16 wParam
,
1027 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1028 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1029 return HOOK_CallHook( hook
, HOOK_WIN16
, code
, wParam
, lParam
);
1032 /***********************************************************************
1035 * Call a hook chain.
1037 LRESULT
HOOK_CallHooks32A( INT32 id
, INT32 code
, WPARAM32 wParam
,
1042 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1043 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1044 return HOOK_CallHook( hook
, HOOK_WIN32
, code
, wParam
, lParam
);
1047 /***********************************************************************
1050 * Call a hook chain.
1052 LRESULT
HOOK_CallHooks32W( INT32 id
, INT32 code
, WPARAM32 wParam
,
1057 if (!(hook
= HOOK_GetHook( id
, GetTaskQueue(0) ))) return 0;
1058 if (!(hook
= HOOK_FindValidHook(hook
))) return 0;
1059 return HOOK_CallHook( hook
, HOOK_WIN32
| HOOK_UNICODE
, code
, wParam
,
1064 /***********************************************************************
1065 * HOOK_ResetQueueHooks
1067 void HOOK_ResetQueueHooks( HQUEUE16 hQueue
)
1069 MESSAGEQUEUE
*queue
;
1071 if ((queue
= (MESSAGEQUEUE
*)GlobalLock16( hQueue
)) != NULL
)
1076 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1078 hook
= queue
->hooks
[id
- WH_MINHOOK
];
1081 if( (data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1083 data
->ownerQueue
= hQueue
;
1091 /***********************************************************************
1092 * HOOK_FreeModuleHooks
1094 void HOOK_FreeModuleHooks( HMODULE16 hModule
)
1096 /* remove all system hooks registered by this module */
1102 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1104 hook
= HOOK_systemHooks
[id
- WH_MINHOOK
];
1106 if( (hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
)) )
1109 if( hptr
->ownerModule
== hModule
)
1111 hptr
->inHookProc
= 0;
1112 HOOK_RemoveHook(hook
);
1120 /***********************************************************************
1121 * HOOK_FreeQueueHooks
1123 void HOOK_FreeQueueHooks( HQUEUE16 hQueue
)
1125 /* remove all hooks registered by this queue */
1127 HOOKDATA
* hptr
= NULL
;
1131 for( id
= WH_MINHOOK
; id
<= WH_MAXHOOK
; id
++ )
1133 hook
= HOOK_GetHook( id
, hQueue
);
1136 next
= HOOK_GetNextHook(hook
);
1138 hptr
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1139 if( hptr
&& hptr
->ownerQueue
== hQueue
)
1141 hptr
->inHookProc
= 0;
1142 HOOK_RemoveHook(hook
);
1150 /***********************************************************************
1151 * SetWindowsHook16 (USER.121)
1153 FARPROC16
SetWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1156 HINSTANCE16 hInst
= __winelib
? 0 : FarGetOwner( HIWORD(proc
) );
1158 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1159 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1163 fprintf( stdnimp
, "WH_DEBUG is broken in 16-bit Windows.\n");
1167 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN16
, hInst
, hTask
);
1168 return (handle
) ? (FARPROC16
)MAKELONG( handle
, HOOK_MAGIC
) : NULL
;
1172 /***********************************************************************
1173 * SetWindowsHook32A (USER32.524)
1175 * FIXME: I don't know if this is correct
1177 HHOOK
SetWindowsHook32A( INT32 id
, HOOKPROC32 proc
)
1179 HINSTANCE16 hInst
= __winelib
? 0 : FarGetOwner( HIWORD(proc
) );
1181 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1182 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1184 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
, hInst
, hTask
);
1185 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : 0;
1189 /***********************************************************************
1190 * SetWindowsHook32W (USER32.527)
1192 * FIXME: I don't know if this is correct
1194 HHOOK
SetWindowsHook32W( INT32 id
, HOOKPROC32 proc
)
1196 HINSTANCE16 hInst
= __winelib
? 0 : FarGetOwner( HIWORD(proc
) );
1198 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1199 HTASK16 hTask
= (id
== WH_MSGFILTER
) ? GetCurrentTask() : 0;
1201 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
| HOOK_UNICODE
,
1203 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : 0;
1207 /***********************************************************************
1208 * SetWindowsHookEx16 (USER.291)
1210 HHOOK
SetWindowsHookEx16( INT16 id
, HOOKPROC16 proc
, HINSTANCE16 hInst
,
1213 HANDLE16 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN16
, hInst
, hTask
);
1214 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1218 /***********************************************************************
1219 * SetWindowsHookEx32A (USER32.525)
1221 HHOOK
SetWindowsHookEx32A( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1227 if (dwThreadID
== GetCurrentThreadId())
1228 hTask
= GetCurrentTask();
1230 hTask
= LOWORD(dwThreadID
);
1232 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
, hInst
, hTask
);
1233 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1237 /***********************************************************************
1238 * SetWindowsHookEx32W (USER32.526)
1240 HHOOK
SetWindowsHookEx32W( INT32 id
, HOOKPROC32 proc
, HINSTANCE32 hInst
,
1246 if (dwThreadID
== GetCurrentThreadId())
1247 hTask
= GetCurrentTask();
1249 hTask
= LOWORD(dwThreadID
);
1251 handle
= HOOK_SetHook( id
, proc
, HOOK_WIN32
| HOOK_UNICODE
, hInst
, hTask
);
1252 return (handle
) ? (HHOOK
)MAKELONG( handle
, HOOK_MAGIC
) : (HHOOK
)NULL
;
1256 /***********************************************************************
1257 * UnhookWindowsHook16 (USER.234)
1259 BOOL16
UnhookWindowsHook16( INT16 id
, HOOKPROC16 proc
)
1261 HANDLE16 hook
= HOOK_GetHook( id
, GetTaskQueue(0) );
1263 dprintf_hook( stddeb
, "UnhookWindowsHook: %d %08lx\n", id
, (DWORD
)proc
);
1267 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1268 if (data
->proc
== (HOOKPROC32
)proc
) break;
1269 hook
= HOOK_GetNextHook( hook
);
1271 if (!hook
) return FALSE
;
1272 return HOOK_RemoveHook( hook
);
1276 /***********************************************************************
1277 * UnhookWindowsHook32 (USER32.556)
1279 BOOL32
UnhookWindowsHook32( INT32 id
, HOOKPROC32 proc
)
1281 HANDLE16 hook
= HOOK_GetHook( id
, GetTaskQueue(0) );
1283 dprintf_hook( stddeb
, "UnhookWindowsHook: %d %08lx\n", id
, (DWORD
)proc
);
1287 HOOKDATA
*data
= (HOOKDATA
*)USER_HEAP_LIN_ADDR(hook
);
1288 if (data
->proc
== proc
) break;
1289 hook
= HOOK_GetNextHook( hook
);
1291 if (!hook
) return FALSE
;
1292 return HOOK_RemoveHook( hook
);
1296 /***********************************************************************
1297 * UnhookWindowHookEx16 (USER.292)
1299 BOOL16
UnhookWindowsHookEx16( HHOOK hhook
)
1301 if (HIWORD(hhook
) != HOOK_MAGIC
) return FALSE
; /* Not a new format hook */
1302 return HOOK_RemoveHook( LOWORD(hhook
) );
1306 /***********************************************************************
1307 * UnhookWindowHookEx32 (USER32.557)
1309 BOOL32
UnhookWindowsHookEx32( HHOOK hhook
)
1311 return UnhookWindowsHookEx16( hhook
);
1315 /***********************************************************************
1316 * CallNextHookEx16 (USER.293)
1318 * I wouldn't have separated this into 16 and 32 bit versions, but I
1319 * need a way to figure out if I need to do a mapping or not.
1321 LRESULT
CallNextHookEx16( HHOOK hhook
, INT16 code
, WPARAM16 wParam
,
1326 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1327 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1329 return HOOK_CallHook( next
, HOOK_WIN16
, code
, wParam
, lParam
);
1333 /***********************************************************************
1334 * CallNextHookEx32 (USER32.16)
1336 * There aren't ANSI and UNICODE versions of this.
1338 LRESULT
CallNextHookEx32( HHOOK hhook
, INT32 code
, WPARAM32 wParam
,
1342 INT32 fromtype
; /* figure out Ansi/Unicode */
1345 if (HIWORD(hhook
) != HOOK_MAGIC
) return 0; /* Not a new format hook */
1346 if (!(next
= HOOK_GetNextHook( LOWORD(hhook
) ))) return 0;
1348 oldhook
= (HOOKDATA
*)USER_HEAP_LIN_ADDR( LOWORD(hhook
) );
1349 fromtype
= oldhook
->flags
& HOOK_MAPTYPE
;
1351 if (!(fromtype
& HOOK_WIN32
))
1352 fprintf(stderr
, "CallNextHookEx32: called from 16bit hook!\n");
1354 return HOOK_CallHook( next
, fromtype
, code
, wParam
, lParam
);
1358 /***********************************************************************
1359 * DefHookProc16 (USER.235)
1361 LRESULT
DefHookProc16( INT16 code
, WPARAM16 wParam
, LPARAM lParam
,
1364 /* Note: the *hhook parameter is never used, since we rely on the
1365 * current hook value from the task queue to find the next hook. */
1366 MESSAGEQUEUE
*queue
;
1368 if (!(queue
= (MESSAGEQUEUE
*)GlobalLock16( GetTaskQueue(0) ))) return 0;
1369 return CallNextHookEx16( queue
->hCurHook
, code
, wParam
, lParam
);
1373 /***********************************************************************
1374 * CallMsgFilter16 (USER.123)
1376 BOOL16
CallMsgFilter16( SEGPTR msg
, INT16 code
)
1378 if (GetSysModalWindow16()) return FALSE
;
1379 if (HOOK_CallHooks16( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
)) return TRUE
;
1380 return HOOK_CallHooks16( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1384 /***********************************************************************
1385 * CallMsgFilter32A (USER32.14)
1388 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1389 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1391 BOOL32
CallMsgFilter32A( LPMSG32 msg
, INT32 code
)
1393 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1394 if (HOOK_CallHooks32A( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1396 return HOOK_CallHooks32A( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);
1400 /***********************************************************************
1401 * CallMsgFilter32W (USER32.15)
1403 BOOL32
CallMsgFilter32W( LPMSG32 msg
, INT32 code
)
1405 if (GetSysModalWindow16()) return FALSE
; /* ??? */
1406 if (HOOK_CallHooks32W( WH_SYSMSGFILTER
, code
, 0, (LPARAM
)msg
))
1408 return HOOK_CallHooks32W( WH_MSGFILTER
, code
, 0, (LPARAM
)msg
);