/*
 * Windows hook functions
 *
 * Copyright 1994, 1995 Alexandre Julliard
 *
 * Based on investigations by Alex Korobka
 */

/*
 * 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.
 */

#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
#include "hook.h"
#include "callback.h"
#include "queue.h"
#include "user.h"
#include "stddebug.h"
#include "debug.h"

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


/***********************************************************************
 *           HOOK_GetNextHook
 *
 * Get the next hook of a given hook.
 */
static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
{
    HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
    if (!data || !hook) return 0;
    if (data->next) return data->next;
    if (!data->ownerQueue) return 0;  /* Already system hook */
    /* Now start enumerating the system hooks */
    return HOOK_systemHooks[data->id - WH_FIRST_HOOK];
}


/***********************************************************************
 *           HOOK_GetHook
 *
 * Get the first hook for a given type.
 */
HANDLE16 HOOK_GetHook( INT16 id , HQUEUE16 hQueue )
{
    MESSAGEQUEUE *queue;
    HANDLE16 hook = 0;

    if ((queue = (MESSAGEQUEUE *)GlobalLock16( hQueue )) != NULL)
        hook = queue->hooks[id - WH_FIRST_HOOK];
    if (!hook) hook = HOOK_systemHooks[id - WH_FIRST_HOOK];
    return hook;
}


/***********************************************************************
 *           HOOK_SetHook
 *
 * Install a given hook.
 */
static HANDLE16 HOOK_SetHook( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
                              HTASK16 hTask )
{
    HOOKDATA *data;
    HANDLE16 handle;
    HQUEUE16 hQueue = 0;

    if ((id < WH_FIRST_HOOK) || (id > WH_LAST_HOOK)) return 0;
    if (!(hInst = GetExePtr( hInst ))) return 0;

    dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
                  id, (UINT32)proc, hInst, hTask );

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

    if (id == WH_CBT || id == WH_DEBUG || id == WH_SHELL)
    {
	fprintf( stdnimp, "Unimplemented hook set: (%d,%08lx,%04x,%04x)!\n",
                 id, (DWORD)proc, hInst, hTask );
    }

    /* 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 = hInst;
    data->inHookProc  = 0;
    dprintf_hook( stddeb, "Setting hook %d: ret=%04x\n", id, handle );

    /* Insert it in the correct linked list */

    if (hQueue)
    {
        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
        data->next = queue->hooks[id - WH_FIRST_HOOK];
        queue->hooks[id - WH_FIRST_HOOK] = handle;
    }
    else
    {
        data->next = HOOK_systemHooks[id - WH_FIRST_HOOK];
        HOOK_systemHooks[id - WH_FIRST_HOOK] = handle;
    }
    return handle;
}


/***********************************************************************
 *           HOOK_RemoveHook
 *
 * Remove a hook from the list.
 */
static BOOL32 HOOK_RemoveHook( HANDLE16 hook )
{
    HOOKDATA *data;
    HANDLE16 *prevHook;

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

    if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return FALSE;
    if (data->inHookProc)
    {
        /* Mark it for deletion later on */
        dprintf_hook( stddeb, "Hook still running, deletion delayed\n" );
        data->proc = (HOOKPROC16)0;
        return TRUE;
    }

    /* Remove it from the linked list */

    if (data->ownerQueue)
    {
        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( data->ownerQueue );
        if (!queue) return FALSE;
        prevHook = &queue->hooks[data->id - WH_FIRST_HOOK];
    }
    else prevHook = &HOOK_systemHooks[data->id - WH_FIRST_HOOK];

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

     if (!*prevHook) return FALSE;
    *prevHook = data->next;
    USER_HEAP_FREE( hook );
    return TRUE;
}


/***********************************************************************
 *           HOOK_CallHook
 *
 * Call a hook procedure.
 */
