Added implementations for InterlockedExchangeAdd() and
[wine/multimedia.git] / windows / hook.c
blob0ea860442f696e33a5ac94f8deb98cd13383de2e
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 "windows.h"
18 #include "hook.h"
19 #include "queue.h"
20 #include "user.h"
21 #include "heap.h"
22 #include "struct32.h"
23 #include "winproc.h"
24 #include "debug.h"
26 #pragma pack(1)
28 /* Hook data (pointed to by a HHOOK) */
29 typedef struct
31 HANDLE16 next; /* 00 Next hook in chain */
32 HOOKPROC32 proc WINE_PACKED; /* 02 Hook procedure */
33 INT16 id; /* 06 Hook id (WH_xxx) */
34 HQUEUE16 ownerQueue; /* 08 Owner queue (0 for system hook) */
35 HMODULE16 ownerModule; /* 0a Owner module */
36 WORD flags; /* 0c flags */
37 } HOOKDATA;
39 #pragma pack(4)
41 #define HOOK_MAGIC ((int)'H' | (int)'K' << 8) /* 'HK' */
43 /* This should probably reside in USER heap */
44 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
46 typedef VOID (*HOOK_MapFunc)(INT32, INT32, WPARAM32 *, LPARAM *);
47 typedef VOID (*HOOK_UnMapFunc)(INT32, INT32, WPARAM32, LPARAM, WPARAM32,
48 LPARAM);
50 /***********************************************************************
51 * HOOK_Map16To32Common
53 static void HOOK_Map16To32Common(INT32 id, INT32 code, WPARAM32 *pwParam,
54 LPARAM *plParam, BOOL32 bA )
57 switch( id )
59 case WH_MSGFILTER:
60 case WH_SYSMSGFILTER:
61 case WH_GETMESSAGE:
62 case WH_JOURNALRECORD:
64 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
65 LPMSG32 lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
67 STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
68 *plParam = (LPARAM)lpmsg32;
69 break;
72 case WH_JOURNALPLAYBACK:
74 LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
75 LPEVENTMSG32 lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
77 lpem32->message = lpem16->message;
78 lpem32->paramL = lpem16->paramL;
79 lpem32->paramH = lpem16->paramH;
80 lpem32->time = lpem16->time;
81 lpem32->hwnd = 0; /* FIXME */
83 *plParam = (LPARAM)lpem32;
84 break;
87 case WH_CALLWNDPROC:
89 LPCWPSTRUCT16 lpcwp16 = PTR_SEG_TO_LIN(*plParam);
90 LPCWPSTRUCT32 lpcwp32 = HeapAlloc( SystemHeap, 0, sizeof(*lpcwp32) );
92 lpcwp32->hwnd = lpcwp16->hwnd;
93 lpcwp32->lParam = lpcwp16->lParam;
95 if (bA) WINPROC_MapMsg16To32A( lpcwp16->message, lpcwp16->wParam,
96 &lpcwp32->message, &lpcwp32->wParam,
97 &lpcwp32->lParam );
98 else WINPROC_MapMsg16To32W( lpcwp16->hwnd,lpcwp16->message, lpcwp16->wParam,
99 &lpcwp32->message, &lpcwp32->wParam,
100 &lpcwp32->lParam );
101 *plParam = (LPARAM)lpcwp32;
102 break;
105 case WH_CBT:
106 switch (code)
108 case HCBT_CREATEWND:
110 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
111 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
112 LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
113 sizeof(*lpcbtcw32) );
114 lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
115 sizeof(*lpcbtcw32->lpcs) );
117 STRUCT32_CREATESTRUCT16to32A( lpcs16,
118 (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
120 if (HIWORD(lpcs16->lpszName))
121 lpcbtcw32->lpcs->lpszName =
122 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszName)
123 : HEAP_strdupAtoW( SystemHeap, 0,
124 PTR_SEG_TO_LIN(lpcs16->lpszName) );
125 else
126 lpcbtcw32->lpcs->lpszName = (LPCSTR)lpcs16->lpszName;
128 if (HIWORD(lpcs16->lpszClass))
129 lpcbtcw32->lpcs->lpszClass =
130 (bA) ? PTR_SEG_TO_LIN(lpcs16->lpszClass)
131 : HEAP_strdupAtoW( SystemHeap, 0,
132 PTR_SEG_TO_LIN(lpcs16->lpszClass) );
133 else
134 lpcbtcw32->lpcs->lpszClass = (LPCSTR)lpcs16->lpszClass;
136 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
138 *plParam = (LPARAM)lpcbtcw32;
139 break;
141 case HCBT_ACTIVATE:
143 LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
144 LPCBTACTIVATESTRUCT32 lpcas32 = HeapAlloc( SystemHeap, 0,
145 sizeof(*lpcas32) );
146 lpcas32->fMouse = lpcas16->fMouse;
147 lpcas32->hWndActive = lpcas16->hWndActive;
148 *plParam = (LPARAM)lpcas32;
149 break;
151 case HCBT_CLICKSKIPPED:
153 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
154 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
155 sizeof(*lpms32) );
157 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
159 /* wHitTestCode may be negative, so convince compiler to do
160 correct sign extension. Yay. :| */
161 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
163 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
164 lpms32->hwnd = lpms16->hwnd;
165 *plParam = (LPARAM)lpms32;
166 break;
168 case HCBT_MOVESIZE:
170 LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
171 LPRECT32 lprect32 = HeapAlloc( SystemHeap, 0,
172 sizeof(*lprect32) );
174 CONV_RECT16TO32( lprect16, lprect32 );
175 *plParam = (LPARAM)lprect32;
176 break;
179 break;
181 case WH_MOUSE:
183 LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
184 LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
185 sizeof(*lpms32) );
187 CONV_POINT16TO32( &lpms16->pt, &lpms32->pt );
189 /* wHitTestCode may be negative, so convince compiler to do
190 correct sign extension. Yay. :| */
191 lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
192 lpms32->dwExtraInfo = lpms16->dwExtraInfo;
193 lpms32->hwnd = lpms16->hwnd;
194 *plParam = (LPARAM)lpms32;
195 break;
198 case WH_DEBUG:
200 LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
201 LPDEBUGHOOKINFO32 lpdh32 = HeapAlloc( SystemHeap, 0,
202 sizeof(*lpdh32) );
204 lpdh32->idThread = 0; /* FIXME */
205 lpdh32->idThreadInstaller = 0; /* FIXME */
206 lpdh32->lParam = lpdh16->lParam; /* FIXME Check for sign ext */
207 lpdh32->wParam = lpdh16->wParam;
208 lpdh32->code = lpdh16->code;
210 /* do sign extension if it was WH_MSGFILTER */
211 if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
213 *plParam = (LPARAM)lpdh32;
214 break;
217 case WH_SHELL:
218 case WH_KEYBOARD:
219 break;
221 case WH_HARDWARE:
222 case WH_FOREGROUNDIDLE:
223 case WH_CALLWNDPROCRET:
224 FIXME(hook, "\t[%i] 16to32 translation unimplemented\n", id);
229 /***********************************************************************
230 * HOOK_Map16To32A
232 static void HOOK_Map16To32A(INT32 id, INT32 code, WPARAM32 *pwParam,
233 LPARAM *plParam)
235 HOOK_Map16To32Common( id, code, pwParam, plParam, TRUE );
239 /***********************************************************************
240 * HOOK_Map16To32W
242 static void HOOK_Map16To32W(INT32 id, INT32 code, WPARAM32 *pwParam,
243 LPARAM *plParam)
245 HOOK_Map16To32Common( id, code, pwParam, plParam, FALSE );
249 /***********************************************************************
250 * HOOK_UnMap16To32Common
252 static void HOOK_UnMap16To32Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
253 LPARAM lParamOrig, WPARAM32 wParam,
254 LPARAM lParam, BOOL32 bA)
256 switch (id)
258 case WH_MSGFILTER:
259 case WH_SYSMSGFILTER:
260 case WH_JOURNALRECORD:
261 case WH_JOURNALPLAYBACK:
263 HeapFree( SystemHeap, 0, (LPVOID)lParam );
264 break;
266 case WH_CALLWNDPROC:
268 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)lParam;
269 if (bA) WINPROC_UnmapMsg16To32A( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
270 lpcwp32->lParam, 0 );
271 else WINPROC_UnmapMsg16To32W( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
272 lpcwp32->lParam, 0 );
273 HeapFree( SystemHeap, 0, lpcwp32 );
274 break;
277 case WH_GETMESSAGE:
279 LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
280 STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
281 HeapFree( SystemHeap, 0, (LPVOID)lParam );
282 break;
285 case WH_MOUSE:
286 case WH_DEBUG:
288 HeapFree( SystemHeap, 0, (LPVOID)lParam );
289 break;
291 case WH_CBT:
292 switch (code)
294 case HCBT_CREATEWND:
296 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
297 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParamOrig);
299 if( !bA )
301 if (HIWORD(lpcbtcw32->lpcs->lpszName))
302 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszName );
303 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
304 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcw32->lpcs->lpszClass );
307 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
309 HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
310 } /* fall through */
312 case HCBT_ACTIVATE:
313 case HCBT_CLICKSKIPPED:
314 case HCBT_MOVESIZE:
316 HeapFree( SystemHeap, 0, (LPVOID)lParam);
317 break;
319 break;
321 case WH_SHELL:
322 case WH_KEYBOARD:
323 break;
325 case WH_HARDWARE:
326 case WH_FOREGROUNDIDLE:
327 case WH_CALLWNDPROCRET:
328 FIXME(hook, "\t[%i] skipping unmap\n", id);
329 break;
334 /***********************************************************************
335 * HOOK_UnMap16To32A
337 static void HOOK_UnMap16To32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
338 LPARAM lParamOrig, WPARAM32 wParam,
339 LPARAM lParam)
341 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
342 lParam, TRUE );
346 /***********************************************************************
347 * HOOK_UnMap16To32W
349 static void HOOK_UnMap16To32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
350 LPARAM lParamOrig, WPARAM32 wParam,
351 LPARAM lParam)
353 HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
354 lParam, FALSE );
358 /***********************************************************************
359 * HOOK_Map32To16Common
361 static void HOOK_Map32To16Common(INT32 id, INT32 code, WPARAM32 *pwParam,
362 LPARAM *plParam, BOOL32 bA)
364 switch (id)
366 case WH_MSGFILTER:
367 case WH_SYSMSGFILTER:
368 case WH_GETMESSAGE:
369 case WH_JOURNALRECORD:
371 LPMSG32 lpmsg32 = (LPMSG32)*plParam;
372 LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
374 STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
376 *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
377 break;
380 case WH_JOURNALPLAYBACK:
382 LPEVENTMSG32 lpem32 = (LPEVENTMSG32)*plParam;
383 LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
385 lpem16->message = lpem32->message;
386 lpem16->paramL = lpem32->paramL;
387 lpem16->paramH = lpem32->paramH;
388 lpem16->time = lpem32->time;
390 *plParam = (LPARAM)SEGPTR_GET( lpem16 );
391 break;
394 case WH_CALLWNDPROC:
396 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)*plParam;
397 LPCWPSTRUCT16 lpcwp16 = SEGPTR_NEW( CWPSTRUCT16 );
399 lpcwp16->hwnd = lpcwp32->hwnd;
400 lpcwp16->lParam = lpcwp32->lParam;
402 if (bA) WINPROC_MapMsg32ATo16( lpcwp32->hwnd, lpcwp32->message,
403 lpcwp32->wParam, &lpcwp16->message,
404 &lpcwp16->wParam, &lpcwp16->lParam );
405 else WINPROC_MapMsg32WTo16( lpcwp32->hwnd, lpcwp32->message,
406 lpcwp32->wParam, &lpcwp16->message,
407 &lpcwp16->wParam, &lpcwp16->lParam );
408 *plParam = (LPARAM)SEGPTR_GET( lpcwp16 );
409 break;
412 case WH_CBT:
413 switch (code)
415 case HCBT_ACTIVATE:
417 LPCBTACTIVATESTRUCT32 lpcas32 = (LPCBTACTIVATESTRUCT32)*plParam;
418 LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
420 lpcas16->fMouse = lpcas32->fMouse;
421 lpcas16->hWndActive = lpcas32->hWndActive;
423 *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
424 break;
427 case HCBT_CLICKSKIPPED:
429 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
430 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
432 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
434 lpms16->hwnd = lpms32->hwnd;
435 lpms16->wHitTestCode = lpms32->wHitTestCode;
436 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
438 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
439 break;
442 case HCBT_MOVESIZE:
444 LPRECT32 lprect32 = (LPRECT32)*plParam;
445 LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
447 CONV_RECT32TO16( lprect32, lprect16 );
449 *plParam = (LPARAM)SEGPTR_GET( lprect16 );
450 break;
453 break;
455 case WH_MOUSE:
457 LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
458 LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
460 CONV_POINT32TO16( &lpms32->pt, &lpms16->pt );
462 lpms16->hwnd = lpms32->hwnd;
463 lpms16->wHitTestCode = lpms32->wHitTestCode;
464 lpms16->dwExtraInfo = lpms32->dwExtraInfo;
466 *plParam = (LPARAM)SEGPTR_GET( lpms16 );
467 break;
470 case WH_DEBUG:
472 LPDEBUGHOOKINFO32 lpdh32 = (LPDEBUGHOOKINFO32)*plParam;
473 LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
475 lpdh16->hModuleHook = 0; /* FIXME */
476 lpdh16->reserved = 0;
477 lpdh16->lParam = lpdh32->lParam;
478 lpdh16->wParam = lpdh32->wParam;
479 lpdh16->code = lpdh32->code;
481 *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
482 break;
485 case WH_SHELL:
486 case WH_KEYBOARD:
487 break;
489 case WH_HARDWARE:
490 case WH_FOREGROUNDIDLE:
491 case WH_CALLWNDPROCRET:
492 FIXME(hook,"\t[%i] 32to16 translation unimplemented\n", id);
497 /***********************************************************************
498 * HOOK_Map32ATo16
500 static void HOOK_Map32ATo16(INT32 id, INT32 code, WPARAM32 *pwParam,
501 LPARAM *plParam)
503 if (id == WH_CBT && code == HCBT_CREATEWND)
505 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)*plParam;
506 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
507 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
509 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
510 STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
512 if (HIWORD(lpcbtcw32->lpcs->lpszName))
513 lpcs16->lpszName =
514 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
515 else
516 lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
518 if (HIWORD(lpcbtcw32->lpcs->lpszClass))
519 lpcs16->lpszClass =
520 SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
521 else
522 lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
524 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
526 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
528 else HOOK_Map32To16Common(id, code, pwParam, plParam, TRUE);
532 /***********************************************************************
533 * HOOK_Map32WTo16
535 static void HOOK_Map32WTo16(INT32 id, INT32 code, WPARAM32 *pwParam,
536 LPARAM *plParam)
538 if (id == WH_CBT && code == HCBT_CREATEWND)
540 LPSTR name, cls;
541 LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
542 LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
543 LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
545 lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
546 STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
547 lpcs16 );
549 name = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszName );
550 cls = SEGPTR_STRDUP_WtoA( lpcbtcw32->lpcs->lpszClass );
551 lpcs16->lpszName = SEGPTR_GET( name );
552 lpcs16->lpszClass = SEGPTR_GET( cls );
553 lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
555 *plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
557 else HOOK_Map32To16Common(id, code, pwParam, plParam, FALSE);
561 /***********************************************************************
562 * HOOK_UnMap32To16Common
564 static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
565 LPARAM lParamOrig, WPARAM32 wParam,
566 LPARAM lParam, BOOL32 bA)
568 switch (id)
570 case WH_MSGFILTER:
571 case WH_SYSMSGFILTER:
572 case WH_JOURNALRECORD:
573 case WH_JOURNALPLAYBACK:
574 case WH_MOUSE:
575 case WH_DEBUG:
576 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
577 break;
579 case WH_CALLWNDPROC:
581 LPCWPSTRUCT16 lpcwp16 = (LPCWPSTRUCT16)PTR_SEG_TO_LIN(lParam);
582 LPCWPSTRUCT32 lpcwp32 = (LPCWPSTRUCT32)lParamOrig;
583 MSGPARAM16 mp16 = { lpcwp16->wParam, lpcwp16->lParam, 0 };
585 if (bA) WINPROC_UnmapMsg32ATo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
586 lpcwp32->lParam, &mp16 );
587 else WINPROC_UnmapMsg32WTo16( lpcwp32->hwnd,lpcwp32->message, lpcwp32->wParam,
588 lpcwp32->lParam, &mp16 );
589 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
590 break;
593 case WH_GETMESSAGE:
595 LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
597 STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
598 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
599 break;
602 case WH_CBT:
603 switch (code)
605 case HCBT_CREATEWND:
607 LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)(lParamOrig);
608 LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
609 LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
611 if (HIWORD(lpcs16->lpszName))
612 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
614 if (HIWORD(lpcs16->lpszClass))
615 SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
617 lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
619 SEGPTR_FREE( lpcs16 );
620 } /* fall through */
622 case HCBT_ACTIVATE:
623 case HCBT_CLICKSKIPPED:
624 case HCBT_MOVESIZE:
626 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
627 break;
629 break;
631 case WH_SHELL:
632 case WH_KEYBOARD:
633 break;
635 case WH_HARDWARE:
636 case WH_FOREGROUNDIDLE:
637 case WH_CALLWNDPROCRET:
638 FIXME(hook, "\t[%i] skipping unmap\n", id);
643 /***********************************************************************
644 * HOOK_UnMap32ATo16
646 static void HOOK_UnMap32ATo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
647 LPARAM lParamOrig, WPARAM32 wParam,
648 LPARAM lParam)
650 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
651 lParam, TRUE );
655 /***********************************************************************
656 * HOOK_UnMap32WTo16
658 static void HOOK_UnMap32WTo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
659 LPARAM lParamOrig, WPARAM32 wParam,
660 LPARAM lParam)
662 HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
663 lParam, FALSE );
667 /***********************************************************************
668 * HOOK_Map32ATo32W
670 static void HOOK_Map32ATo32W(INT32 id, INT32 code, WPARAM32 *pwParam,
671 LPARAM *plParam)
673 if (id == WH_CBT && code == HCBT_CREATEWND)
675 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)*plParam;
676 LPCBT_CREATEWND32W lpcbtcwW = HeapAlloc( SystemHeap, 0,
677 sizeof(*lpcbtcwW) );
678 lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
680 lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
681 *lpcbtcwW->lpcs = *(LPCREATESTRUCT32W)lpcbtcwA->lpcs;
683 if (HIWORD(lpcbtcwA->lpcs->lpszName))
685 lpcbtcwW->lpcs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
686 lpcbtcwA->lpcs->lpszName );
688 else
689 lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
691 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
693 lpcbtcwW->lpcs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
694 lpcbtcwA->lpcs->lpszClass );
696 else
697 lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
698 *plParam = (LPARAM)lpcbtcwW;
700 return;
704 /***********************************************************************
705 * HOOK_UnMap32ATo32W
707 static void HOOK_UnMap32ATo32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
708 LPARAM lParamOrig, WPARAM32 wParam,
709 LPARAM lParam)
711 if (id == WH_CBT && code == HCBT_CREATEWND)
713 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
714 if (HIWORD(lpcbtcwW->lpcs->lpszName))
715 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszName );
716 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
717 HeapFree( SystemHeap, 0, (LPWSTR)lpcbtcwW->lpcs->lpszClass );
718 HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
719 HeapFree( SystemHeap, 0, lpcbtcwW );
721 return;
725 /***********************************************************************
726 * HOOK_Map32WTo32A
728 static void HOOK_Map32WTo32A(INT32 id, INT32 code, WPARAM32 *pwParam,
729 LPARAM *plParam)
731 if (id == WH_CBT && code == HCBT_CREATEWND)
733 LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)*plParam;
734 LPCBT_CREATEWND32A lpcbtcwA = HeapAlloc( SystemHeap, 0,
735 sizeof(*lpcbtcwA) );
736 lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
738 lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
739 *lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
741 if (HIWORD(lpcbtcwW->lpcs->lpszName))
742 lpcbtcwA->lpcs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
743 lpcbtcwW->lpcs->lpszName );
744 else
745 lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
747 if (HIWORD(lpcbtcwW->lpcs->lpszClass))
748 lpcbtcwA->lpcs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
749 lpcbtcwW->lpcs->lpszClass );
750 else
751 lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
752 *plParam = (LPARAM)lpcbtcwA;
754 return;
758 /***********************************************************************
759 * HOOK_UnMap32WTo32A
761 static void HOOK_UnMap32WTo32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
762 LPARAM lParamOrig, WPARAM32 wParam,
763 LPARAM lParam)
765 if (id == WH_CBT && code == HCBT_CREATEWND)
767 LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
768 if (HIWORD(lpcbtcwA->lpcs->lpszName))
769 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszName );
770 if (HIWORD(lpcbtcwA->lpcs->lpszClass))
771 HeapFree( SystemHeap, 0, (LPSTR)lpcbtcwA->lpcs->lpszClass );
772 HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
773 HeapFree( SystemHeap, 0, lpcbtcwA );
775 return;
779 /***********************************************************************
780 * Map Function Tables
782 static const HOOK_MapFunc HOOK_MapFuncs[3][3] =
784 { NULL, HOOK_Map16To32A, HOOK_Map16To32W },
785 { HOOK_Map32ATo16, NULL, HOOK_Map32ATo32W },
786 { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
789 static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] =
791 { NULL, HOOK_UnMap16To32A, HOOK_UnMap16To32W },
792 { HOOK_UnMap32ATo16, NULL, HOOK_UnMap32ATo32W },
793 { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
797 /***********************************************************************
798 * Internal Functions
801 /***********************************************************************
802 * HOOK_GetNextHook
804 * Get the next hook of a given hook.
806 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
808 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
810 if (!data || !hook) return 0;
811 if (data->next) return data->next;
812 if (!data->ownerQueue) return 0; /* Already system hook */
814 /* Now start enumerating the system hooks */
815 return HOOK_systemHooks[data->id - WH_MINHOOK];
819 /***********************************************************************
820 * HOOK_GetHook
822 * Get the first hook for a given type.
824 static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
826 MESSAGEQUEUE *queue;
827 HANDLE16 hook = 0;
829 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
830 hook = queue->hooks[id - WH_MINHOOK];
831 if (!hook) hook = HOOK_systemHooks[id - WH_MINHOOK];
832 return hook;
836 /***********************************************************************
837 * HOOK_SetHook
839 * Install a given hook.
841 static HANDLE16 HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
842 HINSTANCE16 hInst, HTASK16 hTask )
844 HOOKDATA *data;
845 HANDLE16 handle;
846 HQUEUE16 hQueue = 0;
848 if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;
850 TRACE(hook, "Setting hook %d: %08x %04x %04x\n",
851 id, (UINT32)proc, hInst, hTask );
853 if (!hInst && (type!=HOOK_WIN16))
854 hInst = GetModuleHandle32A(NULL);/*FIXME: correct? probably not */
856 if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
858 if (hTask) /* Task-specific hook */
860 if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
861 (id == WH_SYSMSGFILTER)) return 0; /* System-only hooks */
862 if (!(hQueue = GetTaskQueue( hTask ))) return 0;
865 /* Create the hook structure */
867 if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
868 data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
869 data->proc = proc;
870 data->id = id;
871 data->ownerQueue = hQueue;
872 data->ownerModule = hInst;
873 data->flags = type;
875 /* Insert it in the correct linked list */
877 if (hQueue)
879 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
880 data->next = queue->hooks[id - WH_MINHOOK];
881 queue->hooks[id - WH_MINHOOK] = handle;
883 else
885 data->next = HOOK_systemHooks[id - WH_MINHOOK];
886 HOOK_systemHooks[id - WH_MINHOOK] = handle;
888 TRACE(hook, "Setting hook %d: ret=%04x [next=%04x]\n",
889 id, handle, data->next );
890 return handle;
894 /***********************************************************************
895 * HOOK_RemoveHook
897 * Remove a hook from the list.
899 static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
901 HOOKDATA *data;
902 HANDLE16 *prevHook;
904 TRACE(hook, "Removing hook %04x\n", hook );
906 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
907 if (data->flags & HOOK_INUSE)
909 /* Mark it for deletion later on */
910 WARN(hook, "Hook still running, deletion delayed\n" );
911 data->proc = (HOOKPROC32)0;
912 return TRUE;
915 if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput(TRUE);
917 /* Remove it from the linked list */
919 if (data->ownerQueue)
921 MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
922 if (!queue) return FALSE;
923 prevHook = &queue->hooks[data->id - WH_MINHOOK];
925 else prevHook = &HOOK_systemHooks[data->id - WH_MINHOOK];
927 while (*prevHook && *prevHook != hook)
928 prevHook = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHook))->next;
930 if (!*prevHook) return FALSE;
931 *prevHook = data->next;
932 USER_HEAP_FREE( hook );
933 return TRUE;
937 /***********************************************************************
938 * HOOK_FindValidHook
940 static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
942 HOOKDATA *data;
944 for (;;)
946 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
947 if (data->proc) return hook;
948 hook = data->next;
953 /***********************************************************************
954 * HOOK_CallHook
956 * Call a hook procedure.
958 static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
959 WPARAM32 wParam, LPARAM lParam )
961 MESSAGEQUEUE *queue;
962 HANDLE16 prevHook;
963 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
964 LRESULT ret;
966 WPARAM32 wParamOrig = wParam;
967 LPARAM lParamOrig = lParam;
968 HOOK_MapFunc MapFunc;
969 HOOK_UnMapFunc UnMapFunc;
971 MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
972 UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
974 if (MapFunc)
975 MapFunc( data->id, code, &wParam, &lParam );
977 /* Now call it */
979 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
980 prevHook = queue->hCurHook;
981 queue->hCurHook = hook;
982 data->flags |= HOOK_INUSE;
984 TRACE(hook, "Calling hook %04x: %d %08x %08lx\n",
985 hook, code, wParam, lParam );
987 ret = data->proc(code, wParam, lParam);
989 TRACE(hook, "Ret hook %04x = %08lx\n", hook, ret );
991 data->flags &= ~HOOK_INUSE;
992 queue->hCurHook = prevHook;
994 if (UnMapFunc)
995 UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
997 if (!data->proc) HOOK_RemoveHook( hook );
999 return ret;
1002 /***********************************************************************
1003 * Exported Functions & APIs
1006 /***********************************************************************
1007 * HOOK_GetProc16
1009 * Don't call this unless you are the if1632/thunk.c.
1011 HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
1013 HOOKDATA *data;
1014 if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
1015 if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
1016 if ((data->flags & HOOK_MAPTYPE) != HOOK_WIN16) return NULL;
1017 return (HOOKPROC16)data->proc;
1021 /***********************************************************************
1022 * HOOK_IsHooked
1024 * Replacement for calling HOOK_GetHook from other modules.
1026 BOOL32 HOOK_IsHooked( INT16 id )
1028 return HOOK_GetHook( id, GetTaskQueue(0) ) != 0;
1032 /***********************************************************************
1033 * HOOK_CallHooks16
1035 * Call a hook chain.
1037 LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
1038 LPARAM lParam )
1040 HANDLE16 hook;
1042 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1043 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1044 return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
1047 /***********************************************************************
1048 * HOOK_CallHooks32A
1050 * Call a hook chain.
1052 LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
1053 LPARAM lParam )
1055 HANDLE16 hook;
1057 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1058 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1059 return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
1062 /***********************************************************************
1063 * HOOK_CallHooks32W
1065 * Call a hook chain.
1067 LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
1068 LPARAM lParam )
1070 HANDLE16 hook;
1072 if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
1073 if (!(hook = HOOK_FindValidHook(hook))) return 0;
1074 return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
1075 lParam );
1079 /***********************************************************************
1080 * HOOK_ResetQueueHooks
1082 void HOOK_ResetQueueHooks( HQUEUE16 hQueue )
1084 MESSAGEQUEUE *queue;
1086 if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
1088 HOOKDATA* data;
1089 HHOOK hook;
1090 int id;
1091 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1093 hook = queue->hooks[id - WH_MINHOOK];
1094 while( hook )
1096 if( (data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1098 data->ownerQueue = hQueue;
1099 hook = data->next;
1100 } else break;
1106 /***********************************************************************
1107 * HOOK_FreeModuleHooks
1109 void HOOK_FreeModuleHooks( HMODULE16 hModule )
1111 /* remove all system hooks registered by this module */
1113 HOOKDATA* hptr;
1114 HHOOK hook, next;
1115 int id;
1117 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1119 hook = HOOK_systemHooks[id - WH_MINHOOK];
1120 while( hook )
1121 if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
1123 next = hptr->next;
1124 if( hptr->ownerModule == hModule )
1126 hptr->flags &= HOOK_MAPTYPE;
1127 HOOK_RemoveHook(hook);
1129 hook = next;
1131 else hook = 0;
1135 /***********************************************************************
1136 * HOOK_FreeQueueHooks
1138 void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
1140 /* remove all hooks registered by this queue */
1142 HOOKDATA* hptr = NULL;
1143 HHOOK hook, next;
1144 int id;
1146 for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
1148 hook = HOOK_GetHook( id, hQueue );
1149 while( hook )
1151 next = HOOK_GetNextHook(hook);
1153 hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1154 if( hptr && hptr->ownerQueue == hQueue )
1156 hptr->flags &= HOOK_MAPTYPE;
1157 HOOK_RemoveHook(hook);
1159 hook = next;
1165 /***********************************************************************
1166 * SetWindowsHook16 (USER.121)
1168 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
1170 HANDLE16 handle;
1171 HINSTANCE16 hInst = FarGetOwner( HIWORD(proc) );
1173 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1174 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1176 if (id == WH_DEBUG)
1178 FIXME(hook, "WH_DEBUG is broken in 16-bit Windows.\n");
1179 return 0;
1182 handle = HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), hTask );
1183 return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
1187 /***********************************************************************
1188 * SetWindowsHook32A (USER32.525)
1190 * FIXME: I don't know if this is correct
1192 HHOOK WINAPI SetWindowsHook32A( INT32 id, HOOKPROC32 proc )
1194 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1195 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1197 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, 0, hTask );
1198 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1202 /***********************************************************************
1203 * SetWindowsHook32W (USER32.528)
1205 * FIXME: I don't know if this is correct
1207 HHOOK WINAPI SetWindowsHook32W( INT32 id, HOOKPROC32 proc )
1209 /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
1210 HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
1212 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, 0, hTask );
1213 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
1217 /***********************************************************************
1218 * SetWindowsHookEx16 (USER.291)
1220 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
1221 HTASK16 hTask )
1223 HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), hTask );
1224 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1228 /***********************************************************************
1229 * SetWindowsHookEx32A (USER32.526)
1231 HHOOK WINAPI SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1232 DWORD dwThreadID )
1234 HANDLE16 handle;
1235 HTASK16 hTask;
1237 if (dwThreadID == GetCurrentThreadId())
1238 hTask = GetCurrentTask();
1239 else
1240 hTask = LOWORD(dwThreadID); /* FIXME! */
1242 handle = HOOK_SetHook( id, proc, HOOK_WIN32A, hInst, hTask );
1243 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1247 /***********************************************************************
1248 * SetWindowsHookEx32W (USER32.527)
1250 HHOOK WINAPI SetWindowsHookEx32W( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
1251 DWORD dwThreadID )
1253 HANDLE16 handle;
1254 HTASK16 hTask;
1256 if (dwThreadID == GetCurrentThreadId())
1257 hTask = GetCurrentTask();
1258 else
1259 hTask = LOWORD(dwThreadID); /* FIXME! */
1261 handle = HOOK_SetHook( id, proc, HOOK_WIN32W, hInst, hTask );
1262 return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
1266 /***********************************************************************
1267 * UnhookWindowsHook16 (USER.234)
1269 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
1271 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1273 TRACE(hook, "%d %08lx\n", id, (DWORD)proc );
1275 while (hook)
1277 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1278 if (data->proc == (HOOKPROC32)proc) break;
1279 hook = HOOK_GetNextHook( hook );
1281 if (!hook) return FALSE;
1282 return HOOK_RemoveHook( hook );
1286 /***********************************************************************
1287 * UnhookWindowsHook32 (USER32.557)
1289 BOOL32 WINAPI UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
1291 HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
1293 TRACE(hook, "%d %08lx\n", id, (DWORD)proc );
1295 while (hook)
1297 HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
1298 if (data->proc == proc) break;
1299 hook = HOOK_GetNextHook( hook );
1301 if (!hook) return FALSE;
1302 return HOOK_RemoveHook( hook );
1306 /***********************************************************************
1307 * UnhookWindowHookEx16 (USER.292)
1309 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
1311 if (HIWORD(hhook) != HOOK_MAGIC) return FALSE; /* Not a new format hook */
1312 return HOOK_RemoveHook( LOWORD(hhook) );
1316 /***********************************************************************
1317 * UnhookWindowHookEx32 (USER32.558)
1319 BOOL32 WINAPI UnhookWindowsHookEx32( HHOOK hhook )
1321 return UnhookWindowsHookEx16( hhook );
1325 /***********************************************************************
1326 * CallNextHookEx16 (USER.293)
1328 * I wouldn't have separated this into 16 and 32 bit versions, but I
1329 * need a way to figure out if I need to do a mapping or not.
1331 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
1332 LPARAM lParam )
1334 HANDLE16 next;
1336 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1337 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1339 return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
1343 /***********************************************************************
1344 * CallNextHookEx32 (USER32.17)
1346 * There aren't ANSI and UNICODE versions of this.
1348 LRESULT WINAPI CallNextHookEx32( HHOOK hhook, INT32 code, WPARAM32 wParam,
1349 LPARAM lParam )
1351 HANDLE16 next;
1352 INT32 fromtype; /* figure out Ansi/Unicode */
1353 HOOKDATA *oldhook;
1355 if (HIWORD(hhook) != HOOK_MAGIC) return 0; /* Not a new format hook */
1356 if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
1358 oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
1359 fromtype = oldhook->flags & HOOK_MAPTYPE;
1361 if (fromtype == HOOK_WIN16)
1362 ERR(hook, "called from 16bit hook!\n");
1364 return HOOK_CallHook( next, fromtype, code, wParam, lParam );
1368 /***********************************************************************
1369 * DefHookProc16 (USER.235)
1371 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
1372 HHOOK *hhook )
1374 /* Note: the *hhook parameter is never used, since we rely on the
1375 * current hook value from the task queue to find the next hook. */
1376 MESSAGEQUEUE *queue;
1378 if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
1379 return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
1383 /***********************************************************************
1384 * CallMsgFilter16 (USER.123)
1386 BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
1388 if (GetSysModalWindow16()) return FALSE;
1389 if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
1390 return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
1394 /***********************************************************************
1395 * CallMsgFilter32A (USER32.15)
1398 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
1399 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
1401 BOOL32 WINAPI CallMsgFilter32A( LPMSG32 msg, INT32 code )
1403 if (GetSysModalWindow16()) return FALSE; /* ??? */
1404 if (HOOK_CallHooks32A( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1405 return TRUE;
1406 return HOOK_CallHooks32A( WH_MSGFILTER, code, 0, (LPARAM)msg );
1410 /***********************************************************************
1411 * CallMsgFilter32W (USER32.16)
1413 BOOL32 WINAPI CallMsgFilter32W( LPMSG32 msg, INT32 code )
1415 if (GetSysModalWindow16()) return FALSE; /* ??? */
1416 if (HOOK_CallHooks32W( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
1417 return TRUE;
1418 return HOOK_CallHooks32W( WH_MSGFILTER, code, 0, (LPARAM)msg );