/*
 * Windows hook functions
 *
 * Copyright 1994, 1995 Alexandre Julliard
 *                 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
 */

/*
 * Warning!
 * A HHOOK is a 32-bit handle for compatibility with Windows 3.0 where it was
 * a pointer to the next function. Now it is in fact composed of a USER heap
 * handle in the low 16 bits and of a HOOK_MAGIC value in the high 16 bits.
 */

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/winuser16.h"
#include "wine/winbase16.h"
#include "hook.h"
#include "win.h"
#include "queue.h"
#include "user.h"
#include "heap.h"
#include "struct32.h"
#include "winproc.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(hook);

#include "pshpack1.h"

  /* Hook data (pointed to by a HHOOK) */
typedef struct
{
    HANDLE16   next;               /* 00 Next hook in chain */
    HOOKPROC   proc;               /* 02 Hook procedure (original) */
    INT16      id;                 /* 06 Hook id (WH_xxx) */
    HQUEUE16   ownerQueue;         /* 08 Owner queue (0 for system hook) */
    HMODULE16  ownerModule;        /* 0a Owner module */
    WORD       flags;              /* 0c flags */
} HOOKDATA;

#include "poppack.h"

#define HOOK_MAGIC  ((int)'H' | (int)'K' << 8)  /* 'HK' */
#define HHOOK_32(h) ((HHOOK)(h ? MAKELONG(h, HOOK_MAGIC) : 0))
#define HHOOK_16(h) ((HANDLE16)((HIWORD(h) == HOOK_MAGIC) ? LOWORD(h) : 0))

  /* This should probably reside in USER heap */
static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };

/* ### start build ### */
extern LONG CALLBACK HOOK_CallTo16_long_wwl(HOOKPROC16,WORD,WORD,LONG);
/* ### stop build ### */


/***********************************************************************
 *           call_hook_16
 */