static LRESULT HOOK_CallHook( HANDLE16 hook, INT16 code,
                              WPARAM16 wParam, LPARAM lParam )
{
    HOOKDATA *data;
    MESSAGEQUEUE *queue;
    HANDLE16 prevHook;
    LRESULT ret;

    /* Find the first hook with a valid proc */

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

    /* Now call it */

    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
    prevHook = queue->hCurHook;
    queue->hCurHook = hook;
    data->inHookProc = 1;

    dprintf_hook( stddeb, "Calling hook %04x: %d %04lx %08lx\n",
                  hook, code, (DWORD)wParam, lParam );
    ret = CallHookProc( data->proc, code, wParam, lParam );
    dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );

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


/***********************************************************************
 *           HOOK_CallHooks
 *
 * Call a hook chain.
 */
LRESULT HOOK_CallHooks( INT16 id, INT16 code, WPARAM16 wParam, LPARAM lParam )
{
    HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
    if (!hook) return 0;
    return HOOK_CallHook( hook, code, wParam, lParam );
}


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

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

  for( id = WH_FIRST_HOOK; id <= WH_LAST_HOOK; id++ )
    {
       hook = HOOK_systemHooks[id - WH_FIRST_HOOK];
       while( hook )
          if( (hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook)) )
	    {
	      next = hptr->next;
	      if( hptr->ownerModule == hModule )
                {
                  hptr->inHookProc = 0;
                  HOOK_RemoveHook(hook);
                }
	      hook = next;
	    }
	  else hook = 0;
    }
}

/***********************************************************************
 *	     HOOK_FreeQueueHooks
 */
void HOOK_FreeQueueHooks( HQUEUE16 hQueue )
{
  /* remove all hooks registered by this queue */

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

  for( id = WH_FIRST_HOOK; id <= WH_LAST_HOOK; id++ )
    {
       hook = HOOK_GetHook( id, hQueue );
       while( hook )
	{
	  next = HOOK_GetNextHook(hook);

	  hptr = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
	  if( hptr && hptr->ownerQueue == hQueue )
	    {
	      hptr->inHookProc = 0;
	      HOOK_RemoveHook(hook);
	    }
	  hook = next;
	}
    }
}

/***********************************************************************
 *           SetWindowsHook   (USER.121)
 */
FARPROC16 SetWindowsHook( INT16 id, HOOKPROC16 proc )
{
    HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;

    HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
    if (!handle) return (FARPROC16)-1;
    if (!((HOOKDATA *)USER_HEAP_LIN_ADDR( handle ))->next) return 0;
    /* Not sure if the return value is correct; should not matter much
     * since it's never used (see DefHookProc). -- AJ */
    return (FARPROC16)MAKELONG( handle, HOOK_MAGIC );
}


/***********************************************************************
 *           UnhookWindowsHook   (USER.234)
 */
BOOL16 UnhookWindowsHook( INT16 id, HOOKPROC16 proc )
{
    HANDLE16 hook = HOOK_GetHook( id , 0 );

    dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );

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


/***********************************************************************
 *           DefHookProc   (USER.235)
 */
LRESULT DefHookProc( 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;
    HANDLE16 next;

    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
    if (!(next = HOOK_GetNextHook( queue->hCurHook ))) return 0;
    return HOOK_CallHook( next, code, wParam, lParam );
}


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


/***********************************************************************
 *           SetWindowsHookEx   (USER.291)
 */
HHOOK SetWindowsHookEx( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
                        HTASK16 hTask )
{
    HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
    return MAKELONG( handle, HOOK_MAGIC );
}


/***********************************************************************
 *           UnhookWindowHookEx   (USER.292)
 */
BOOL16 UnhookWindowsHookEx( HHOOK hhook )
{
    if (HIWORD(hhook) != HOOK_MAGIC) return FALSE;  /* Not a new format hook */
    return HOOK_RemoveHook( LOWORD(hhook) );
}


/***********************************************************************
 *           CallNextHookEx   (USER.293)
 */
LRESULT CallNextHookEx(HHOOK hhook, INT16 code, WPARAM16 wParam, LPARAM lParam)
{
    HANDLE16 next;
    if (HIWORD(hhook) != HOOK_MAGIC) return 0;  /* Not a new format hook */
    if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
    return HOOK_CallHook( next, code, wParam, lParam );
}
