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