inline static LRESULT call_hook_16( HOOKPROC16 proc, INT id, INT code, WPARAM wparam, LPARAM lparam )
{
    LRESULT ret = HOOK_CallTo16_long_wwl( proc, code, wparam, lparam );
    /* 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_hook_16_to_32
 *
 * Convert hook params to 32-bit and call 32-bit hook procedure
 */
static LRESULT call_hook_16_to_32( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam,
                                   BOOL unicode )
{
    LRESULT ret = 0;

    switch( id )
    {
    case WH_MSGFILTER:
    case WH_SYSMSGFILTER:
    case WH_JOURNALRECORD:
    {
        MSG16 *msg16 = MapSL(lparam);
        MSG msg32;

        STRUCT32_MSG16to32( msg16, &msg32 );
        ret = proc( code, wparam, (LPARAM)&msg32 );
        break;
    }

    case WH_GETMESSAGE:
    {
        MSG16 *msg16 = MapSL(lparam);
        MSG msg32;

        STRUCT32_MSG16to32( msg16, &msg32 );
        ret = proc( code, wparam, (LPARAM)&msg32 );
        STRUCT32_MSG32to16( &msg32, msg16 );
        break;
    }

    case WH_JOURNALPLAYBACK:
    {
        EVENTMSG16 *em16 = MapSL(lparam);
        EVENTMSG em32;

        em32.message = em16->message;
        em32.paramL  = em16->paramL;
        em32.paramH  = em16->paramH;
        em32.time    = em16->time;
        em32.hwnd    = 0;  /* FIXME */
        ret = proc( code, wparam, (LPARAM)&em32 );
        break;
    }

    case WH_CALLWNDPROC:
    {
        CWPSTRUCT16 *cwp16 = MapSL(lparam);
        CWPSTRUCT cwp32;

        cwp32.hwnd   = WIN_Handle32(cwp16->hwnd);
        cwp32.lParam = cwp16->lParam;

        if (unicode)
            WINPROC_MapMsg16To32W( cwp32.hwnd, cwp16->message, cwp16->wParam,
                                   &cwp32.message, &cwp32.wParam, &cwp32.lParam );
        else
            WINPROC_MapMsg16To32A( cwp32.hwnd, cwp16->message, cwp16->wParam,
                                   &cwp32.message, &cwp32.wParam, &cwp32.lParam );

        ret = proc( code, wparam, (LPARAM)&cwp32 );

        if (unicode)
            WINPROC_UnmapMsg16To32W( cwp32.hwnd, cwp32.message, cwp32.wParam, cwp32.lParam, 0 );
        else
            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 );
                STRUCT32_CREATESTRUCT16to32A( cs16, &cs32 );

                if (unicode)
                {
                    cs32.lpszName = (LPSTR)map_str_16_to_32W( cs16->lpszName );
                    cs32.lpszClass = (LPSTR)map_str_16_to_32W( cs16->lpszClass );
                    ret = proc( code, wparam, (LPARAM)&cbtcw32 );
                    unmap_str_16_to_32W( (LPWSTR)cs32.lpszName );
                    unmap_str_16_to_32W( (LPWSTR)cs32.lpszClass );
                }
                else
                {
                    cs32.lpszName = MapSL( cs16->lpszName );
                    cs32.lpszClass = MapSL( cs16->lpszClass );
                    ret = proc( 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 = proc( 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 = proc( code, wparam, (LPARAM)&ms32 );
                break;
            }
        case HCBT_MOVESIZE:
            {
                RECT16 *rect16 = MapSL(lparam);
                RECT rect32;

                CONV_RECT16TO32( rect16, &rect32 );
                ret = proc( 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 = proc( code, wparam, (LPARAM)&ms32 );
        break;
    }

    case WH_DEBUG:
    {
        DEBUGHOOKINFO16 *dh16 = MapSL(lparam);
        DEBUGHOOKINFO dh32;

        dh32.idThread = 0;            /* FIXME */
        dh32.idThreadInstaller = 0;   /* FIXME */
        dh32.lParam = dh16->lParam;   /* FIXME Check for sign ext */
        dh32.wParam = dh16->wParam;
        dh32.code   = dh16->code;

        /* do sign extension if it was WH_MSGFILTER */
        if (wparam == 0xffff) wparam = WH_MSGFILTER;
        ret = proc( code, wparam, (LPARAM)&dh32 );
        break;
    }

    case WH_SHELL:
    case WH_KEYBOARD:
        ret = proc( code, wparam, lparam );
        break;

    case WH_HARDWARE:
    case WH_FOREGROUNDIDLE:
    case WH_CALLWNDPROCRET:
    default:
        FIXME("\t[%i] 16to32 translation unimplemented\n", id);
        ret = proc( code, wparam, lparam );
        break;
    }
    return ret;
}


/***********************************************************************
 *           call_hook_32_to_16
 *
 * Convert hook params to 16-bit and call 16-bit hook procedure
 */
static LRESULT call_hook_32_to_16( HOOKPROC16 proc, INT id, INT code, WPARAM wparam, LPARAM lparam,
                                   BOOL unicode )
{
    LRESULT ret = 0;

    switch (id)
    {
    case WH_MSGFILTER:
    case WH_SYSMSGFILTER:
    case WH_JOURNALRECORD:
    {
        MSG *msg32 = (MSG *)lparam;
        MSG16 msg16;

        STRUCT32_MSG32to16( msg32, &msg16 );
        lparam = MapLS( &msg16 );
        ret = call_hook_16( proc, id, code, wparam, lparam );
        UnMapLS( lparam );
        break;
    }

    case WH_GETMESSAGE:
    {
        MSG *msg32 = (MSG *)lparam;
        MSG16 msg16;

        STRUCT32_MSG32to16( msg32, &msg16 );
        lparam = MapLS( &msg16 );
        ret = call_hook_16( proc, id, code, wparam, lparam );
        UnMapLS( lparam );
        STRUCT32_MSG16to32( &msg16, msg32 );
        break;
    }

    case WH_JOURNALPLAYBACK:
    {
        EVENTMSG *em32 = (EVENTMSG *)lparam;
        EVENTMSG16 em16;

        em16.message = em32->message;
        em16.paramL  = em32->paramL;
        em16.paramH  = em32->paramH;
        em16.time    = em32->time;
        lparam = MapLS( &em16 );
        ret = call_hook_16( proc, id, code, wparam, lparam );
        UnMapLS( lparam );
        break;
    }

    case WH_CALLWNDPROC:
    {
        CWPSTRUCT *cwp32 = (CWPSTRUCT *)lparam;
        CWPSTRUCT16 cwp16;
        MSGPARAM16 mp16;

        cwp16.hwnd   = HWND_16(cwp32->hwnd);
        cwp16.lParam = cwp32->lParam;

        if (unicode)
            WINPROC_MapMsg32WTo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
                                   &cwp16.message, &cwp16.wParam, &cwp16.lParam );
        else
            WINPROC_MapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
                                   &cwp16.message, &cwp16.wParam, &cwp16.lParam );

        lparam = MapLS( &cwp16 );
        ret = call_hook_16( proc, id, code, wparam, lparam );
        UnMapLS( lparam );

        mp16.wParam  = cwp16.wParam;
        mp16.lParam  = cwp16.lParam;
        mp16.lResult = 0;
        if (unicode)
            WINPROC_UnmapMsg32WTo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
                                     cwp32->lParam, &mp16 );
        else
            WINPROC_UnmapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
                                     cwp32->lParam, &mp16 );
        break;
    }

    case WH_CBT:
        switch (code)
        {
        case HCBT_CREATEWND:
            {
                CBT_CREATEWNDA *cbtcw32 = (CBT_CREATEWNDA *)lparam;
                CBT_CREATEWND16 cbtcw16;
                CREATESTRUCT16 cs16;

                STRUCT32_CREATESTRUCT32Ato16( cbtcw32->lpcs, &cs16 );
                cbtcw16.lpcs = (CREATESTRUCT16 *)MapLS( &cs16 );
                cbtcw16.hwndInsertAfter = HWND_16( cbtcw32->hwndInsertAfter );
                lparam = MapLS( &cbtcw16 );

                if (unicode)
                {
                    cs16.lpszName = map_str_32W_to_16( (LPWSTR)cbtcw32->lpcs->lpszName );
                    cs16.lpszClass = map_str_32W_to_16( (LPWSTR)cbtcw32->lpcs->lpszClass );
                    ret = call_hook_16( proc, id, code, wparam, lparam );
                    unmap_str_32W_to_16( cs16.lpszName );
                    unmap_str_32W_to_16( cs16.lpszClass );
                }
                else
                {
                    cs16.lpszName = MapLS( cbtcw32->lpcs->lpszName );
                    cs16.lpszClass = MapLS( cbtcw32->lpcs->lpszClass );
                    ret = call_hook_16( proc, id, code, wparam, lparam );
                    UnMapLS( cs16.lpszName );
                    UnMapLS( cs16.lpszClass );
                }
                cbtcw32->hwndInsertAfter = WIN_Handle32( cbtcw16.hwndInsertAfter );
                UnMapLS( (SEGPTR)cbtcw16.lpcs );
                UnMapLS( lparam );
                break;
            }

        case HCBT_ACTIVATE:
            {
                CBTACTIVATESTRUCT *cas32 = (CBTACTIVATESTRUCT *)lparam;
                CBTACTIVATESTRUCT16 cas16;

                cas16.fMouse     = cas32->fMouse;
                cas16.hWndActive = HWND_16( cas32->hWndActive );

                lparam = MapLS( &cas16 );
                ret = call_hook_16( proc, id, code, wparam, lparam );
                UnMapLS( lparam );
                break;
            }
        case HCBT_CLICKSKIPPED:
            {
                MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lparam;
                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;

                lparam = MapLS( &ms16 );
                ret = call_hook_16( proc, id, code, wparam, lparam );
                UnMapLS( lparam );
                break;
            }
        case HCBT_MOVESIZE:
            {
                RECT *rect32 = (RECT *)lparam;
                RECT16 rect16;

                CONV_RECT32TO16( rect32, &rect16 );
                lparam = MapLS( &rect16 );
                ret = call_hook_16( proc, id, code, wparam, lparam );
                UnMapLS( lparam );
                break;
            }
        }
        break;

    case WH_MOUSE:
    {
        MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lparam;
        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;

        lparam = MapLS( &ms16 );
        ret = call_hook_16( proc, id, code, wparam, lparam );
        UnMapLS( lparam );
        break;
    }

    case WH_DEBUG:
    {
        DEBUGHOOKINFO *dh32 = (DEBUGHOOKINFO *)lparam;
        DEBUGHOOKINFO16 dh16;

        dh16.hModuleHook = 0; /* FIXME */
        dh16.reserved    = 0;
        dh16.lParam      = dh32->lParam;
        dh16.wParam      = dh32->wParam;
        dh16.code        = dh32->code;

        lparam = MapLS( &dh16 );
        ret = call_hook_16( proc, id, code, wparam, lparam );
        UnMapLS( lparam );
        break;
    }

    case WH_SHELL:
    case WH_KEYBOARD:
        ret = call_hook_16( proc, id, code, wparam, lparam );
        break;

    case WH_HARDWARE:
    case WH_FOREGROUNDIDLE:
    case WH_CALLWNDPROCRET:
    default:
        FIXME("\t[%i] 32to16 translation unimplemented\n", id);
        ret = call_hook_16( proc, id, code, wparam, lparam );
        break;
    }
    return ret;
}


