Replaced most uses of the auto-generated glue code by explicit calls
[wine] / dlls / user / hook16.c
1 /*
2  * Windows 16-bit hook functions
3  *
4  * Copyright 1994, 1995, 2002 Alexandre Julliard
5  * Copyright 1996 Andrew Lewycky
6  *
7  * Based on investigations by Alex Korobka
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "wownt32.h"
28 #include "wine/winuser16.h"
29 #include "message.h"
30 #include "win.h"
31 #include "winproc.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(hook);
35
36
37 static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp );
38 static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp );
39 static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp );
40 static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp );
41 static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp );
42 static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp );
43 static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp );
44
45 #define WH_MAXHOOK16 WH_SHELL  /* Win16 only supports up to WH_SHELL */
46 #define NB_HOOKS16 (WH_MAXHOOK16 - WH_MINHOOK + 1)
47
48 static const HOOKPROC hook_procs[NB_HOOKS16] =
49 {
50     call_WH_MSGFILTER,   /* WH_MSGFILTER        */
51     NULL,                /* WH_JOURNALRECORD */
52     NULL,                /* WH_JOURNALPLAYBACK */
53     call_WH_KEYBOARD,    /* WH_KEYBOARD */
54     call_WH_GETMESSAGE,  /* WH_GETMESSAGE */
55     call_WH_CALLWNDPROC, /* WH_CALLWNDPROC */
56     call_WH_CBT,         /* WH_CBT */
57     NULL,                /* WH_SYSMSGFILTER */
58     call_WH_MOUSE,       /* WH_MOUSE */
59     NULL,                /* WH_HARDWARE */
60     NULL,                /* WH_DEBUG */
61     call_WH_SHELL        /* WH_SHELL */
62 };
63
64
65 /* this structure is stored in the thread queue */
66 struct hook16_queue_info
67 {
68     INT        id;                /* id of current hook */
69     HHOOK      hook[NB_HOOKS16];  /* Win32 hook handles */
70     HOOKPROC16 proc[NB_HOOKS16];  /* 16-bit hook procedures */
71 };
72
73
74
75 /***********************************************************************
76  *           map_msg_16_to_32
77  */
78 inline static void map_msg_16_to_32( const MSG16 *msg16, MSG *msg32 )
79 {
80     msg32->hwnd    = WIN_Handle32(msg16->hwnd);
81     msg32->message = msg16->message;
82     msg32->wParam  = msg16->wParam;
83     msg32->lParam  = msg16->lParam;
84     msg32->time    = msg16->time;
85     msg32->pt.x    = msg16->pt.x;
86     msg32->pt.y    = msg16->pt.y;
87 }
88
89
90 /***********************************************************************
91  *           map_msg_32_to_16
92  */
93 inline static void map_msg_32_to_16( const MSG *msg32, MSG16 *msg16 )
94 {
95     msg16->hwnd    = HWND_16(msg32->hwnd);
96     msg16->message = msg32->message;
97     msg16->wParam  = msg32->wParam;
98     msg16->lParam  = msg32->lParam;
99     msg16->time    = msg32->time;
100     msg16->pt.x    = msg32->pt.x;
101     msg16->pt.y    = msg32->pt.y;
102 }
103
104
105 /***********************************************************************
106  *           call_hook_16
107  */
108 static LRESULT call_hook_16( INT id, INT code, WPARAM wp, LPARAM lp )
109 {
110     struct hook16_queue_info *info = QUEUE_Current()->hook16_info;
111     WORD args[4];
112     LRESULT ret;
113     INT prev_id = info->id;
114     info->id = id;
115
116     args[3] = code;
117     args[2] = wp;
118     args[1] = HIWORD(lp);
119     args[0] = LOWORD(lp);
120     WOWCallback16Ex( (DWORD)info->proc[id - WH_MINHOOK], WCB16_PASCAL, sizeof(args), args, &ret );
121
122     info->id = prev_id;
123
124     /* Grrr. While the hook procedure is supposed to have an LRESULT return
125        value even in Win16, it seems that for those hook types where the
126        return value is interpreted as BOOL, Windows doesn't actually check
127        the HIWORD ...  Some buggy Win16 programs, notably WINFILE, rely on
128        that, because they neglect to clear DX ... */
129     if (id != WH_JOURNALPLAYBACK) ret = LOWORD( ret );
130     return ret;
131 }
132
133
134 /***********************************************************************
135  *              call_WH_MSGFILTER
136  */
137 static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp )
138 {
139     MSG *msg32 = (MSG *)lp;
140     MSG16 msg16;
141     LRESULT ret;
142
143     map_msg_32_to_16( msg32, &msg16 );
144     lp = MapLS( &msg16 );
145     ret = call_hook_16( WH_MSGFILTER, code, wp, lp );
146     UnMapLS( lp );
147     return ret;
148 }
149
150
151 /***********************************************************************
152  *              call_WH_KEYBOARD
153  */
154 static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp )
155 {
156     return call_hook_16( WH_KEYBOARD, code, wp, lp );
157 }
158
159
160 /***********************************************************************
161  *              call_WH_GETMESSAGE
162  */
163 static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp )
164 {
165     MSG *msg32 = (MSG *)lp;
166     MSG16 msg16;
167     LRESULT ret;
168
169     map_msg_32_to_16( msg32, &msg16 );
170
171     lp = MapLS( &msg16 );
172     ret = call_hook_16( WH_GETMESSAGE, code, wp, lp );
173     UnMapLS( lp );
174
175     map_msg_16_to_32( &msg16, msg32 );
176     return ret;
177 }
178
179
180 /***********************************************************************
181  *              call_WH_CALLWNDPROC
182  */
183 static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp )
184 {
185     CWPSTRUCT *cwp32 = (CWPSTRUCT *)lp;
186     CWPSTRUCT16 cwp16;
187     MSGPARAM16 mp16;
188     LRESULT ret;
189
190     cwp16.hwnd   = HWND_16(cwp32->hwnd);
191     cwp16.lParam = cwp32->lParam;
192
193     WINPROC_MapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
194                            &cwp16.message, &cwp16.wParam, &cwp16.lParam );
195
196     lp = MapLS( &cwp16 );
197     ret = call_hook_16( WH_CALLWNDPROC, code, wp, lp );
198     UnMapLS( lp );
199
200     mp16.wParam  = cwp16.wParam;
201     mp16.lParam  = cwp16.lParam;
202     mp16.lResult = 0;
203     WINPROC_UnmapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam, cwp32->lParam, &mp16 );
204     return ret;
205 }
206
207
208 /***********************************************************************
209  *              call_WH_CBT
210  */
211 static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp )
212 {
213     LRESULT ret = 0;
214
215     switch (code)
216     {
217     case HCBT_CREATEWND:
218         {
219             CBT_CREATEWNDA *cbtcw32 = (CBT_CREATEWNDA *)lp;
220             CBT_CREATEWND16 cbtcw16;
221             CREATESTRUCT16 cs16;
222
223             cs16.lpCreateParams = cbtcw32->lpcs->lpCreateParams;
224             cs16.hInstance      = MapHModuleLS(cbtcw32->lpcs->hInstance);
225             cs16.hMenu          = HMENU_16(cbtcw32->lpcs->hMenu);
226             cs16.hwndParent     = HWND_16(cbtcw32->lpcs->hwndParent);
227             cs16.cy             = cbtcw32->lpcs->cy;
228             cs16.cx             = cbtcw32->lpcs->cx;
229             cs16.y              = cbtcw32->lpcs->y;
230             cs16.x              = cbtcw32->lpcs->x;
231             cs16.style          = cbtcw32->lpcs->style;
232             cs16.lpszName       = MapLS( cbtcw32->lpcs->lpszName );
233             cs16.lpszClass      = MapLS( cbtcw32->lpcs->lpszClass );
234             cs16.dwExStyle      = cbtcw32->lpcs->dwExStyle;
235
236             cbtcw16.lpcs = (CREATESTRUCT16 *)MapLS( &cs16 );
237             cbtcw16.hwndInsertAfter = HWND_16( cbtcw32->hwndInsertAfter );
238
239             lp = MapLS( &cbtcw16 );
240             ret = call_hook_16( WH_CBT, code, wp, lp );
241             UnMapLS( cs16.lpszName );
242             UnMapLS( cs16.lpszClass );
243
244             cbtcw32->hwndInsertAfter = WIN_Handle32( cbtcw16.hwndInsertAfter );
245             UnMapLS( (SEGPTR)cbtcw16.lpcs );
246             UnMapLS( lp );
247             break;
248         }
249
250     case HCBT_ACTIVATE:
251         {
252             CBTACTIVATESTRUCT *cas32 = (CBTACTIVATESTRUCT *)lp;
253             CBTACTIVATESTRUCT16 cas16;
254
255             cas16.fMouse     = cas32->fMouse;
256             cas16.hWndActive = HWND_16( cas32->hWndActive );
257
258             lp = MapLS( &cas16 );
259             ret = call_hook_16( WH_CBT, code, wp, lp );
260             UnMapLS( lp );
261             break;
262         }
263     case HCBT_CLICKSKIPPED:
264         {
265             MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
266             MOUSEHOOKSTRUCT16 ms16;
267
268             ms16.pt.x         = ms32->pt.x;
269             ms16.pt.y         = ms32->pt.y;
270             ms16.hwnd         = HWND_16( ms32->hwnd );
271             ms16.wHitTestCode = ms32->wHitTestCode;
272             ms16.dwExtraInfo  = ms32->dwExtraInfo;
273
274             lp = MapLS( &ms16 );
275             ret = call_hook_16( WH_CBT, code, wp, lp );
276             UnMapLS( lp );
277             break;
278         }
279     case HCBT_MOVESIZE:
280         {
281             RECT *rect32 = (RECT *)lp;
282             RECT16 rect16;
283
284             CONV_RECT32TO16( rect32, &rect16 );
285             lp = MapLS( &rect16 );
286             ret = call_hook_16( WH_CBT, code, wp, lp );
287             UnMapLS( lp );
288             break;
289         }
290     }
291     return ret;
292 }
293
294
295 /***********************************************************************
296  *              call_WH_MOUSE
297  */
298 static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp )
299 {
300     MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
301     MOUSEHOOKSTRUCT16 ms16;
302     LRESULT ret;
303
304     ms16.pt.x         = ms32->pt.x;
305     ms16.pt.y         = ms32->pt.y;
306     ms16.hwnd         = HWND_16( ms32->hwnd );
307     ms16.wHitTestCode = ms32->wHitTestCode;
308     ms16.dwExtraInfo  = ms32->dwExtraInfo;
309
310     lp = MapLS( &ms16 );
311     ret = call_hook_16( WH_MOUSE, code, wp, lp );
312     UnMapLS( lp );
313     return ret;
314 }
315
316
317 /***********************************************************************
318  *              call_WH_SHELL
319  */
320 static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp )
321 {
322     return call_hook_16( WH_SHELL, code, wp, lp );
323 }
324
325
326 /***********************************************************************
327  *              SetWindowsHook (USER.121)
328  */
329 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
330 {
331     HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
332
333     /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
334     HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
335
336     return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
337 }
338
339
340 /***********************************************************************
341  *              SetWindowsHookEx (USER.291)
342  */
343 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst, HTASK16 hTask )
344 {
345     MESSAGEQUEUE *queue = QUEUE_Current();
346     struct hook16_queue_info *info;
347     HHOOK hook;
348     int index = id - WH_MINHOOK;
349
350     if (!queue) return 0;
351     if (id < WH_MINHOOK || id > WH_MAXHOOK16) return 0;
352     if (!hook_procs[index])
353     {
354         FIXME( "hook type %d broken in Win16\n", id );
355         return 0;
356     }
357     if (!hTask) FIXME( "System-global hooks (%d) broken in Win16\n", id );
358     else if (hTask != GetCurrentTask())
359     {
360         FIXME( "setting hook (%d) on other task not supported\n", id );
361         return 0;
362     }
363
364     if (!(info = queue->hook16_info))
365     {
366         if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) ))) return 0;
367         queue->hook16_info = info;
368     }
369     if (info->hook[index])
370     {
371         FIXME( "Multiple hooks (%d) for the same task not supported yet\n", id );
372         return 0;
373     }
374     if (!(hook = SetWindowsHookExA( id, hook_procs[index], 0, GetCurrentThreadId() ))) return 0;
375     info->hook[index] = hook;
376     info->proc[index] = proc;
377     return hook;
378 }
379
380
381 /***********************************************************************
382  *              UnhookWindowsHook (USER.234)
383  */
384 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
385 {
386     MESSAGEQUEUE *queue = QUEUE_Current();
387     struct hook16_queue_info *info;
388     int index = id - WH_MINHOOK;
389
390     if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE;
391     if (!queue || !(info = queue->hook16_info)) return FALSE;
392     if (info->proc[index] != proc) return FALSE;
393     if (!UnhookWindowsHookEx( info->hook[index] )) return FALSE;
394     info->hook[index] = 0;
395     info->proc[index] = 0;
396     return TRUE;
397 }
398
399
400 /***********************************************************************
401  *              UnhookWindowsHookEx (USER.292)
402  */
403 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
404 {
405     MESSAGEQUEUE *queue = QUEUE_Current();
406     struct hook16_queue_info *info;
407     int index;
408
409     if (!queue || !(info = queue->hook16_info)) return FALSE;
410     for (index = 0; index < NB_HOOKS16; index++)
411     {
412         if (info->hook[index] == hhook)
413         {
414             info->hook[index] = 0;
415             info->proc[index] = 0;
416             return UnhookWindowsHookEx( hhook );
417         }
418     }
419     return FALSE;
420 }
421
422
423 /***********************************************************************
424  *              CallMsgFilter32 (USER.823)
425  */
426 BOOL16 WINAPI CallMsgFilter32_16( MSG32_16 *lpmsg16_32, INT16 code, BOOL16 wHaveParamHigh )
427 {
428     MSG msg32;
429     BOOL16 ret;
430
431     if (GetSysModalWindow16()) return FALSE;
432     msg32.hwnd      = WIN_Handle32( lpmsg16_32->msg.hwnd );
433     msg32.message   = lpmsg16_32->msg.message;
434     msg32.lParam    = lpmsg16_32->msg.lParam;
435     msg32.time      = lpmsg16_32->msg.time;
436     msg32.pt.x      = lpmsg16_32->msg.pt.x;
437     msg32.pt.y      = lpmsg16_32->msg.pt.y;
438     if (wHaveParamHigh) msg32.wParam = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
439     else msg32.wParam = lpmsg16_32->msg.wParam;
440
441     ret = (BOOL16)CallMsgFilterA(&msg32, code);
442
443     lpmsg16_32->msg.hwnd    = HWND_16( msg32.hwnd );
444     lpmsg16_32->msg.message = msg32.message;
445     lpmsg16_32->msg.wParam  = LOWORD(msg32.wParam);
446     lpmsg16_32->msg.lParam  = msg32.lParam;
447     lpmsg16_32->msg.time    = msg32.time;
448     lpmsg16_32->msg.pt.x    = msg32.pt.x;
449     lpmsg16_32->msg.pt.y    = msg32.pt.y;
450     if (wHaveParamHigh) lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
451     return ret;
452 }
453
454
455 /***********************************************************************
456  *              CallMsgFilter (USER.123)
457  */
458 BOOL16 WINAPI CallMsgFilter16( MSG16 *msg, INT16 code )
459 {
460     return CallMsgFilter32_16( (MSG32_16 *)msg, code, FALSE );
461 }
462
463
464 /***********************************************************************
465  *              CallNextHookEx (USER.293)
466  */
467 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wparam, LPARAM lparam )
468 {
469     MESSAGEQUEUE *queue = QUEUE_Current();
470     struct hook16_queue_info *info;
471     LRESULT ret = 0;
472
473     if (!queue || !(info = queue->hook16_info)) return 0;
474
475     switch (info->id)
476     {
477     case WH_MSGFILTER:
478     {
479         MSG16 *msg16 = MapSL(lparam);
480         MSG msg32;
481
482         map_msg_16_to_32( msg16, &msg32 );
483         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
484         break;
485     }
486
487     case WH_GETMESSAGE:
488     {
489         MSG16 *msg16 = MapSL(lparam);
490         MSG msg32;
491
492         map_msg_16_to_32( msg16, &msg32 );
493         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
494         map_msg_32_to_16( &msg32, msg16 );
495         break;
496     }
497
498     case WH_CALLWNDPROC:
499     {
500         CWPSTRUCT16 *cwp16 = MapSL(lparam);
501         CWPSTRUCT cwp32;
502
503         cwp32.hwnd   = WIN_Handle32(cwp16->hwnd);
504         cwp32.lParam = cwp16->lParam;
505
506         WINPROC_MapMsg16To32A( cwp32.hwnd, cwp16->message, cwp16->wParam,
507                                &cwp32.message, &cwp32.wParam, &cwp32.lParam );
508         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cwp32 );
509         WINPROC_UnmapMsg16To32A( cwp32.hwnd, cwp32.message, cwp32.wParam, cwp32.lParam, 0 );
510         break;
511     }
512
513     case WH_CBT:
514         switch (code)
515         {
516         case HCBT_CREATEWND:
517             {
518                 CBT_CREATEWNDA cbtcw32;
519                 CREATESTRUCTA cs32;
520                 CBT_CREATEWND16 *cbtcw16 = MapSL(lparam);
521                 CREATESTRUCT16 *cs16 = MapSL( (SEGPTR)cbtcw16->lpcs );
522
523                 cbtcw32.lpcs = &cs32;
524                 cbtcw32.hwndInsertAfter = WIN_Handle32( cbtcw16->hwndInsertAfter );
525
526                 cs32.lpCreateParams = cs16->lpCreateParams;
527                 cs32.hInstance      = MapHModuleSL(cs16->hInstance);
528                 cs32.hMenu          = HMENU_32(cs16->hMenu);
529                 cs32.hwndParent     = WIN_Handle32(cs16->hwndParent);
530                 cs32.cy             = cs16->cy;
531                 cs32.cx             = cs16->cx;
532                 cs32.y              = cs16->y;
533                 cs32.x              = cs16->x;
534                 cs32.style          = cs16->style;
535                 cs32.lpszName       = MapSL( cs16->lpszName );
536                 cs32.lpszClass      = MapSL( cs16->lpszClass );
537                 cs32.dwExStyle      = cs16->dwExStyle;
538
539                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cbtcw32 );
540                 cbtcw16->hwndInsertAfter = HWND_16( cbtcw32.hwndInsertAfter );
541                 break;
542             }
543         case HCBT_ACTIVATE:
544             {
545                 CBTACTIVATESTRUCT16 *cas16 = MapSL(lparam);
546                 CBTACTIVATESTRUCT cas32;
547                 cas32.fMouse = cas16->fMouse;
548                 cas32.hWndActive = WIN_Handle32(cas16->hWndActive);
549                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cas32 );
550                 break;
551             }
552         case HCBT_CLICKSKIPPED:
553             {
554                 MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
555                 MOUSEHOOKSTRUCT ms32;
556
557                 ms32.pt.x = ms16->pt.x;
558                 ms32.pt.y = ms16->pt.y;
559                 /* wHitTestCode may be negative, so convince compiler to do
560                    correct sign extension. Yay. :| */
561                 ms32.wHitTestCode = (INT)(INT16)ms16->wHitTestCode;
562                 ms32.dwExtraInfo = ms16->dwExtraInfo;
563                 ms32.hwnd = WIN_Handle32( ms16->hwnd );
564                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
565                 break;
566             }
567         case HCBT_MOVESIZE:
568             {
569                 RECT16 *rect16 = MapSL(lparam);
570                 RECT rect32;
571
572                 CONV_RECT16TO32( rect16, &rect32 );
573                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&rect32 );
574                 break;
575             }
576         }
577         break;
578
579     case WH_MOUSE:
580     {
581         MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
582         MOUSEHOOKSTRUCT ms32;
583
584         ms32.pt.x = ms16->pt.x;
585         ms32.pt.y = ms16->pt.y;
586         /* wHitTestCode may be negative, so convince compiler to do
587            correct sign extension. Yay. :| */
588         ms32.wHitTestCode = (INT)((INT16)ms16->wHitTestCode);
589         ms32.dwExtraInfo = ms16->dwExtraInfo;
590         ms32.hwnd = WIN_Handle32(ms16->hwnd);
591         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
592         break;
593     }
594
595     case WH_SHELL:
596     case WH_KEYBOARD:
597         ret = CallNextHookEx( hhook, code, wparam, lparam );
598         break;
599
600     case WH_HARDWARE:
601     case WH_FOREGROUNDIDLE:
602     case WH_CALLWNDPROCRET:
603     case WH_SYSMSGFILTER:
604     case WH_JOURNALRECORD:
605     case WH_JOURNALPLAYBACK:
606     default:
607         FIXME("\t[%i] 16to32 translation unimplemented\n", info->id);
608         ret = CallNextHookEx( hhook, code, wparam, lparam );
609         break;
610     }
611     return ret;
612 }
613
614
615 /***********************************************************************
616  *              DefHookProc (USER.235)
617  */
618 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wparam, LPARAM lparam, HHOOK *hhook )
619 {
620     return CallNextHookEx16( *hhook, code, wparam, lparam );
621 }