Rewrote hook support to store the hook chain in the server.
Split off 16-bit hook functions and re-implemented them on top of the
32-bit ones; system-wide 16-bit hooks are no longer supported at this
point.

diff --git a/dlls/user/hook16.c b/dlls/user/hook16.c
new file mode 100644
index 0000000..0b3a676
--- /dev/null
+++ b/dlls/user/hook16.c
@@ -0,0 +1,617 @@
+/*
+ * Windows 16-bit hook functions
+ *
+ * Copyright 1994, 1995, 2002 Alexandre Julliard
+ * Copyright 1996 Andrew Lewycky
+ *
+ * Based on investigations by Alex Korobka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wownt32.h"
+#include "wine/winuser16.h"
+#include "queue.h"
+#include "win.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(hook);
+
+
+static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp );
+static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp );
+static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp );
+static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp );
+static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp );
+static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp );
+static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp );
+
+#define WH_MAXHOOK16 WH_SHELL  /* Win16 only supports up to WH_SHELL */
+#define NB_HOOKS16 (WH_MAXHOOK16 - WH_MINHOOK + 1)
+
+static const HOOKPROC hook_procs[NB_HOOKS16] =
+{
+    call_WH_MSGFILTER,   /* WH_MSGFILTER	*/
+    NULL,                /* WH_JOURNALRECORD */
+    NULL,                /* WH_JOURNALPLAYBACK */
+    call_WH_KEYBOARD,    /* WH_KEYBOARD */
+    call_WH_GETMESSAGE,  /* WH_GETMESSAGE */
+    call_WH_CALLWNDPROC, /* WH_CALLWNDPROC */
+    call_WH_CBT,         /* WH_CBT */
+    NULL,                /* WH_SYSMSGFILTER */
+    call_WH_MOUSE,       /* WH_MOUSE */
+    NULL,                /* WH_HARDWARE */
+    NULL,                /* WH_DEBUG */
+    call_WH_SHELL        /* WH_SHELL */
+};
+
+
+/* this structure is stored in the thread queue */
+struct hook16_queue_info
+{
+    INT        id;                /* id of current hook */
+    HHOOK      hook[NB_HOOKS16];  /* Win32 hook handles */
+    HOOKPROC16 proc[NB_HOOKS16];  /* 16-bit hook procedures */
+};
+
+
+/* ### start build ### */
+extern LONG CALLBACK HOOK_CallTo16_long_wwl(HOOKPROC16,WORD,WORD,LONG);
+/* ### stop build ### */
+
+
+/***********************************************************************
+ *           map_msg_16_to_32
+ */
+inline static void map_msg_16_to_32( const MSG16 *msg16, MSG *msg32 )
+{
+    msg32->hwnd    = WIN_Handle32(msg16->hwnd);
+    msg32->message = msg16->message;
+    msg32->wParam  = msg16->wParam;
+    msg32->lParam  = msg16->lParam;
+    msg32->time    = msg16->time;
+    msg32->pt.x    = msg16->pt.x;
+    msg32->pt.y    = msg16->pt.y;
+}
+
+
+/***********************************************************************
+ *           map_msg_32_to_16
+ */
+inline static void map_msg_32_to_16( const MSG *msg32, MSG16 *msg16 )
+{
+    msg16->hwnd    = HWND_16(msg32->hwnd);
+    msg16->message = msg32->message;
+    msg16->wParam  = msg32->wParam;
+    msg16->lParam  = msg32->lParam;
+    msg16->time    = msg32->time;
+    msg16->pt.x    = msg32->pt.x;
+    msg16->pt.y    = msg32->pt.y;
+}
+
+
+/***********************************************************************
+ *           call_hook_16
+ */
+static LRESULT call_hook_16( INT id, INT code, WPARAM wp, LPARAM lp )
+{
+    struct hook16_queue_info *info = QUEUE_Current()->hook16_info;
+    LRESULT ret;
+    INT prev_id = info->id;
+    info->id = id;
+    ret = HOOK_CallTo16_long_wwl( info->proc[id - WH_MINHOOK], code, wp, lp );
+    info->id = prev_id;
+
+    /* Grrr. While the hook procedure is supposed to have an LRESULT return
+       value even in Win16, it seems that for those hook types where the
+       return value is interpreted as BOOL, Windows doesn't actually check
+       the HIWORD ...  Some buggy Win16 programs, notably WINFILE, rely on
+       that, because they neglect to clear DX ... */
+    if (id != WH_JOURNALPLAYBACK) ret = LOWORD( ret );
+    return ret;
+}
+
+
+/***********************************************************************
+ *		call_WH_MSGFILTER
+ */
+static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp )
+{
+    MSG *msg32 = (MSG *)lp;
+    MSG16 msg16;
+    LRESULT ret;
+
+    map_msg_32_to_16( msg32, &msg16 );
+    lp = MapLS( &msg16 );
+    ret = call_hook_16( WH_MSGFILTER, code, wp, lp );
+    UnMapLS( lp );
+    return ret;
+}
+
+
+/***********************************************************************
+ *		call_WH_KEYBOARD
+ */
+static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp )
+{
+    return call_hook_16( WH_KEYBOARD, code, wp, lp );
+}
+
+
+/***********************************************************************
+ *		call_WH_GETMESSAGE
+ */
+static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp )
+{
+    MSG *msg32 = (MSG *)lp;
+    MSG16 msg16;
+    LRESULT ret;
+
+    map_msg_32_to_16( msg32, &msg16 );
+
+    lp = MapLS( &msg16 );
+    ret = call_hook_16( WH_GETMESSAGE, code, wp, lp );
+    UnMapLS( lp );
+
+    map_msg_16_to_32( &msg16, msg32 );
+    return ret;
+}
+
+
+/***********************************************************************
+ *		call_WH_CALLWNDPROC
+ */
+static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp )
+{
+    CWPSTRUCT *cwp32 = (CWPSTRUCT *)lp;
+    CWPSTRUCT16 cwp16;
+    MSGPARAM16 mp16;
+    LRESULT ret;
+
+    cwp16.hwnd   = HWND_16(cwp32->hwnd);
+    cwp16.lParam = cwp32->lParam;
+
+    WINPROC_MapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
+                           &cwp16.message, &cwp16.wParam, &cwp16.lParam );
+
+    lp = MapLS( &cwp16 );
+    ret = call_hook_16( WH_CALLWNDPROC, code, wp, lp );
+    UnMapLS( lp );
+
+    mp16.wParam  = cwp16.wParam;
+    mp16.lParam  = cwp16.lParam;
+    mp16.lResult = 0;
+    WINPROC_UnmapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam, cwp32->lParam, &mp16 );
+    return ret;
+}
+
+
+/***********************************************************************
+ *		call_WH_CBT
+ */
+static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp )
+{
+    LRESULT ret = 0;
+
+    switch (code)
+    {
+    case HCBT_CREATEWND:
+        {
+            CBT_CREATEWNDA *cbtcw32 = (CBT_CREATEWNDA *)lp;
+            CBT_CREATEWND16 cbtcw16;
+            CREATESTRUCT16 cs16;
+
+            cs16.lpCreateParams = cbtcw32->lpcs->lpCreateParams;
+            cs16.hInstance      = MapHModuleLS(cbtcw32->lpcs->hInstance);
+            cs16.hMenu          = HMENU_16(cbtcw32->lpcs->hMenu);
+            cs16.hwndParent     = HWND_16(cbtcw32->lpcs->hwndParent);
+            cs16.cy             = cbtcw32->lpcs->cy;
+            cs16.cx             = cbtcw32->lpcs->cx;
+            cs16.y              = cbtcw32->lpcs->y;
+            cs16.x              = cbtcw32->lpcs->x;
+            cs16.style          = cbtcw32->lpcs->style;
+            cs16.lpszName       = MapLS( cbtcw32->lpcs->lpszName );
+            cs16.lpszClass      = MapLS( cbtcw32->lpcs->lpszClass );
+            cs16.dwExStyle      = cbtcw32->lpcs->dwExStyle;
+
+            cbtcw16.lpcs = (CREATESTRUCT16 *)MapLS( &cs16 );
+            cbtcw16.hwndInsertAfter = HWND_16( cbtcw32->hwndInsertAfter );
+
+            lp = MapLS( &cbtcw16 );
+            ret = call_hook_16( WH_CBT, code, wp, lp );
+            UnMapLS( cs16.lpszName );
+            UnMapLS( cs16.lpszClass );
+
+            cbtcw32->hwndInsertAfter = WIN_Handle32( cbtcw16.hwndInsertAfter );
+            UnMapLS( (SEGPTR)cbtcw16.lpcs );
+            UnMapLS( lp );
+            break;
+        }
+
+    case HCBT_ACTIVATE:
+        {
+            CBTACTIVATESTRUCT *cas32 = (CBTACTIVATESTRUCT *)lp;
+            CBTACTIVATESTRUCT16 cas16;
+
+            cas16.fMouse     = cas32->fMouse;
+            cas16.hWndActive = HWND_16( cas32->hWndActive );
+
+            lp = MapLS( &cas16 );
+            ret = call_hook_16( WH_CBT, code, wp, lp );
+            UnMapLS( lp );
+            break;
+        }
+    case HCBT_CLICKSKIPPED:
+        {
+            MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
+            MOUSEHOOKSTRUCT16 ms16;
+
+            ms16.pt.x         = ms32->pt.x;
+            ms16.pt.y         = ms32->pt.y;
+            ms16.hwnd         = HWND_16( ms32->hwnd );
+            ms16.wHitTestCode = ms32->wHitTestCode;
+            ms16.dwExtraInfo  = ms32->dwExtraInfo;
+
+            lp = MapLS( &ms16 );
+            ret = call_hook_16( WH_CBT, code, wp, lp );
+            UnMapLS( lp );
+            break;
+        }
+    case HCBT_MOVESIZE:
+        {
+            RECT *rect32 = (RECT *)lp;
+            RECT16 rect16;
+
+            CONV_RECT32TO16( rect32, &rect16 );
+            lp = MapLS( &rect16 );
+            ret = call_hook_16( WH_CBT, code, wp, lp );
+            UnMapLS( lp );
+            break;
+        }
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *		call_WH_MOUSE
+ */
+static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp )
+{
+    MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
+    MOUSEHOOKSTRUCT16 ms16;
+    LRESULT ret;
+
+    ms16.pt.x         = ms32->pt.x;
+    ms16.pt.y         = ms32->pt.y;
+    ms16.hwnd         = HWND_16( ms32->hwnd );
+    ms16.wHitTestCode = ms32->wHitTestCode;
+    ms16.dwExtraInfo  = ms32->dwExtraInfo;
+
+    lp = MapLS( &ms16 );
+    ret = call_hook_16( WH_MOUSE, code, wp, lp );
+    UnMapLS( lp );
+    return ret;
+}
+
+
+/***********************************************************************
+ *		call_WH_SHELL
+ */
+static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp )
+{
+    return call_hook_16( WH_SHELL, code, wp, lp );
+}
+
+
+/***********************************************************************
+ *		SetWindowsHook (USER.121)
+ */
+FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
+{
+    HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
+
+    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
+    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+
+    return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
+}
+
+
+/***********************************************************************
+ *		SetWindowsHookEx (USER.291)
+ */
+HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst, HTASK16 hTask )
+{
+    MESSAGEQUEUE *queue = QUEUE_Current();
+    struct hook16_queue_info *info;
+    HHOOK hook;
+    int index = id - WH_MINHOOK;
+
+    if (!queue) return 0;
+    if (id < WH_MINHOOK || id > WH_MAXHOOK16) return 0;
+    if (!hook_procs[index])
+    {
+        FIXME( "hook type %d broken in Win16\n", id );
+        return 0;
+    }
+    if (!hTask) FIXME( "System-global hooks (%d) broken in Win16\n", id );
+    else if (hTask != GetCurrentTask())
+    {
+        FIXME( "setting hook (%d) on other task not supported\n", id );
+        return 0;
+    }
+
+    if (!(info = queue->hook16_info))
+    {
+        if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) ))) return 0;
+        queue->hook16_info = info;
+    }
+    if (info->hook[index])
+    {
+        FIXME( "Multiple hooks (%d) for the same task not supported yet\n", id );
+        return 0;
+    }
+    if (!(hook = SetWindowsHookExA( id, hook_procs[index], 0, GetCurrentThreadId() ))) return 0;
+    info->hook[index] = hook;
+    info->proc[index] = proc;
+    return hook;
+}
+
+
+/***********************************************************************
+ *		UnhookWindowsHook (USER.234)
+ */
+BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
+{
+    MESSAGEQUEUE *queue = QUEUE_Current();
+    struct hook16_queue_info *info;
+    int index = id - WH_MINHOOK;
+
+    if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE;
+    if (!queue || !(info = queue->hook16_info)) return FALSE;
+    if (info->proc[index] != proc) return FALSE;
+    if (!UnhookWindowsHookEx( info->hook[index] )) return FALSE;
+    info->hook[index] = 0;
+    info->proc[index] = 0;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *		UnhookWindowsHookEx (USER.292)
+ */
+BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
+{
+    MESSAGEQUEUE *queue = QUEUE_Current();
+    struct hook16_queue_info *info;
+    int index;
+
+    if (!queue || !(info = queue->hook16_info)) return FALSE;
+    for (index = 0; index < NB_HOOKS16; index++)
+    {
+        if (info->hook[index] == hhook)
+        {
+            info->hook[index] = 0;
+            info->proc[index] = 0;
+            return UnhookWindowsHookEx( hhook );
+        }
+    }
+    return FALSE;
+}
+
+
+/***********************************************************************
+ *		CallMsgFilter32 (USER.823)
+ */
+BOOL16 WINAPI CallMsgFilter32_16( MSG32_16 *lpmsg16_32, INT16 code, BOOL16 wHaveParamHigh )
+{
+    MSG msg32;
+    BOOL16 ret;
+
+    if (GetSysModalWindow16()) return FALSE;
+    msg32.hwnd      = WIN_Handle32( lpmsg16_32->msg.hwnd );
+    msg32.message   = lpmsg16_32->msg.message;
+    msg32.lParam    = lpmsg16_32->msg.lParam;
+    msg32.time      = lpmsg16_32->msg.time;
+    msg32.pt.x      = lpmsg16_32->msg.pt.x;
+    msg32.pt.y      = lpmsg16_32->msg.pt.y;
+    if (wHaveParamHigh) msg32.wParam = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
+    else msg32.wParam = lpmsg16_32->msg.wParam;
+
+    ret = (BOOL16)CallMsgFilterA(&msg32, code);
+
+    lpmsg16_32->msg.hwnd    = HWND_16( msg32.hwnd );
+    lpmsg16_32->msg.message = msg32.message;
+    lpmsg16_32->msg.wParam  = LOWORD(msg32.wParam);
+    lpmsg16_32->msg.lParam  = msg32.lParam;
+    lpmsg16_32->msg.time    = msg32.time;
+    lpmsg16_32->msg.pt.x    = msg32.pt.x;
+    lpmsg16_32->msg.pt.y    = msg32.pt.y;
+    if (wHaveParamHigh) lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
+    return ret;
+}
+
+
+/***********************************************************************
+ *		CallMsgFilter (USER.123)
+ */
+BOOL16 WINAPI CallMsgFilter16( MSG16 *msg, INT16 code )
+{
+    return CallMsgFilter32_16( (MSG32_16 *)msg, code, FALSE );
+}
+
+
+/***********************************************************************
+ *		CallNextHookEx (USER.293)
+ */
+LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wparam, LPARAM lparam )
+{
+    MESSAGEQUEUE *queue = QUEUE_Current();
+    struct hook16_queue_info *info;
+    LRESULT ret = 0;
+
+    if (!queue || !(info = queue->hook16_info)) return 0;
+
+    switch (info->id)
+    {
+    case WH_MSGFILTER:
+    {
+        MSG16 *msg16 = MapSL(lparam);
+        MSG msg32;
+
+        map_msg_16_to_32( msg16, &msg32 );
+        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
+        break;
+    }
+
+    case WH_GETMESSAGE:
+    {
+        MSG16 *msg16 = MapSL(lparam);
+        MSG msg32;
+
+        map_msg_16_to_32( msg16, &msg32 );
+        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
+        map_msg_32_to_16( &msg32, msg16 );
+        break;
+    }
+
+    case WH_CALLWNDPROC:
+    {
+        CWPSTRUCT16 *cwp16 = MapSL(lparam);
+        CWPSTRUCT cwp32;
+
+        cwp32.hwnd   = WIN_Handle32(cwp16->hwnd);
+        cwp32.lParam = cwp16->lParam;
+
+        WINPROC_MapMsg16To32A( cwp32.hwnd, cwp16->message, cwp16->wParam,
+                               &cwp32.message, &cwp32.wParam, &cwp32.lParam );
+        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cwp32 );
+        WINPROC_UnmapMsg16To32A( cwp32.hwnd, cwp32.message, cwp32.wParam, cwp32.lParam, 0 );
+        break;
+    }
+
+    case WH_CBT:
+        switch (code)
+        {
+        case HCBT_CREATEWND:
+            {
+                CBT_CREATEWNDA cbtcw32;
+                CREATESTRUCTA cs32;
+                CBT_CREATEWND16 *cbtcw16 = MapSL(lparam);
+                CREATESTRUCT16 *cs16 = MapSL( (SEGPTR)cbtcw16->lpcs );
+
+                cbtcw32.lpcs = &cs32;
+                cbtcw32.hwndInsertAfter = WIN_Handle32( cbtcw16->hwndInsertAfter );
+
+                cs32.lpCreateParams = cs16->lpCreateParams;
+                cs32.hInstance      = MapHModuleSL(cs16->hInstance);
+                cs32.hMenu          = HMENU_32(cs16->hMenu);
+                cs32.hwndParent     = WIN_Handle32(cs16->hwndParent);
+                cs32.cy             = cs16->cy;
+                cs32.cx             = cs16->cx;
+                cs32.y              = cs16->y;
+                cs32.x              = cs16->x;
+                cs32.style          = cs16->style;
+                cs32.lpszName       = MapSL( cs16->lpszName );
+                cs32.lpszClass      = MapSL( cs16->lpszClass );
+                cs32.dwExStyle      = cs16->dwExStyle;
+
+                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cbtcw32 );
+                cbtcw16->hwndInsertAfter = HWND_16( cbtcw32.hwndInsertAfter );
+                break;
+            }
+        case HCBT_ACTIVATE:
+            {
+                CBTACTIVATESTRUCT16 *cas16 = MapSL(lparam);
+                CBTACTIVATESTRUCT cas32;
+                cas32.fMouse = cas16->fMouse;
+                cas32.hWndActive = WIN_Handle32(cas16->hWndActive);
+                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cas32 );
+                break;
+            }
+        case HCBT_CLICKSKIPPED:
+            {
+                MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
+                MOUSEHOOKSTRUCT ms32;
+
+                ms32.pt.x = ms16->pt.x;
+                ms32.pt.y = ms16->pt.y;
+                /* wHitTestCode may be negative, so convince compiler to do
+                   correct sign extension. Yay. :| */
+                ms32.wHitTestCode = (INT)(INT16)ms16->wHitTestCode;
+                ms32.dwExtraInfo = ms16->dwExtraInfo;
+                ms32.hwnd = WIN_Handle32( ms16->hwnd );
+                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
+                break;
+            }
+        case HCBT_MOVESIZE:
+            {
+                RECT16 *rect16 = MapSL(lparam);
+                RECT rect32;
+
+                CONV_RECT16TO32( rect16, &rect32 );
+                ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&rect32 );
+                break;
+            }
+        }
+        break;
+
+    case WH_MOUSE:
+    {
+        MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
+        MOUSEHOOKSTRUCT ms32;
+
+        ms32.pt.x = ms16->pt.x;
+        ms32.pt.y = ms16->pt.y;
+        /* wHitTestCode may be negative, so convince compiler to do
+           correct sign extension. Yay. :| */
+        ms32.wHitTestCode = (INT)((INT16)ms16->wHitTestCode);
+        ms32.dwExtraInfo = ms16->dwExtraInfo;
+        ms32.hwnd = WIN_Handle32(ms16->hwnd);
+        ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
+        break;
+    }
+
+    case WH_SHELL:
+    case WH_KEYBOARD:
+        ret = CallNextHookEx( hhook, code, wparam, lparam );
+        break;
+
+    case WH_HARDWARE:
+    case WH_FOREGROUNDIDLE:
+    case WH_CALLWNDPROCRET:
+    case WH_SYSMSGFILTER:
+    case WH_JOURNALRECORD:
+    case WH_JOURNALPLAYBACK:
+    default:
+        FIXME("\t[%i] 16to32 translation unimplemented\n", info->id);
+        ret = CallNextHookEx( hhook, code, wparam, lparam );
+        break;
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *		DefHookProc (USER.235)
+ */
+LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wparam, LPARAM lparam, HHOOK *hhook )
+{
+    return CallNextHookEx16( *hhook, code, wparam, lparam );
+}