/***********************************************************************
 *           call_hook_32_to_32
 *
 * Convert hook params to/from Unicode and call hook procedure
 */
static LRESULT call_hook_32_to_32( HOOKPROC proc, INT id, INT code, WPARAM wparam, LPARAM lparam,
                                   BOOL to_unicode )
{
    if (id != WH_CBT || code != HCBT_CREATEWND) return proc( code, wparam, lparam );

    if (to_unicode)  /* ASCII to Unicode */
    {
        CBT_CREATEWNDA *cbtcwA = (CBT_CREATEWNDA *)lparam;
        CBT_CREATEWNDW cbtcwW;
        CREATESTRUCTW csW;
        LRESULT ret;

        cbtcwW.lpcs = &csW;
        cbtcwW.hwndInsertAfter = cbtcwA->hwndInsertAfter;
        csW = *(CREATESTRUCTW *)cbtcwA->lpcs;

        if (HIWORD(cbtcwA->lpcs->lpszName))
            csW.lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0, cbtcwA->lpcs->lpszName );
        if (HIWORD(cbtcwA->lpcs->lpszClass))
            csW.lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0, cbtcwA->lpcs->lpszClass );
        ret = proc( code, wparam, (LPARAM)&cbtcwW );
        cbtcwA->hwndInsertAfter = cbtcwW.hwndInsertAfter;
        if (HIWORD(csW.lpszName)) HeapFree( GetProcessHeap(), 0, (LPWSTR)csW.lpszName );
        if (HIWORD(csW.lpszClass)) HeapFree( GetProcessHeap(), 0, (LPWSTR)csW.lpszClass );
        return ret;
    }
    else  /* Unicode to ASCII */
    {
        CBT_CREATEWNDW *cbtcwW = (CBT_CREATEWNDW *)lparam;
        CBT_CREATEWNDA cbtcwA;
        CREATESTRUCTA csA;
        LRESULT ret;

        cbtcwA.lpcs = &csA;
        cbtcwA.hwndInsertAfter = cbtcwW->hwndInsertAfter;
        csA = *(CREATESTRUCTA *)cbtcwW->lpcs;

        if (HIWORD(cbtcwW->lpcs->lpszName))
            csA.lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0, cbtcwW->lpcs->lpszName );
        if (HIWORD(cbtcwW->lpcs->lpszClass))
            csA.lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0, cbtcwW->lpcs->lpszClass );
        ret = proc( code, wparam, (LPARAM)&cbtcwA );
        cbtcwW->hwndInsertAfter = cbtcwA.hwndInsertAfter;
        if (HIWORD(csA.lpszName)) HeapFree( GetProcessHeap(), 0, (LPSTR)csA.lpszName );
        if (HIWORD(csA.lpszClass)) HeapFree( GetProcessHeap(), 0, (LPSTR)csA.lpszClass );
        return ret;
    }
}


