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