/***********************************************************************
 *           call_hook
 *
 * Call a hook procedure.
 */
inline static LRESULT call_hook( HOOKDATA *data, INT fromtype, INT code,
                                 WPARAM wparam, LPARAM lparam )
{
    INT type = (data->flags & HOOK_MAPTYPE);
    LRESULT ret;

    /* Suspend window structure locks before calling user code */
    int iWndsLocks = WIN_SuspendWndsLock();

    if (type == HOOK_WIN16)
    {
        if (fromtype == HOOK_WIN16)  /* 16->16 */
            ret = call_hook_16( (HOOKPROC16)data->proc, data->id, code, wparam, lparam );
        else  /* 32->16 */
            ret = call_hook_32_to_16( (HOOKPROC16)data->proc, data->id, code, wparam,
                                      lparam, (type == HOOK_WIN32W) );
    }
    else if (fromtype == HOOK_WIN16)  /* 16->32 */
        ret = call_hook_16_to_32( data->proc, data->id, code, wparam,
                                  lparam, (type == HOOK_WIN32W) );
    else /* 32->32, check unicode */
    {
        if (type == fromtype)
            ret = data->proc( code, wparam, lparam );
        else
            ret = call_hook_32_to_32( data->proc, data->id, code, wparam,
                                      lparam, (type == HOOK_WIN32W) );
    }
    WIN_RestoreWndsLock(iWndsLocks);
    return ret;
}


/***********************************************************************
 *           HOOK_GetNextHook
 *
 * Get the next hook of a given hook.
 */
static HHOOK HOOK_GetNextHook( HHOOK hook )
{
    HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hook));

    if (!data || !hook) return 0;
    if (data->next) return HHOOK_32(data->next);
    if (!data->ownerQueue) return 0;  /* Already system hook */

    /* Now start enumerating the system hooks */
    return HHOOK_32(HOOK_systemHooks[data->id - WH_MINHOOK]);
}


/***********************************************************************
 *           HOOK_GetHook
 *
 * Get the first hook for a given type.
 */
static HHOOK HOOK_GetHook( INT16 id )
{
    MESSAGEQUEUE *queue;
    HANDLE16 handle = 0;

    if ((queue = QUEUE_Current()) != NULL)
        handle = queue->hooks[id - WH_MINHOOK];
    if (!handle) handle = HOOK_systemHooks[id - WH_MINHOOK];
    return HHOOK_32(handle);
}


/***********************************************************************
 *           HOOK_SetHook
 *
 * Install a given hook.
 */
static HHOOK HOOK_SetHook( INT16 id, LPVOID proc, INT type,
		           HMODULE16 hModule, DWORD dwThreadId )
{
    HOOKDATA *data;
    HANDLE16 handle;
    HQUEUE16 hQueue = 0;

    if ((id < WH_MINHOOK) || (id > WH_MAXHOOK)) return 0;

    TRACE("Setting hook %d: %08x %04x %08lx\n",
                  id, (UINT)proc, hModule, dwThreadId );

    /* Create task queue if none present */
    InitThreadInput16( 0, 0 );

    if (id == WH_JOURNALPLAYBACK) EnableHardwareInput16(FALSE);

    if (dwThreadId)  /* Task-specific hook */
    {
	if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
	    (id == WH_SYSMSGFILTER)) return 0;  /* System-only hooks */
        if (!(hQueue = GetThreadQueue16( dwThreadId )))
            return 0;
    }

    /* Create the hook structure */

    if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
    data = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
    data->proc        = proc;
    data->id          = id;
    data->ownerQueue  = hQueue;
    data->ownerModule = hModule;
    data->flags       = type;

    /* Insert it in the correct linked list */

    if (hQueue)
    {
        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
        data->next = queue->hooks[id - WH_MINHOOK];
        queue->hooks[id - WH_MINHOOK] = handle;
        QUEUE_Unlock( queue );
    }
    else
    {
        data->next = HOOK_systemHooks[id - WH_MINHOOK];
        HOOK_systemHooks[id - WH_MINHOOK] = handle;
    }
    TRACE("Setting hook %d: ret=%04x [next=%04x]\n",
			   id, handle, data->next );

    return HHOOK_32(handle);
}


/***********************************************************************
 *           HOOK_RemoveHook
 *
 * Remove a hook from the list.
 */
static BOOL HOOK_RemoveHook( HHOOK hook )
{
    HOOKDATA *data;
    HANDLE16 *prevHandle;

    TRACE("Removing hook %04x\n", hook );

    if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hook)))) return FALSE;
    if (data->flags & HOOK_INUSE)
    {
        /* Mark it for deletion later on */
        WARN("Hook still running, deletion delayed\n" );
        data->proc = (HOOKPROC)0;
        return TRUE;
    }

    if (data->id == WH_JOURNALPLAYBACK) EnableHardwareInput16(TRUE);

    /* Remove it from the linked list */

    if (data->ownerQueue)
    {
        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( data->ownerQueue );
        if (!queue) return FALSE;
        prevHandle = &queue->hooks[data->id - WH_MINHOOK];
        QUEUE_Unlock( queue );
    }
    else prevHandle = &HOOK_systemHooks[data->id - WH_MINHOOK];

    while (*prevHandle && *prevHandle != HHOOK_16(hook))
        prevHandle = &((HOOKDATA *)USER_HEAP_LIN_ADDR(*prevHandle))->next;

    if (!*prevHandle) return FALSE;
    *prevHandle = data->next;

    USER_HEAP_FREE(HHOOK_16(hook));
    return TRUE;
}


/***********************************************************************
 *           HOOK_FindValidHook
 */
static HHOOK HOOK_FindValidHook( HHOOK hook )
{
    HOOKDATA *data;

    for (;;)
    {
	if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hook)))) return 0;
	if (data->proc) return hook;
	hook = HHOOK_32(data->next);
    }
}

/***********************************************************************
 *           HOOK_CallHook
 *
 * Call a hook procedure.
 */
static LRESULT HOOK_CallHook( HHOOK hook, INT fromtype, INT code,
                              WPARAM wParam, LPARAM lParam )
{
    MESSAGEQUEUE *queue;
    HANDLE16 prevHandle;
    HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hook));
    LRESULT ret;

    if (!(queue = QUEUE_Current())) return 0;
    prevHandle = queue->hCurHook;
    queue->hCurHook = HHOOK_16(hook);

    TRACE("Calling hook %04x: %d %08x %08lx\n", hook, code, wParam, lParam );

    data->flags |= HOOK_INUSE;
    ret = call_hook( data, fromtype, code, wParam, lParam );
    data->flags &= ~HOOK_INUSE;

    TRACE("Ret hook %04x = %08lx\n", hook, ret );

    queue->hCurHook = prevHandle;
    if (!data->proc) HOOK_RemoveHook( hook );
    return ret;
}

/***********************************************************************
 *           Exported Functions & APIs
 */

/***********************************************************************
 *           HOOK_IsHooked
 *
 * Replacement for calling HOOK_GetHook from other modules.
 */
BOOL HOOK_IsHooked( INT16 id )
{
    return HOOK_GetHook( id ) != 0;
}


/***********************************************************************
 *           HOOK_CallHooks16
 *
 * Call a hook chain.
 */
LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
                          LPARAM lParam )
{
    HHOOK hook;

    if (!(hook = HOOK_GetHook( id ))) return 0;
    if (!(hook = HOOK_FindValidHook(hook))) return 0;
    return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
}

/***********************************************************************
 *           HOOK_CallHooksA
 *
 * Call a hook chain.
 */
LRESULT HOOK_CallHooksA( INT id, INT code, WPARAM wParam,
                           LPARAM lParam )
{
    HHOOK hook;

    if (!(hook = HOOK_GetHook( id ))) return 0;
    if (!(hook = HOOK_FindValidHook(hook))) return 0;
    return HOOK_CallHook( hook, HOOK_WIN32A, code, wParam, lParam );
}

/***********************************************************************
 *           HOOK_CallHooksW
 *
 * Call a hook chain.
 */
LRESULT HOOK_CallHooksW( INT id, INT code, WPARAM wParam,
                           LPARAM lParam )
{
    HHOOK hook;

    if (!(hook = HOOK_GetHook( id ))) return 0;
    if (!(hook = HOOK_FindValidHook(hook))) return 0;
    return HOOK_CallHook( hook, HOOK_WIN32W, code, wParam,
			  lParam );
}


/***********************************************************************
 *	     HOOK_FreeModuleHooks
 */
void HOOK_FreeModuleHooks( HMODULE16 hModule )
{
 /* remove all system hooks registered by this module */

  HOOKDATA*     hptr;
  HANDLE16      handle, next;
  int           id;

  for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
    {
       handle = HOOK_systemHooks[id - WH_MINHOOK];
       while( handle )
          if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(handle)) )
	    {
	      next = hptr->next;
	      if( hptr->ownerModule == hModule )
                {
                  hptr->flags &= HOOK_MAPTYPE;
                  HOOK_RemoveHook(HHOOK_32(handle));
                }
	      handle = next;
	    }
	  else handle = 0;
    }
}

/***********************************************************************
 *	     HOOK_FreeQueueHooks
 */
void HOOK_FreeQueueHooks(void)
{
  /* remove all hooks registered by the current queue */

  HOOKDATA*	hptr = NULL;
  HHOOK 	hook, next;
  int 		id;

  for( id = WH_MINHOOK; id <= WH_MAXHOOK; id++ )
    {
       hook = HOOK_GetHook( id );
       while( hook )
	{
	  next = HOOK_GetNextHook(hook);

	  hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hook));
	  if( hptr && hptr->ownerQueue )
	    {
	      hptr->flags &= HOOK_MAPTYPE;
	      HOOK_RemoveHook(hook);
	    }
	  hook = next;
	}
    }
}


/***********************************************************************
 *		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 );
}

/***********************************************************************
 *		SetWindowsHookA (USER32.@)
 */
HHOOK WINAPI SetWindowsHookA( INT id, HOOKPROC proc )
{
    return SetWindowsHookExA( id, proc, 0, GetCurrentThreadId() );
}

/***********************************************************************
 *		SetWindowsHookW (USER32.@)
 */
HHOOK WINAPI SetWindowsHookW( INT id, HOOKPROC proc )
{
    return SetWindowsHookExW( id, proc, 0, GetCurrentThreadId() );
}


/***********************************************************************
 *		SetWindowsHookEx (USER.291)
 */
HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
                                 HTASK16 hTask )
{
    if (id == WH_DEBUG)
    {
	FIXME("WH_DEBUG is broken in 16-bit Windows.\n");
	return 0;
    }
    return HOOK_SetHook( id, proc, HOOK_WIN16, GetExePtr(hInst), (DWORD)hTask );
}

/***********************************************************************
 *		SetWindowsHookExA (USER32.@)
 */
HHOOK WINAPI SetWindowsHookExA( INT id, HOOKPROC proc, HINSTANCE hInst,
                                  DWORD dwThreadId )
{
    return HOOK_SetHook( id, proc, HOOK_WIN32A, MapHModuleLS(hInst), dwThreadId );
}

/***********************************************************************
 *		SetWindowsHookExW (USER32.@)
 */
HHOOK WINAPI SetWindowsHookExW( INT id, HOOKPROC proc, HINSTANCE hInst,
                                  DWORD dwThreadId )
{
    return HOOK_SetHook( id, proc, HOOK_WIN32W, MapHModuleLS(hInst), dwThreadId );
}


/***********************************************************************
 *		UnhookWindowsHook (USER.234)
 */
BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
{
    return UnhookWindowsHook( id, (HOOKPROC)proc );
}

/***********************************************************************
 *		UnhookWindowsHook (USER32.@)
 */
BOOL WINAPI UnhookWindowsHook( INT id, HOOKPROC proc )
{
    HHOOK hook = HOOK_GetHook( id );

    TRACE("%d %08lx\n", id, (DWORD)proc );

    while (hook)
    {
        HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hook));
        if (data->proc == proc) break;
        hook = HOOK_GetNextHook( hook );
    }
    if (!hook) return FALSE;
    return HOOK_RemoveHook( hook );
}


/***********************************************************************
 *		UnhookWindowsHookEx (USER.292)
 */
BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
{
    return HOOK_RemoveHook(hhook);
}

/***********************************************************************
 *		UnhookWindowsHookEx (USER32.@)
 */
BOOL WINAPI UnhookWindowsHookEx( HHOOK hhook )
{
    return HOOK_RemoveHook(hhook);
}


/***********************************************************************
 *		CallNextHookEx (USER.293)
 *
 * I wouldn't have separated this into 16 and 32 bit versions, but I
 * need a way to figure out if I need to do a mapping or not.
 */
LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
                                 LPARAM lParam )
{
    HHOOK next;

    if (!(next = HOOK_GetNextHook(hhook))) return 0;

    return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
}


/***********************************************************************
 *		CallNextHookEx (USER32.@)
 *
 * There aren't ANSI and UNICODE versions of this.
 */
LRESULT WINAPI CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam,
                                 LPARAM lParam )
{
    HHOOK next;
    INT fromtype;	/* figure out Ansi/Unicode */
    HOOKDATA *oldhook;

    if (!(next = HOOK_GetNextHook(hhook))) return 0;

    oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR(HHOOK_16(hhook));
    fromtype = oldhook->flags & HOOK_MAPTYPE;

    if (fromtype == HOOK_WIN16)
      ERR("called from 16bit hook!\n");

    return HOOK_CallHook( next, fromtype, code, wParam, lParam );
}


/***********************************************************************
 *		DefHookProc (USER.235)
 */
LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
                              HHOOK *hhook )
{
    /* Note: the *hhook parameter is never used, since we rely on the
     * current hook value from the task queue to find the next hook. */
    MESSAGEQUEUE *queue;

    if (!(queue = QUEUE_Current())) return 0;
    return CallNextHookEx16(HHOOK_32(queue->hCurHook), code, wParam, lParam);
}


/***********************************************************************
 *		CallMsgFilter (USER.123)
 */
BOOL16 WINAPI CallMsgFilter16( SEGPTR msg, INT16 code )
{
    if (GetSysModalWindow16()) return FALSE;
    if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
    return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
}


/***********************************************************************
 *		CallMsgFilter32 (USER.823)
 */
BOOL16 WINAPI CallMsgFilter32_16( SEGPTR msg16_32, INT16 code, BOOL16 wHaveParamHigh )
{
    MSG32_16 *lpmsg16_32 = MapSL(msg16_32);

    if (wHaveParamHigh == FALSE)
    {
        lpmsg16_32->wParamHigh = 0;
        /* WARNING: msg16_32->msg has to be the first variable in the struct */
        return CallMsgFilter16(msg16_32, code);
    }
    else
    {
        MSG msg32;
        BOOL16 ret;

        msg32.hwnd      = WIN_Handle32( lpmsg16_32->msg.hwnd );
        msg32.message   = lpmsg16_32->msg.message;
        msg32.wParam    = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
        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;

        ret = (BOOL16)CallMsgFilterA(&msg32, (INT)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;
        lpmsg16_32->wParamHigh  = HIWORD(msg32.wParam);

        return ret;
    }
}


/***********************************************************************
 *		CallMsgFilterA (USER32.@)
 *
 * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
 * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
 */
BOOL WINAPI CallMsgFilterA( LPMSG msg, INT code )
{
    if (GetSysModalWindow16()) return FALSE;	/* ??? */
    if (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
      return TRUE;
    return HOOK_CallHooksA( WH_MSGFILTER, code, 0, (LPARAM)msg );
}


/***********************************************************************
 *		CallMsgFilterW (USER32.@)
 */
BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code )
{
    if (GetSysModalWindow16()) return FALSE;	/* ??? */
    if (HOOK_CallHooksW( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
      return TRUE;
    return HOOK_CallHooksW( WH_MSGFILTER, code, 0, (LPARAM)msg );
}


/***********************************************************************
 *           SetWinEventHook                            [USER32.@]
 *
 * Set up an event hook for a set of events.
 *
 * PARAMS
 *  dwMin     [I] Lowest event handled by pfnProc
 *  dwMax     [I] Highest event handled by pfnProc
 *  hModule   [I] DLL containing pfnProc
 *  pfnProc   [I] Callback event hook function
 *  dwProcess [I] Process to get events from, or 0 for all processes
 *  dwThread  [I] Thread to get events from, or 0 for all threads
 *  dwFlags   [I] Flags indicating the status of pfnProc
 *
 * RETURNS
 *  Success: A handle representing the hook.
 *  Failure: A NULL handle.
 *
 * BUGS
 *  Not implemented.
 */
HWINEVENTHOOK WINAPI SetWinEventHook(DWORD dwMin, DWORD dwMax, HMODULE hModule,
                                     WINEVENTPROC pfnProc, DWORD dwProcess,
                                     DWORD dwThread, DWORD dwFlags)
{
  FIXME("(%ld,%ld,0x%08x,%p,%ld,%ld,0x%08lx)-stub!\n", dwMin, dwMax, hModule,
        pfnProc, dwProcess, dwThread, dwFlags);

  return (HWINEVENTHOOK)0;
}

/***********************************************************************
 *           UnhookWinEvent                             [USER32.@]
 *
 * Remove an event hook for a set of events.
 *
 * PARAMS
 *  hEventHook [I] Event hook to remove
 *
 * RETURNS
 *  Success: TRUE. The event hook has been removed.
 *  Failure: FALSE, if hEventHook is invalid.
 *
 * BUGS
 *  Not implemented.
 */
BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK hEventHook)
{
  FIXME("(%p)-stub!\n", (void*)hEventHook);

  if (!hEventHook)
    return FALSE;

  return TRUE;
}

/***********************************************************************
 *           NotifyWinEvent                             [USER32.@]
 *
 * Inform the OS that an event has occurred.
 *
 * PARAMS
 *  dwEvent  [I] Id of the event
 *  hWnd     [I] Window holding the object that created the event
 *  nId      [I] Type of object that created the event
 *  nChildId [I] Child object of nId, or CHILDID_SELF.
 *
 * RETURNS
 *  Nothing.
 *
 * BUGS
 *  Not implemented.
 */
VOID WINAPI NotifyWinEvent(DWORD dwEvent, HWND hWnd, LONG nId, LONG nChildId)
{
  FIXME("(%ld,0x%08x,%ld,%ld)-stub!\n", dwEvent, hWnd, nId, nChildId);
}

/***********************************************************************
 *           IsWinEventHookInstalled                       [USER32.@]
 *
 * Determine if an event hook is installed for an event.
 *
 * PARAMS
 *  dwEvent  [I] Id of the event
 *
 * RETURNS
 *  TRUE,  If there are any hooks installed for the event.
 *  FALSE, Otherwise.
 *
 * BUGS
 *  Not implemented.
 */
BOOL WINAPI IsWinEventHookInstalled(DWORD dwEvent)
{
  FIXME("(%ld)-stub!\n", dwEvent);
  return TRUE;
}
